@@ -20,6 +20,8 @@ const {
20
20
21
21
const builtin = require ( './builtin' ) ;
22
22
23
+ const existsChecker = new Map ( ) ;
24
+
23
25
function replace ( origin , target ) {
24
26
Object . keys ( origin ) . forEach ( ( key ) => {
25
27
delete origin [ key ] ;
@@ -507,6 +509,7 @@ class TypeChecker {
507
509
} else {
508
510
this . libraries = libraries ;
509
511
}
512
+ existsChecker . set ( filename , this ) ;
510
513
}
511
514
512
515
error ( message , token ) {
@@ -567,6 +570,7 @@ class TypeChecker {
567
570
} ) ;
568
571
569
572
find = checker . findProperty ( extendModel , propName , isException , moduleName , extendFrom ) ;
573
+
570
574
if ( ! find ) {
571
575
return ;
572
576
}
@@ -744,7 +748,7 @@ class TypeChecker {
744
748
const item = ast . imports [ i ] ;
745
749
const aliasId = item . lexeme ;
746
750
747
- const innerModule = ! ! item . innerPath ;
751
+ let innerModule = ! ! item . innerPath ;
748
752
const mainModule = item . mainModule ;
749
753
750
754
if ( ! mainModule && ! innerModule && ! pkg . libraries [ aliasId ] && pkg . name !== aliasId ) {
@@ -776,6 +780,7 @@ class TypeChecker {
776
780
this . error ( `the submodule id "${ module } " has not been exported in "${ mainModule } "` , item ) ;
777
781
}
778
782
realSpecPath = path . join ( libPath , libMeta . exports [ module ] ) ;
783
+ innerModule = true ;
779
784
} else if ( innerModule ) {
780
785
if ( item . innerPath . endsWith ( '.dara' ) || item . innerPath . endsWith ( '.tea' ) || item . innerPath . endsWith ( '.spec' ) ) {
781
786
realSpecPath = path . join ( pkgDir , item . innerPath ) ;
@@ -808,7 +813,7 @@ class TypeChecker {
808
813
const lexer = new Lexer ( source , realSpecPath ) ;
809
814
const parser = new Parser ( lexer ) ;
810
815
const depAst = parser . program ( ) ;
811
- const checker = new TypeChecker ( source , realSpecPath , this . root , this . libraries , innerModule ) . check ( depAst ) ;
816
+ const checker = existsChecker . get ( realSpecPath ) || new TypeChecker ( source , realSpecPath , this . root , this . libraries , innerModule ) . check ( depAst ) ;
812
817
this . dependencies . set ( aliasId , checker ) ;
813
818
if ( innerModule ) {
814
819
this . innerDep . set ( aliasId , checker . ast ) ;
@@ -817,6 +822,34 @@ class TypeChecker {
817
822
}
818
823
}
819
824
825
+ checkExports ( ) {
826
+ const filePath = this . filename ;
827
+ const pkgDir = path . dirname ( filePath ) ;
828
+ const pkgPath = this . inner ? getDarafile ( this . root ) : getDarafile ( pkgDir ) ;
829
+ if ( ! fs . existsSync ( pkgPath ) ) {
830
+ return ;
831
+ }
832
+
833
+ const pkg = JSON . parse ( stripComments ( fs . readFileSync ( pkgPath , 'utf-8' ) ) ) ;
834
+ if ( ! pkg . exports ) {
835
+ return ;
836
+ }
837
+ const exports = Object . keys ( pkg . exports ) ;
838
+ for ( let i = 0 ; i < exports . length ; i ++ ) {
839
+ const aliasId = exports [ i ] ;
840
+ if ( this . innerDep . has ( aliasId ) ) {
841
+ continue ;
842
+ }
843
+ const exportSpec = path . join ( pkgDir , pkg . exports [ aliasId ] ) ;
844
+ const source = fs . readFileSync ( exportSpec , 'utf-8' ) ;
845
+ const lexer = new Lexer ( source , exportSpec ) ;
846
+ const parser = new Parser ( lexer ) ;
847
+ const depAst = parser . program ( ) ;
848
+ const checker = existsChecker . get ( exportSpec ) || new TypeChecker ( source , exportSpec , this . root , this . libraries , true ) . check ( depAst ) ;
849
+ this . innerDep . set ( aliasId , checker . ast ) ;
850
+ }
851
+ }
852
+
820
853
check ( ast ) {
821
854
assert . equal ( ast . type , 'module' ) ;
822
855
// 类型系统
@@ -845,6 +878,9 @@ class TypeChecker {
845
878
this . postCheckInit ( ast ) ;
846
879
// check unused virtualVariable & virtualMethod
847
880
this . postCheckTypes ( ast ) ;
881
+ if ( ! this . inner ) {
882
+ this . checkExports ( ast ) ;
883
+ }
848
884
ast . models = { } ;
849
885
for ( var [ key , value ] of this . models ) {
850
886
ast . models [ key ] = value ;
@@ -2547,7 +2583,6 @@ class TypeChecker {
2547
2583
} else {
2548
2584
model = this . models . get ( type . name ) ;
2549
2585
}
2550
-
2551
2586
const find = checker . findProperty ( model , propName , model . isException ) ;
2552
2587
if ( ! find ) {
2553
2588
return ;
@@ -3368,7 +3403,7 @@ function analyze(source, filePath) {
3368
3403
while ( ! key . done ) {
3369
3404
const ast = builtin . get ( key . value ) ;
3370
3405
if ( ast . type === 'module' ) {
3371
- builtin . set ( key . value , new TypeChecker ( source , filePath ) . check ( ast ) ) ;
3406
+ builtin . set ( key . value , new TypeChecker ( source , filePath , null , null , true ) . check ( ast ) ) ;
3372
3407
}
3373
3408
key = it . next ( ) ;
3374
3409
}
0 commit comments