Multiply entities beyond necessity even more (force better build parallelism)
[hiphop-php.git] / hphp / hack / src / parser / mode_parser.rs
blob6ef2f85555b7bca2769b5f9a4afaa3f49ccfed82
1 // Copyright (c) 2019, Facebook, Inc.
2 // All rights reserved.
3 //
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 minimal_parser::MinimalSyntaxParser;
8 use oxidized::file_info::Mode;
9 use parser_core_types::{
10     lexable_token::LexableToken,
11     source_text::SourceText,
12     syntax::{self, SyntaxVariant},
13     token_kind::TokenKind,
15 use parser_rust::parser_env::ParserEnv;
17 pub fn parse_mode(text: &SourceText) -> Option<Mode> {
18     if let Some(header) = MinimalSyntaxParser::parse_header_only(ParserEnv::default(), text) {
19         match header.syntax {
20             SyntaxVariant::MarkupSection(section_children) => {
21                 if let syntax::MarkupSectionChildren {
22                     markup_prefix: pfx,
23                     markup_text: txt,
24                     markup_suffix:
25                         syntax::Syntax {
26                             syntax: SyntaxVariant::MarkupSuffix(suffix_children),
27                             ..
28                         },
29                     ..
30                 } = *section_children
31                 {
32                     let syntax::MarkupSuffixChildren {
33                         markup_suffix_less_than_question: ltq,
34                         markup_suffix_name: name,
35                     } = *suffix_children;
36                     return match &name.syntax {
37                         SyntaxVariant::Missing => Some(Mode::Mphp),
38                         SyntaxVariant::Token(t) if t.kind() == TokenKind::Equal => Some(Mode::Mphp),
39                         _ => {
40                             let is_hhi = text.file_path().ends_with(".hhi");
41                             let skip_length = pfx.value.full_width
42                                 + txt.value.full_width
43                                 + ltq.value.full_width
44                                 + name.leading_width();
46                             let language = text
47                                 .sub_as_str(skip_length, name.width())
48                                 .to_ascii_lowercase();
49                             if language == "php" {
50                                 Some(Mode::Mphp)
51                             } else if is_hhi {
52                                 Some(Mode::Mdecl)
53                             } else {
54                                 let skip_length = skip_length + name.width();
55                                 let s = text.sub_as_str(skip_length, name.trailing_width()).trim();
57                                 let mut chars = s.chars();
58                                 let c0 = chars.next();
59                                 let c1 = chars.next();
61                                 let mode = if c0 != Some('/') || c1 != Some('/') {
62                                     return Mode::from_string("");
63                                 } else {
64                                     chars.as_str()
65                                 };
67                                 let mode = match mode.trim().split_whitespace().next() {
68                                     None => "",
69                                     Some(mode) => mode,
70                                 };
71                                 Mode::from_string(mode)
72                             }
73                         }
74                     };
75                 }
76             }
77             _ => (),
78         }
79     } else {
80         // no header - assume .hack file
81     }
82     Some(Mode::Mstrict)