mirror of
https://github.com/RustPython/Parser.git
synced 2025-08-04 02:39:22 +00:00
Simplify import AST in line with CPython.
This commit is contained in:
parent
5e468baa16
commit
69c4d0b240
2 changed files with 58 additions and 66 deletions
104
src/compile.rs
104
src/compile.rs
|
@ -267,61 +267,63 @@ impl Compiler {
|
||||||
self.set_source_location(&statement.location);
|
self.set_source_location(&statement.location);
|
||||||
|
|
||||||
match &statement.node {
|
match &statement.node {
|
||||||
ast::Statement::Import { import_parts } => {
|
ast::Statement::Import { names } => {
|
||||||
for ast::SingleImport {
|
// import a, b, c as d
|
||||||
module,
|
for name in names {
|
||||||
symbols,
|
self.emit(Instruction::Import {
|
||||||
alias,
|
name: name.symbol.clone(),
|
||||||
level,
|
symbols: vec![],
|
||||||
} in import_parts
|
level: 0,
|
||||||
{
|
});
|
||||||
let level = *level;
|
|
||||||
if let Some(alias) = alias {
|
if let Some(alias) = &name.alias {
|
||||||
// import module as alias
|
self.store_name(alias);
|
||||||
self.emit(Instruction::Import {
|
|
||||||
name: module.clone(),
|
|
||||||
symbols: vec![],
|
|
||||||
level,
|
|
||||||
});
|
|
||||||
self.store_name(&alias);
|
|
||||||
} else if symbols.is_empty() {
|
|
||||||
// import module
|
|
||||||
self.emit(Instruction::Import {
|
|
||||||
name: module.clone(),
|
|
||||||
symbols: vec![],
|
|
||||||
level,
|
|
||||||
});
|
|
||||||
self.store_name(&module.clone());
|
|
||||||
} else {
|
} else {
|
||||||
let import_star = symbols
|
self.store_name(&name.symbol);
|
||||||
.iter()
|
}
|
||||||
.any(|import_symbol| import_symbol.symbol == "*");
|
}
|
||||||
if import_star {
|
}
|
||||||
// from module import *
|
ast::Statement::ImportFrom {
|
||||||
self.emit(Instruction::ImportStar {
|
level,
|
||||||
name: module.clone(),
|
module,
|
||||||
level,
|
names,
|
||||||
});
|
} => {
|
||||||
|
let import_star = names.iter().any(|n| n.symbol == "*");
|
||||||
|
|
||||||
|
if import_star {
|
||||||
|
// from .... import *
|
||||||
|
self.emit(Instruction::ImportStar {
|
||||||
|
name: module.clone().unwrap(),
|
||||||
|
level: *level,
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
// from mod import a, b as c
|
||||||
|
// First, determine the fromlist (for import lib):
|
||||||
|
let from_list = names.iter().map(|n| n.symbol.clone()).collect();
|
||||||
|
|
||||||
|
// Load module once:
|
||||||
|
self.emit(Instruction::Import {
|
||||||
|
name: module.clone().unwrap(),
|
||||||
|
symbols: from_list,
|
||||||
|
level: *level,
|
||||||
|
});
|
||||||
|
|
||||||
|
for name in names {
|
||||||
|
// import symbol from module:
|
||||||
|
self.emit(Instruction::ImportFrom {
|
||||||
|
name: name.symbol.to_string(),
|
||||||
|
});
|
||||||
|
|
||||||
|
// Store module under proper name:
|
||||||
|
if let Some(alias) = &name.alias {
|
||||||
|
self.store_name(alias);
|
||||||
} else {
|
} else {
|
||||||
// from module import symbol
|
self.store_name(&name.symbol);
|
||||||
// from module import symbol as alias
|
|
||||||
let (names, symbols_strings): (Vec<String>, Vec<String>) = symbols
|
|
||||||
.iter()
|
|
||||||
.map(|ast::ImportSymbol { symbol, alias }| {
|
|
||||||
(
|
|
||||||
alias.clone().unwrap_or_else(|| symbol.to_string()),
|
|
||||||
symbol.to_string(),
|
|
||||||
)
|
|
||||||
})
|
|
||||||
.unzip();
|
|
||||||
self.emit(Instruction::Import {
|
|
||||||
name: module.clone(),
|
|
||||||
symbols: symbols_strings,
|
|
||||||
level,
|
|
||||||
});
|
|
||||||
names.iter().rev().for_each(|name| self.store_name(&name));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Pop module from stack:
|
||||||
|
self.emit(Instruction::Pop);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ast::Statement::Expression { expression } => {
|
ast::Statement::Expression { expression } => {
|
||||||
|
|
|
@ -296,24 +296,14 @@ impl SymbolTableBuilder {
|
||||||
ast::Statement::Break | ast::Statement::Continue | ast::Statement::Pass => {
|
ast::Statement::Break | ast::Statement::Continue | ast::Statement::Pass => {
|
||||||
// No symbols here.
|
// No symbols here.
|
||||||
}
|
}
|
||||||
ast::Statement::Import { import_parts } => {
|
ast::Statement::Import { names } | ast::Statement::ImportFrom { names, .. } => {
|
||||||
for part in import_parts {
|
for name in names {
|
||||||
if let Some(alias) = &part.alias {
|
if let Some(alias) = &name.alias {
|
||||||
// `import mymodule as myalias`
|
// `import mymodule as myalias`
|
||||||
self.register_name(alias, SymbolRole::Assigned)?;
|
self.register_name(alias, SymbolRole::Assigned)?;
|
||||||
} else if part.symbols.is_empty() {
|
|
||||||
// `import module`
|
|
||||||
self.register_name(&part.module, SymbolRole::Assigned)?;
|
|
||||||
} else {
|
} else {
|
||||||
// `from mymodule import myimport`
|
// `import module`
|
||||||
for symbol in &part.symbols {
|
self.register_name(&name.symbol, SymbolRole::Assigned)?;
|
||||||
if let Some(alias) = &symbol.alias {
|
|
||||||
// `from mymodule import myimportname as myalias`
|
|
||||||
self.register_name(alias, SymbolRole::Assigned)?;
|
|
||||||
} else {
|
|
||||||
self.register_name(&symbol.symbol, SymbolRole::Assigned)?;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue