/* Ċ Ġ* ĠMinecraft ĠDev Ġfor ĠIntelliJ Ċ Ġ* Ċ Ġ* Ġhttps :// minecraft dev . org Ċ Ġ* Ċ Ġ* ĠCopyright Ġ( c ) Ġ 2 0 2 1 Ġm inecraft - dev Ċ Ġ* Ċ Ġ* ĠMIT ĠLicense Ċ Ġ*/ Ċ Ċ package Ġcom . de mon wav . mc dev . platform . mixin . fold ing Ċ Ċ import Ġcom . de mon wav . mc dev . platform . mixin . Mixin Module Type Ċ import Ġcom . de mon wav . mc dev . platform . mixin . handlers . Accessor Handler Ċ import Ġcom . de mon wav . mc dev . platform . mixin . handlers . Invoker Handler Ċ import Ġcom . de mon wav . mc dev . platform . mixin . util . Mixin Constants . Annotations . ACCESS OR Ċ import Ġcom . de mon wav . mc dev . platform . mixin . util . Mixin Constants . Annotations . INV OK ER Ċ import Ġcom . de mon wav . mc dev . util . referenced Method Ċ import Ġcom . intellij . lang . AST Node Ċ import Ġcom . intellij . lang . fold ing . Custom Fold ing Builder Ċ import Ġcom . intellij . lang . fold ing . Fold ing Descriptor Ċ import Ġcom . intellij . openapi . editor . Document Ċ import Ġcom . intellij . openapi . editor . Fold ing Group Ċ import Ġcom . intellij . openapi . util . Text Range Ċ import Ġcom . intellij . psi . Java Recursive Element Walk ing Visitor Ċ import Ġcom . intellij . psi . Java TokenType Ċ import Ġcom . intellij . psi . Psi Element Ċ import Ġcom . intellij . psi . Psi Identifier Ċ import Ġcom . intellij . psi . Psi Java File Ċ import Ġcom . intellij . psi . Psi MethodCall Expression Ċ import Ġcom . intellij . psi . Psi Parent hesized Expression Ċ import Ġcom . intellij . psi . Psi Type Ċ import Ġcom . intellij . psi . Psi Type Cast Expression Ċ import Ġcom . intellij . psi . util . elementType Ċ import Ġcom . intellij . psi . util . parent OfType Ċ Ċ class ĠAccess or Mixin Fold ing Builder Ġ: ĠCustom Fold ing Builder () Ġ{ ĊĊĠĠĠ Ġoverride Ġfun Ġis D umb Aware (): ĠBoolean Ġ= Ġfalse ĊĊĠĠĠ Ġoverride Ġfun Ġis Region Collapsed ByDefault ( node : ĠAST Node ): ĠBoolean Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġsettings Ġ= ĠM ixin Fold ing Settings . instance . state ĊĠĠĠĠĠĠĠ Ġval Ġelement Ġ= Ġnode . psi ĊĠĠĠĠĠĠĠ Ġval Ġparent Ġ= Ġelement . parent OfType < Psi MethodCall Expression >() Ġ?: Ġreturn Ġfalse ĊĠĠĠĠĠĠĠ Ġval Ġref Method Ġ= Ġparent . referenced Method ĊĊĠĠĠĠĠĠĠ Ġreturn Ġwhen Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġref Method Ġ== Ġnull Ġ-> Ġfalse ĊĠĠĠĠĠĠĠĠĠĠĠ Ġref Method . has Annotation ( INV OK ER ) Ġ-> Ġwhen Ġ( element ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġis ĠPsi Identifier Ġ-> Ġsettings . fold Invoker Method Calls ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġis ĠPsi Parent hesized Expression Ġ-> Ġsettings . fold Invoker Cast s ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġelse Ġ-> Ġfalse ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġref Method . has Annotation ( ACCESS OR ) Ġ-> Ġwhen Ġ( element ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġis ĠPsi Identifier Ġ-> Ġsettings . fold Accessor Method Calls ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġis ĠPsi Parent hesized Expression Ġ-> Ġsettings . fold Accessor Cast s ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġelse Ġ-> Ġfalse ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġelse Ġ-> Ġfalse ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun Ġget Language Placeholder Text ( node : ĠAST Node , Ġrange : ĠText Range ): ĠString Ġ{ ĊĠĠĠĠĠĠĠ Ġ// ĠAccess or Ġparentheses ĊĠĠĠĠĠĠĠ Ġif Ġ( node . elementType Ġ== ĠJava TokenType . LP AREN TH Ġ|| Ġnode . elementType Ġ== ĠJava TokenType . RP AREN TH ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġ"" ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġreturn Ġwhen Ġ( val Ġelement Ġ= Ġnode . psi ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġis ĠPsi Parent hesized Expression Ġ-> Ġfold Accessor Cast Expression ( element ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġis ĠPsi Identifier Ġ-> Ġfold Accessor Identifier ( element ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġelse Ġ-> Ġnull ĊĠĠĠĠĠĠĠ Ġ} Ġ?: Ġnode . text ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġfold Accessor Identifier ( identifier : ĠPsi Identifier ): ĠString ? Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġexpr Ġ= Ġidentifier . parent OfType < Psi MethodCall Expression >() Ġ?: Ġreturn Ġnull ĊĠĠĠĠĠĠĠ Ġval Ġmethod Ġ= Ġexpr . referenced Method Ġ?: Ġreturn Ġnull ĊĊĠĠĠĠĠĠĠ Ġif Ġ( method . has Annotation ( INV OK ER )) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĠInv oker Handler . getInstance ()?. find Invoker Target For Reference ( method )?. element ?. name ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġif Ġ( method . has Annotation ( ACCESS OR )) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġname Ġ= ĠAccess or Handler . getInstance ()?. find Accessor Target For Reference ( method )?. element ?. name ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ?: Ġreturn Ġnull ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn Ġif Ġ( method . returnType Ġ== ĠPsi Type . VOID ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ"$ name Ġ= Ġ" ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} Ġelse Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġname ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġreturn Ġnull ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġfun Ġfold Accessor Cast Expression ( expr : ĠPsi Parent hesized Expression ): ĠString ? Ġ{ ĊĠĠĠĠĠĠĠ Ġval Ġcast Expression Ġ= Ġexpr . expression Ġas ? ĠPsi Type Cast Expression Ġ?: Ġreturn Ġnull ĊĠĠĠĠĠĠĠ Ġreturn Ġcast Expression . operand ?. text ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġoverride Ġfun Ġbuild Language Fold Regions ( ĊĠĠĠĠĠĠĠ Ġdescriptors : ĠMutable List < Fold ing Descriptor >, ĊĠĠĠĠĠĠĠ Ġroot : ĠPsi Element , ĊĠĠĠĠĠĠĠ Ġdocument : ĠDocument , ĊĠĠĠĠĠĠĠ Ġquick : ĠBoolean ĊĠĠĠ Ġ) Ġ{ ĊĠĠĠĠĠĠĠ Ġif Ġ( root Ġ! is ĠPsi Java File Ġ|| Ġ! Mixin Module Type . isIn Module ( root )) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġroot . accept ( Visitor ( descriptors )) ĊĠĠĠ Ġ} ĊĊĠĠĠ Ġprivate Ġclass ĠVisitor ( private Ġval Ġdescriptors : ĠMutable List < Fold ing Descriptor >) Ġ: ĊĠĠĠĠĠĠĠ ĠJava Recursive Element Walk ing Visitor () Ġ{ ĊĊĠĠĠĠĠĠĠ Ġval Ġsettings Ġ= ĠM ixin Fold ing Settings . instance . state ĊĊĠĠĠĠĠĠĠ Ġoverride Ġfun Ġvisit MethodCall Expression ( expression : ĠPsi MethodCall Expression ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġsuper . visit MethodCall Expression ( expression ) ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ! settings . fold Invoker Cast s Ġ&& Ġ! settings . fold Invoker Method Calls Ġ&& ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ! settings . fold Accessor Cast s Ġ&& Ġ! settings . fold Accessor Method Calls ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠThis Ġis Ġwhat Ġwe 're Ġactually Ġgoing Ġto Ġfold , Ġnot Ġthe ĠPsi MethodCall Expression ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġreference Expression Ġ= Ġexpression . method Expression ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġref Method Ġ= Ġexpression . referenced Method Ġ?: Ġreturn ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġinvok er Ġ= Ġref Method . has Annotation ( INV OK ER ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( inv oker Ġ&& Ġ! settings . fold Invoker Cast s Ġ&& Ġ! settings . fold Invoker Method Calls ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġaccessor Ġ= Ġref Method . has Annotation ( ACCESS OR ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( accessor Ġ&& Ġ! settings . fold Accessor Cast s Ġ&& Ġ! settings . fold Accessor Method Calls ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠThe Ġfinal Ġelement Ġmust Ġbe Ġa Ġmethod Ġname Ġ( identifier ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġidentifier Ġ= Ġreference Expression . last Child Ġas ? ĠPsi Identifier Ġ?: Ġreturn ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( inv oker Ġ&& Ġsettings . fold Invoker Method Calls ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġdescriptors . add ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠFold ing Descriptor ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġidentifier . node , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġidentifier . text Range ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( accessor Ġ&& Ġsettings . fold Accessor Method Calls ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġfold Accessor MethodCall ( expression , Ġidentifier ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠWe Ġhave Ġfol ded Ġthe Ġmethod Ġcall Ġby Ġthis Ġpoint ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠNow Ġwe Ġneed Ġto Ġdecide Ġto Ġfold Ġthe Ġcast Ġexpression ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠNote : ĠThere Ġmay Ġnot Ġbe Ġa Ġcast Ġexpression ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠThe Ġpattern Ġwe 're Ġexpecting Ġis Ġsomething Ġlike : ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠĠĠĠ Ġ(( Mixin World Accessor ) Ġworld ). call Some Method (...) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠSo Ġif Ġthere 's Ġa Ġcast Ġexpression Ġhere Ġit 'll Ġbe Ġinside Ġa Ġp aren this ized Ġexpression ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġparent het ical Ġ= Ġreference Expression . firstChild Ġas ? ĠPsi Parent hesized Expression Ġ?: Ġreturn ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġcast Expression Ġ= Ġparent het ical . expression Ġas ? ĠPsi Type Cast Expression Ġ?: Ġreturn ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠCan 't Ġfold Ġwithout Ġan Ġoperand ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( cast Expression . operand Ġ== Ġnull ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ(( inv oker Ġ&& Ġsettings . fold Invoker Cast s ) Ġ|| Ġ( accessor Ġ&& Ġsettings . fold Accessor Cast s )) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġdescriptors . add ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠFold ing Descriptor ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġparent het ical . node , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġparent het ical . text Range ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠ Ġprivate Ġfun Ġfold Accessor MethodCall ( ĊĠĠĠĠĠĠĠĠĠĠĠ Ġexpression : ĠPsi MethodCall Expression , ĊĠĠĠĠĠĠĠĠĠĠĠ Ġidentifier : ĠPsi Identifier ĊĠĠĠĠĠĠĠ Ġ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġargument List Ġ= Ġexpression . argument List ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġopen Paren Ġ= Ġargument List . firstChild ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġclose Paren Ġ= Ġargument List . last Child ĊĠĠĠĠĠĠĠĠĠĠĠ Ġif Ġ( open Paren . elementType Ġ!== ĠJava TokenType . LP AREN TH Ġ|| Ġclose Paren . elementType Ġ!== ĠJava TokenType . RP AREN TH ) Ġ{ ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġreturn ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ} ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠAll Ġof Ġthese Ġfold s Ġgo Ġtogether ĊĠĠĠĠĠĠĠĠĠĠĠ Ġval Ġgroup Ġ= ĠFold ing Group . new Group (" access MethodCall ") ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠFor Ġa Ġgetter Ġwe Ġcould Ġdo Ġboth Ġ() Ġin Ġa Ġsingle Ġfold ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġbut Ġfor Ġa Ġsetter Ġwe Ġhave Ġto Ġdo Ġthem Ġseparate Ġ( since Ġthere 's Ġan Ġexpression Ġin Ġside Ġof Ġthem ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// ĠIn Ġpractice Ġit Ġdoesn 't Ġreally Ġmatter , Ġso Ġjust Ġalways Ġhandling Ġthem Ġseparate Ġreduce 's Ġthe Ġnumber Ġof ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ// Ġspecial Ġcases Ġthe Ġcode Ġhas Ġto Ġunderstand . ĊĠĠĠĠĠĠĠĠĠĠĠ Ġdescriptors . add ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠFold ing Descriptor ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġopen Paren . node , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġopen Paren . text Range , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġgroup ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġdescriptors . add ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠFold ing Descriptor ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġclose Paren . node , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġclose Paren . text Range , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġgroup ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĊĠĠĠĠĠĠĠĠĠĠĠ Ġdescriptors . add ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ ĠFold ing Descriptor ( ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġidentifier . node , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġidentifier . text Range , ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġgroup ĊĠĠĠĠĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠĠĠĠĠ Ġ) ĊĠĠĠĠĠĠĠ Ġ} ĊĠĠĠ Ġ} Ċ } Ċ