mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-08-17 15:09:19 +02:00
pastojs: for in using resolver scope
git-svn-id: trunk@37803 -
This commit is contained in:
parent
7d0942a774
commit
84dbb4e2ef
@ -258,6 +258,12 @@ Works:
|
|||||||
- rg:=rg, rg1:=rg2, rg:=enum, =, <>,
|
- rg:=rg, rg1:=rg2, rg:=enum, =, <>,
|
||||||
- set of int/enum/char range, in
|
- set of int/enum/char range, in
|
||||||
- array[rg], low(array), high(array), length(array)
|
- array[rg], low(array), high(array), length(array)
|
||||||
|
- enumeration for..in..do
|
||||||
|
- enum, enum range, set of enum, set of enum range
|
||||||
|
- int, int range, set of int, set of int range
|
||||||
|
- char, char range, set of char, set of char range
|
||||||
|
- array
|
||||||
|
- class
|
||||||
|
|
||||||
ToDos:
|
ToDos:
|
||||||
- remove hasOwnProperty from rtl set functions
|
- remove hasOwnProperty from rtl set functions
|
||||||
@ -273,13 +279,6 @@ ToDos:
|
|||||||
- check memleaks
|
- check memleaks
|
||||||
- make records more lightweight
|
- make records more lightweight
|
||||||
- pointer of record
|
- pointer of record
|
||||||
- enumeration for..in..do
|
|
||||||
- enum, enum range, set of enum, set of enum range
|
|
||||||
- int, int range, set of int, set of int range
|
|
||||||
- char, char range, set of char, set of char range
|
|
||||||
- array
|
|
||||||
- operator
|
|
||||||
- class
|
|
||||||
- nested types in class
|
- nested types in class
|
||||||
- asm: pas() - useful for overloads and protect an identifier from optimization
|
- asm: pas() - useful for overloads and protect an identifier from optimization
|
||||||
- ifthen
|
- ifthen
|
||||||
@ -324,6 +323,7 @@ Not in Version 1.0:
|
|||||||
- class helpers, type helpers, record helpers,
|
- class helpers, type helpers, record helpers,
|
||||||
- generics
|
- generics
|
||||||
- operator overloading
|
- operator overloading
|
||||||
|
- operator enumerator
|
||||||
- inline
|
- inline
|
||||||
- anonymous functions
|
- anonymous functions
|
||||||
- extended RTTI
|
- extended RTTI
|
||||||
@ -1286,7 +1286,7 @@ type
|
|||||||
Procedure CreateRTTIAnonymous(El: TPasType; AContext: TConvertContext;
|
Procedure CreateRTTIAnonymous(El: TPasType; AContext: TConvertContext;
|
||||||
var First, Last: TJSStatementList); virtual;
|
var First, Last: TJSStatementList); virtual;
|
||||||
Function CreateGetEnumeratorLoop(El: TPasImplForLoop;
|
Function CreateGetEnumeratorLoop(El: TPasImplForLoop;
|
||||||
const ResolvedIn: TPasResolverResult; AContext: TConvertContext): TJSElement; virtual;
|
AContext: TConvertContext): TJSElement; virtual;
|
||||||
Function CreateCallRTLFreeLoc(Setter, Getter: TJSElement; Src: TPasElement): TJSElement; virtual;
|
Function CreateCallRTLFreeLoc(Setter, Getter: TJSElement; Src: TPasElement): TJSElement; virtual;
|
||||||
Function CreatePropertyGet(Prop: TPasProperty; Ref: TResolvedReference;
|
Function CreatePropertyGet(Prop: TPasProperty; Ref: TResolvedReference;
|
||||||
AContext: TConvertContext; PosEl: TPasElement): TJSElement; virtual;
|
AContext: TConvertContext; PosEl: TPasElement): TJSElement; virtual;
|
||||||
@ -10211,7 +10211,7 @@ begin
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
function TPasToJSConverter.CreateGetEnumeratorLoop(El: TPasImplForLoop;
|
function TPasToJSConverter.CreateGetEnumeratorLoop(El: TPasImplForLoop;
|
||||||
const ResolvedIn: TPasResolverResult; AContext: TConvertContext): TJSElement;
|
AContext: TConvertContext): TJSElement;
|
||||||
// for Item in List do
|
// for Item in List do
|
||||||
// convert to
|
// convert to
|
||||||
// var $in=List.GetEnumerator();
|
// var $in=List.GetEnumerator();
|
||||||
@ -10237,6 +10237,7 @@ var
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
var
|
var
|
||||||
|
ForScope: TPasForLoopScope;
|
||||||
Statements: TJSStatementList;
|
Statements: TJSStatementList;
|
||||||
VarSt: TJSVariableStatement;
|
VarSt: TJSVariableStatement;
|
||||||
FuncContext: TConvertContext;
|
FuncContext: TConvertContext;
|
||||||
@ -10245,48 +10246,30 @@ var
|
|||||||
TrySt: TJSTryFinallyStatement;
|
TrySt: TJSTryFinallyStatement;
|
||||||
WhileSt: TJSWhileStatement;
|
WhileSt: TJSWhileStatement;
|
||||||
AssignSt: TJSSimpleAssignStatement;
|
AssignSt: TJSSimpleAssignStatement;
|
||||||
TypeEl: TPasType;
|
|
||||||
ClassScope: TPasClassScope;
|
|
||||||
GetEnumerator, MoveNext, Current: TPasIdentifier;
|
|
||||||
GetEnumeratorFunc, MoveNextFunc: TPasFunction;
|
GetEnumeratorFunc, MoveNextFunc: TPasFunction;
|
||||||
ResolvedFunc: TPasResolverResult;
|
|
||||||
CurrentProp: TPasProperty;
|
CurrentProp: TPasProperty;
|
||||||
DotContext: TDotContext;
|
DotContext: TDotContext;
|
||||||
begin
|
begin
|
||||||
// find class
|
ForScope:=TPasForLoopScope(El.CustomData);
|
||||||
TypeEl:=AContext.Resolver.ResolveAliasType(ResolvedIn.TypeEl);
|
|
||||||
if not (TypeEl is TPasClassType) then
|
|
||||||
RaiseNotSupported(El.StartExpr,AContext,20171221212820);
|
|
||||||
ClassScope:=TypeEl.CustomData as TPasClassScope;
|
|
||||||
// find function GetEnumerator
|
// find function GetEnumerator
|
||||||
GetEnumerator:=ClassScope.FindIdentifier('GetEnumerator');
|
GetEnumeratorFunc:=ForScope.GetEnumerator;
|
||||||
if GetEnumerator=nil then
|
if (GetEnumeratorFunc=nil) then
|
||||||
RaiseNotSupported(El.StartExpr,AContext,20171221212820);
|
RaiseNotSupported(El,AContext,20171225104212);
|
||||||
if GetEnumerator.Element.ClassType<>TPasFunction then
|
if GetEnumeratorFunc.ClassType<>TPasFunction then
|
||||||
RaiseNotSupported(El.StartExpr,AContext,20171221212820);
|
RaiseNotSupported(El,AContext,20171225104237);
|
||||||
GetEnumeratorFunc:=TPasFunction(GetEnumerator.Element);
|
|
||||||
// find enumerator class
|
|
||||||
AContext.Resolver.ComputeElement(GetEnumeratorFunc.FuncType.ResultEl,ResolvedFunc,[rcType]);
|
|
||||||
if ResolvedFunc.BaseType<>btContext then
|
|
||||||
RaiseNotSupported(El.StartExpr,AContext,20171221213612);
|
|
||||||
TypeEl:=AContext.Resolver.ResolveAliasType(ResolvedFunc.TypeEl);
|
|
||||||
if not (TypeEl is TPasClassType) then
|
|
||||||
RaiseNotSupported(El.StartExpr,AContext,20171221213632);
|
|
||||||
ClassScope:=TypeEl.CustomData as TPasClassScope;
|
|
||||||
// find function MoveNext
|
// find function MoveNext
|
||||||
MoveNext:=ClassScope.FindIdentifier('MoveNext');
|
MoveNextFunc:=ForScope.MoveNext;
|
||||||
if MoveNext=nil then
|
if (MoveNextFunc=nil) then
|
||||||
RaiseNotSupported(El.StartExpr,AContext,20171221213747);
|
RaiseNotSupported(El,AContext,20171225104249);
|
||||||
if MoveNext.Element.ClassType<>TPasFunction then
|
if MoveNextFunc.ClassType<>TPasFunction then
|
||||||
RaiseNotSupported(El.StartExpr,AContext,20171221213754);
|
RaiseNotSupported(El,AContext,20171225104256);
|
||||||
MoveNextFunc:=TPasFunction(MoveNext.Element);
|
|
||||||
// find property Current
|
// find property Current
|
||||||
Current:=ClassScope.FindIdentifier('Current');
|
CurrentProp:=ForScope.Current;
|
||||||
if Current=nil then
|
if (CurrentProp=nil) then
|
||||||
RaiseNotSupported(El.StartExpr,AContext,20171221213911);
|
RaiseNotSupported(El,AContext,20171225104306);
|
||||||
if Current.Element.ClassType<>TPasProperty then
|
if CurrentProp.ClassType<>TPasProperty then
|
||||||
RaiseNotSupported(El.StartExpr,AContext,20171221213921);
|
RaiseNotSupported(El,AContext,20171225104316);
|
||||||
CurrentProp:=TPasProperty(Current.Element);
|
|
||||||
|
|
||||||
// get function context
|
// get function context
|
||||||
FuncContext:=AContext;
|
FuncContext:=AContext;
|
||||||
@ -10844,12 +10827,12 @@ var
|
|||||||
StartInt, EndInt: MaxPrecInt;
|
StartInt, EndInt: MaxPrecInt;
|
||||||
HasLoopVar, HasEndVar, HasInVar: Boolean;
|
HasLoopVar, HasEndVar, HasInVar: Boolean;
|
||||||
InKind: TInKind;
|
InKind: TInKind;
|
||||||
|
ForScope: TPasForLoopScope;
|
||||||
|
|
||||||
function InitWithResolver: boolean;
|
function InitWithResolver: boolean;
|
||||||
var
|
var
|
||||||
EnumType: TPasEnumType;
|
EnumType: TPasEnumType;
|
||||||
TypeEl: TPasType;
|
TypeEl: TPasType;
|
||||||
C: TClass;
|
|
||||||
begin
|
begin
|
||||||
Result:=true;
|
Result:=true;
|
||||||
AContext.Resolver.ComputeElement(El.VariableName,ResolvedVar,[rcNoImplicitProc]);
|
AContext.Resolver.ComputeElement(El.VariableName,ResolvedVar,[rcNoImplicitProc]);
|
||||||
@ -10867,19 +10850,13 @@ var
|
|||||||
end;
|
end;
|
||||||
ltIn:
|
ltIn:
|
||||||
begin
|
begin
|
||||||
AContext.Resolver.ComputeElement(El.StartExpr,ResolvedIn,[]);
|
if ForScope.GetEnumerator<>nil then
|
||||||
|
|
||||||
if (ResolvedIn.BaseType=btContext) then
|
|
||||||
begin
|
begin
|
||||||
TypeEl:=AContext.Resolver.ResolveAliasType(ResolvedIn.TypeEl);
|
ConvertForStatement:=CreateGetEnumeratorLoop(El,AContext);
|
||||||
C:=TypeEl.ClassType;
|
exit(false);
|
||||||
if C=TPasClassType then
|
|
||||||
begin
|
|
||||||
ConvertForStatement:=CreateGetEnumeratorLoop(El,ResolvedIn,AContext);
|
|
||||||
exit(false);
|
|
||||||
end;
|
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
AContext.Resolver.ComputeElement(El.StartExpr,ResolvedIn,[]);
|
||||||
HasInVar:=true;
|
HasInVar:=true;
|
||||||
InValue:=AContext.Resolver.Eval(El.StartExpr,[],false);
|
InValue:=AContext.Resolver.Eval(El.StartExpr,[],false);
|
||||||
if InValue=nil then
|
if InValue=nil then
|
||||||
@ -11079,6 +11056,7 @@ begin
|
|||||||
Result:=Nil;
|
Result:=Nil;
|
||||||
if AContext.Access<>caRead then
|
if AContext.Access<>caRead then
|
||||||
RaiseInconsistency(20170213213740);
|
RaiseInconsistency(20170213213740);
|
||||||
|
ForScope:=El.CustomData as TPasForLoopScope; // can be nil!
|
||||||
case El.LoopType of
|
case El.LoopType of
|
||||||
ltNormal,ltDown: ;
|
ltNormal,ltDown: ;
|
||||||
ltIn:
|
ltIn:
|
||||||
|
Loading…
Reference in New Issue
Block a user