/*
* Copyright 2013-2016 Sergey Ignatov, Alexander Zolotov, Florin Patan
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.goide.regexp;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.psi.PsiElement;
import com.intellij.util.containers.ContainerUtil;
import org.intellij.lang.regexp.RegExpLanguageHost;
import org.intellij.lang.regexp.psi.RegExpChar;
import org.intellij.lang.regexp.psi.RegExpGroup;
import org.intellij.lang.regexp.psi.RegExpNamedGroupRef;
import org.intellij.lang.regexp.psi.RegExpSimpleClass;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.Set;
// see https://golang.org/pkg/regexp/syntax/
public class GoRegexHost implements RegExpLanguageHost {
@Override
public boolean characterNeedsEscaping(char c) {
return false;
}
@Override
public boolean supportsPerl5EmbeddedComments() {
return false;
}
@Override
public boolean supportsPossessiveQuantifiers() {
return false;
}
@Override
public boolean supportsPythonConditionalRefs() {
return false;
}
@Override
public boolean supportsNamedGroupSyntax(RegExpGroup group) {
return group.isPythonNamedGroup(); // only (?P<name>) group is supported
}
@Override
public boolean supportsNamedGroupRefSyntax(RegExpNamedGroupRef ref) {
return false;
}
@Override
public boolean supportsExtendedHexCharacter(RegExpChar regExpChar) {
return true;
}
@Override
public boolean isValidCategory(@NotNull String category) {
return Lazy.KNOWN_PROPERTIES.contains(category);
}
@NotNull
@Override
public String[][] getAllKnownProperties() {
return Lazy.KNOWN_PROPERTIES_ARRAY;
}
@Nullable
@Override
public String getPropertyDescription(@Nullable String name) {
return name;
}
@NotNull
@Override
public String[][] getKnownCharacterClasses() {
return Lazy.CHARACTER_CLASSES;
}
@Override
public boolean supportsSimpleClass(RegExpSimpleClass simpleClass) {
switch (simpleClass.getKind()) {
case HORIZONTAL_SPACE:
case NON_HORIZONTAL_SPACE:
case NON_VERTICAL_SPACE:
case XML_NAME_START:
case NON_XML_NAME_START:
case XML_NAME_PART:
case NON_XML_NAME_PART:
case UNICODE_GRAPHEME:
case UNICODE_LINEBREAK:
return false;
case ANY:
case DIGIT:
case NON_DIGIT:
case WORD:
case NON_WORD:
case SPACE:
case NON_SPACE:
case VERTICAL_SPACE:
return true;
}
return false;
}
@Override
public boolean supportsLiteralBackspace(RegExpChar aChar) {
return false;
}
@Override
public boolean supportsInlineOptionFlag(char flag, PsiElement context) {
return StringUtil.containsChar("imsU", flag);
}
private interface Lazy {
// SDK/unicode/tables.go
Set<String> KNOWN_PROPERTIES = ContainerUtil.immutableSet("C", "Cc", "Cf", "Co", "Cs", "L", "Ll", "Lm", "Lo", "Lt", "Lu", "M", "Mc",
"Me", "Mn", "N", "Nd", "Nl", "No", "P", "Pc", "Pd", "Pe", "Pf", "Pi", "Po",
"Ps", "S", "Sc", "Sk", "Sm", "So", "Z", "Zl", "Zp", "Zs",
"Ahom", "Anatolian_Hieroglyphs", "Arabic", "Armenian", "Avestan", "Balinese",
"Bamum", "Bassa_Vah", "Batak", "Bengali", "Bopomofo", "Brahmi", "Braille",
"Buginese", "Buhid", "Canadian_Aboriginal", "Carian", "Caucasian_Albanian",
"Chakma", "Cham", "Cherokee", "Common", "Coptic", "Cuneiform", "Cypriot",
"Cyrillic", "Deseret", "Devanagari", "Duployan", "Egyptian_Hieroglyphs",
"Elbasan", "Ethiopic", "Georgian", "Glagolitic", "Gothic", "Grantha", "Greek",
"Gujarati", "Gurmukhi", "Han", "Hangul", "Hanunoo", "Hatran", "Hebrew",
"Hiragana", "Imperial_Aramaic", "Inherited", "Inscriptional_Pahlavi",
"Inscriptional_Parthian", "Javanese", "Kaithi", "Kannada", "Katakana",
"Kayah_Li", "Kharoshthi", "Khmer", "Khojki", "Khudawadi", "Lao", "Latin",
"Lepcha", "Limbu", "Linear_A", "Linear_B", "Lisu", "Lycian", "Lydian",
"Mahajani", "Malayalam", "Mandaic", "Manichaean", "Meetei_Mayek",
"Mende_Kikakui", "Meroitic_Cursive", "Meroitic_Hieroglyphs", "Miao", "Modi",
"Mongolian", "Mro", "Multani", "Myanmar", "Nabataean", "New_Tai_Lue", "Nko",
"Ogham", "Ol_Chiki", "Old_Hungarian", "Old_Italic", "Old_North_Arabian",
"Old_Permic", "Old_Persian", "Old_South_Arabian", "Old_Turkic", "Oriya",
"Osmanya", "Pahawh_Hmong", "Palmyrene", "Pau_Cin_Hau", "Phags_Pa",
"Phoenician", "Psalter_Pahlavi", "Rejang", "Runic", "Samaritan", "Saurashtra",
"Sharada", "Shavian", "Siddham", "SignWriting", "Sinhala", "Sora_Sompeng",
"Sundanese", "Syloti_Nagri", "Syriac", "Tagalog", "Tagbanwa", "Tai_Le",
"Tai_Tham", "Tai_Viet", "Takri", "Tamil", "Telugu", "Thaana", "Thai",
"Tibetan", "Tifinagh", "Tirhuta", "Ugaritic", "Vai", "Warang_Citi", "Yi");
String[][] KNOWN_PROPERTIES_ARRAY = ContainerUtil.map2Array(KNOWN_PROPERTIES, new String[KNOWN_PROPERTIES.size()][2],
s -> new String[]{s, ""});
String[][] CHARACTER_CLASSES = {
// Empty strings
{"A", "at beginning of text"},
{"b", "at ASCII word boundary (\\w on one side and \\W, \\A, or \\z on the other)"},
{"B", "not at ASCII word boundary"},
{"z", "at end of text"},
{"Z", "end of the text but for the final terminator, if any"},
// Escape sequences
{"a", "bell (== \007)"},
{"f", "form feed (== \014)"},
{"t", "horizontal tab (== \011)"},
{"n", "newline (== \012)"},
{"r", "carriage return (== \015)"},
{"v", "vertical tab character (== \013)"},
{"*", "literal *, for any punctuation character *"},
{"Q", "nothing, but quotes all characters until \\E"},
{"E", "nothing, but ends quoting started by \\Q"},
// Perl character classes (all ASCII-only):
{"d", "digits (== [0-9])"},
{"D", "not digits (== [^0-9])"},
{"s", "whitespace (== [\t\n\f\r ])"},
{"S", "not whitespace (== [^\t\n\f\r ])"},
{"w", "word characters (== [0-9A-Za-z_])"},
{"W", "not word characters (== [^0-9A-Za-z_])"},
};
}
}