@@ -21,94 +21,99 @@ export async function importBlocks(block: Block, factory: BlockFactory, file: st
21
21
let namedBlockReferences : Promise < [ string , string , postcss . AtRule , Block ] > [ ] = [ ] ;
22
22
23
23
if ( ! root ) {
24
- throw new errors . InvalidBlockSyntax ( `Error finding PostCSS root for block ${ block . name } ` ) ;
25
- }
24
+ block . addError ( new errors . InvalidBlockSyntax ( `Error finding PostCSS root for block ${ block . name } ` ) ) ;
25
+ } else {
26
+ // For each `@block` expression, read in the block file, parse and
27
+ // push to block references Promise array.
28
+ root . walkAtRules ( BLOCK_IMPORT , ( atRule : postcss . AtRule ) => {
29
+ // imports: `<blocks-list> from <block-path>`
30
+ // blockList: `<default-block> | <named-blocks> | <default-block> " , " <named-blocks> | <named-blocks> " , " <default-block>`
31
+ // blockPath: `' " ' <any-value> ' " ' | " ' " <any-value> " ' "`
32
+ let imports = atRule . params ;
33
+ let [ blockList = "" , blockPath = "" ] = imports . split ( FROM_EXPR ) ;
34
+ blockPath = stripQuotes ( blockPath ) ;
26
35
27
- // For each `@block` expression, read in the block file, parse and
28
- // push to block references Promise array.
29
- root . walkAtRules ( BLOCK_IMPORT , ( atRule : postcss . AtRule ) => {
30
- // imports: `<blocks-list> from <block-path>`
31
- // blockList: `<default-block> | <named-blocks> | <default-block> " , " <named-blocks> | <named-blocks> " , " <default-block>`
32
- // blockPath: `' " ' <any-value> ' " ' | " ' " <any-value> " ' "`
33
- let imports = atRule . params ;
34
- let [ blockList = "" , blockPath = "" ] = imports . split ( FROM_EXPR ) ;
35
- blockPath = stripQuotes ( blockPath ) ;
36
+ if ( ! blockList || ! blockPath ) {
37
+ block . addError ( new errors . InvalidBlockSyntax (
38
+ `Malformed block reference: \`@block ${ atRule . params } \`` ,
39
+ sourceRange ( factory . configuration , block . stylesheet , file , atRule ) ,
40
+ ) ) ;
41
+ } else {
42
+ // Import file, then parse file, then save block reference.
43
+ let blockPromise : Promise < Block > = factory . getBlockRelative ( block . identifier , blockPath ) ;
36
44
37
- if ( ! blockList || ! blockPath ) {
38
- throw new errors . InvalidBlockSyntax (
39
- `Malformed block reference: \`@block ${ atRule . params } \`` ,
40
- sourceRange ( factory . configuration , block . stylesheet , file , atRule ) ,
41
- ) ;
42
- }
45
+ blockPromise = blockPromise . catch ( ( e ) => {
46
+ if ( e instanceof errors . CssBlockError ) {
47
+ e . importStack . push ( sourceRange ( factory . configuration , block . stylesheet , file , atRule ) ) ;
48
+ }
49
+ throw e ;
50
+ } ) ;
43
51
44
- // Import file, then parse file, then save block reference.
45
- let blockPromise : Promise < Block > = factory . getBlockRelative ( block . identifier , blockPath ) ;
52
+ let blockNames = parseBlockNames ( blockList , true ) ;
53
+ for ( let localName of Object . keys ( blockNames ) ) {
54
+ let remoteName = blockNames [ localName ] ;
55
+ // Validate our imported block name is a valid CSS identifier.
56
+ if ( ! CLASS_NAME_IDENT . test ( localName ) ) {
57
+ block . addError ( new errors . InvalidBlockSyntax (
58
+ `Illegal block name in import. "${ localName } " is not a legal CSS identifier.` ,
59
+ sourceRange ( factory . configuration , block . stylesheet , file , atRule ) ,
60
+ ) ) ;
61
+ }
62
+ if ( ! CLASS_NAME_IDENT . test ( remoteName ) ) {
63
+ block . addError ( new errors . InvalidBlockSyntax (
64
+ `Illegal block name in import. "${ remoteName } " is not a legal CSS identifier.` ,
65
+ sourceRange ( factory . configuration , block . stylesheet , file , atRule ) ,
66
+ ) ) ;
67
+ }
68
+ if ( localName === DEFAULT_EXPORT && remoteName === DEFAULT_EXPORT ) {
69
+ block . addError ( new errors . InvalidBlockSyntax (
70
+ `Default Block from "${ blockPath } " must be aliased to a unique local identifier.` ,
71
+ sourceRange ( factory . configuration , block . stylesheet , file , atRule ) ,
72
+ ) ) ;
73
+ }
74
+ if ( isBlockNameReserved ( localName ) ) {
75
+ block . addError ( new errors . InvalidBlockSyntax (
76
+ `Cannot import "${ remoteName } " as reserved word "${ localName } "` ,
77
+ sourceRange ( factory . configuration , block . stylesheet , file , atRule ) ,
78
+ ) ) ;
79
+ }
46
80
47
- blockPromise = blockPromise . catch ( ( e ) => {
48
- if ( e instanceof errors . CssBlockError ) {
49
- e . importStack . push ( sourceRange ( factory . configuration , block . stylesheet , file , atRule ) ) ;
81
+ // Once block is parsed, save named block reference
82
+ let namedResult : Promise < [ string , string , postcss . AtRule , Block ] > = blockPromise . then ( ( block : Block ) : [ string , string , postcss . AtRule , Block ] => {
83
+ let referencedBlock = block . getExportedBlock ( remoteName ) ;
84
+ if ( ! referencedBlock ) {
85
+ throw new errors . InvalidBlockSyntax (
86
+ `Cannot import Block "${ remoteName } ". No Block named "${ remoteName } " exported by "${ blockPath } ".` ,
87
+ sourceRange ( factory . configuration , block . stylesheet , file , atRule ) ,
88
+ ) ;
89
+ }
90
+ return [ localName , blockPath , atRule , referencedBlock ] ;
91
+ } ) ;
92
+ namedBlockReferences . push ( namedResult ) ;
93
+ }
50
94
}
51
- throw e ;
52
95
} ) ;
53
96
54
- let blockNames = parseBlockNames ( blockList , true ) ;
55
- for ( let localName of Object . keys ( blockNames ) ) {
56
- let remoteName = blockNames [ localName ] ;
57
- // Validate our imported block name is a valid CSS identifier.
58
- if ( ! CLASS_NAME_IDENT . test ( localName ) ) {
59
- throw new errors . InvalidBlockSyntax (
60
- `Illegal block name in import. "${ localName } " is not a legal CSS identifier.` ,
61
- sourceRange ( factory . configuration , block . stylesheet , file , atRule ) ,
62
- ) ;
63
- }
64
- if ( ! CLASS_NAME_IDENT . test ( remoteName ) ) {
65
- throw new errors . InvalidBlockSyntax (
66
- `Illegal block name in import. "${ remoteName } " is not a legal CSS identifier.` ,
67
- sourceRange ( factory . configuration , block . stylesheet , file , atRule ) ,
68
- ) ;
69
- }
70
- if ( localName === DEFAULT_EXPORT && remoteName === DEFAULT_EXPORT ) {
71
- throw new errors . InvalidBlockSyntax (
72
- `Default Block from "${ blockPath } " must be aliased to a unique local identifier.` ,
73
- sourceRange ( factory . configuration , block . stylesheet , file , atRule ) ,
74
- ) ;
75
- }
76
- if ( isBlockNameReserved ( localName ) ) {
77
- throw new errors . InvalidBlockSyntax (
78
- `Cannot import "${ remoteName } " as reserved word "${ localName } "` ,
79
- sourceRange ( factory . configuration , block . stylesheet , file , atRule ) ,
80
- ) ;
81
- }
82
-
83
- // Once block is parsed, save named block reference
84
- let namedResult : Promise < [ string , string , postcss . AtRule , Block ] > = blockPromise . then ( ( block : Block ) : [ string , string , postcss . AtRule , Block ] => {
85
- let referencedBlock = block . getExportedBlock ( remoteName ) ;
86
- if ( ! referencedBlock ) {
87
- throw new errors . InvalidBlockSyntax (
88
- `Cannot import Block "${ remoteName } ". No Block named "${ remoteName } " exported by "${ blockPath } ".` ,
97
+ // When all import promises have resolved, save the block references and
98
+ // resolve.
99
+ let results ;
100
+ try {
101
+ results = await Promise . all ( namedBlockReferences ) ;
102
+ let localNames : ObjectDictionary < string > = { } ;
103
+ results . forEach ( ( [ localName , importPath , atRule , otherBlock ] ) => {
104
+ if ( localNames [ localName ] ) {
105
+ block . addError ( new errors . InvalidBlockSyntax (
106
+ `Blocks ${ localNames [ localName ] } and ${ importPath } cannot both have the name ${ localName } in this scope.` ,
89
107
sourceRange ( factory . configuration , block . stylesheet , file , atRule ) ,
90
- ) ;
108
+ ) ) ;
109
+ } else {
110
+ block . addBlockReference ( localName , otherBlock ) ;
111
+ localNames [ localName ] = importPath ;
91
112
}
92
- return [ localName , blockPath , atRule , referencedBlock ] ;
93
113
} ) ;
94
- namedBlockReferences . push ( namedResult ) ;
114
+ } catch ( e ) {
115
+ block . addError ( e ) ;
95
116
}
96
-
97
- } ) ;
98
-
99
- // When all import promises have resolved, save the block references and resolve.
100
- let results = await Promise . all ( namedBlockReferences ) ;
101
- let localNames : ObjectDictionary < string > = { } ;
102
- results . forEach ( ( [ localName , importPath , atRule , otherBlock ] ) => {
103
- if ( localNames [ localName ] ) {
104
- throw new errors . InvalidBlockSyntax (
105
- `Blocks ${ localNames [ localName ] } and ${ importPath } cannot both have the name ${ localName } in this scope.` ,
106
- sourceRange ( factory . configuration , block . stylesheet , file , atRule ) ,
107
- ) ;
108
- } else {
109
- block . addBlockReference ( localName , otherBlock ) ;
110
- localNames [ localName ] = importPath ;
111
- }
112
- } ) ;
117
+ }
113
118
return block ;
114
119
}
0 commit comments