@@ -32,6 +32,16 @@ const CONFIG_AIRMOBILE = "airmobile";
3232
3333const PROFILE_MOBILE_DEVICE = "mobileDevice" ;
3434
35+ const AIR_PLATFORM_TYPES = [
36+ "air" ,
37+ "ios" ,
38+ "ios_simulator" ,
39+ "android" ,
40+ "windows" ,
41+ "mac" ,
42+ "linux" ,
43+ ] ;
44+
3545interface SWFDebugConfiguration extends vscode . DebugConfiguration {
3646 program ?: string ;
3747 profile ?: string ;
@@ -129,24 +139,48 @@ export default class SWFDebugConfigurationProvider
129139 }
130140 asconfigPath = asconfigPathParts . slice ( 1 ) . join ( path . sep ) ;
131141 }
132- let asconfigJSON : any = null ;
142+ let asconfigJSON : any | null = null ;
133143 if ( workspaceFolder !== undefined ) {
134144 asconfigPath ??= FILE_NAME_ASCONFIG_JSON ;
135- if ( asconfigPath && ! path . isAbsolute ( asconfigPath ) ) {
145+ if ( ! path . isAbsolute ( asconfigPath ) ) {
136146 asconfigPath = path . resolve ( workspaceFolder . uri . fsPath , asconfigPath ) ;
137147 }
138- if ( asconfigPath && fs . existsSync ( asconfigPath ) ) {
139- try {
140- let asconfigFile = fs . readFileSync ( asconfigPath , "utf8" ) ;
141- asconfigJSON = json5 . parse ( asconfigFile ) ;
142- } catch ( error ) {
143- //something went terribly wrong!
144- vscode . window . showErrorMessage (
145- `Failed to debug SWF. Error reading file: ${ asconfigPath } `
146- ) ;
147- console . error ( error ) ;
148- return undefined ;
148+ let currentAsconfigPath : string | null = asconfigPath ;
149+ while ( currentAsconfigPath ) {
150+ if ( fs . existsSync ( currentAsconfigPath ) ) {
151+ try {
152+ const asconfigFile : string = fs . readFileSync (
153+ currentAsconfigPath ,
154+ "utf8"
155+ ) ;
156+ const parsedAsconfigFile : any = json5 . parse ( asconfigFile ) ;
157+ if ( asconfigJSON ) {
158+ asconfigJSON = mergeConfigs ( asconfigJSON , parsedAsconfigFile ) ;
159+ } else {
160+ asconfigJSON = parsedAsconfigFile ;
161+ }
162+ if ( parsedAsconfigFile . extends ) {
163+ currentAsconfigPath = parsedAsconfigFile . extends ;
164+ if ( currentAsconfigPath ) {
165+ if ( ! path . isAbsolute ( currentAsconfigPath ) ) {
166+ currentAsconfigPath = path . resolve (
167+ workspaceFolder . uri . fsPath ,
168+ currentAsconfigPath
169+ ) ;
170+ }
171+ continue ;
172+ }
173+ }
174+ } catch ( error ) {
175+ //something went terribly wrong!
176+ vscode . window . showErrorMessage (
177+ `Failed to debug SWF. Error reading file: ${ currentAsconfigPath } `
178+ ) ;
179+ console . error ( error ) ;
180+ return undefined ;
181+ }
149182 }
183+ currentAsconfigPath = null ;
150184 }
151185 }
152186 if ( ! asconfigPath ) {
@@ -644,3 +678,275 @@ function findApplicationID(appDescriptorContent: string): string | undefined {
644678 }
645679 return undefined ;
646680}
681+
682+ function mergeConfigs ( configData : any , baseConfigData : any ) : any {
683+ const result : any = { } ;
684+ const keys = new Set < PropertyKey > ( ) ;
685+ for ( const key in baseConfigData ) {
686+ if ( baseConfigData . hasOwnProperty ( key ) ) {
687+ keys . add ( key ) ;
688+ }
689+ }
690+ for ( const key in configData ) {
691+ if ( configData . hasOwnProperty ( key ) ) {
692+ keys . add ( key ) ;
693+ }
694+ }
695+ keys . forEach ( function (
696+ value : PropertyKey ,
697+ key : PropertyKey ,
698+ set : Set < PropertyKey >
699+ ) : void {
700+ if ( key === "extends" ) {
701+ //safe to skip
702+ return ;
703+ }
704+ var hasConfig = configData . hasOwnProperty ( key ) ;
705+ var hasBase = baseConfigData . hasOwnProperty ( key ) ;
706+ if ( hasConfig && hasBase ) {
707+ if ( key === "application" ) {
708+ result [ key ] = mergeApplication ( configData [ key ] , baseConfigData [ key ] ) ;
709+ } else if ( key === "compilerOptions" ) {
710+ result [ key ] = mergeCompilerOptions (
711+ configData [ key ] ,
712+ baseConfigData [ key ]
713+ ) ;
714+ } else if ( key === "airOptions" ) {
715+ result [ key ] = mergeAIROptions (
716+ configData [ key ] ,
717+ baseConfigData [ key ] ,
718+ true
719+ ) ;
720+ } else {
721+ result [ key ] = mergeObjectsSimple ( configData [ key ] , baseConfigData [ key ] ) ;
722+ }
723+ } else if ( hasConfig ) {
724+ result [ key ] = configData [ key ] ;
725+ } else if ( hasBase ) {
726+ result [ key ] = baseConfigData [ key ] ;
727+ }
728+ } ) ;
729+ return result ;
730+ }
731+
732+ function mergeObjectsSimple ( object : any , baseObject : any ) : any {
733+ if ( typeof object !== "object" || Array . isArray ( object ) ) {
734+ return object ;
735+ }
736+ var result : any = { } ;
737+ for ( const key in baseObject ) {
738+ if ( baseObject . hasOwnProperty ( key ) ) {
739+ result [ key ] = baseObject [ key ] ;
740+ }
741+ }
742+ for ( const key in object ) {
743+ if ( object . hasOwnProperty ( key ) ) {
744+ result [ key ] = object [ key ] ;
745+ }
746+ }
747+ return result ;
748+ }
749+
750+ function mergeArrays ( array : any [ ] , baseArray : any [ ] ) : any [ ] {
751+ const result : any [ ] = baseArray . slice ( ) ;
752+ for ( const item of array ) {
753+ const isObject = typeof item === "object" ;
754+ if (
755+ ! result . find ( function ( existingItem : any ) : boolean {
756+ if ( isObject ) {
757+ for ( const key in existingItem ) {
758+ if ( ! ( key in item ) || item [ key ] !== existingItem [ key ] ) {
759+ return false ;
760+ }
761+ }
762+ for ( const key in item ) {
763+ if ( ! ( key in existingItem ) || item [ key ] !== existingItem [ key ] ) {
764+ return false ;
765+ }
766+ }
767+ return true ;
768+ }
769+ return item === existingItem ;
770+ } )
771+ ) {
772+ result . push ( item ) ;
773+ }
774+ }
775+ return result ;
776+ }
777+
778+ function mergeArrayWithComparisonKey (
779+ array : any [ ] ,
780+ baseArray : any [ ] ,
781+ comparisonKey : string
782+ ) : any [ ] {
783+ var result : any [ ] = array . slice ( ) ;
784+ var values = new Set < any > ( ) ;
785+ for ( const pair of array ) {
786+ values . add ( pair [ comparisonKey ] ) ;
787+ }
788+ for ( const pair of baseArray ) {
789+ var valueToCompare : any = pair [ comparisonKey ] ;
790+ if ( values . has ( valueToCompare ) ) {
791+ //if we already added this value, skip it because its been
792+ //overridden in the main config
793+ continue ;
794+ }
795+ result . push ( pair ) ;
796+ }
797+ return result ;
798+ }
799+
800+ function mergeCompilerOptions (
801+ compilerOptions : any ,
802+ baseCompilerOptions : any
803+ ) : any {
804+ const result : any = { } ;
805+ for ( const key in baseCompilerOptions ) {
806+ if ( baseCompilerOptions . hasOwnProperty ( key ) ) {
807+ result [ key ] = baseCompilerOptions [ key ] ;
808+ }
809+ }
810+ for ( const key in compilerOptions ) {
811+ if ( compilerOptions . hasOwnProperty ( key ) ) {
812+ var newValue : any = compilerOptions [ key ] ;
813+ if ( key === "define" ) {
814+ if ( result . hasOwnProperty ( key ) ) {
815+ var oldDefine : any = result [ key ] ;
816+ result [ key ] = mergeArrayWithComparisonKey (
817+ newValue as any [ ] ,
818+ oldDefine as any [ ] ,
819+ "name"
820+ ) ;
821+ } else {
822+ result [ key ] = newValue ;
823+ }
824+ } else if ( Array . isArray ( newValue ) ) {
825+ if ( result . hasOwnProperty ( key ) ) {
826+ var oldArray : any = result [ key ] ;
827+ if ( Array . isArray ( oldArray ) ) {
828+ result [ key ] = mergeArrays ( newValue as any [ ] , oldArray as any [ ] ) ;
829+ } else {
830+ result [ key ] = newValue ;
831+ }
832+ } else {
833+ result [ key ] = newValue ;
834+ }
835+ } else {
836+ result [ key ] = newValue ;
837+ }
838+ }
839+ }
840+ return result ;
841+ }
842+
843+ function mergeApplication ( application : any , baseApplication : any ) : any {
844+ if ( typeof application === "string" ) {
845+ //overrides all fields
846+ return application ;
847+ }
848+ var result : any = { } ;
849+ if ( typeof baseApplication === "string" ) {
850+ for ( const key in AIR_PLATFORM_TYPES ) {
851+ if ( AIR_PLATFORM_TYPES . hasOwnProperty ( key ) ) {
852+ var keyValue = AIR_PLATFORM_TYPES [ key ] ;
853+ result [ keyValue ] = baseApplication ;
854+ }
855+ }
856+ } else {
857+ result = baseApplication ;
858+ }
859+ return mergeObjectsSimple ( application , result ) ;
860+ }
861+
862+ function mergeAIROptions (
863+ airOptions : any ,
864+ baseAIROptions : any ,
865+ handlePlatforms : boolean
866+ ) : any {
867+ const result : any = { } ;
868+ const keys = new Set < PropertyKey > ( ) ;
869+ for ( const key in baseAIROptions ) {
870+ if ( baseAIROptions . hasOwnProperty ( key ) ) {
871+ keys . add ( key ) ;
872+ }
873+ }
874+ for ( const key in airOptions ) {
875+ if ( airOptions . hasOwnProperty ( key ) ) {
876+ keys . add ( key ) ;
877+ }
878+ }
879+ var platforms = new Set ( ) ;
880+ for ( const key in AIR_PLATFORM_TYPES ) {
881+ if ( AIR_PLATFORM_TYPES . hasOwnProperty ( key ) ) {
882+ var keyValue = AIR_PLATFORM_TYPES [ key ] ;
883+ platforms . add ( keyValue ) ;
884+ }
885+ }
886+ keys . forEach ( function (
887+ value : PropertyKey ,
888+ key : PropertyKey ,
889+ set : Set < PropertyKey >
890+ ) : void {
891+ var hasConfig : Boolean = airOptions . hasOwnProperty ( key ) ;
892+ var hasBase : Boolean = baseAIROptions . hasOwnProperty ( key ) ;
893+ if ( hasConfig && hasBase ) {
894+ var newValue : any = airOptions [ key ] ;
895+ var baseValue : any = baseAIROptions [ key ] ;
896+ if ( handlePlatforms && platforms . has ( key ) ) {
897+ result [ key ] = mergeAIROptions ( newValue , baseValue , false ) ;
898+ } else if ( key === "files" ) {
899+ result [ key ] = mergeArrayWithComparisonKey (
900+ newValue as any [ ] ,
901+ baseValue as any [ ] ,
902+ "path"
903+ ) ;
904+ } else if ( key === "signingOptions" ) {
905+ result [ key ] = mergeSigningOptions ( newValue , baseValue ) ;
906+ } else if ( Array . isArray ( newValue ) && Array . isArray ( baseValue ) ) {
907+ result [ key ] = mergeArrays ( newValue as any [ ] , baseValue as any [ ] ) ;
908+ } else {
909+ result [ key ] = mergeObjectsSimple ( airOptions [ key ] , baseAIROptions [ key ] ) ;
910+ }
911+ } else if ( hasConfig ) {
912+ result [ key ] = airOptions [ key ] ;
913+ } else if ( hasBase ) {
914+ result [ key ] = baseAIROptions [ key ] ;
915+ }
916+ } ) ;
917+ return result ;
918+ }
919+
920+ function mergeSigningOptions (
921+ signingOptions : any ,
922+ baseSigningOptions : any
923+ ) : any {
924+ const hasDebug = signingOptions . hasOwnProperty ( "debug" ) ;
925+ const hasRelease = signingOptions . hasOwnProperty ( "release" ) ;
926+ if ( ! hasDebug && ! hasRelease ) {
927+ //nothing to merge. fully overrides the base
928+ return signingOptions ;
929+ }
930+ if ( hasDebug && hasRelease ) {
931+ //also fully overrides the base
932+ return signingOptions ;
933+ }
934+ const hasBaseDebug : Boolean = baseSigningOptions . hasOwnProperty ( "debug" ) ;
935+ const hasBaseRelease : Boolean = baseSigningOptions . hasOwnProperty ( "release" ) ;
936+ const result : any = { } ;
937+ if ( hasDebug ) {
938+ result [ "debug" ] = signingOptions [ "debug" ] ;
939+ } else if ( hasBaseDebug ) {
940+ result [ "debug" ] = baseSigningOptions [ "debug" ] ;
941+ } else if ( ! hasBaseRelease ) {
942+ result [ "debug" ] = baseSigningOptions ;
943+ }
944+ if ( hasRelease ) {
945+ result [ "release" ] = signingOptions [ "release" ] ;
946+ } else if ( hasBaseRelease ) {
947+ result [ "release" ] = baseSigningOptions [ "release" ] ;
948+ } else if ( ! hasBaseDebug ) {
949+ result [ "release" ] = baseSigningOptions ;
950+ }
951+ return result ;
952+ }
0 commit comments