mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2026-01-06 11:10:36 +01:00
* Patch from Mattias Gaertner:
jswriter:
fixed some empty lines
pasresolver:
procedure str, function str
fppas2js:
procedure str,function str
write less empty blocks
target platform browser and nodejs
git-svn-id: trunk@35633 -
This commit is contained in:
parent
a2d397c064
commit
44c5fe99c9
@ -127,7 +127,7 @@ Type
|
||||
// one per type of statement
|
||||
Procedure WriteValue(V : TJSValue); virtual;
|
||||
Procedure WriteRegularExpressionLiteral(El: TJSRegularExpressionLiteral);
|
||||
Procedure WriteVariableStatement(el: TJSVariableStatement);
|
||||
Procedure WriteVariableStatement(El: TJSVariableStatement);
|
||||
Procedure WriteEmptyBlockStatement(El: TJSEmptyBlockStatement); virtual;
|
||||
Procedure WriteEmptyStatement(El: TJSEmptyStatement);virtual;
|
||||
Procedure WriteLiteral(El: TJSLiteral);virtual;
|
||||
@ -157,6 +157,8 @@ Type
|
||||
Procedure WriteFuncDef(FD: TJSFuncDef);virtual;
|
||||
Procedure WritePrimaryExpression(El: TJSPrimaryExpression);virtual;
|
||||
Procedure WriteBinary(El: TJSBinary);virtual;
|
||||
Function IsEmptyStatement(El: TJSElement): boolean;
|
||||
Function HasLineEnding(El: TJSElement): boolean;
|
||||
Public
|
||||
Function EscapeString(const S: TJSString; Quote: TJSEscapeQuote = jseqDouble): TJSString;
|
||||
Constructor Create(AWriter : TTextWriter);
|
||||
@ -584,6 +586,7 @@ procedure TJSWriter.WriteFuncDef(FD: TJSFuncDef);
|
||||
Var
|
||||
C : Boolean;
|
||||
I : Integer;
|
||||
A: TJSElement;
|
||||
|
||||
begin
|
||||
C:=(woCompact in Options);
|
||||
@ -609,10 +612,11 @@ begin
|
||||
FSkipCurlyBrackets:=True;
|
||||
//writeln('TJSWriter.WriteFuncDef '+FD.Body.ClassName);
|
||||
WriteJS(FD.Body);
|
||||
If (Assigned(FD.Body.A))
|
||||
and (not (FD.Body.A is TJSStatementList))
|
||||
and (not (FD.Body.A is TJSSourceElements))
|
||||
and (not (FD.Body.A is TJSEmptyBlockStatement))
|
||||
A:=FD.Body.A;
|
||||
If (Assigned(A))
|
||||
and (not (A is TJSStatementList))
|
||||
and (not (A is TJSSourceElements))
|
||||
and (not (A is TJSEmptyBlockStatement))
|
||||
then
|
||||
if C then
|
||||
Write('; ')
|
||||
@ -861,7 +865,7 @@ begin
|
||||
Indent;
|
||||
if not C then writeln('');
|
||||
end;
|
||||
if Assigned(El.A) and (El.A.ClassType<>TJSEmptyBlockStatement) then
|
||||
if not IsEmptyStatement(El.A) then
|
||||
begin
|
||||
WriteJS(El.A);
|
||||
LastEl:=El.A;
|
||||
@ -926,6 +930,9 @@ Var
|
||||
S : AnsiString;
|
||||
AllowCompact, WithBrackets: Boolean;
|
||||
begin
|
||||
{$IFDEF VerboseJSWriter}
|
||||
System.writeln('TJSWriter.WriteBinary SkipRoundBrackets=',FSkipRoundBrackets);
|
||||
{$ENDIF}
|
||||
WithBrackets:=not FSkipRoundBrackets;
|
||||
if WithBrackets then
|
||||
Write('(');
|
||||
@ -945,6 +952,25 @@ begin
|
||||
Write(')');
|
||||
end;
|
||||
|
||||
function TJSWriter.IsEmptyStatement(El: TJSElement): boolean;
|
||||
begin
|
||||
if (El=nil) then
|
||||
exit(true);
|
||||
if (El.ClassType=TJSEmptyStatement) and not (woEmptyStatementAsComment in Options) then
|
||||
exit(true);
|
||||
Result:=false;
|
||||
end;
|
||||
|
||||
function TJSWriter.HasLineEnding(El: TJSElement): boolean;
|
||||
begin
|
||||
if El<>nil then
|
||||
begin
|
||||
if (El.ClassType=TJSStatementList) or (El.ClassType=TJSSourceElements) then
|
||||
exit(true);
|
||||
end;
|
||||
Result:=false;
|
||||
end;
|
||||
|
||||
procedure TJSWriter.WriteConditionalExpression(El: TJSConditionalExpression);
|
||||
|
||||
begin
|
||||
@ -987,22 +1013,29 @@ end;
|
||||
|
||||
procedure TJSWriter.WriteIfStatement(El: TJSIfStatement);
|
||||
|
||||
var
|
||||
BTrueEmpty, C: Boolean;
|
||||
begin
|
||||
C:=woCompact in Options;
|
||||
Write('if (');
|
||||
FSkipRoundBrackets:=true;
|
||||
WriteJS(El.Cond);
|
||||
FSkipRoundBrackets:=false;
|
||||
Write(')');
|
||||
If Not (woCompact in Options) then
|
||||
If Not C then
|
||||
Write(' ');
|
||||
if (El.BTrue<>nil) and (not (El.BTrue is TJSEmptyStatement)) then
|
||||
begin
|
||||
BTrueEmpty:=IsEmptyStatement(El.BTrue);
|
||||
if not BTrueEmpty then
|
||||
WriteJS(El.BTrue);
|
||||
end;
|
||||
if Assigned(El.BFalse) then
|
||||
if not IsEmptyStatement(El.BFalse) then
|
||||
begin
|
||||
if (El.BTrue=nil) or (El.BTrue is TJSEmptyStatement) then
|
||||
Writeln('{}')
|
||||
if BTrueEmpty then
|
||||
begin
|
||||
if C then
|
||||
Write('{}')
|
||||
else
|
||||
Writeln('{}');
|
||||
end
|
||||
else
|
||||
Write(' ');
|
||||
Write('else ');
|
||||
@ -1131,7 +1164,7 @@ begin
|
||||
Indent;
|
||||
WriteJS(EC.Body);
|
||||
Undent;
|
||||
if ((EC.Body is TJSStatementList) or (EC.Body is TJSEmptyBlockStatement)) then
|
||||
if (EC.Body is TJSStatementList) or (EC.Body is TJSEmptyBlockStatement) then
|
||||
begin
|
||||
if C then
|
||||
begin
|
||||
@ -1226,12 +1259,15 @@ Var
|
||||
begin
|
||||
C:=woCompact in Options;
|
||||
Write('try {');
|
||||
if Not C then writeln('');
|
||||
FSkipCurlyBrackets:=True;
|
||||
Indent;
|
||||
WriteJS(El.Block);
|
||||
if Not C then writeln('');
|
||||
Undent;
|
||||
if not IsEmptyStatement(El.Block) then
|
||||
begin
|
||||
if Not C then writeln('');
|
||||
FSkipCurlyBrackets:=True;
|
||||
Indent;
|
||||
WriteJS(El.Block);
|
||||
if (Not C) and (not (El.Block is TJSStatementList)) then writeln('');
|
||||
Undent;
|
||||
end;
|
||||
Write('}');
|
||||
If (El is TJSTryCatchFinallyStatement) or (El is TJSTryCatchStatement) then
|
||||
begin
|
||||
@ -1241,11 +1277,14 @@ begin
|
||||
Write(' {')
|
||||
else
|
||||
Writeln(' {');
|
||||
FSkipCurlyBrackets:=True;
|
||||
Indent;
|
||||
WriteJS(El.BCatch);
|
||||
Undent;
|
||||
if Not C then writeln('');
|
||||
if not IsEmptyStatement(El.BCatch) then
|
||||
begin
|
||||
FSkipCurlyBrackets:=True;
|
||||
Indent;
|
||||
WriteJS(El.BCatch);
|
||||
Undent;
|
||||
if (Not C) and (not (El.BCatch is TJSStatementList)) then writeln('');
|
||||
end;
|
||||
Write('}');
|
||||
end;
|
||||
If (El is TJSTryCatchFinallyStatement) or (El is TJSTryFinallyStatement) then
|
||||
@ -1254,11 +1293,14 @@ begin
|
||||
Write(' finally {')
|
||||
else
|
||||
Writeln(' finally {');
|
||||
Indent;
|
||||
FSkipCurlyBrackets:=True;
|
||||
WriteJS(El.BFinally);
|
||||
Undent;
|
||||
if Not C then writeln('');
|
||||
if not IsEmptyStatement(El.BFinally) then
|
||||
begin
|
||||
Indent;
|
||||
FSkipCurlyBrackets:=True;
|
||||
WriteJS(El.BFinally);
|
||||
Undent;
|
||||
if (Not C) and (not (El.BFinally is TJSStatementList)) then writeln('');
|
||||
end;
|
||||
Write('}');
|
||||
end;
|
||||
end;
|
||||
@ -1267,7 +1309,7 @@ procedure TJSWriter.WriteFunctionBody(El: TJSFunctionBody);
|
||||
|
||||
begin
|
||||
//writeln('TJSWriter.WriteFunctionBody '+El.A.ClassName+' FSkipBrackets='+BoolToStr(FSkipCurlyBrackets,'true','false'));
|
||||
if Assigned(El.A) and (not (El.A is TJSEmptyBlockStatement)) then
|
||||
if not IsEmptyStatement(El.A) then
|
||||
WriteJS(El.A);
|
||||
end;
|
||||
|
||||
@ -1311,11 +1353,11 @@ begin
|
||||
WriteElements(El.Statements);
|
||||
end;
|
||||
|
||||
procedure TJSWriter.WriteVariableStatement(el: TJSVariableStatement);
|
||||
procedure TJSWriter.WriteVariableStatement(El: TJSVariableStatement);
|
||||
|
||||
begin
|
||||
Write('var ');
|
||||
WriteJS(EL.A);
|
||||
WriteJS(El.A);
|
||||
end;
|
||||
|
||||
procedure TJSWriter.WriteJS(El: TJSElement);
|
||||
|
||||
@ -110,7 +110,7 @@ Works:
|
||||
- procedure break, procedure continue
|
||||
- built-in functions pred, succ for range type and enums
|
||||
- untyped parameters
|
||||
|
||||
- built-in procedure str(const boolean|integer|enumvalue|classinstance,var s: string)
|
||||
|
||||
ToDo:
|
||||
- fix slow lookup declaration proc in PParser
|
||||
@ -159,9 +159,9 @@ Notes:
|
||||
@f(); @ operator applies to result of f
|
||||
f(); use f's result
|
||||
FuncVar:=Func; if mode=objfpc: incompatible
|
||||
if mode=delphi: implicit addr of function f, not yet implemented
|
||||
if f=g then : can implicit resolve each side once, at the moment: always implicit
|
||||
p(f), f as var parameter: always implicit, thus incompatible
|
||||
if mode=delphi: implicit addr of function f
|
||||
if f=g then : can implicit resolve each side once
|
||||
p(f), f as var parameter: can implicit
|
||||
}
|
||||
unit PasResolver;
|
||||
|
||||
@ -430,7 +430,9 @@ type
|
||||
bfLow,
|
||||
bfHigh,
|
||||
bfPred,
|
||||
bfSucc
|
||||
bfSucc,
|
||||
bfStrProc,
|
||||
bfStrFunc
|
||||
);
|
||||
TResolverBuiltInProcs = set of TResolverBuiltInProc;
|
||||
const
|
||||
@ -450,7 +452,9 @@ const
|
||||
'Low',
|
||||
'High',
|
||||
'Pred',
|
||||
'Succ'
|
||||
'Succ',
|
||||
'Str',
|
||||
'Str'
|
||||
);
|
||||
bfAllStandardProcs = [Succ(bfCustom)..high(TResolverBuiltInProc)];
|
||||
|
||||
@ -1042,6 +1046,8 @@ type
|
||||
ErrorEl: TPasElement; RaiseOnError: boolean): boolean;
|
||||
procedure ConvertRangeToFirstValue(var ResolvedEl: TPasResolverResult);
|
||||
function IsCharLiteral(const Value: string): boolean; virtual;
|
||||
function CheckBuiltInMinParamCount(Proc: TResElDataBuiltInProc; Expr: TPasExpr;
|
||||
MinCount: integer; RaiseOnError: boolean): boolean;
|
||||
protected
|
||||
// built-in functions
|
||||
function BI_Length_OnGetCallCompatibility(Proc: TResElDataBuiltInProc;
|
||||
@ -1082,6 +1088,17 @@ type
|
||||
Expr: TPasExpr; RaiseOnError: boolean): integer; virtual;
|
||||
procedure BI_PredSucc_OnGetCallResult({%H-}Proc: TResElDataBuiltInProc;
|
||||
{%H-}Params: TParamsExpr; out ResolvedEl: TPasResolverResult); virtual;
|
||||
function BI_Str_CheckParam(Param: TPasExpr;
|
||||
const ParamResolved: TPasResolverResult; ArgNo: integer;
|
||||
RaiseOnError: boolean): integer;
|
||||
function BI_StrProc_OnGetCallCompatibility(Proc: TResElDataBuiltInProc;
|
||||
Expr: TPasExpr; RaiseOnError: boolean): integer; virtual;
|
||||
procedure BI_StrProc_OnFinishParamsExpr(Proc: TResElDataBuiltInProc;
|
||||
Params: TParamsExpr); virtual;
|
||||
function BI_StrFunc_OnGetCallCompatibility(Proc: TResElDataBuiltInProc;
|
||||
Expr: TPasExpr; RaiseOnError: boolean): integer; virtual;
|
||||
procedure BI_StrFunc_OnGetCallResult({%H-}Proc: TResElDataBuiltInProc;
|
||||
{%H-}Params: TParamsExpr; out ResolvedEl: TPasResolverResult); virtual;
|
||||
public
|
||||
constructor Create;
|
||||
destructor Destroy; override;
|
||||
@ -4168,6 +4185,9 @@ begin
|
||||
ComputeElement(Expr,ExprResolved,[rcSkipTypeAlias]);
|
||||
if (rrfCanBeStatement in ExprResolved.Flags) then
|
||||
exit;
|
||||
{$IFDEF VerbosePasResolver}
|
||||
writeln('TPasResolver.ResolveImplSimple El=',GetObjName(El),' El.Expr=',GetObjName(El.Expr),' ExprResolved=',GetResolverResultDesc(ExprResolved));
|
||||
{$ENDIF}
|
||||
RaiseMsg(20170216152127,nIllegalExpression,sIllegalExpression,[],El);
|
||||
end;
|
||||
|
||||
@ -4215,9 +4235,9 @@ begin
|
||||
Primitive:=TPrimitiveExpr(El);
|
||||
case Primitive.Kind of
|
||||
pekIdent: ResolveNameExpr(El,Primitive.Value,Access);
|
||||
pekNumber: exit;
|
||||
pekString: exit;
|
||||
pekNil,pekBoolConst: exit;
|
||||
pekNumber: ;
|
||||
pekString: ;
|
||||
pekNil,pekBoolConst: ;
|
||||
else
|
||||
RaiseNotYetImplemented(20160922163451,El);
|
||||
end;
|
||||
@ -4243,6 +4263,11 @@ begin
|
||||
end
|
||||
else
|
||||
RaiseNotYetImplemented(20170222184329,El);
|
||||
|
||||
if El.format1<>nil then
|
||||
ResolveExpr(El.format1,rraRead);
|
||||
if El.format2<>nil then
|
||||
ResolveExpr(El.format2,rraRead);
|
||||
end;
|
||||
|
||||
procedure TPasResolver.ResolveStatementConditionExpr(El: TPasExpr);
|
||||
@ -6077,6 +6102,19 @@ begin
|
||||
end;
|
||||
end;
|
||||
|
||||
function TPasResolver.CheckBuiltInMinParamCount(Proc: TResElDataBuiltInProc;
|
||||
Expr: TPasExpr; MinCount: integer; RaiseOnError: boolean): boolean;
|
||||
begin
|
||||
if (not (Expr is TParamsExpr)) or (length(TParamsExpr(Expr).Params)<MinCount) then
|
||||
begin
|
||||
if RaiseOnError then
|
||||
RaiseMsg(20170216152248,nWrongNumberOfParametersForCallTo,
|
||||
sWrongNumberOfParametersForCallTo,[Proc.Signature],Expr);
|
||||
exit(false);
|
||||
end;
|
||||
Result:=true;
|
||||
end;
|
||||
|
||||
function TPasResolver.BI_Length_OnGetCallCompatibility(
|
||||
Proc: TResElDataBuiltInProc; Expr: TPasExpr; RaiseOnError: boolean): integer;
|
||||
// check params of built in proc 'length'
|
||||
@ -6085,13 +6123,8 @@ var
|
||||
Param: TPasExpr;
|
||||
ParamResolved: TPasResolverResult;
|
||||
begin
|
||||
if (not (Expr is TParamsExpr)) or (length(TParamsExpr(Expr).Params)<1) then
|
||||
begin
|
||||
if RaiseOnError then
|
||||
RaiseMsg(20170216152248,nWrongNumberOfParametersForCallTo,
|
||||
sWrongNumberOfParametersForCallTo,[Proc.Signature],Expr);
|
||||
if not CheckBuiltInMinParamCount(Proc,Expr,1,RaiseOnError) then
|
||||
exit(cIncompatible);
|
||||
end;
|
||||
Params:=TParamsExpr(Expr);
|
||||
|
||||
// first param: string or dynamic array
|
||||
@ -6142,13 +6175,8 @@ var
|
||||
ParamResolved: TPasResolverResult;
|
||||
ArrayType: TPasArrayType;
|
||||
begin
|
||||
if (not (Expr is TParamsExpr)) or (length(TParamsExpr(Expr).Params)<2) then
|
||||
begin
|
||||
if RaiseOnError then
|
||||
RaiseMsg(20170216152253,nWrongNumberOfParametersForCallTo,
|
||||
sWrongNumberOfParametersForCallTo,[Proc.Signature],Expr);
|
||||
if not CheckBuiltInMinParamCount(Proc,Expr,2,RaiseOnError) then
|
||||
exit(cIncompatible);
|
||||
end;
|
||||
Params:=TParamsExpr(Expr);
|
||||
|
||||
// first param: string or array variable
|
||||
@ -6222,13 +6250,8 @@ var
|
||||
ParamResolved: TPasResolverResult;
|
||||
EnumType: TPasEnumType;
|
||||
begin
|
||||
if (not (Expr is TParamsExpr)) or (length(TParamsExpr(Expr).Params)<2) then
|
||||
begin
|
||||
if RaiseOnError then
|
||||
RaiseMsg(20170216152259,nWrongNumberOfParametersForCallTo,
|
||||
sWrongNumberOfParametersForCallTo,[Proc.Signature],Expr);
|
||||
if not CheckBuiltInMinParamCount(Proc,Expr,2,RaiseOnError) then
|
||||
exit(cIncompatible);
|
||||
end;
|
||||
Params:=TParamsExpr(Expr);
|
||||
|
||||
// first param: variable of set of enumtype
|
||||
@ -6412,13 +6435,8 @@ var
|
||||
Param: TPasExpr;
|
||||
ParamResolved, IncrResolved: TPasResolverResult;
|
||||
begin
|
||||
if (not (Expr is TParamsExpr)) or (length(TParamsExpr(Expr).Params)<1) then
|
||||
begin
|
||||
if RaiseOnError then
|
||||
RaiseMsg(20170216152318,nWrongNumberOfParametersForCallTo,
|
||||
sWrongNumberOfParametersForCallTo,[Proc.Signature],Expr);
|
||||
if not CheckBuiltInMinParamCount(Proc,Expr,1,RaiseOnError) then
|
||||
exit(cIncompatible);
|
||||
end;
|
||||
Params:=TParamsExpr(Expr);
|
||||
|
||||
// first param: var Integer
|
||||
@ -6498,13 +6516,8 @@ var
|
||||
Param: TPasExpr;
|
||||
ParamResolved: TPasResolverResult;
|
||||
begin
|
||||
if (not (Expr is TParamsExpr)) or (length(TParamsExpr(Expr).Params)<1) then
|
||||
begin
|
||||
if RaiseOnError then
|
||||
RaiseMsg(20170216152326,nWrongNumberOfParametersForCallTo,
|
||||
sWrongNumberOfParametersForCallTo,[Proc.Signature],Expr);
|
||||
if not CheckBuiltInMinParamCount(Proc,Expr,1,RaiseOnError) then
|
||||
exit(cIncompatible);
|
||||
end;
|
||||
Params:=TParamsExpr(Expr);
|
||||
|
||||
// first param: pointer or proc type
|
||||
@ -6551,13 +6564,8 @@ var
|
||||
Param: TPasExpr;
|
||||
ParamResolved: TPasResolverResult;
|
||||
begin
|
||||
if (not (Expr is TParamsExpr)) or (length(TParamsExpr(Expr).Params)<1) then
|
||||
begin
|
||||
if RaiseOnError then
|
||||
RaiseMsg(20170216152332,nWrongNumberOfParametersForCallTo,
|
||||
sWrongNumberOfParametersForCallTo,[Proc.Signature],Expr);
|
||||
if not CheckBuiltInMinParamCount(Proc,Expr,1,RaiseOnError) then
|
||||
exit(cIncompatible);
|
||||
end;
|
||||
Params:=TParamsExpr(Expr);
|
||||
|
||||
// first param: enum or char
|
||||
@ -6606,13 +6614,8 @@ var
|
||||
ParamResolved: TPasResolverResult;
|
||||
TypeEl: TPasType;
|
||||
begin
|
||||
if (not (Expr is TParamsExpr)) or (length(TParamsExpr(Expr).Params)<1) then
|
||||
begin
|
||||
if RaiseOnError then
|
||||
RaiseMsg(20170216152337,nWrongNumberOfParametersForCallTo,
|
||||
sWrongNumberOfParametersForCallTo,[Proc.Signature],Expr);
|
||||
if not CheckBuiltInMinParamCount(Proc,Expr,1,RaiseOnError) then
|
||||
exit(cIncompatible);
|
||||
end;
|
||||
Params:=TParamsExpr(Expr);
|
||||
|
||||
// first param: enum, range or char
|
||||
@ -6698,13 +6701,8 @@ var
|
||||
Param: TPasExpr;
|
||||
ParamResolved: TPasResolverResult;
|
||||
begin
|
||||
if (not (Expr is TParamsExpr)) or (length(TParamsExpr(Expr).Params)<1) then
|
||||
begin
|
||||
if RaiseOnError then
|
||||
RaiseMsg(20170216152341,nWrongNumberOfParametersForCallTo,
|
||||
sWrongNumberOfParametersForCallTo,[Proc.Signature],Expr);
|
||||
if not CheckBuiltInMinParamCount(Proc,Expr,1,RaiseOnError) then
|
||||
exit(cIncompatible);
|
||||
end;
|
||||
Params:=TParamsExpr(Expr);
|
||||
|
||||
// first param: enum, range, set, char or integer
|
||||
@ -6740,6 +6738,165 @@ begin
|
||||
ResolvedEl.Flags:=ResolvedEl.Flags-[rrfWritable];
|
||||
end;
|
||||
|
||||
function TPasResolver.BI_Str_CheckParam(Param: TPasExpr;
|
||||
const ParamResolved: TPasResolverResult; ArgNo: integer; RaiseOnError: boolean
|
||||
): integer;
|
||||
|
||||
function CheckFormat(FormatExpr: TPasExpr; Index: integer;
|
||||
const ParamResolved: TPasResolverResult): boolean;
|
||||
var
|
||||
ResolvedEl: TPasResolverResult;
|
||||
Ok: Boolean;
|
||||
begin
|
||||
if FormatExpr=nil then exit(true);
|
||||
Result:=false;
|
||||
Ok:=false;
|
||||
if ParamResolved.BaseType in btAllFloats then
|
||||
// floats supports value:Width:Precision
|
||||
Ok:=true
|
||||
else
|
||||
// all other only support only Width
|
||||
Ok:=Index<2;
|
||||
if not Ok then
|
||||
begin
|
||||
if RaiseOnError then
|
||||
RaiseMsg(20170319222319,nIllegalExpression,sIllegalExpression,[],FormatExpr);
|
||||
exit;
|
||||
end;
|
||||
ComputeElement(FormatExpr,ResolvedEl,[]);
|
||||
if not (ResolvedEl.BaseType in btAllInteger) then
|
||||
begin
|
||||
if RaiseOnError then
|
||||
RaiseMsg(20170319221515,nXExpectedButYFound,sXExpectedButYFound,
|
||||
['integer',GetResolverResultDescription(ResolvedEl)],FormatExpr);
|
||||
exit;
|
||||
end;
|
||||
if not (rrfReadable in ResolvedEl.Flags) then
|
||||
begin
|
||||
if RaiseOnError then
|
||||
RaiseMsg(20170319221755,nNotReadable,sNotReadable,[],FormatExpr);
|
||||
exit;
|
||||
end;
|
||||
Result:=true;
|
||||
end;
|
||||
|
||||
var
|
||||
TypeEl: TPasType;
|
||||
begin
|
||||
Result:=cIncompatible;
|
||||
if ParamResolved.BaseType in (btAllInteger+btAllBooleans+btAllFloats) then
|
||||
Result:=cExact
|
||||
else if ParamResolved.BaseType=btContext then
|
||||
begin
|
||||
TypeEl:=ParamResolved.TypeEl;
|
||||
if TypeEl.ClassType=TPasEnumType then
|
||||
Result:=cExact
|
||||
end;
|
||||
if Result=cIncompatible then
|
||||
begin
|
||||
if RaiseOnError then
|
||||
RaiseMsg(20170319220517,nIncompatibleTypeArgNo,sIncompatibleTypeArgNo,
|
||||
[IntToStr(ArgNo),GetTypeDesc(ParamResolved.TypeEl),'boolean, integer, enum value'],
|
||||
Param);
|
||||
exit;
|
||||
end;
|
||||
if not CheckFormat(Param.format1,1,ParamResolved) then
|
||||
exit(cIncompatible);
|
||||
if not CheckFormat(Param.format2,2,ParamResolved) then
|
||||
exit(cIncompatible);
|
||||
end;
|
||||
|
||||
function TPasResolver.BI_StrProc_OnGetCallCompatibility(
|
||||
Proc: TResElDataBuiltInProc; Expr: TPasExpr; RaiseOnError: boolean): integer;
|
||||
// check params of built-in procedure 'Str'
|
||||
var
|
||||
Params: TParamsExpr;
|
||||
Param: TPasExpr;
|
||||
ParamResolved: TPasResolverResult;
|
||||
begin
|
||||
if not CheckBuiltInMinParamCount(Proc,Expr,2,RaiseOnError) then
|
||||
exit(cIncompatible);
|
||||
Params:=TParamsExpr(Expr);
|
||||
|
||||
// first param: boolean, integer, enum, class instance
|
||||
Param:=Params.Params[0];
|
||||
ComputeElement(Param,ParamResolved,[]);
|
||||
Result:=BI_Str_CheckParam(Param,ParamResolved,1,RaiseOnError);
|
||||
if Result=cIncompatible then
|
||||
exit;
|
||||
|
||||
// second parameter: string variable
|
||||
Param:=Params.Params[1];
|
||||
ComputeElement(Param,ParamResolved,[]);
|
||||
Result:=cIncompatible;
|
||||
if ResolvedElCanBeVarParam(ParamResolved) then
|
||||
begin
|
||||
if ParamResolved.BaseType in btAllStrings then
|
||||
Result:=cExact;
|
||||
end;
|
||||
if Result=cIncompatible then
|
||||
begin
|
||||
if RaiseOnError then
|
||||
RaiseMsg(20170319220806,nIncompatibleTypeArgNo,sIncompatibleTypeArgNo,
|
||||
['1',GetTypeDesc(ParamResolved.TypeEl),'string variable'],
|
||||
Param);
|
||||
exit;
|
||||
end;
|
||||
|
||||
if length(Params.Params)>2 then
|
||||
begin
|
||||
if RaiseOnError then
|
||||
RaiseMsg(20170216152345,nWrongNumberOfParametersForCallTo,
|
||||
sWrongNumberOfParametersForCallTo,[Proc.Signature],Params.Params[2]);
|
||||
exit(cIncompatible);
|
||||
end;
|
||||
|
||||
Result:=cExact;
|
||||
end;
|
||||
|
||||
procedure TPasResolver.BI_StrProc_OnFinishParamsExpr(Proc: TResElDataBuiltInProc;
|
||||
Params: TParamsExpr);
|
||||
var
|
||||
P: TPasExprArray;
|
||||
begin
|
||||
if Proc=nil then ;
|
||||
P:=Params.Params;
|
||||
FinishParamExpressionAccess(P[0],rraRead);
|
||||
FinishParamExpressionAccess(P[1],rraVarParam);
|
||||
end;
|
||||
|
||||
function TPasResolver.BI_StrFunc_OnGetCallCompatibility(
|
||||
Proc: TResElDataBuiltInProc; Expr: TPasExpr; RaiseOnError: boolean): integer;
|
||||
var
|
||||
Params: TParamsExpr;
|
||||
Param: TPasExpr;
|
||||
ParamResolved: TPasResolverResult;
|
||||
i: Integer;
|
||||
begin
|
||||
if not CheckBuiltInMinParamCount(Proc,Expr,1,RaiseOnError) then
|
||||
exit(cIncompatible);
|
||||
Params:=TParamsExpr(Expr);
|
||||
|
||||
// param: string, boolean, integer, enum, class instance
|
||||
for i:=0 to length(Params.Params)-1 do
|
||||
begin
|
||||
Param:=Params.Params[i];
|
||||
ComputeElement(Param,ParamResolved,[]);
|
||||
Result:=BI_Str_CheckParam(Param,ParamResolved,i+1,RaiseOnError);
|
||||
if Result=cIncompatible then
|
||||
exit;
|
||||
end;
|
||||
|
||||
Result:=cExact;
|
||||
end;
|
||||
|
||||
procedure TPasResolver.BI_StrFunc_OnGetCallResult(Proc: TResElDataBuiltInProc;
|
||||
Params: TParamsExpr; out ResolvedEl: TPasResolverResult);
|
||||
begin
|
||||
if Params=nil then ;
|
||||
SetResolverIdentifier(ResolvedEl,btString,Proc.Proc,FBaseTypes[btString],[rrfReadable]);
|
||||
end;
|
||||
|
||||
constructor TPasResolver.Create;
|
||||
begin
|
||||
inherited Create;
|
||||
@ -7255,6 +7412,13 @@ begin
|
||||
if bfSucc in BaseProcs then
|
||||
AddBuiltInProc('Succ','function Succ(const ordinal): ordinal',
|
||||
@BI_PredSucc_OnGetCallCompatibility,@BI_PredSucc_OnGetCallResult,nil,bfSucc);
|
||||
if bfStrProc in BaseProcs then
|
||||
AddBuiltInProc('Str','procedure Str(const var; var String)',
|
||||
@BI_StrProc_OnGetCallCompatibility,nil,
|
||||
@BI_StrProc_OnFinishParamsExpr,bfStrProc,[bipfCanBeStatement]);
|
||||
if bfStrFunc in BaseProcs then
|
||||
AddBuiltInProc('Str','function Str(const var): String',
|
||||
@BI_StrFunc_OnGetCallCompatibility,@BI_StrFunc_OnGetCallResult,nil,bfStrFunc);
|
||||
end;
|
||||
|
||||
function TPasResolver.AddBaseType(aName: shortstring; Typ: TResolverBaseType
|
||||
|
||||
@ -507,7 +507,7 @@ type
|
||||
ElType: TPasType;
|
||||
end;
|
||||
|
||||
{ TPasEnumValue }
|
||||
{ TPasEnumValue - Parent is TPasEnumType }
|
||||
|
||||
TPasEnumValue = class(TPasElement)
|
||||
public
|
||||
|
||||
@ -159,6 +159,9 @@ type
|
||||
Procedure TestIncDec;
|
||||
Procedure TestIncStringFail;
|
||||
Procedure TestVarExternal;
|
||||
Procedure TestStr_BaseTypes;
|
||||
Procedure TestStr_StringFail;
|
||||
Procedure TestStr_CharFail;
|
||||
|
||||
// strings
|
||||
Procedure TestString_SetLength;
|
||||
@ -179,6 +182,7 @@ type
|
||||
Procedure TestEnumOrd;
|
||||
Procedure TestEnumPredSucc;
|
||||
Procedure TestEnum_CastIntegerToEnum;
|
||||
Procedure TestEnum_Str;
|
||||
|
||||
// operators
|
||||
Procedure TestPrgAssignment;
|
||||
@ -560,7 +564,7 @@ begin
|
||||
+' Scanner at'
|
||||
+' at '+aFilename+'('+IntToStr(aRow)+','+IntToStr(aCol)+')'
|
||||
+' Line="'+Scanner.CurLine+'"');
|
||||
raise E;
|
||||
Fail(E.Message);
|
||||
end;
|
||||
on E: EPasResolve do
|
||||
begin
|
||||
@ -575,12 +579,12 @@ begin
|
||||
WriteSources(aFilename,aRow,aCol);
|
||||
writeln('ERROR: TTestResolver.ParseProgram PasResolver: '+E.ClassName+':'+E.Message
|
||||
+' at '+aFilename+'('+IntToStr(aRow)+','+IntToStr(aCol)+')');
|
||||
raise E;
|
||||
Fail(E.Message);
|
||||
end;
|
||||
on E: Exception do
|
||||
begin
|
||||
writeln('ERROR: TTestResolver.ParseProgram Exception: '+E.ClassName+':'+E.Message);
|
||||
raise E;
|
||||
Fail(E.Message);
|
||||
end;
|
||||
end;
|
||||
TAssert.AssertSame('Has resolver',ResolverEngine,Parser.Engine);
|
||||
@ -607,7 +611,7 @@ begin
|
||||
+' Col='+IntToStr(Scanner.CurColumn)
|
||||
+' Line="'+Scanner.CurLine+'"'
|
||||
);
|
||||
raise E;
|
||||
Fail(E.Message);
|
||||
end;
|
||||
on E: EPasResolve do
|
||||
begin
|
||||
@ -617,12 +621,12 @@ begin
|
||||
+' Col='+IntToStr(Scanner.CurColumn)
|
||||
+' Line="'+Scanner.CurLine+'"'
|
||||
);
|
||||
raise E;
|
||||
Fail(E.Message);
|
||||
end;
|
||||
on E: Exception do
|
||||
begin
|
||||
writeln('ERROR: TTestResolver.ParseUnit Exception: '+E.ClassName+':'+E.Message);
|
||||
raise E;
|
||||
Fail(E.Message);
|
||||
end;
|
||||
end;
|
||||
TAssert.AssertSame('Has resolver',ResolverEngine,Parser.Engine);
|
||||
@ -1196,7 +1200,7 @@ begin
|
||||
WriteSources(aFilename,aRow,aCol);
|
||||
s:='[TTestResolver.RaiseErrorAtSrc] '+aFilename+'('+IntToStr(aRow)+','+IntToStr(aCol)+') Error: '+Msg;
|
||||
writeln('ERROR: ',s);
|
||||
raise EAssertionFailedError.Create(s);
|
||||
Fail(s);
|
||||
end;
|
||||
|
||||
procedure TCustomTestResolver.RaiseErrorAtSrcMarker(Msg: string; aMarker: PSrcMarker);
|
||||
@ -1219,7 +1223,7 @@ function TCustomTestResolver.AddModule(aFilename: string): TTestEnginePasResolve
|
||||
begin
|
||||
//writeln('TTestResolver.AddModule ',aFilename);
|
||||
if FindModuleWithFilename(aFilename)<>nil then
|
||||
raise EAssertionFailedError.Create('TTestResolver.AddModule: file "'+aFilename+'" already exists');
|
||||
Fail('TTestResolver.AddModule: file "'+aFilename+'" already exists');
|
||||
Result:=TTestEnginePasResolver.Create;
|
||||
Result.Filename:=aFilename;
|
||||
Result.AddObjFPCBuiltInIdentifiers;
|
||||
@ -1406,7 +1410,7 @@ begin
|
||||
+' Line="'+CurEngine.Scanner.CurLine+'"'
|
||||
);
|
||||
WriteSources(ErrFilename,ErrRow,ErrCol);
|
||||
raise E;
|
||||
Fail(E.Message);
|
||||
end;
|
||||
end;
|
||||
//writeln('TTestResolver.OnPasResolverFindUnit END ',CurUnitName);
|
||||
@ -1415,7 +1419,7 @@ begin
|
||||
end;
|
||||
end;
|
||||
writeln('TTestResolver.OnPasResolverFindUnit missing unit "',aUnitName,'"');
|
||||
raise EAssertionFailedError.Create('can''t find unit "'+aUnitName+'"');
|
||||
Fail('can''t find unit "'+aUnitName+'"');
|
||||
end;
|
||||
|
||||
procedure TCustomTestResolver.OnFindReference(El: TPasElement; FindData: pointer);
|
||||
@ -1445,7 +1449,7 @@ var
|
||||
s:='TTestResolver.OnCheckElementParent El='+GetTreeDesc(El)+' '+
|
||||
ResolverEngine.GetElementSourcePosStr(El)+' '+Msg;
|
||||
writeln('ERROR: ',s);
|
||||
raise EAssertionFailedError.Create(s);
|
||||
Fail(s);
|
||||
end;
|
||||
|
||||
begin
|
||||
@ -1811,6 +1815,62 @@ begin
|
||||
ParseProgram;
|
||||
end;
|
||||
|
||||
procedure TTestResolver.TestStr_BaseTypes;
|
||||
begin
|
||||
StartProgram(false);
|
||||
Add('var');
|
||||
Add(' b: boolean;');
|
||||
Add(' i: longint;');
|
||||
Add(' i64: int64;');
|
||||
Add(' s: single;');
|
||||
Add(' d: double;');
|
||||
Add(' aString: string;');
|
||||
Add('begin');
|
||||
Add(' Str(b,{#a_var}aString);');
|
||||
Add(' Str(b:1,aString);');
|
||||
Add(' Str(b:i,aString);');
|
||||
Add(' Str(i,aString);');
|
||||
Add(' Str(i:2,aString);');
|
||||
Add(' Str(i:i64,aString);');
|
||||
Add(' Str(i64,aString);');
|
||||
Add(' Str(i64:3,aString);');
|
||||
Add(' Str(i64:i,aString);');
|
||||
Add(' Str(s,aString);');
|
||||
Add(' Str(d,aString);');
|
||||
Add(' Str(d:4,aString);');
|
||||
Add(' Str(d:4:5,aString);');
|
||||
Add(' Str(d:4:i,aString);');
|
||||
Add(' aString:=Str(b);');
|
||||
Add(' aString:=Str(i:3);');
|
||||
Add(' aString:=Str(d:3:4);');
|
||||
Add(' aString:=Str(b,i,d);');
|
||||
ParseProgram;
|
||||
CheckAccessMarkers;
|
||||
end;
|
||||
|
||||
procedure TTestResolver.TestStr_StringFail;
|
||||
begin
|
||||
StartProgram(false);
|
||||
Add('var');
|
||||
Add(' aString: string;');
|
||||
Add('begin');
|
||||
Add(' Str(aString,aString);');
|
||||
CheckResolverException('Incompatible type arg no. 1: Got "String", expected "boolean, integer, enum value"',
|
||||
nIncompatibleTypeArgNo);
|
||||
end;
|
||||
|
||||
procedure TTestResolver.TestStr_CharFail;
|
||||
begin
|
||||
StartProgram(false);
|
||||
Add('var');
|
||||
Add(' c: char;');
|
||||
Add(' aString: string;');
|
||||
Add('begin');
|
||||
Add(' Str(c,aString);');
|
||||
CheckResolverException('Incompatible type arg no. 1: Got "Char", expected "boolean, integer, enum value"',
|
||||
nIncompatibleTypeArgNo);
|
||||
end;
|
||||
|
||||
procedure TTestResolver.TestString_SetLength;
|
||||
begin
|
||||
StartProgram(false);
|
||||
@ -2127,6 +2187,22 @@ begin
|
||||
CheckAccessMarkers;
|
||||
end;
|
||||
|
||||
procedure TTestResolver.TestEnum_Str;
|
||||
begin
|
||||
StartProgram(false);
|
||||
Add('type');
|
||||
Add(' TFlag = (red, green, blue);');
|
||||
Add('var');
|
||||
Add(' f: TFlag;');
|
||||
Add(' i: longint;');
|
||||
Add(' aString: string;');
|
||||
Add('begin');
|
||||
Add(' aString:=str(f);');
|
||||
Add(' aString:=str(f:3);');
|
||||
Add(' str(f,aString);');
|
||||
ParseProgram;
|
||||
end;
|
||||
|
||||
procedure TTestResolver.TestPrgAssignment;
|
||||
var
|
||||
El: TPasElement;
|
||||
|
||||
@ -153,8 +153,7 @@ Works:
|
||||
- use 0o for octal literals
|
||||
|
||||
ToDos:
|
||||
- function str, procedure str
|
||||
- try raise E1 except on E: E2 end;
|
||||
- class external
|
||||
|
||||
Not in Version 1.0:
|
||||
- write, writeln
|
||||
@ -245,8 +244,8 @@ resourcestring
|
||||
sMissingExternalName = 'Missing external name';
|
||||
|
||||
const
|
||||
DefaultFuncNameArray_SetLength = 'arraySetLength'; // rtl.arraySetLength
|
||||
DefaultFuncNameArray_NewMultiDim = 'arrayNewMultiDim'; // rtl.arrayNewMultiDim
|
||||
DefaultFuncNameArray_SetLength = 'arraySetLength'; // rtl.arraySetLength
|
||||
DefaultFuncNameAs = 'as'; // rtl.as
|
||||
DefaultFuncNameCreateClass = 'createClass'; // rtl.createClass
|
||||
DefaultFuncNameFreeClassInstance = '$destroy';
|
||||
@ -268,6 +267,8 @@ const
|
||||
DefaultFuncNameSet_Reference = 'refSet'; // rtl.refSet
|
||||
DefaultFuncNameSet_SymDiffSet = 'symDiffSet'; // rtl.symDiffSet >< (symmetrical difference)
|
||||
DefaultFuncNameSet_Union = 'unionSet'; // rtl.unionSet +
|
||||
DefaultFuncNameSpaceLeft = 'spaceLeft'; // rtl.spaceLeft
|
||||
DefaultVarNameExceptObject = '$e';
|
||||
DefaultVarNameImplementation = '$impl';
|
||||
DefaultVarNameLoopEnd = '$loopend';
|
||||
DefaultVarNameModules = 'pas';
|
||||
@ -544,9 +545,20 @@ type
|
||||
|
||||
TPas2JSIsElementUsedEvent = function(Sender: TObject; El: TPasElement): boolean of object;
|
||||
|
||||
TPasToJsPlatform = (
|
||||
PlatformBrowser,
|
||||
PlatformNodeJS
|
||||
);
|
||||
TPasToJsPlatforms = set of TPasToJsPlatform;
|
||||
const
|
||||
PasToJsPlatformNames: array[TPasToJsPlatform] of string = (
|
||||
'Browser',
|
||||
'NodeJS'
|
||||
);
|
||||
type
|
||||
TPasToJsProcessor = (
|
||||
pECMAScript5,
|
||||
pECMAScript6
|
||||
ProcessorECMAScript5,
|
||||
ProcessorECMAScript6
|
||||
);
|
||||
TPasToJsProcessors = set of TPasToJsProcessor;
|
||||
const
|
||||
@ -614,9 +626,12 @@ type
|
||||
FFuncNameSet_Reference: String;
|
||||
FFuncNameSet_SymDiffSet: String;
|
||||
FFuncNameSet_Union: String;
|
||||
FFuncNameSpaceLeft: String;
|
||||
FOnIsElementUsed: TPas2JSIsElementUsedEvent;
|
||||
FOptions: TPasToJsConverterOptions;
|
||||
FTargetPlatform: TPasToJsPlatform;
|
||||
FTargetProcessor: TPasToJsProcessor;
|
||||
FVarNameExceptObject: String;
|
||||
FVarNameImplementation: String;
|
||||
FVarNameLoopEnd: String;
|
||||
FVarNameModules: String;
|
||||
@ -635,7 +650,6 @@ type
|
||||
DataClass: TPas2JsElementDataClass): TPas2JsElementData;
|
||||
procedure AddElementData(Data: TPas2JsElementData);
|
||||
Procedure AddToSourceElements(Src: TJSSourceElements; El: TJSElement);
|
||||
procedure SetTargetProcessor(const AValue: TPasToJsProcessor);
|
||||
procedure SetUseEnumNumbers(const AValue: boolean);
|
||||
procedure SetUseLowerCase(const AValue: boolean);
|
||||
procedure SetUseSwitchStatement(const AValue: boolean);
|
||||
@ -658,7 +672,6 @@ type
|
||||
Function TransformVariableName(El: TPasElement; AContext : TConvertContext) : String; virtual;
|
||||
Function TransformModuleName(El: TPasModule; AContext : TConvertContext) : String; virtual;
|
||||
Function IsPreservedWord(aName: string): boolean; virtual;
|
||||
Function GetExceptionObjectName(AContext: TConvertContext) : string;
|
||||
// Never create an element manually, always use the below functions
|
||||
Function IsElementUsed(El: TPasElement): boolean; virtual;
|
||||
Function CreateElement(C: TJSElementClass; Src: TPasElement): TJSElement; virtual;
|
||||
@ -702,9 +715,10 @@ type
|
||||
RecordExpr: TJSElement; AContext: TConvertContext): TJSElement; virtual;
|
||||
Function CreateCallback(El: TPasElement; ResolvedEl: TPasResolverResult;
|
||||
AContext: TConvertContext): TJSElement; virtual;
|
||||
Function CreateAssignStatement(LeftEl: TPasElement; AssignContext: TAssignContext): TJSElement; virtual;
|
||||
// Statements
|
||||
Function ConvertImplBlockElements(El: TPasImplBlock; AContext: TConvertContext): TJSElement; virtual;
|
||||
Function ConvertBeginEndStatement(El: TPasImplBeginBlock; AContext: TConvertContext): TJSElement; virtual;
|
||||
Function ConvertImplBlockElements(El: TPasImplBlock; AContext: TConvertContext; NilIfEmpty: boolean): TJSElement; virtual;
|
||||
Function ConvertBeginEndStatement(El: TPasImplBeginBlock; AContext: TConvertContext; NilIfEmpty: boolean): TJSElement; virtual;
|
||||
Function ConvertStatement(El: TPasImplStatement; AContext: TConvertContext ): TJSElement; virtual;
|
||||
Function ConvertAssignStatement(El: TPasImplAssign; AContext: TConvertContext): TJSElement; virtual;
|
||||
Function ConvertRaiseStatement(El: TPasImplRaise; AContext: TConvertContext ): TJSElement; virtual;
|
||||
@ -741,6 +755,9 @@ type
|
||||
Function ConvertBuiltInHigh(El: TParamsExpr; AContext: TConvertContext): TJSElement; virtual;
|
||||
Function ConvertBuiltInPred(El: TParamsExpr; AContext: TConvertContext): TJSElement; virtual;
|
||||
Function ConvertBuiltInSucc(El: TParamsExpr; AContext: TConvertContext): TJSElement; virtual;
|
||||
Function ConvertBuiltInStrProc(El: TParamsExpr; AContext: TConvertContext): TJSElement; virtual;
|
||||
Function ConvertBuiltInStrFunc(El: TParamsExpr; AContext: TConvertContext): TJSElement; virtual;
|
||||
Function ConvertBuiltInStrParam(El: TPasExpr; AContext: TConvertContext; IsFirst: boolean): TJSElement; virtual;
|
||||
Function ConvertRecordValues(El: TRecordValues; AContext: TConvertContext): TJSElement; virtual;
|
||||
Function ConvertSelfExpression(El: TSelfExpr; AContext: TConvertContext): TJSElement; virtual;
|
||||
Function ConvertBinaryExpression(El: TBinaryExpr; AContext: TConvertContext): TJSElement; virtual;
|
||||
@ -776,7 +793,8 @@ type
|
||||
Function ConvertPasElement(El : TPasElement; Resolver: TPasResolver) : TJSElement;
|
||||
// options
|
||||
Property Options: TPasToJsConverterOptions read FOptions write FOptions;
|
||||
Property TargetProcessor: TPasToJsProcessor read FTargetProcessor write SetTargetProcessor;
|
||||
Property TargetPlatform: TPasToJsPlatform read FTargetPlatform write FTargetPlatform;
|
||||
Property TargetProcessor: TPasToJsProcessor read FTargetProcessor write FTargetProcessor;
|
||||
Property UseLowerCase: boolean read GetUseLowerCase write SetUseLowerCase default true;
|
||||
Property UseSwitchStatement: boolean read GetUseSwitchStatement write SetUseSwitchStatement;// default false, because slower than "if" in many engines
|
||||
Property UseEnumNumbers: boolean read GetUseEnumNumbers write SetUseEnumNumbers; // default false
|
||||
@ -806,6 +824,8 @@ type
|
||||
Property FuncNameSet_Reference: String read FFuncNameSet_Reference write FFuncNameSet_Reference; // rtl.refSet
|
||||
Property FuncNameSet_SymDiffSet: String read FFuncNameSet_SymDiffSet write FFuncNameSet_SymDiffSet; // rtl.symDiffSet (symmetrical difference ><
|
||||
Property FuncNameSet_Union: String read FFuncNameSet_Union write FFuncNameSet_Union; // rtl.unionSet +
|
||||
Property FuncNameSpaceLeft: String read FFuncNameSpaceLeft write FFuncNameSpaceLeft;
|
||||
Property VarNameExceptObject: String read FVarNameExceptObject write FVarNameExceptObject;
|
||||
Property VarNameImplementation: String read FVarNameImplementation write FVarNameImplementation;// empty to not use, default '$impl'
|
||||
Property VarNameLoopEnd: String read FVarNameLoopEnd write FVarNameLoopEnd;
|
||||
Property VarNameModules: String read FVarNameModules write FVarNameModules;
|
||||
@ -813,9 +833,6 @@ type
|
||||
Property VarNameWith: String read FVarNameWith write FVarNameWith;
|
||||
end;
|
||||
|
||||
var
|
||||
DefaultJSExceptionObject: string = '$e';
|
||||
|
||||
function CodePointToJSString(u: cardinal): TJSString;
|
||||
function PosLast(c: char; const s: string): integer;
|
||||
|
||||
@ -2202,11 +2219,11 @@ begin
|
||||
S:=copy(El.Value,2,length(El.Value));
|
||||
case El.Value[1] of
|
||||
'$': S:='0x'+S;
|
||||
'&': if TargetProcessor=pECMAScript5 then
|
||||
'&': if TargetProcessor=ProcessorECMAScript5 then
|
||||
S:='0'+S
|
||||
else
|
||||
S:='0o'+S;
|
||||
'%': if TargetProcessor=pECMAScript5 then
|
||||
'%': if TargetProcessor=ProcessorECMAScript5 then
|
||||
S:=''
|
||||
else
|
||||
S:='0b'+S;
|
||||
@ -2948,6 +2965,8 @@ begin
|
||||
bfHigh: Result:=ConvertBuiltInHigh(El,AContext);
|
||||
bfPred: Result:=ConvertBuiltInPred(El,AContext);
|
||||
bfSucc: Result:=ConvertBuiltInSucc(El,AContext);
|
||||
bfStrProc: Result:=ConvertBuiltInStrProc(El,AContext);
|
||||
bfStrFunc: Result:=ConvertBuiltInStrFunc(El,AContext);
|
||||
else
|
||||
RaiseNotSupported(El,AContext,20161130164955,'built in proc '+ResolverBuiltInProcNames[BuiltInProc.BuiltIn]);
|
||||
end;
|
||||
@ -3142,7 +3161,7 @@ var
|
||||
ResolvedParam0: TPasResolverResult;
|
||||
ArrayType: TPasArrayType;
|
||||
Call: TJSCallExpression;
|
||||
ValInit, Arg, LHS: TJSElement;
|
||||
ValInit, Arg: TJSElement;
|
||||
AssignSt: TJSSimpleAssignStatement;
|
||||
AssignContext: TAssignContext;
|
||||
ElType: TPasType;
|
||||
@ -3163,7 +3182,6 @@ begin
|
||||
{$IFDEF VerbosePasResolver}
|
||||
writeln('TPasToJSConverter.ConvertBuiltInSetLength array');
|
||||
{$ENDIF}
|
||||
LHS:=nil;
|
||||
AssignContext:=TAssignContext.Create(El,nil,AContext);
|
||||
try
|
||||
AContext.Resolver.ComputeElement(El.Value,AssignContext.LeftResolved,[rcNoImplicitProc]);
|
||||
@ -3187,26 +3205,8 @@ begin
|
||||
Call.Args.Elements.AddElement.Expr:=ValInit;
|
||||
|
||||
// create left side: array =
|
||||
LHS:=ConvertElement(Param0,AssignContext);
|
||||
if AssignContext.Call<>nil then
|
||||
begin
|
||||
// array has a setter -> right side was already added as parameter
|
||||
if AssignContext.RightSide<>nil then
|
||||
RaiseInconsistency(20170207215447);
|
||||
Result:=LHS;
|
||||
end
|
||||
else
|
||||
begin
|
||||
AssignSt:=TJSSimpleAssignStatement(CreateElement(TJSSimpleAssignStatement,El));
|
||||
AssignSt.LHS:=LHS;
|
||||
AssignSt.Expr:=AssignContext.RightSide;
|
||||
AssignContext.RightSide:=nil;
|
||||
Result:=AssignSt;
|
||||
end;
|
||||
|
||||
Result:=CreateAssignStatement(Param0,AssignContext);
|
||||
finally
|
||||
if Result=nil then
|
||||
LHS.Free;
|
||||
AssignContext.RightSide.Free;
|
||||
AssignContext.Free;
|
||||
end;
|
||||
@ -3241,12 +3241,9 @@ var
|
||||
Call: TJSCallExpression;
|
||||
Param0: TPasExpr;
|
||||
AssignContext: TAssignContext;
|
||||
AssignSt: TJSSimpleAssignStatement;
|
||||
LHS: TJSElement;
|
||||
FunName: String;
|
||||
begin
|
||||
Result:=nil;
|
||||
LHS:=nil;
|
||||
Param0:=El.Params[0];
|
||||
AssignContext:=TAssignContext.Create(El,nil,AContext);
|
||||
try
|
||||
@ -3264,26 +3261,8 @@ begin
|
||||
Call.Args.Elements.AddElement.Expr:=ConvertElement(Param0,AContext);
|
||||
Call.Args.Elements.AddElement.Expr:=ConvertElement(El.Params[1],AContext);
|
||||
|
||||
// create left side: aSet =
|
||||
LHS:=ConvertElement(Param0,AssignContext);
|
||||
if AssignContext.Call<>nil then
|
||||
begin
|
||||
// set has a setter -> right side was already added as parameter
|
||||
if AssignContext.RightSide<>nil then
|
||||
RaiseInconsistency(20170301145100);
|
||||
Result:=LHS;
|
||||
end
|
||||
else
|
||||
begin
|
||||
AssignSt:=TJSSimpleAssignStatement(CreateElement(TJSSimpleAssignStatement,El));
|
||||
AssignSt.LHS:=LHS;
|
||||
AssignSt.Expr:=AssignContext.RightSide;
|
||||
AssignContext.RightSide:=nil;
|
||||
Result:=AssignSt;
|
||||
end;
|
||||
Result:=CreateAssignStatement(Param0,AssignContext);
|
||||
finally
|
||||
if Result=nil then
|
||||
LHS.Free;
|
||||
AssignContext.RightSide.Free;
|
||||
AssignContext.Free;
|
||||
end;
|
||||
@ -3617,7 +3596,7 @@ end;
|
||||
|
||||
function TPasToJSConverter.ConvertBuiltInSucc(El: TParamsExpr;
|
||||
AContext: TConvertContext): TJSElement;
|
||||
// pred(enumvalue) -> enumvalue-1
|
||||
// succ(enumvalue) -> enumvalue+1
|
||||
var
|
||||
ResolvedEl: TPasResolverResult;
|
||||
Param: TPasExpr;
|
||||
@ -3642,6 +3621,163 @@ begin
|
||||
DoError(20170210120626,nExpectedXButFoundY,sExpectedXButFoundY,['enum',GetResolverResultDescription(ResolvedEl)],Param);
|
||||
end;
|
||||
|
||||
function TPasToJSConverter.ConvertBuiltInStrProc(El: TParamsExpr;
|
||||
AContext: TConvertContext): TJSElement;
|
||||
// convert 'str(value,aString)' to 'aString = <string>'
|
||||
// for the conversion see ConvertBuiltInStrFunc
|
||||
var
|
||||
AssignContext: TAssignContext;
|
||||
StrVar: TPasExpr;
|
||||
begin
|
||||
Result:=nil;
|
||||
AssignContext:=TAssignContext.Create(El,nil,AContext);
|
||||
try
|
||||
StrVar:=El.Params[1];
|
||||
AContext.Resolver.ComputeElement(StrVar,AssignContext.LeftResolved,[rcNoImplicitProc]);
|
||||
|
||||
// create right side
|
||||
AssignContext.RightSide:=ConvertBuiltInStrParam(El.Params[0],AContext,true);
|
||||
SetResolverValueExpr(AssignContext.RightResolved,btString,
|
||||
AContext.Resolver.BaseType[btString],El,[rrfReadable]);
|
||||
|
||||
// create 'StrVar = rightside'
|
||||
Result:=CreateAssignStatement(StrVar,AssignContext);
|
||||
finally
|
||||
AssignContext.RightSide.Free;
|
||||
AssignContext.Free;
|
||||
end;
|
||||
end;
|
||||
|
||||
function TPasToJSConverter.ConvertBuiltInStrFunc(El: TParamsExpr;
|
||||
AContext: TConvertContext): TJSElement;
|
||||
// convert 'str(boolean)' to '""+boolean'
|
||||
// convert 'str(integer)' to '""+integer'
|
||||
// convert 'str(float)' to '""+float'
|
||||
// convert 'str(float:width)' to rtl.spaceLeft('""+float,width)'
|
||||
// convert 'str(float:width:precision)' to 'rtl.spaceLeft(float.toFixed(precision),width)'
|
||||
var
|
||||
i: Integer;
|
||||
Param: TPasExpr;
|
||||
Sum, Add: TJSElement;
|
||||
AddEl: TJSAdditiveExpressionPlus;
|
||||
begin
|
||||
{$IFDEF VerbosePas2JS}
|
||||
writeln('TPasToJSConverter.ConvertBuiltInStrFunc Count=',length(El.Params));
|
||||
{$ENDIF}
|
||||
Result:=nil;
|
||||
Sum:=nil;
|
||||
Add:=nil;
|
||||
try
|
||||
for i:=0 to length(El.Params)-1 do
|
||||
begin
|
||||
Param:=El.Params[i];
|
||||
Add:=ConvertBuiltInStrParam(Param,AContext,i=0);
|
||||
if Sum=nil then
|
||||
Sum:=Add
|
||||
else
|
||||
begin
|
||||
AddEl:=TJSAdditiveExpressionPlus(CreateElement(TJSAdditiveExpressionPlus,Param));
|
||||
AddEl.A:=Sum;
|
||||
AddEl.B:=Add;
|
||||
Sum:=AddEl;
|
||||
end;
|
||||
Add:=nil;
|
||||
end;
|
||||
Result:=Sum;
|
||||
finally
|
||||
Add.Free;
|
||||
if Result=nil then
|
||||
Sum.Free;
|
||||
end;
|
||||
end;
|
||||
|
||||
function TPasToJSConverter.ConvertBuiltInStrParam(El: TPasExpr;
|
||||
AContext: TConvertContext; IsFirst: boolean): TJSElement;
|
||||
var
|
||||
ResolvedEl: TPasResolverResult;
|
||||
NeedStrLit: Boolean;
|
||||
Add: TJSElement;
|
||||
Call: TJSCallExpression;
|
||||
PlusEl: TJSAdditiveExpressionPlus;
|
||||
Bracket: TJSBracketMemberExpression;
|
||||
procedure PrependStrLit;
|
||||
begin
|
||||
PlusEl:=TJSAdditiveExpressionPlus(CreateElement(TJSAdditiveExpressionPlus,El));
|
||||
PlusEl.A:=CreateLiteralString(El,'');
|
||||
PlusEl.B:=Add;
|
||||
Add:=PlusEl;
|
||||
end;
|
||||
|
||||
begin
|
||||
Result:=nil;
|
||||
AContext.Resolver.ComputeElement(El,ResolvedEl,[]);
|
||||
Add:=nil;
|
||||
Call:=nil;
|
||||
Bracket:=nil;
|
||||
try
|
||||
NeedStrLit:=false;
|
||||
if ResolvedEl.BaseType in (btAllBooleans+btAllInteger) then
|
||||
begin
|
||||
NeedStrLit:=true;
|
||||
Add:=ConvertElement(El,AContext);
|
||||
end
|
||||
else if ResolvedEl.BaseType in btAllFloats then
|
||||
begin
|
||||
NeedStrLit:=true;
|
||||
Add:=ConvertElement(El,AContext);
|
||||
if El.format2<>nil then
|
||||
begin
|
||||
// precision -> rtl El.toFixed(precision);
|
||||
NeedStrLit:=false;
|
||||
Call:=CreateCallExpression(El);
|
||||
Call.Expr:=CreateDotExpression(El,Add,CreateBuiltInIdentifierExpr('toFixed'));
|
||||
Call.Args.Elements.AddElement.Expr:=ConvertElement(El.format2,AContext);
|
||||
Add:=Call;
|
||||
Call:=nil;
|
||||
end;
|
||||
end
|
||||
else if ResolvedEl.BaseType=btContext then
|
||||
begin
|
||||
if ResolvedEl.TypeEl.ClassType=TPasEnumType then
|
||||
begin
|
||||
// create enumtype[enumvalue]
|
||||
Bracket:=TJSBracketMemberExpression(CreateElement(TJSBracketMemberExpression,El));
|
||||
Bracket.MExpr:=CreateReferencePathExpr(TPasEnumType(ResolvedEl.TypeEl),AContext);
|
||||
Bracket.Name:=ConvertElement(El,AContext);
|
||||
Add:=Bracket;
|
||||
Bracket:=nil;
|
||||
end
|
||||
else
|
||||
RaiseNotSupported(El,AContext,20170320123827);
|
||||
end
|
||||
else
|
||||
RaiseNotSupported(El,AContext,20170320093001);
|
||||
|
||||
if El.format1<>nil then
|
||||
begin
|
||||
// width -> leading spaces
|
||||
if NeedStrLit then
|
||||
PrependStrLit;
|
||||
// create 'rtl.spaceLeft(add,width)'
|
||||
Call:=CreateCallExpression(El);
|
||||
Call.Expr:=CreateMemberExpression([VarNameRTL,FuncNameSpaceLeft]);
|
||||
Call.Args.Elements.AddElement.Expr:=Add;
|
||||
Add:=nil;
|
||||
Call.Args.Elements.AddElement.Expr:=ConvertElement(El.format1,AContext);
|
||||
Add:=Call;
|
||||
Call:=nil;
|
||||
end
|
||||
else if IsFirst and NeedStrLit then
|
||||
PrependStrLit;
|
||||
Result:=Add;
|
||||
finally
|
||||
Call.Free;
|
||||
Bracket.Free;
|
||||
if Result=nil then
|
||||
Add.Free;
|
||||
end;
|
||||
end;
|
||||
|
||||
function TPasToJSConverter.ConvertRecordValues(El: TRecordValues;
|
||||
AContext: TConvertContext): TJSElement;
|
||||
|
||||
@ -3884,7 +4020,7 @@ begin
|
||||
if El.ElseBranch<>nil then
|
||||
begin
|
||||
JSCaseEl:=SwitchEl.Cases.AddCase;
|
||||
JSCaseEl.Body:=ConvertImplBlockElements(El.ElseBranch,AContext);
|
||||
JSCaseEl.Body:=ConvertImplBlockElements(El.ElseBranch,AContext,false);
|
||||
SwitchEl.TheDefault:=JSCaseEl;
|
||||
end;
|
||||
ok:=true;
|
||||
@ -4465,12 +4601,6 @@ begin
|
||||
until false;
|
||||
end;
|
||||
|
||||
procedure TPasToJSConverter.SetTargetProcessor(const AValue: TPasToJsProcessor);
|
||||
begin
|
||||
if FTargetProcessor=AValue then Exit;
|
||||
FTargetProcessor:=AValue;
|
||||
end;
|
||||
|
||||
constructor TPasToJSConverter.Create;
|
||||
begin
|
||||
FOptions:=[coLowerCase];
|
||||
@ -4497,6 +4627,8 @@ begin
|
||||
FFuncNameSet_Reference:=DefaultFuncNameSet_Reference;
|
||||
FFuncNameSet_SymDiffSet:=DefaultFuncNameSet_SymDiffSet;
|
||||
FFuncNameSet_Union:=DefaultFuncNameSet_Union;
|
||||
FFuncNameSpaceLeft:=DefaultFuncNameSpaceLeft;
|
||||
FVarNameExceptObject:=DefaultVarNameExceptObject;
|
||||
FVarNameImplementation:=DefaultVarNameImplementation;
|
||||
FVarNameLoopEnd:=DefaultVarNameLoopEnd;
|
||||
FVarNameModules:=DefaultVarNameModules;
|
||||
@ -4638,14 +4770,14 @@ begin
|
||||
end;
|
||||
|
||||
function TPasToJSConverter.ConvertBeginEndStatement(El: TPasImplBeginBlock;
|
||||
AContext: TConvertContext): TJSElement;
|
||||
AContext: TConvertContext; NilIfEmpty: boolean): TJSElement;
|
||||
|
||||
begin
|
||||
Result:=ConvertImplBlockElements(El,AContext);
|
||||
Result:=ConvertImplBlockElements(El,AContext,NilIfEmpty);
|
||||
end;
|
||||
|
||||
function TPasToJSConverter.ConvertImplBlockElements(El: TPasImplBlock;
|
||||
AContext: TConvertContext): TJSElement;
|
||||
AContext: TConvertContext; NilIfEmpty: boolean): TJSElement;
|
||||
|
||||
var
|
||||
First, Last: TJSStatementList;
|
||||
@ -4655,7 +4787,12 @@ var
|
||||
|
||||
begin
|
||||
if Not (Assigned(El.Elements) and (El.Elements.Count>0)) then
|
||||
Result:=TJSEmptyBlockStatement(CreateElement(TJSEmptyBlockStatement,El))
|
||||
begin
|
||||
if NilIfEmpty then
|
||||
Result:=nil
|
||||
else
|
||||
Result:=TJSEmptyBlockStatement(CreateElement(TJSEmptyBlockStatement,El));
|
||||
end
|
||||
else
|
||||
begin
|
||||
First:=nil;
|
||||
@ -4708,7 +4845,7 @@ begin
|
||||
Body:=FDS.AFunction.Body;
|
||||
FuncContext:=TFunctionContext.Create(El,Body,AContext);
|
||||
FuncContext.This:=AContext.GetThis;
|
||||
Body.A:=ConvertImplBlockElements(El,FuncContext);
|
||||
Body.A:=ConvertImplBlockElements(El,FuncContext,false);
|
||||
end;
|
||||
ok:=true;
|
||||
finally
|
||||
@ -4754,15 +4891,15 @@ begin
|
||||
if El.FinallyExcept is TPasImplTryFinally then
|
||||
begin
|
||||
T:=TJSTryFinallyStatement(CreateElement(TJSTryFinallyStatement,El));
|
||||
T.Block:=ConvertImplBlockElements(El,AContext);
|
||||
T.BFinally:=ConvertImplBlockElements(El.FinallyExcept,AContext);
|
||||
T.Block:=ConvertImplBlockElements(El,AContext,true);
|
||||
T.BFinally:=ConvertImplBlockElements(El.FinallyExcept,AContext,true);
|
||||
end
|
||||
else
|
||||
begin
|
||||
T:=TJSTryCatchStatement(CreateElement(TJSTryCatchStatement,El));
|
||||
T.Block:=ConvertImplBlockElements(El,AContext);
|
||||
T.Block:=ConvertImplBlockElements(El,AContext,true);
|
||||
if NeedExceptObject then
|
||||
T.Ident:=TJSString(GetExceptionObjectName(AContext));
|
||||
T.Ident:=TJSString(VarNameExceptObject);
|
||||
//T.BCatch:=ConvertElement(El.FinallyExcept,AContext);
|
||||
ExceptBlock:=El.FinallyExcept;
|
||||
if (ExceptBlock.Elements.Count>0)
|
||||
@ -4780,13 +4917,20 @@ begin
|
||||
Last:=IfSt;
|
||||
end;
|
||||
if El.ElseBranch<>nil then
|
||||
Last.BFalse:=ConvertImplBlockElements(El.ElseBranch,AContext);
|
||||
Last.BFalse:=ConvertImplBlockElements(El.ElseBranch,AContext,true)
|
||||
else
|
||||
begin
|
||||
// default else: throw exceptobject
|
||||
Last.BFalse:=TJSThrowStatement(CreateElement(TJSThrowStatement,El));
|
||||
TJSThrowStatement(Last.BFalse).A:=
|
||||
CreateBuiltInIdentifierExpr(VarNameExceptObject);
|
||||
end;
|
||||
end
|
||||
else
|
||||
begin
|
||||
if El.ElseBranch<>nil then
|
||||
RaiseNotSupported(El.ElseBranch,AContext,20170205003014);
|
||||
T.BCatch:=ConvertImplBlockElements(ExceptBlock,AContext);
|
||||
T.BCatch:=ConvertImplBlockElements(ExceptBlock,AContext,true);
|
||||
end;
|
||||
end;
|
||||
Result:=T;
|
||||
@ -4925,7 +5069,7 @@ begin
|
||||
// Pascal 'else' or 'otherwise' -> create JS "else{}"
|
||||
if LastIfSt=nil then
|
||||
RaiseNotSupported(SubEl,AContext,20161128120802,'case-of needs at least one case');
|
||||
LastIfSt.BFalse:=ConvertImplBlockElements(El.ElseBranch,AContext);
|
||||
LastIfSt.BFalse:=ConvertImplBlockElements(El.ElseBranch,AContext,true);
|
||||
end
|
||||
else
|
||||
RaiseNotSupported(SubEl,AContext,20161128113055);
|
||||
@ -5170,6 +5314,34 @@ begin
|
||||
end;
|
||||
end;
|
||||
|
||||
function TPasToJSConverter.CreateAssignStatement(LeftEl: TPasElement;
|
||||
AssignContext: TAssignContext): TJSElement;
|
||||
var
|
||||
LHS: TJSElement;
|
||||
AssignSt: TJSSimpleAssignStatement;
|
||||
begin
|
||||
Result:=nil;
|
||||
LHS:=ConvertElement(LeftEl,AssignContext);
|
||||
if AssignContext.Call<>nil then
|
||||
begin
|
||||
// has a setter -> right side was already added as parameter
|
||||
if AssignContext.RightSide<>nil then
|
||||
begin
|
||||
LHS.Free;
|
||||
RaiseInconsistency(20170207215447);
|
||||
end;
|
||||
Result:=LHS;
|
||||
end
|
||||
else
|
||||
begin
|
||||
AssignSt:=TJSSimpleAssignStatement(CreateElement(TJSSimpleAssignStatement,AssignContext.PasElement));
|
||||
AssignSt.LHS:=LHS;
|
||||
AssignSt.Expr:=AssignContext.RightSide;
|
||||
AssignContext.RightSide:=nil;
|
||||
Result:=AssignSt;
|
||||
end;
|
||||
end;
|
||||
|
||||
function TPasToJSConverter.ConvertImplBlock(El: TPasImplBlock;
|
||||
AContext: TConvertContext): TJSElement;
|
||||
|
||||
@ -5182,7 +5354,7 @@ begin
|
||||
else if (El.ClassType=TPasImplRepeatUntil) then
|
||||
Result:=ConvertRepeatStatement(TPasImplRepeatUntil(El),AContext)
|
||||
else if (El.ClassType=TPasImplBeginBlock) then
|
||||
Result:=ConvertBeginEndStatement(TPasImplBeginBlock(El),AContext)
|
||||
Result:=ConvertBeginEndStatement(TPasImplBeginBlock(El),AContext,true)
|
||||
else if (El.ClassType=TInitializationSection) then
|
||||
Result:=ConvertInitializationSection(TInitializationSection(El),AContext)
|
||||
else if (El.ClassType=TFinalizationSection) then
|
||||
@ -5295,7 +5467,7 @@ begin
|
||||
if El.ExceptObject<>Nil then
|
||||
E:=ConvertElement(El.ExceptObject,AContext)
|
||||
else
|
||||
E:=CreateBuiltInIdentifierExpr(GetExceptionObjectName(AContext));
|
||||
E:=CreateBuiltInIdentifierExpr(VarNameExceptObject);
|
||||
T:=TJSThrowStatement(CreateElement(TJSThrowStatement,El));
|
||||
T.A:=E;
|
||||
Result:=T;
|
||||
@ -5430,9 +5602,7 @@ begin
|
||||
try
|
||||
C:=ConvertElement(El.ConditionExpr,AContext);
|
||||
if Assigned(El.IfBranch) then
|
||||
BThen:=ConvertElement(El.IfBranch,AContext)
|
||||
else
|
||||
BThen:=TJSEmptyBlockStatement(CreateElement(TJSEmptyBlockStatement,El));
|
||||
BThen:=ConvertElement(El.IfBranch,AContext);
|
||||
if Assigned(El.ElseBranch) then
|
||||
BElse:=ConvertElement(El.ElseBranch,AContext);
|
||||
ok:=true;
|
||||
@ -5502,7 +5672,7 @@ begin
|
||||
C:=ConvertElement(EL.ConditionExpr,AContext);
|
||||
N:=TJSUnaryNotExpression(CreateElement(TJSUnaryNotExpression,EL.ConditionExpr));
|
||||
N.A:=C;
|
||||
B:=ConvertImplBlockElements(El,AContext);
|
||||
B:=ConvertImplBlockElements(El,AContext,false);
|
||||
ok:=true;
|
||||
finally
|
||||
if not ok then
|
||||
@ -5734,11 +5904,6 @@ begin
|
||||
begin
|
||||
B:=ConvertElement(El.Body,AContext);
|
||||
AddToStatementList(FirstSt,LastSt,B,El.Body);
|
||||
end
|
||||
else
|
||||
begin
|
||||
B:=TJSEmptyBlockStatement(CreateElement(TJSEmptyBlockStatement,El));
|
||||
AddToStatementList(FirstSt,LastSt,B,El);
|
||||
end;
|
||||
Result:=FirstSt;
|
||||
finally
|
||||
@ -5779,15 +5944,6 @@ begin
|
||||
end;
|
||||
end;
|
||||
|
||||
function TPasToJSConverter.GetExceptionObjectName(AContext: TConvertContext
|
||||
): string;
|
||||
begin
|
||||
if AContext=nil then ;
|
||||
Result:=DefaultJSExceptionObject; // use the same as the FPC RTL
|
||||
if UseLowerCase then
|
||||
Result:=lowercase(Result);
|
||||
end;
|
||||
|
||||
function TPasToJSConverter.IsElementUsed(El: TPasElement): boolean;
|
||||
begin
|
||||
if Assigned(OnIsElementUsed) then
|
||||
@ -6789,7 +6945,7 @@ begin
|
||||
// create "T.isPrototypeOf(exceptObject)"
|
||||
Call:=CreateCallExpression(El);
|
||||
Call.Expr:=DotExpr;
|
||||
Call.Args.Elements.AddElement.Expr:=CreateBuiltInIdentifierExpr(GetExceptionObjectName(AContext));
|
||||
Call.Args.Elements.AddElement.Expr:=CreateBuiltInIdentifierExpr(VarNameExceptObject);
|
||||
IfSt.Cond:=Call;
|
||||
|
||||
if El.VarEl<>nil then
|
||||
@ -6803,11 +6959,11 @@ begin
|
||||
VarDecl:=TJSVarDeclaration(CreateElement(TJSVarDeclaration,El));
|
||||
V.A:=VarDecl;
|
||||
VarDecl.Name:=TransformVariableName(El,El.VariableName,AContext);
|
||||
VarDecl.Init:=CreateBuiltInIdentifierExpr(GetExceptionObjectName(AContext));
|
||||
VarDecl.Init:=CreateBuiltInIdentifierExpr(VarNameExceptObject);
|
||||
// add statements
|
||||
AddToStatementList(ListFirst,ListLast,ConvertElement(El.Body,AContext),El);
|
||||
end
|
||||
else
|
||||
else if El.Body<>nil then
|
||||
// add statements
|
||||
IfSt.BTrue:=ConvertElement(El.Body,AContext);
|
||||
|
||||
@ -7360,7 +7516,6 @@ begin
|
||||
Result:=true;
|
||||
if aName=VarNameModules then exit;
|
||||
if aName=VarNameRTL then exit;
|
||||
if aName=GetExceptionObjectName(nil) then exit;
|
||||
|
||||
l:=low(JSReservedWords);
|
||||
r:=high(JSReservedWords);
|
||||
@ -7387,7 +7542,10 @@ begin
|
||||
aContext:=TRootContext.Create(El,nil,nil);
|
||||
try
|
||||
aContext.Resolver:=Resolver;
|
||||
Result:=ConvertElement(El,aContext);
|
||||
if (El.ClassType=TPasImplBeginBlock) then
|
||||
Result:=ConvertBeginEndStatement(TPasImplBeginBlock(El),AContext,false)
|
||||
else
|
||||
Result:=ConvertElement(El,aContext);
|
||||
finally
|
||||
FreeAndNil(aContext);
|
||||
end;
|
||||
|
||||
@ -187,8 +187,8 @@ begin
|
||||
R:=TPasImplIfElse.Create('',Nil);
|
||||
R.ConditionExpr:=CreateCondition;
|
||||
E:=TJSIfStatement(Convert(R,TJSIfStatement));
|
||||
AssertEquals('If branch is empty block statement',TJSEmptyBlockStatement,E.btrue.ClassType);
|
||||
AssertNull('No else branch',E.bfalse);
|
||||
AssertNull('If branch is empty',E.BTrue);
|
||||
AssertNull('No else branch',E.BFalse);
|
||||
AssertIdentifier('Left hand side OK',E.Cond,'a');
|
||||
end;
|
||||
|
||||
@ -668,7 +668,7 @@ begin
|
||||
// Convert
|
||||
El:=TJSTryCatchStatement(Convert(T,TJSTryCatchStatement));
|
||||
// check "catch(exceptobject)"
|
||||
AssertEquals('Correct exception object name',lowercase(DefaultJSExceptionObject),String(El.Ident));
|
||||
AssertEquals('Correct exception object name',lowercase(DefaultVarNameExceptObject),String(El.Ident));
|
||||
// check "if"
|
||||
I:=TJSIfStatement(AssertElement('On block is if',TJSIfStatement,El.BCatch));
|
||||
// check if condition "exception.isPrototypeOf(exceptobject)"
|
||||
@ -679,14 +679,14 @@ begin
|
||||
AssertNotNull('args of exception.isPrototypeOf(exceptobject)',IC.Args);
|
||||
AssertEquals('args of exception.isPrototypeOf(exceptobject)',1,IC.Args.Elements.Count);
|
||||
ExObj:=IC.Args.Elements.Elements[0].Expr;
|
||||
Assertidentifier('arg of exception.isPrototypeOf(exceptobject)',ExObj,lowercase(DefaultJSExceptionObject));
|
||||
Assertidentifier('arg of exception.isPrototypeOf(exceptobject)',ExObj,lowercase(DefaultVarNameExceptObject));
|
||||
// check statement "var e = exceptobject;"
|
||||
L:=AssertListStatement('On block is always a list',I.BTrue);
|
||||
writeln('TTestStatementConverter.TestTryExceptStatementOnE ',L.A.ClassName);
|
||||
VS:=TJSVariableStatement(AssertElement('First statement in list is a var statement',TJSVariableStatement,L.A));
|
||||
V:=TJSVarDeclaration(AssertElement('var declaration e=ExceptObject',TJSVarDeclaration,VS.A));
|
||||
AssertEquals('Variable name is identifier in On A : Ex do','e',V.Name);
|
||||
Assertidentifier('Variable init is exception object',V.Init,lowercase(DefaultJSExceptionObject));
|
||||
Assertidentifier('Variable init is exception object',V.Init,lowercase(DefaultVarNameExceptObject));
|
||||
// check "b = c;"
|
||||
AssertAssignStatement('Original assignment in second statement',L.B,'b','c');
|
||||
end;
|
||||
@ -727,7 +727,7 @@ begin
|
||||
// Convert
|
||||
El:=TJSTryCatchStatement(Convert(T,TJSTryCatchStatement));
|
||||
// check "catch(exceptobject)"
|
||||
AssertEquals('Correct exception object name',lowercase(DefaultJSExceptionObject),String(El.Ident));
|
||||
AssertEquals('Correct exception object name',lowercase(DefaultVarNameExceptObject),String(El.Ident));
|
||||
// check "if"
|
||||
I:=TJSIfStatement(AssertElement('On block is if',TJSIfStatement,El.BCatch));
|
||||
// check if condition "exception.isPrototypeOf(exceptobject)"
|
||||
@ -738,16 +738,16 @@ begin
|
||||
AssertNotNull('args of exception.isPrototypeOf(ExceptObject)',IC.Args);
|
||||
AssertEquals('args of exception.isPrototypeOf(ExceptObject)',1,IC.Args.Elements.Count);
|
||||
ExObj:=IC.Args.Elements.Elements[0].Expr;
|
||||
Assertidentifier('arg of exception.isPrototypeOf(ExceptObject)',ExObj,lowercase(DefaultJSExceptionObject));
|
||||
Assertidentifier('arg of exception.isPrototypeOf(ExceptObject)',ExObj,lowercase(DefaultVarNameExceptObject));
|
||||
// check statement "var e = exceptobject;"
|
||||
L:=AssertListStatement('On block is always a list',I.BTrue);
|
||||
writeln('TTestStatementConverter.TestTryExceptStatementOnE ',L.A.ClassName);
|
||||
VS:=TJSVariableStatement(AssertElement('First statement in list is a var statement',TJSVariableStatement,L.A));
|
||||
V:=TJSVarDeclaration(AssertElement('var declaration e=ExceptObject',TJSVarDeclaration,VS.A));
|
||||
AssertEquals('Variable name is identifier in On A : Ex do','e',V.Name);
|
||||
Assertidentifier('Variable init is exception object',V.Init,lowercase(DefaultJSExceptionObject));
|
||||
Assertidentifier('Variable init is exception object',V.Init,lowercase(DefaultVarNameExceptObject));
|
||||
R:=TJSThrowStatement(AssertElement('On block is throw statement',TJSThrowStatement,L.B));
|
||||
Assertidentifier('R expression is original exception ',R.A,lowercase(DefaultJSExceptionObject));
|
||||
Assertidentifier('R expression is original exception ',R.A,lowercase(DefaultVarNameExceptObject));
|
||||
end;
|
||||
|
||||
Procedure TTestStatementConverter.TestVariableStatement;
|
||||
|
||||
@ -164,6 +164,7 @@ type
|
||||
Procedure TestString_Compare;
|
||||
Procedure TestString_SetLength;
|
||||
Procedure TestString_CharAt;
|
||||
Procedure TestStr;
|
||||
|
||||
// alias types
|
||||
Procedure TestAliasTypeRef;
|
||||
@ -211,6 +212,7 @@ type
|
||||
Procedure TestSet_Property;
|
||||
|
||||
// statements
|
||||
Procedure TestNestBegin;
|
||||
Procedure TestIncDec;
|
||||
Procedure TestAssignments;
|
||||
Procedure TestArithmeticOperators1;
|
||||
@ -458,7 +460,7 @@ begin
|
||||
+' Col='+IntToStr(CurEngine.Scanner.CurColumn)
|
||||
+' Line="'+CurEngine.Scanner.CurLine+'"'
|
||||
);
|
||||
raise E;
|
||||
Fail(E.Message);
|
||||
end;
|
||||
end;
|
||||
//writeln('TTestModule.OnPasResolverFindUnit END ',CurUnitName);
|
||||
@ -467,7 +469,7 @@ begin
|
||||
end;
|
||||
end;
|
||||
writeln('TTestModule.OnPasResolverFindUnit missing unit "',aUnitName,'"');
|
||||
raise Exception.Create('can''t find unit "'+aUnitName+'"');
|
||||
Fail('can''t find unit "'+aUnitName+'"');
|
||||
end;
|
||||
|
||||
procedure TCustomTestModule.SetUp;
|
||||
@ -547,7 +549,7 @@ begin
|
||||
+' '+E.Filename+'('+IntToStr(E.Row)+','+IntToStr(E.Column)+')'
|
||||
+' Line="'+Scanner.CurLine+'"'
|
||||
);
|
||||
raise E;
|
||||
Fail(E.Message);
|
||||
end;
|
||||
on E: EPasResolve do
|
||||
begin
|
||||
@ -556,12 +558,12 @@ begin
|
||||
writeln('ERROR: TTestModule.ParseModule PasResolver: '+E.ClassName+':'+E.Message
|
||||
+' '+E.PasElement.SourceFilename
|
||||
+'('+IntToStr(Row)+','+IntToStr(Col)+')');
|
||||
raise E;
|
||||
Fail(E.Message);
|
||||
end;
|
||||
on E: Exception do
|
||||
begin
|
||||
writeln('ERROR: TTestModule.ParseModule Exception: '+E.ClassName+':'+E.Message);
|
||||
raise E;
|
||||
Fail(E.Message);
|
||||
end;
|
||||
end;
|
||||
AssertNotNull('Module resulted in Module',FModule);
|
||||
@ -609,7 +611,7 @@ function TCustomTestModule.AddModule(aFilename: string
|
||||
begin
|
||||
//writeln('TTestModuleConverter.AddModule ',aFilename);
|
||||
if FindModuleWithFilename(aFilename)<>nil then
|
||||
raise Exception.Create('TTestModuleConverter.AddModule: file "'+aFilename+'" already exists');
|
||||
Fail('TTestModuleConverter.AddModule: file "'+aFilename+'" already exists');
|
||||
Result:=TTestEnginePasResolver.Create;
|
||||
Result.Filename:=aFilename;
|
||||
Result.AddObjFPCBuiltInIdentifiers([btChar,btString,btLongint,btInt64,btBoolean,btDouble]);
|
||||
@ -695,14 +697,14 @@ begin
|
||||
writeln('ERROR: TTestModule.ConvertModule Scanner: '+E.ClassName+':'+E.Message
|
||||
+' '+Scanner.CurFilename
|
||||
+'('+IntToStr(Scanner.CurRow)+','+IntToStr(Scanner.CurColumn)+')');
|
||||
raise E;
|
||||
Fail(E.Message);
|
||||
end;
|
||||
on E: EParserError do begin
|
||||
WriteSource(Scanner.CurFilename,Scanner.CurRow,Scanner.CurColumn);
|
||||
writeln('ERROR: TTestModule.ConvertModule Parser: '+E.ClassName+':'+E.Message
|
||||
+' '+Scanner.CurFilename
|
||||
+'('+IntToStr(Scanner.CurRow)+','+IntToStr(Scanner.CurColumn)+')');
|
||||
raise E;
|
||||
Fail(E.Message);
|
||||
end;
|
||||
on E: EPasResolve do
|
||||
begin
|
||||
@ -711,7 +713,7 @@ begin
|
||||
writeln('ERROR: TTestModule.ConvertModule PasResolver: '+E.ClassName+':'+E.Message
|
||||
+' '+E.PasElement.SourceFilename
|
||||
+'('+IntToStr(Row)+','+IntToStr(Col)+')');
|
||||
raise E;
|
||||
Fail(E.Message);
|
||||
end;
|
||||
on E: EPas2JS do
|
||||
begin
|
||||
@ -725,12 +727,12 @@ begin
|
||||
end
|
||||
else
|
||||
writeln('ERROR: TTestModule.ConvertModule Exception: '+E.ClassName+':'+E.Message);
|
||||
raise E;
|
||||
Fail(E.Message);
|
||||
end;
|
||||
on E: Exception do
|
||||
begin
|
||||
writeln('ERROR: TTestModule.ConvertModule Exception: '+E.ClassName+':'+E.Message);
|
||||
raise E;
|
||||
Fail(E.Message);
|
||||
end;
|
||||
end;
|
||||
FJSSource:=TStringList.Create;
|
||||
@ -1526,8 +1528,7 @@ begin
|
||||
' this.FuncA(Bar);',
|
||||
'};',
|
||||
'this.FuncA = function (Bar) {',
|
||||
' if (Bar == 3) {',
|
||||
' };',
|
||||
' if (Bar == 3);',
|
||||
'};'
|
||||
]),
|
||||
LinesToStr([
|
||||
@ -1563,8 +1564,7 @@ begin
|
||||
' FuncB(i);',
|
||||
' };',
|
||||
' function FuncB(i) {',
|
||||
' if (i == 3) {',
|
||||
' };',
|
||||
' if (i == 3);',
|
||||
' };',
|
||||
' FuncC(4);',
|
||||
'};'
|
||||
@ -1628,12 +1628,9 @@ begin
|
||||
'this.i = 0;'
|
||||
]),
|
||||
LinesToStr([
|
||||
'if (this.Func2()) {',
|
||||
'};',
|
||||
'if (this.i == this.Func1()) {',
|
||||
'};',
|
||||
'if (this.i == this.Func1()) {',
|
||||
'};'
|
||||
'if (this.Func2());',
|
||||
'if (this.i == this.Func1());',
|
||||
'if (this.i == this.Func1());'
|
||||
]));
|
||||
end;
|
||||
|
||||
@ -2230,6 +2227,7 @@ begin
|
||||
Add('var');
|
||||
Add(' e: TMyEnum;');
|
||||
Add(' i: longint;');
|
||||
Add(' s: string;');
|
||||
Add('begin');
|
||||
Add(' i:=ord(red);');
|
||||
Add(' i:=ord(green);');
|
||||
@ -2244,6 +2242,9 @@ begin
|
||||
Add(' e:=succ(e);');
|
||||
Add(' e:=tmyenum(1);');
|
||||
Add(' e:=tmyenum(i);');
|
||||
Add(' s:=str(e);');
|
||||
Add(' str(e,s)');
|
||||
Add(' s:=str(e:3);');
|
||||
ConvertProgram;
|
||||
CheckSource('TestEnumNumber',
|
||||
LinesToStr([ // statements
|
||||
@ -2254,7 +2255,8 @@ begin
|
||||
' Green:1',
|
||||
' };',
|
||||
'this.e = 0;',
|
||||
'this.i = 0;'
|
||||
'this.i = 0;',
|
||||
'this.s = "";'
|
||||
]),
|
||||
LinesToStr([
|
||||
'this.i=this.TMyEnum.Red;',
|
||||
@ -2270,6 +2272,9 @@ begin
|
||||
'this.e=this.e+1;',
|
||||
'this.e=1;',
|
||||
'this.e=this.i;',
|
||||
'this.s = this.TMyEnum[this.e];',
|
||||
'this.s = this.TMyEnum[this.e];',
|
||||
'this.s = rtl.spaceLeft(this.TMyEnum[this.e], 3);',
|
||||
'']));
|
||||
end;
|
||||
|
||||
@ -2687,6 +2692,23 @@ begin
|
||||
'']));
|
||||
end;
|
||||
|
||||
procedure TTestModule.TestNestBegin;
|
||||
begin
|
||||
StartProgram(false);
|
||||
Add('begin');
|
||||
Add(' begin');
|
||||
Add(' begin');
|
||||
Add(' end;');
|
||||
Add(' begin');
|
||||
Add(' if true then ;');
|
||||
Add(' end;');
|
||||
Add(' end;');
|
||||
ConvertProgram;
|
||||
CheckSource('TestNestBegin',
|
||||
'',
|
||||
'if (true) ;');
|
||||
end;
|
||||
|
||||
procedure TTestModule.TestUnitImplVars;
|
||||
begin
|
||||
StartUnit(false);
|
||||
@ -3103,6 +3125,55 @@ begin
|
||||
'']));
|
||||
end;
|
||||
|
||||
procedure TTestModule.TestStr;
|
||||
begin
|
||||
StartProgram(false);
|
||||
Add('var');
|
||||
Add(' b: boolean;');
|
||||
Add(' i: longint;');
|
||||
Add(' d: double;');
|
||||
Add(' s: string;');
|
||||
Add('begin');
|
||||
Add(' s:=str(b);');
|
||||
Add(' s:=str(i);');
|
||||
Add(' s:=str(d);');
|
||||
Add(' s:=str(i,i);');
|
||||
Add(' s:=str(i:3);');
|
||||
Add(' s:=str(d:3:2);');
|
||||
Add(' s:=str(i:4,i);');
|
||||
Add(' s:=str(i,i:5);');
|
||||
Add(' s:=str(i:4,i:5);');
|
||||
Add(' str(b,s);');
|
||||
Add(' str(i,s);');
|
||||
Add(' str(d,s);');
|
||||
Add(' str(i:3,s);');
|
||||
Add(' str(d:3:2,s);');
|
||||
ConvertProgram;
|
||||
CheckSource('TestStr',
|
||||
LinesToStr([ // statements
|
||||
'this.b = false;',
|
||||
'this.i = 0;',
|
||||
'this.d = 0.0;',
|
||||
'this.s = "";',
|
||||
'']),
|
||||
LinesToStr([ // this.$main
|
||||
'this.s = ""+this.b;',
|
||||
'this.s = ""+this.i;',
|
||||
'this.s = ""+this.d;',
|
||||
'this.s = (""+this.i)+this.i;',
|
||||
'this.s = rtl.spaceLeft(""+this.i,3);',
|
||||
'this.s = rtl.spaceLeft(this.d.toFixed(2),3);',
|
||||
'this.s = rtl.spaceLeft("" + this.i, 4) + this.i;',
|
||||
'this.s = ("" + this.i) + rtl.spaceLeft("" + this.i, 5);',
|
||||
'this.s = rtl.spaceLeft("" + this.i, 4) + rtl.spaceLeft("" + this.i, 5);',
|
||||
'this.s = ""+this.b;',
|
||||
'this.s = ""+this.i;',
|
||||
'this.s = ""+this.d;',
|
||||
'this.s = rtl.spaceLeft(""+this.i,3);',
|
||||
'this.s = rtl.spaceLeft(this.d.toFixed(2),3);',
|
||||
'']));
|
||||
end;
|
||||
|
||||
procedure TTestModule.TestProcTwoArgs;
|
||||
begin
|
||||
StartProgram(false);
|
||||
@ -3290,7 +3361,7 @@ begin
|
||||
' var $loopend1 = 2;',
|
||||
' for (this.vI = 1; this.vI <= $loopend1; this.vI++);',
|
||||
' if(this.vI>$loopend1)this.vI--;',
|
||||
' if (this.vI==3){} ;'
|
||||
' if (this.vI==3) ;'
|
||||
]));
|
||||
end;
|
||||
|
||||
@ -3389,7 +3460,7 @@ begin
|
||||
LinesToStr([ // this.$main
|
||||
'this.vI = 1;',
|
||||
'if (vI==1) {',
|
||||
'vI=2;',
|
||||
' vI=2;',
|
||||
'}',
|
||||
'if (vI==2){ vI=3; }',
|
||||
';',
|
||||
@ -3452,6 +3523,11 @@ begin
|
||||
Add(' else');
|
||||
Add(' vi:=5');
|
||||
Add(' end;');
|
||||
Add(' try');
|
||||
Add(' VI:=6;');
|
||||
Add(' except');
|
||||
Add(' on einvalidcast do ;');
|
||||
Add(' end;');
|
||||
ConvertProgram;
|
||||
CheckSource('TestTryExcept',
|
||||
LinesToStr([ // statements
|
||||
@ -3479,21 +3555,27 @@ begin
|
||||
'};',
|
||||
'try {',
|
||||
' this.vI = 3;',
|
||||
'} catch ('+DefaultJSExceptionObject+') {',
|
||||
' throw '+DefaultJSExceptionObject+';',
|
||||
'} catch ('+DefaultVarNameExceptObject+') {',
|
||||
' throw '+DefaultVarNameExceptObject+';',
|
||||
'};',
|
||||
'try {',
|
||||
' this.vI = 4;',
|
||||
'} catch ('+DefaultJSExceptionObject+') {',
|
||||
' if (this.EInvalidCast.isPrototypeOf('+DefaultJSExceptionObject+')) throw '+DefaultJSExceptionObject,
|
||||
' else if (this.Exception.isPrototypeOf('+DefaultJSExceptionObject+')) {',
|
||||
' var E = '+DefaultJSExceptionObject+';',
|
||||
'} catch ('+DefaultVarNameExceptObject+') {',
|
||||
' if (this.EInvalidCast.isPrototypeOf('+DefaultVarNameExceptObject+')) throw '+DefaultVarNameExceptObject,
|
||||
' else if (this.Exception.isPrototypeOf('+DefaultVarNameExceptObject+')) {',
|
||||
' var E = '+DefaultVarNameExceptObject+';',
|
||||
' if (E.Msg == "") throw E;',
|
||||
' } else {',
|
||||
' this.vI = 5;',
|
||||
' }',
|
||||
'};'
|
||||
]));
|
||||
'};',
|
||||
'try {',
|
||||
' this.vI = 6;',
|
||||
'} catch ('+DefaultVarNameExceptObject+') {',
|
||||
' if (this.EInvalidCast.isPrototypeOf('+DefaultVarNameExceptObject+')){' ,
|
||||
' } else throw '+DefaultVarNameExceptObject,
|
||||
'};',
|
||||
'']));
|
||||
end;
|
||||
|
||||
procedure TTestModule.TestCaseOf;
|
||||
@ -3614,8 +3696,7 @@ begin
|
||||
]),
|
||||
LinesToStr([ // this.$main
|
||||
'var $tmp1 = this.vI;',
|
||||
'if (($tmp1 >= 1) && ($tmp1 <= 3)) this.vI = 14 else if (($tmp1 == 4) || ($tmp1 == 5)) this.vI = 16 else if ((($tmp1 >= 6) && ($tmp1 <= 7)) || (($tmp1 >= 9) && ($tmp1 <= 10))) {} else {',
|
||||
'};'
|
||||
'if (($tmp1 >= 1) && ($tmp1 <= 3)) this.vI = 14 else if (($tmp1 == 4) || ($tmp1 == 5)) this.vI = 16 else if ((($tmp1 >= 6) && ($tmp1 <= 7)) || (($tmp1 >= 9) && ($tmp1 <= 10))) ;'
|
||||
]));
|
||||
end;
|
||||
|
||||
@ -3674,8 +3755,8 @@ begin
|
||||
]),
|
||||
LinesToStr([ // this.$main
|
||||
'this.Arr = [];',
|
||||
'if (this.Arr.length == 0) {};',
|
||||
'if (0 == this.Arr.length) {};',
|
||||
'if (this.Arr.length == 0);',
|
||||
'if (0 == this.Arr.length);',
|
||||
'this.DoIt([],[]);',
|
||||
'']));
|
||||
end;
|
||||
@ -3714,8 +3795,8 @@ begin
|
||||
]),
|
||||
LinesToStr([ // this.$main
|
||||
'this.Arr2 = [];',
|
||||
'if (this.Arr2.length == 0) {};',
|
||||
'if (0 == this.Arr2.length) {};',
|
||||
'if (this.Arr2.length == 0);',
|
||||
'if (0 == this.Arr2.length);',
|
||||
'this.i = 0;',
|
||||
'this.i = 0;',
|
||||
'this.i = this.Arr2.length-1;',
|
||||
@ -4735,8 +4816,7 @@ begin
|
||||
'this.oO = this.TObject.$create("Create");',
|
||||
'this.oA = this.TClassA.$create("Create");',
|
||||
'this.oB = this.TClassB.$create("Create");',
|
||||
'if (this.TClassA.isPrototypeOf(this.oO)) {',
|
||||
'};',
|
||||
'if (this.TClassA.isPrototypeOf(this.oO));',
|
||||
'this.oB = rtl.as(this.oO, this.TClassB);',
|
||||
'rtl.as(this.oO, this.TClassB).ProcB();'
|
||||
]));
|
||||
@ -5065,7 +5145,7 @@ begin
|
||||
LinesToStr([ // this.$main
|
||||
'this.Obj = this.TObject.$create("Create");',
|
||||
'this.TObject.vI = 3;',
|
||||
'if (this.TObject.vI == 4){};',
|
||||
'if (this.TObject.vI == 4);',
|
||||
'this.TObject.Sub=null;',
|
||||
'this.Obj.$class.Sub=null;',
|
||||
'this.Obj.Sub.$class.Sub=null;',
|
||||
@ -5225,8 +5305,7 @@ begin
|
||||
]),
|
||||
LinesToStr([ // this.$main
|
||||
'this.Obj.Fy = this.Obj.Fx + 1;',
|
||||
'if (this.Obj.GetInt() == 2) {',
|
||||
'};',
|
||||
'if (this.Obj.GetInt() == 2);',
|
||||
'this.Obj.SetInt(this.Obj.GetInt() + 2);',
|
||||
'this.Obj.SetInt(this.Obj.Fx);'
|
||||
]));
|
||||
@ -5297,13 +5376,11 @@ begin
|
||||
]),
|
||||
LinesToStr([ // this.$main
|
||||
'this.TObject.Fy = this.TObject.Fx + 1;',
|
||||
'if (this.TObject.GetInt() == 2) {',
|
||||
'};',
|
||||
'if (this.TObject.GetInt() == 2);',
|
||||
'this.TObject.SetInt(this.TObject.GetInt() + 2);',
|
||||
'this.TObject.SetInt(this.TObject.Fx);',
|
||||
'this.Obj.$class.Fy = this.Obj.Fx + 1;',
|
||||
'if (this.Obj.$class.GetInt() == 2) {',
|
||||
'};',
|
||||
'if (this.Obj.$class.GetInt() == 2);',
|
||||
'this.Obj.$class.SetInt(this.Obj.$class.GetInt() + 2);',
|
||||
'this.Obj.$class.SetInt(this.Obj.Fx);'
|
||||
]));
|
||||
@ -5568,8 +5645,7 @@ begin
|
||||
'this.b = false;'
|
||||
]),
|
||||
LinesToStr([ // this.$main
|
||||
'if (this.Obj != null) {',
|
||||
'};',
|
||||
'if (this.Obj != null);',
|
||||
'this.b = (this.Obj != null) || false;'
|
||||
]));
|
||||
end;
|
||||
@ -5921,24 +5997,18 @@ begin
|
||||
'this.ProcA = function (A) {',
|
||||
' A.set(null);',
|
||||
' A.set(A.get());',
|
||||
' if (A.get() == null) {',
|
||||
' };',
|
||||
' if (null == A.get()) {',
|
||||
' };',
|
||||
' if (A.get() == null);',
|
||||
' if (null == A.get());',
|
||||
'};',
|
||||
'this.ProcB = function (A) {',
|
||||
' A.set(null);',
|
||||
' A.set(A.get());',
|
||||
' if (A.get() == null) {',
|
||||
' };',
|
||||
' if (null == A.get()) {',
|
||||
' };',
|
||||
' if (A.get() == null);',
|
||||
' if (null == A.get());',
|
||||
'};',
|
||||
'this.ProcC = function (A) {',
|
||||
' if (A == null) {',
|
||||
' };',
|
||||
' if (null == A) {',
|
||||
' };',
|
||||
' if (A == null);',
|
||||
' if (null == A);',
|
||||
'};',
|
||||
'this.o = null;',
|
||||
'']),
|
||||
|
||||
@ -529,8 +529,7 @@ begin
|
||||
'this.o = null;',
|
||||
'']),
|
||||
LinesToStr([
|
||||
'if (this.o.FFoo){',
|
||||
'};',
|
||||
'if (this.o.FFoo);',
|
||||
'']));
|
||||
end;
|
||||
|
||||
@ -566,8 +565,7 @@ begin
|
||||
'this.o = null;',
|
||||
'']),
|
||||
LinesToStr([
|
||||
'if (this.o.GetFoo()){',
|
||||
'};',
|
||||
'if (this.o.GetFoo()) ;',
|
||||
'']));
|
||||
end;
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user