pastojs: for in using resolver scope

git-svn-id: trunk@37803 -
This commit is contained in:
Mattias Gaertner 2017-12-25 09:50:27 +00:00
parent 7d0942a774
commit 84dbb4e2ef

View File

@ -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: