@@ -14,16 +14,13 @@ const stringMatcher = /(?:".*?"|'.*?'|["'].*?$)/g; //Matches st
1414const braceMatcher = / (?: { (?: (? ! { ) .) * ?} | { (?: (? ! { ) .) * ?$ ) / g; //Matches well paired braces (complete or open to end of string)
1515const bracketMatcher = / (?: \[ (?: (? ! \[ ) .) * ?\] | \[ (?: (? ! \[ ) .) * ?$ ) / g; //Matches well paired square brackets (complete or open to end of string)
1616const matchedParens = / (?: \( (?: (? ! \( ) .) * ?\) ) / g; //Matches well paired parentheses
17- const slashMatcher = / \/ / g; //Matches forward slashes
18- const asExtensionMatcher = / \. a s $ / i; //Matches strings ending in .as
1917
2018interface SymbolChainLink { identifier : string ; called : boolean ; }
2119
2220export class ActionContext {
2321
24- public static rootPath : string = '' ; //TODO: Need a more accurate value for this to avoid i/o errors when the vscode folder is not the class root
25-
2622 private static _classes : ActionClass [ ] = [ ] ;
23+ private static _wildcardImports : { [ path : string ] : Promise < string [ ] > } = Object . create ( null ) ;
2724 private static _classLookup : { [ fullTypeOrUri : string ] : ActionClass } = Object . create ( null ) ;
2825 private static _intrinsicImports : { [ shortType : string ] : ActionClass } = Object . create ( null ) ;
2926 private static _globalCompletions : CompletionItem [ ] = [ ] ;
@@ -85,7 +82,7 @@ export class ActionContext {
8582 }
8683 }
8784 returnType = nextClass . importMap [ returnType ] || returnType ;
88- nextClass = await this . getClassByFullType ( returnType ) ;
85+ nextClass = await this . getClassByFullType ( returnType , nextClass . baseUri ) ;
8986 if ( symbolCalled && nextClass . constructorMethod ) {
9087 nextVisibility = VisibilityFilter . PUBLIC_INSTANCE ;
9188 }
@@ -124,7 +121,7 @@ export class ActionContext {
124121
125122 let member : ActionParameter ;
126123 if ( ambientClass . superClass && chainLength === 1 && symbolChain [ 0 ] . identifier === 'super' ) {
127- let superClass = await this . getClassByFullType ( ambientClass . superClass ) ;
124+ let superClass = await this . getClassByFullType ( ambientClass . superClass , ambientClass . baseUri ) ;
128125 member = superClass && superClass . constructorMethod ;
129126 } else {
130127 let memberAndClass = await this . traverseSymbolChainToMember ( symbolChain , ambientClass , lineIndex ) ;
@@ -247,7 +244,7 @@ export class ActionContext {
247244 symbolName = symbolChain [ 0 ] . identifier ;
248245 returnType = ambientClass . importMap [ symbolName ] ;
249246 if ( returnType ) {
250- return [ null , await this . getClassByFullType ( returnType ) ] ;
247+ return [ null , await this . getClassByFullType ( returnType , ambientClass . baseUri ) ] ;
251248 } else if ( this . _intrinsicImports [ symbolName ] ) {
252249 return [ null , this . _intrinsicImports [ symbolName ] ] ;
253250 }
@@ -287,7 +284,7 @@ export class ActionContext {
287284 }
288285 }
289286 returnType = nextClass . importMap [ returnType ] || returnType ;
290- nextClass = await this . getClassByFullType ( returnType ) ;
287+ nextClass = await this . getClassByFullType ( returnType , nextClass . baseUri ) ;
291288 if ( symbolCalled && nextClass . constructorMethod ) {
292289 nextVisibility = VisibilityFilter . PUBLIC_INSTANCE ;
293290 }
@@ -373,7 +370,7 @@ export class ActionContext {
373370 }
374371
375372 if ( actionClass . superClass ) {
376- let superActionClass = await this . getClassByFullType ( actionClass . superClass ) ;
373+ let superActionClass = await this . getClassByFullType ( actionClass . superClass , actionClass . baseUri ) ;
377374 if ( superActionClass ) {
378375 completionItems = completionItems . concat ( await this . getInnerSymbols ( superActionClass , visibilityFilter , null , false , skipMap , rank ) ) ;
379376 }
@@ -451,27 +448,18 @@ export class ActionContext {
451448 this . _classLookup [ actionClass . fileUri ] = actionClass ;
452449 }
453450
454- public static getClassByFullType ( fullType : string ) : Thenable < ActionClass > {
455- if ( ! fullType ) {
456- return Promise . resolve ( null ) ;
457- }
458- if ( this . _classLookup [ fullType ] ) {
459- return Promise . resolve ( this . _classLookup [ fullType ] ) ;
460- }
461- return this . requestClassParse ( fullType ) ;
462- }
463-
464- public static requestClassParse ( fullType : string , forceReparse : boolean = false ) : Thenable < ActionClass > {
465- ActionConfig . LOG_LEVEL !== LogLevel . NONE && logIt ( { level : LogLevel . INFO , message : `request class parse! ${ fullType } ` } ) ;
451+ public static getClassByFullType ( fullType : string , basePath : string , forceReparse = false ) : Thenable < ActionClass > {
452+ ActionConfig . LOG_LEVEL !== LogLevel . NONE && logIt ( { level : LogLevel . VERBOSE , message : `Request class parse! ${ fullType } ` } ) ;
466453
467454 if ( fullType in this . _classLookup && ! forceReparse ) {
468455 return Promise . resolve ( this . _classLookup [ fullType ] ) ;
469456 } else {
470- let path = this . typeOrPackageToPath ( fullType ) ;
471- ActionConfig . LOG_LEVEL !== LogLevel . NONE && logIt ( { level : LogLevel . INFO , message : `Type to path: ${ path } ` } ) ;
457+ let path = this . typeOrPackageToPath ( fullType , basePath ) ;
458+ ActionConfig . LOG_LEVEL !== LogLevel . NONE && logIt ( { level : LogLevel . VERBOSE , message : `Type to path: ${ path } ` } ) ;
472459 let promises : [ PromiseLike < any > , Promise < string > ] = [ ActionParser . initialise ( ) , LoadQueue . enqueue ( path ) ] ;
473460 return Promise . all ( promises )
474461 . then ( res => {
462+ if ( ! res ) return null ;
475463 let ac = ActionParser . parseFile ( path , res [ 1 ] ) ;
476464 this . registerClass ( ac ) ;
477465 return ac ;
@@ -480,18 +468,22 @@ export class ActionContext {
480468 }
481469 }
482470
483- public static requestPackageParse ( packageDescriptor : string , forceReparse : boolean = false ) : Promise < string [ ] > {
484- return DirectoryUtility . fileNamesInDirectory ( this . typeOrPackageToPath ( packageDescriptor ) , / \. a s $ / i)
485- . then ( fileNames => fileNames . map ( fileName => {
486- let fullType = this . pathToFullType ( fileName ) ;
487- if ( fullType && ( forceReparse || ! this . _classLookup [ fullType ] ) ) {
488- let path = this . typeOrPackageToPath ( fullType ) ;
489- LoadQueue . enqueue ( path )
490- . then ( contents => this . registerClass ( ActionParser . parseFile ( path , contents ) ) )
491- . catch ( e => ActionConfig . LOG_LEVEL !== LogLevel . NONE && logIt ( { level : LogLevel . ERROR , message : `Load error! ${ path } ${ e } ` } ) ) ;
492- }
493- return fullType ;
494- } ) ) ;
471+ public static requestPackageParse ( packageDescriptor : string , basePath : string , forceReparse = false ) : Promise < string [ ] > {
472+ let lookupKey = basePath + packageDescriptor ;
473+ if ( ! forceReparse && lookupKey in this . _wildcardImports ) {
474+ return this . _wildcardImports [ lookupKey ] ;
475+ }
476+ this . _wildcardImports [ lookupKey ] = DirectoryUtility . fileNamesInDirectory ( this . typeOrPackageToPath ( packageDescriptor , basePath ) , / \. a s $ / i)
477+ . then ( fileNames => Promise . all ( fileNames . map ( fileName => {
478+ return LoadQueue . enqueue ( fileName )
479+ . then ( contents => {
480+ if ( ! contents ) return null ;
481+ let parsedClass = ActionParser . parseFile ( fileName , contents ) ;
482+ this . registerClass ( parsedClass ) ;
483+ return parsedClass . fullType ;
484+ } ) ;
485+ } ) ) ) ;
486+ return this . _wildcardImports [ lookupKey ] ;
495487 }
496488
497489 public static fullTypeToPackage ( fullType : string ) : string {
@@ -506,26 +498,14 @@ export class ActionContext {
506498 return rawType . indexOf ( '.' ) === - 1 ;
507499 }
508500
509- public static typeOrPackageToPath ( typeDescriptor : string ) : string {
501+ public static typeOrPackageToPath ( typeDescriptor : string , basePath : string ) : string {
510502 let isPackage = this . fullTypeToShortType ( typeDescriptor ) === '*' ;
511- let path = DirectoryUtility . concatPaths ( this . rootPath , DirectoryUtility . typeToPath ( typeDescriptor ) ) ;
503+ let path = DirectoryUtility . concatPaths ( basePath , DirectoryUtility . typeToPath ( typeDescriptor ) ) ;
512504 if ( isPackage ) {
513505 return path . substring ( 0 , path . length - 1 ) ;
514506 } else {
515507 return path + '.as' ;
516508 }
517509 }
518510
519- public static pathToFullType ( path : string ) : string {
520- if ( path . indexOf ( this . rootPath ) !== 0 ) {
521- ActionConfig . LOG_LEVEL !== LogLevel . NONE && logIt ( { level : LogLevel . WARNING , message : `Can't determine type from path: '${ path } ' as it does not begin with the current rootPath: '${ this . rootPath } '!` } ) ;
522- return '' ;
523- }
524- if ( path . substr ( - 3 ) . toLowerCase ( ) !== '.as' ) {
525- ActionConfig . LOG_LEVEL !== LogLevel . NONE && logIt ( { level : LogLevel . WARNING , message : `Unexpected file extension in path '${ path } '!` } ) ;
526- return '' ;
527- }
528- return path . substring ( this . rootPath . length ) . replace ( slashMatcher , '.' ) . replace ( asExtensionMatcher , '' ) ;
529- }
530-
531511}
0 commit comments