123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339(*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*)openFlow_asttype'locbinding='loc*stringtype'locident='loc*stringtype'locsource='loc*stringletrecfold_bindings_of_pattern=Pattern.(letpropertyfacc=Object.(function|Property(_,{Property.pattern=p;_})|RestElement(_,{RestElement.argument=p;comments=_})->fold_bindings_of_patternfaccp)inletelementfacc=Array.(function|Hole_->acc|Element(_,{Element.argument=p;default=_})|RestElement(_,{RestElement.argument=p;comments=_})->fold_bindings_of_patternfaccp)infunfacc->function|(_,Identifier{Identifier.name;_})->faccname|(_,Object{Object.properties;_})->List.fold_left(propertyf)accproperties|(_,Array{Array.elements;_})->List.fold_left(elementf)accelements(* This is for assignment and default param destructuring `[a.b=1]=c`, ignore these for now. *)|(_,Expression_)->acc)letfold_bindings_of_variable_declarationsfaccdeclarations=letopenFlow_ast.Statement.VariableDeclarationinList.fold_left(funacc->function|(_,{Declarator.id=pattern;_})->lethas_anno=(* Only the toplevel annotation in a pattern is meaningful *)letopenFlow_ast.Patterninmatchpatternwith|(_,Array{Array.annot=Flow_ast.Type.Available_;_})|(_,Object{Object.annot=Flow_ast.Type.Available_;_})|(_,Identifier{Identifier.annot=Flow_ast.Type.Available_;_})->true|_->falseinfold_bindings_of_pattern(fhas_anno)accpattern)accdeclarationsletpartition_directivesstatements=letopenFlow_ast.Statementinletrechelperdirectives=function|((_,Expression{Expression.directive=Some_;_})asdirective)::rest->helper(directive::directives)rest|rest->(List.revdirectives,rest)inhelper[]statementslethoist_function_declarationsstmts=letopenFlow_ast.Statementinlet(func_decs,other_stmts)=List.partition(function(* function f() {} *)|(_,FunctionDeclaration{Flow_ast.Function.id=Some_;_})(* export function f() {} *)|(_,ExportNamedDeclaration{ExportNamedDeclaration.declaration=Some(_,FunctionDeclaration{Flow_ast.Function.id=Some_;_});_;})(* export default function f() {} *)|(_,ExportDefaultDeclaration{ExportDefaultDeclaration.declaration=ExportDefaultDeclaration.Declaration(_,FunctionDeclaration{Flow_ast.Function.id=Some_;_});_;})(* declare function f(): void; *)|(_,DeclareFunction_)(* declare export function f(): void; *)|(_,DeclareExportDeclarationDeclareExportDeclaration.{declaration=Some(Function_);_})->true|_->false)stmtsinfunc_decs@other_stmtsletnegate_number_literal(value,raw)=letraw_len=String.lengthrawinletraw=ifraw_len>0&&raw.[0]='-'thenString.subraw1(raw_len-1)else"-"^rawin(~-.value,raw)letis_call_to_invariantcallee=matchcalleewith|(_,Expression.Identifier(_,{Identifier.name="invariant";_}))->true|_->falseletis_call_to_is_arraycallee=matchcalleewith|(_,Flow_ast.Expression.Member{Flow_ast.Expression.Member._object=(_,Flow_ast.Expression.Identifier(_,{Flow_ast.Identifier.name="Array";comments=_}));property=Flow_ast.Expression.Member.PropertyIdentifier(_,{Flow_ast.Identifier.name="isArray";comments=_});comments=_;})->true|_->falseletis_call_to_object_dot_freezecallee=matchcalleewith|(_,Flow_ast.Expression.Member{Flow_ast.Expression.Member._object=(_,Flow_ast.Expression.Identifier(_,{Flow_ast.Identifier.name="Object";comments=_}));property=Flow_ast.Expression.Member.PropertyIdentifier(_,{Flow_ast.Identifier.name="freeze";comments=_});comments=_;})->true|_->falseletis_call_to_object_static_methodcallee=matchcalleewith|(_,Flow_ast.Expression.Member{Flow_ast.Expression.Member._object=(_,Flow_ast.Expression.Identifier(_,{Flow_ast.Identifier.name="Object";comments=_}));property=Flow_ast.Expression.Member.PropertyIdentifier_;comments=_;})->true|_->falseletloc_of_statement=fstletloc_of_expression=fstletloc_of_pattern=fstletloc_of_ident=fstletname_of_ident(_,{Identifier.name;comments=_})=nameletsource_of_ident(loc,{Identifier.name;comments=_})=(loc,name)letident_of_source?comments(loc,name)=(loc,{Identifier.name;comments})letmk_comments?(leading=[])?(trailing=[])a={Syntax.leading;trailing;internal=a}letmk_comments_opt?(leading=[])?(trailing=[])()=match(leading,trailing)with|([],[])->None|(_,_)->Some(mk_comments~leading~trailing())letmk_comments_with_internal_opt?(leading=[])?(trailing=[])~internal()=match(leading,trailing,internal)with|([],[],[])->None|_->Some(mk_comments~leading~trailinginternal)letmerge_comments~inner~outer=letopenSyntaxinmatch(inner,outer)with|(None,c)|(c,None)->c|(Someinner,Someouter)->mk_comments_opt~leading:(outer.leading@inner.leading)~trailing:(inner.trailing@outer.trailing)()letmerge_comments_with_internal~inner~outer=match(inner,outer)with|(inner,None)->inner|(None,Some{Syntax.leading;trailing;_})->mk_comments_with_internal_opt~leading~trailing~internal:[]()|(Some{Syntax.leading=inner_leading;trailing=inner_trailing;internal},Some{Syntax.leading=outer_leading;trailing=outer_trailing;_})->mk_comments_with_internal_opt~leading:(outer_leading@inner_leading)~trailing:(inner_trailing@outer_trailing)~internal()letsplit_commentscomments=matchcommentswith|None->(None,None)|Some{Syntax.leading;trailing;_}->(mk_comments_opt~leading(),mk_comments_opt~trailing())letstring_of_assignment_operatorop=letopenFlow_ast.Expression.Assignmentinmatchopwith|PlusAssign->"+="|MinusAssign->"-="|MultAssign->"*="|ExpAssign->"**="|DivAssign->"/="|ModAssign->"%="|LShiftAssign->"<<="|RShiftAssign->">>="|RShift3Assign->">>>="|BitOrAssign->"|="|BitXorAssign->"^="|BitAndAssign->"&="|NullishAssign->"??="|AndAssign->"&&="|OrAssign->"||="letstring_of_binary_operatorop=letopenFlow_ast.Expression.Binaryinmatchopwith|Equal->"=="|NotEqual->"!="|StrictEqual->"==="|StrictNotEqual->"!=="|LessThan->"<"|LessThanEqual->"<="|GreaterThan->">"|GreaterThanEqual->">="|LShift->"<<"|RShift->">>"|RShift3->">>>"|Plus->"+"|Minus->"-"|Mult->"*"|Exp->"**"|Div->"/"|Mod->"%"|BitOr->"|"|Xor->"^"|BitAnd->"&"|In->"in"|Instanceof->"instanceof"moduleExpressionSort=structtypet=|Array|ArrowFunction|Assignment|Binary|Call|Class|Comprehension|Conditional|Function|Generator|Identifier|Import|JSXElement|JSXFragment|Literal|Logical|Member|MetaProperty|New|Object|OptionalCall|OptionalMember|Sequence|Super|TaggedTemplate|TemplateLiteral|This|TypeCast|Unary|Update|Yieldletto_string=function|Array->"array"|ArrowFunction->"arrow function"|Assignment->"assignment expression"|Binary->"binary expression"|Call->"call expression"|Class->"class"|Comprehension->"comprehension expression"|Conditional->"conditional expression"|Function->"function"|Generator->"generator"|Identifier->"identifier"|Import->"import expression"|JSXElement->"JSX element"|JSXFragment->"JSX fragment"|Literal->"literal"|Logical->"logical expression"|Member->"member expression"|MetaProperty->"metaproperty expression"|New->"new expression"|Object->"object"|OptionalCall->"optional call expression"|OptionalMember->"optional member expression"|Sequence->"sequence"|Super->"`super` reference"|TaggedTemplate->"tagged template expression"|TemplateLiteral->"template literal"|This->"`this` reference"|TypeCast->"type cast"|Unary->"unary expression"|Update->"update expression"|Yield->"yield expression"end