Merge pull request #293 from ahmedcharles/pubrestricted

Add support for pub(restricted).
This commit is contained in:
Niko Matsakis 2018-01-31 05:47:33 -05:00 committed by GitHub
commit 50fb8a5d74
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
13 changed files with 73 additions and 32 deletions

View File

@ -1,6 +1,6 @@
language: rust
rust:
- 1.16.0
- 1.18.0
- beta
- nightly
script:

View File

@ -15,7 +15,7 @@ extern {
}
}
pub Expr = {
pub(crate) Expr = {
<l:Expr> "-" <r:Factor> => l - r,
<l:Expr> "+" <r:Factor> => l + r,
Factor,

View File

@ -396,7 +396,8 @@ fn emit_recursive_ascent(session: &Session, grammar: &r::Grammar, report_file :
}
rust!(rust,
"pub use self::{}parse{}::parse_{};",
"{}use self::{}parse{}::parse_{};",
grammar.nonterminals[&user_nt].visibility,
grammar.prefix,
start_nt,
user_nt);

View File

@ -342,10 +342,24 @@ pub struct Parameter {
pub ty: TypeRef,
}
#[derive(Clone, Debug, PartialEq, Eq)]
pub enum Visibility {
Pub(Option<Path>),
Priv,
}
impl Visibility {
pub fn is_pub(&self) -> bool {
match *self {
Visibility::Pub(_) => true,
Visibility::Priv => false,
}
}
}
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct NonterminalData {
// a "public" nonterminal is one that we will use as a start symbol
pub public: bool,
pub visibility: Visibility,
pub name: NonterminalString,
pub annotations: Vec<Annotation>,
pub span: Span,
@ -646,6 +660,16 @@ impl Symbol {
}
}
impl Display for Visibility {
fn fmt(&self, fmt: &mut Formatter) -> Result<(), Error> {
match *self {
Visibility::Pub(Some(ref path)) => write!(fmt, "pub({}) ", path),
Visibility::Pub(None) => write!(fmt, "pub "),
Visibility::Priv => Ok(()),
}
}
}
impl<T: Display> Display for WhereClause<T> {
fn fmt(&self, fmt: &mut Formatter) -> Result<(), Error> {
match *self {

View File

@ -17,7 +17,11 @@ pub use grammar::parse_tree::{Annotation,
NonterminalString,
Path,
Span,
TerminalLiteral, TerminalString, TypeParameter, WhereClause};
TerminalLiteral,
TerminalString,
TypeParameter,
Visibility,
WhereClause};
#[derive(Clone, Debug)]
pub struct Grammar {
@ -75,6 +79,7 @@ pub struct TerminalSet {
#[derive(Clone, Debug)]
pub struct NonterminalData {
pub name: NonterminalString,
pub visibility: Visibility,
pub span: Span,
pub annotations: Vec<Annotation>,
pub productions: Vec<Production>,

View File

@ -135,6 +135,7 @@ impl<'codegen, 'grammar, W: Write, C> CodeGenerator<'codegen, 'grammar, W, C> {
rust!(self.out, "#[allow(dead_code)]");
try!(self.out.write_pub_fn_header(self.grammar,
&self.grammar.nonterminals[&self.start_symbol].visibility,
format!("parse_{}", self.user_start_symbol),
type_parameters,
parameters,

View File

@ -3,6 +3,7 @@
use collections::{Map, Set};
use grammar::parse_tree::WhereClause;
use grammar::repr::*;
use intern::intern;
use lr1::core::*;
use lr1::lookahead::Token;
use rust::RustWrite;
@ -749,6 +750,7 @@ impl<'ascent, 'grammar, W: Write> CodeGenerator<'ascent, 'grammar, W, TableDrive
format!("_: {}", self.phantom_data_type())];
try!(self.out.write_pub_fn_header(self.grammar,
&Visibility::Pub(Some(Path::from_id(intern("crate")))),
format!("{}reduce", self.prefix),
vec![],
parameters,

View File

@ -54,11 +54,12 @@ impl<'ascent, 'grammar, W: Write> CodeGenerator<'ascent, 'grammar, W, TestAll> {
this.states,
"super::super::super",
this.out));
rust!(this.out,
"pub use self::{}parse{}::parse_{};",
this.prefix,
this.start_symbol,
this.user_start_symbol);
let pub_use = format!("{}use self::{}parse{}::parse_{};",
this.grammar.nonterminals[&this.user_start_symbol].visibility,
this.prefix,
this.start_symbol,
this.user_start_symbol);
rust!(this.out, "{}", pub_use);
rust!(this.out, "}}");
rust!(this.out, "mod {}parse_table {{", this.prefix);
@ -68,11 +69,7 @@ impl<'ascent, 'grammar, W: Write> CodeGenerator<'ascent, 'grammar, W, TestAll> {
this.states,
"super::super::super",
this.out));
rust!(this.out,
"pub use self::{}parse{}::parse_{};",
this.prefix,
this.start_symbol,
this.user_start_symbol);
rust!(this.out, "{}", pub_use);
rust!(this.out, "}}");
Ok(())

View File

@ -137,6 +137,7 @@ impl<'s> LowerState<'s> {
self.nonterminals.insert(nt_name,
r::NonterminalData {
name: nt_name,
visibility: nt.visibility.clone(),
annotations: nt.annotations,
span: nt.span,
productions: productions,
@ -215,7 +216,7 @@ impl<'s> LowerState<'s> {
grammar.items
.iter()
.filter_map(|item| item.as_nonterminal())
.filter(|nt| nt.public)
.filter(|nt| nt.visibility.is_pub())
.map(|nt| {
// create a synthetic symbol `__Foo` for each public symbol `Foo`
// with a rule like:
@ -241,6 +242,7 @@ impl<'s> LowerState<'s> {
self.nonterminals.insert(fake_name,
r::NonterminalData {
name: fake_name,
visibility: nt.visibility.clone(),
annotations: vec![],
span: nt.span,
productions: vec![production],

View File

@ -10,7 +10,8 @@ use grammar::parse_tree::{ActionKind, Alternative, Annotation,
Path,
RepeatOp, RepeatSymbol,
Span, Symbol, SymbolKind,
TerminalLiteral, TerminalString, TypeRef};
TerminalLiteral, TerminalString, TypeRef,
Visibility};
use normalize::resolve;
use normalize::{NormResult, NormError};
use normalize::norm_util::{self, Symbols};
@ -198,7 +199,7 @@ impl MacroExpander {
}
Ok(GrammarItem::Nonterminal(NonterminalData {
public: mdef.public,
visibility: mdef.visibility.clone(),
span: span,
name: msym_name,
annotations: mdef.annotations.clone(),
@ -363,7 +364,7 @@ impl MacroExpander {
};
Ok(GrammarItem::Nonterminal(NonterminalData {
public: false,
visibility: Visibility::Priv,
span: span,
name: name,
annotations: inline(span),
@ -397,7 +398,7 @@ impl MacroExpander {
});
Ok(GrammarItem::Nonterminal(NonterminalData {
public: false,
visibility: Visibility::Priv,
span: span,
name: name,
annotations: inline(span),
@ -436,7 +437,7 @@ impl MacroExpander {
let ty_ref = TypeRef::Nominal { path: path, types: vec![base_symbol_ty] };
Ok(GrammarItem::Nonterminal(NonterminalData {
public: false,
visibility: Visibility::Priv,
span: span,
name: name,
annotations: vec![],
@ -475,7 +476,7 @@ impl MacroExpander {
let ty_ref = TypeRef::Nominal { path: path, types: vec![base_symbol_ty] };
Ok(GrammarItem::Nonterminal(NonterminalData {
public: false,
visibility: Visibility::Priv,
span: span,
name: name,
annotations: inline(span),
@ -506,7 +507,7 @@ impl MacroExpander {
-> NormResult<GrammarItem> {
let name = NonterminalString(intern(name));
Ok(GrammarItem::Nonterminal(NonterminalData {
public: false,
visibility: Visibility::Priv,
span: span,
name: name,
annotations: inline(span),

View File

@ -124,7 +124,7 @@ impl<'grammar> Validator<'grammar> {
}
}
GrammarItem::Nonterminal(ref data) => {
if data.public && !data.args.is_empty() {
if data.visibility.is_pub() && !data.args.is_empty() {
return_err!(data.span, "macros cannot be marked public");
}
let inline_annotation = intern(INLINE);
@ -139,7 +139,7 @@ impl<'grammar> Validator<'grammar> {
return_err!(annotation.id_span,
"duplicate annotation `{}`",
annotation.id);
} else if annotation.id == inline_annotation && data.public {
} else if annotation.id == inline_annotation && data.visibility.is_pub() {
return_err!(annotation.id_span,
"public items cannot be marked #[inline]");
}

View File

@ -93,11 +93,17 @@ GrammarItem: GrammarItem = {
Use: GrammarItem =
<u:"use"> ";" => GrammarItem::Use(strip(u).to_string());
Visibility: Visibility = {
"pub" "(" <p:Path> ")" => Visibility::Pub(Some(p)),
"pub" => Visibility::Pub(None),
() => Visibility::Priv,
};
Nonterminal: GrammarItem =
<annotations:Annotation*>
<p:"pub"?> <lo:@L> <n:NonterminalName> <hi:@R>
<v:Visibility> <lo:@L> <n:NonterminalName> <hi:@R>
<t:(":" <TypeRef>)?> "=" <a:Alternatives> => {
GrammarItem::Nonterminal(NonterminalData { public: p.is_some(),
GrammarItem::Nonterminal(NonterminalData { visibility: v,
span: Span(lo, hi),
name: n.0,
annotations: annotations,

View File

@ -2,6 +2,7 @@
//! which then gets serialized.
use grammar::repr::Grammar;
use grammar::parse_tree::Visibility;
use tls::Tls;
use std::fmt;
use std::io::{self, Write};
@ -106,6 +107,7 @@ impl<W:Write> RustWrite<W> {
pub fn write_pub_fn_header(&mut self,
grammar: &Grammar,
visibility: &Visibility,
name: String,
type_parameters: Vec<String>,
parameters: Vec<String>,
@ -113,7 +115,7 @@ impl<W:Write> RustWrite<W> {
where_clauses: Vec<String>)
-> io::Result<()>
{
self.write_fn_header_helper(grammar, "pub ", name, type_parameters,
self.write_fn_header_helper(grammar, visibility, name, type_parameters,
parameters, return_type, where_clauses)
}
@ -126,13 +128,13 @@ impl<W:Write> RustWrite<W> {
where_clauses: Vec<String>)
-> io::Result<()>
{
self.write_fn_header_helper(grammar, "", name, type_parameters,
self.write_fn_header_helper(grammar, &Visibility::Priv, name, type_parameters,
parameters, return_type, where_clauses)
}
fn write_fn_header_helper(&mut self,
grammar: &Grammar,
qualifiers: &str,
visibility: &Visibility,
name: String,
type_parameters: Vec<String>,
parameters: Vec<String>,
@ -140,7 +142,7 @@ impl<W:Write> RustWrite<W> {
where_clauses: Vec<String>)
-> io::Result<()>
{
rust!(self, "{}fn {}<", qualifiers, name);
rust!(self, "{}fn {}<", visibility, name);
for type_parameter in &grammar.type_parameters {
rust!(self, "{0:1$}{2},", "", TAB, type_parameter);