1 // Copyright (c) 2019, Facebook, Inc.
2 // All rights reserved.
4 // This source code is licensed under the MIT license found in the
5 // LICENSE file in the "hack" directory of this source tree.
7 use naming_special_names_rust::special_idents;
10 aast_visitor::{visit, AstParams, Node, Visitor},
13 use parser_core_types::{
15 syntax_error::{Error as ErrorMsg, SyntaxError},
21 in_static_methodish: bool,
25 errors: Vec<SyntaxError>,
30 Self { errors: vec![] }
33 fn add_error(&mut self, pos: &Pos, msg: ErrorMsg) {
34 let (start_offset, end_offset) = pos.info_raw();
36 .push(SyntaxError::make(start_offset, end_offset, msg));
39 fn name_eq_this_and_in_static_method(c: &Context, name: impl AsRef<str>) -> bool {
41 && c.in_static_methodish
42 && name.as_ref().eq_ignore_ascii_case(special_idents::THIS)
46 impl Visitor for Checker {
47 type P = AstParams<Context, ()>;
49 fn object(&mut self) -> &mut dyn Visitor<P = Self::P> {
56 p: &aast::Class_<Pos, (), (), ()>,
70 p: &aast::Method_<Pos, (), (), ()>,
75 in_static_methodish: p.static_,
82 fn visit_fun_(&mut self, c: &mut Context, p: &aast::Fun_<Pos, (), (), ()>) -> Result<(), ()> {
86 in_static_methodish: p.static_ || c.in_static_methodish,
93 fn visit_expr(&mut self, c: &mut Context, p: &aast::Expr<Pos, (), (), ()>) -> Result<(), ()> {
94 use aast::{ClassId, ClassId_::*, Expr, Expr_::*, Lid};
96 if let Await(_) = p.1 {
98 self.add_error(&p.0, syntax_error::toplevel_await_use)
100 } else if let Some((_, Expr(_, f), ..)) = p.1.as_call() {
101 if let Some((ClassId(_, CIexpr(Expr(pos, Id(id)))), ..)) = f.as_class_const() {
102 if Self::name_eq_this_and_in_static_method(c, &id.1) {
103 self.add_error(&pos, syntax_error::this_in_static);
106 } else if let Some(Lid(pos, (_, name))) = p.1.as_lvar() {
107 if Self::name_eq_this_and_in_static_method(c, name) {
108 self.add_error(pos, syntax_error::this_in_static);
115 pub fn check_program(program: &aast::Program<Pos, (), (), ()>) -> Vec<SyntaxError> {
116 let mut checker = Checker::new();
117 let mut context = Context {
120 in_static_methodish: false,
122 visit(&mut checker, &mut context, program).unwrap();