String (String urlPattern) { int pos = urlPattern.indexOf('{'); return pos >= 0 ? urlPattern.substring(0, pos) : urlPattern; } @Nullable private static String transformPattern(@NotNull String urlPattern, QualifiedName moduleQName, @Nullable PsiNamedElement element, String pyVersion) { Map<String, String> macros = new HashMap<>(); macros.put("element.name", element == null ? null : element.getName()); PyClass pyClass = element == null ? null : PsiTreeUtil.getParentOfType(element, PyClass.class, false); macros.put("class.name", pyClass == null ? null : pyClass.getName()); if (element != null) { StringBuilder qName = new StringBuilder(moduleQName.toString()).append("."); if (element instanceof PyFunction && ((PyFunction)element).getContainingClass() != null) { qName.append(((PyFunction)element).getContainingClass().getName()).append("."); } qName.append(element.getName()); macros.put("element.qname", qName.toString()); } else { macros.put("element.qname", ""); } String functionName = element instanceof PyFunction && element.getName() != null ? element.getName() : ""; macros.put("function.name", functionName); macros.put("functionToProperty.name", functionToProperty(functionName)); macros.put("module.name", moduleQName.toString()); macros.put("python.version", pyVersion); macros.put("module.basename", moduleQName.getLastComponent()); macros.put("functionIsProperty?", Boolean.toString(!functionName.equals(functionToProperty(functionName)))); final String pattern = transformPattern(urlPattern, macros); if (pattern == null) { return rootForPattern(urlPattern); } return pattern; } private static String functionToProperty(@NotNull String name) { String functionOrProp = StringUtil.getPropertyName(name); if (functionOrProp == null) { functionOrProp = name; } return functionOrProp; } @Nullable private static String transformPattern(@NotNull String urlPattern, Map<String, String> macroValues) { for (Map.Entry<String, String> entry : macroValues.entrySet()) { if (entry.getValue() == null) { if (urlPattern.contains("{" + entry.getKey())) { return null; } continue; } if (entry.getKey().endsWith("?")) { String regex = "\\{" + Pattern.quote(entry.getKey()) + "([^}]+)\\}"; Matcher matcher = Pattern.compile(regex).matcher(urlPattern); if (matcher.find()) { String value = Boolean.parseBoolean(entry.getValue()) ? matcher.group(1) : ""; urlPattern = urlPattern.replaceAll(regex, value); } } urlPattern = urlPattern .replace("{" + entry.getKey() + "}", entry.getValue()) .replace("{" + entry.getKey() + ".lower}", StringUtil.toLowerCase(entry.getValue())) .replace("{" + entry.getKey() + ".slashes}", entry.getValue().replace(".", "/")) .replace("{" + entry.getKey() + ".dashes}", entry.getValue().replace("_", "-")); } return urlPattern.replace("{}", ""); } }