Every import spec, classified Bare vs Quoted, via the lexer so a `from`/`import` inside a comment or string is never a false hit. */
(src: &str)
| 182 | |
| 183 | /* Every import spec, classified Bare vs Quoted, via the lexer so a `from`/`import` inside a comment or string is never a false hit. */ |
| 184 | pub fn scan_imports(src: &str) -> Vec<ImportSpec> { |
| 185 | let (tokens, _errs) = lex(src); |
| 186 | let mut out = Vec::new(); |
| 187 | let mut i = 0; |
| 188 | while i < tokens.len() { |
| 189 | match tokens[i].kind { |
| 190 | TokenType::From => { |
| 191 | if let Some((spec, next)) = read_spec(src, &tokens, i + 1) { |
| 192 | out.push(spec); |
| 193 | // Step past the `import` of this from-statement so it isn't read as a fresh statement. |
| 194 | i = if tokens.get(next).map(|x| x.kind) == Some(TokenType::Import) { next + 1 } else { next }; |
| 195 | } else { |
| 196 | i += 1; |
| 197 | } |
| 198 | } |
| 199 | TokenType::Import => { |
| 200 | // `import a, b as c`: comma-separated specs, each with an optional `as` alias. |
| 201 | let mut j = i + 1; |
| 202 | while let Some((spec, next)) = read_spec(src, &tokens, j) { |
| 203 | out.push(spec); |
| 204 | j = next; |
| 205 | if tokens.get(j).map(|x| x.kind) == Some(TokenType::As) { |
| 206 | j += if tokens.get(j + 1).map(|x| x.kind) == Some(TokenType::Name) { 2 } else { 1 }; |
| 207 | } |
| 208 | if tokens.get(j).map(|x| x.kind) != Some(TokenType::Comma) { break; } |
| 209 | j += 1; |
| 210 | } |
| 211 | i = j.max(i + 1); |
| 212 | } |
| 213 | _ => i += 1, |
| 214 | } |
| 215 | } |
| 216 | out |
| 217 | } |