(text: &str, struct_name: &str)
| 1045 | let mut i = 0usize; |
| 1046 | while i < text.len() { |
| 1047 | let rest = &text[i..]; |
| 1048 | let res_pos = rest.find("res://"); |
| 1049 | let dlc_pos = rest.find("dlc://"); |
| 1050 | let rel = match (res_pos, dlc_pos) { |
| 1051 | (Some(a), Some(b)) => a.min(b), |
| 1052 | (Some(a), None) | (None, Some(a)) => a, |
| 1053 | (None, None) => break, |
| 1054 | }; |
| 1055 | let start = i + rel; |
| 1056 | let mut end = start; |
| 1057 | for (offset, ch) in text[start..].char_indices() { |
| 1058 | if is_virtual_ref_delim(ch) { |
| 1059 | break; |
| 1060 | } |
| 1061 | end = start + offset + ch.len_utf8(); |
| 1062 | } |
| 1063 | let raw = trim_virtual_ref_tail(&text[start..end]); |
| 1064 | if !raw.is_empty() { |
| 1065 | refs.push(TextRef { |
| 1066 | raw: raw.to_string(), |
| 1067 | line: line_number_at(text, start), |
| 1068 | }); |
| 1069 | } |
| 1070 | i = end.max(start + 1); |
| 1071 | } |
| 1072 | refs |
| 1073 | } |
| 1074 | |
| 1075 | fn is_virtual_ref_delim(ch: char) -> bool { |
| 1076 | ch.is_whitespace() |
| 1077 | || matches!( |
| 1078 | ch, |
| 1079 | '"' | '\'' | '`' | ',' | ';' | ')' | '(' | ']' | '[' | '}' | '{' | '<' | '>' |
| 1080 | ) |
| 1081 | } |
| 1082 | |
| 1083 | fn trim_virtual_ref_tail(raw: &str) -> &str { |
| 1084 | raw.trim_end_matches(['.', ':', '!', '?']) |
| 1085 | } |
| 1086 | |
| 1087 | fn index_script_source(file: &Path, text: &str, index: &mut ScriptDoctorIndex) { |
| 1088 | for type_name in parse_struct_names(text) { |
| 1089 | let fields = parse_struct_fields(text, &type_name); |
| 1090 | if !fields.is_empty() { |
| 1091 | index.custom_type_fields.insert(type_name, fields); |
| 1092 | } |
| 1093 | } |
| 1094 | for type_name in parse_enum_names(text) { |
| 1095 | let fields = parse_enum_fields(text, &type_name); |
| 1096 | if !fields.is_empty() { |
| 1097 | index.custom_type_fields.insert(type_name, fields); |
| 1098 | } |
| 1099 | } |
| 1100 | for state_name in parse_state_struct_names(text) { |
no test coverage detected