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 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) {
20 SyntaxVariant::MarkupSection(section_children) => {
21 if let syntax::MarkupSectionChildren {
26 syntax: SyntaxVariant::MarkupSuffix(suffix_children),
32 let syntax::MarkupSuffixChildren {
33 markup_suffix_less_than_question: ltq,
34 markup_suffix_name: name,
36 return match &name.syntax {
37 SyntaxVariant::Missing => Some(Mode::Mphp),
38 SyntaxVariant::Token(t) if t.kind() == TokenKind::Equal => Some(Mode::Mphp),
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();
47 .sub_as_str(skip_length, name.width())
48 .to_ascii_lowercase();
49 if language == "php" {
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("");
67 let mode = match mode.trim().split_whitespace().next() {
71 Mode::from_string(mode)
80 // no header - assume .hack file