fixed PY-6947 Separate RST into plugin suitable for inclusion into PhpStorm/WebStorm

This commit is contained in:
Ekaterina Tuzova
2012-07-25 15:40:34 +04:00
parent c4886e55c7
commit 9ce7f48e4b
49 changed files with 9963 additions and 20 deletions
+9 -1
View File
@@ -42,7 +42,8 @@ setProperty("pluginFilter", [
"coffeescript",
"python-remote-interpreter",
"diagram-api", "uml",
"python-uml", "localization"
"python-uml", "localization",
"rest"
])
private List<String> pycharmPlatformApiModules() {
@@ -357,6 +358,13 @@ private layoutFull(Map args, String target, Set usedJars) {
}
}
}
dir("rest") {
dir("lib") {
jar("rest.jar") {
module("rest")
}
}
}
}
def layouts = includeFile("$home/build/scripts/layouts.gant")
+1
View File
@@ -31,6 +31,7 @@
<orderEntry type="module" module-name="uml" />
<orderEntry type="module" module-name="python-uml" />
<orderEntry type="module" module-name="localization" />
<orderEntry type="module" module-name="rest" />
</component>
</module>
+1
View File
@@ -39,6 +39,7 @@
<orderEntry type="module" module-name="FirefoxConnector" />
<orderEntry type="library" name="Velocity" level="project" />
<orderEntry type="module" module-name="localization" />
<orderEntry type="module" module-name="rest" />
</component>
<component name="copyright">
<Base>
+14
View File
@@ -0,0 +1,14 @@
<idea-plugin version="2" xmlns:xi="http://www.w3.org/2001/XInclude">
<name>ReStructuredText Support</name>
<id>org.jetbrains.plugins.rest</id>
<version>VERSION</version>
<description>This plugin enables support for ReStructuredText files (*.rst)</description>
<vendor logo="/general/ijLogo.png">JetBrains</vendor>
<depends>com.intellij.modules.ultimate</depends>
<xi:include href="/META-INF/rest.xml" xpointer="xpointer(/idea-plugin/*)"/>
<extensions defaultExtensionNs="com.intellij">
<errorHandler implementation="com.intellij.diagnostic.ITNReporter"/>
</extensions>
</idea-plugin>
+27
View File
@@ -0,0 +1,27 @@
<idea-plugin version="2">
<extensions defaultExtensionNs="com.intellij">
<fileTypeFactory implementation="com.jetbrains.rest.RestFileTypeFactory"/>
<lang.syntaxHighlighterFactory key="ReST"
implementationClass="com.jetbrains.rest.RestHighlighterFactory"/>
<lang.parserDefinition language="ReST" implementationClass="com.jetbrains.rest.parsing.RestParserDefinition"/>
<colorSettingsPage implementation="com.jetbrains.rest.RestColorsPage"/>
<projectService serviceInterface="com.jetbrains.rest.ReSTService"
serviceImplementation="com.jetbrains.rest.ReSTService"/>
<completion.contributor language="ReST" implementationClass="com.jetbrains.rest.completion.DirectiveCompletionContributor"/>
<completion.contributor language="ReST" implementationClass="com.jetbrains.rest.completion.OptionCompletionContributor"/>
<completion.contributor language="ReST" implementationClass="com.jetbrains.rest.completion.ReferenceCompletionContributor"/>
<gotoDeclarationHandler implementation="com.jetbrains.rest.RestGotoProvider" order="FIRST"/>
<lang.psiStructureViewFactory language="ReST"
implementationClass="com.jetbrains.rest.structureView.RestStructureViewFactory"/>
<annotator language="ReST" implementationClass="com.jetbrains.rest.validation.RestAnnotatingVisitor"/>
<lang.substitutor language="TEXT" implementationClass="com.jetbrains.rest.RestLanguageSubstitutor"/>
</extensions>
<extensions defaultExtensionNs="com.intellij.spellchecker">
<support language="ReST" implementationClass="com.jetbrains.rest.spellchecker.RestSpellcheckerStrategy"/>
</extensions>
</idea-plugin>
+17
View File
@@ -0,0 +1,17 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="JAVA_MODULE" version="4">
<component name="NewModuleRootManager" inherit-compiler-output="true">
<exclude-output />
<content url="file://$MODULE_DIR$">
<sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/resources" isTestSource="false" />
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
<orderEntry type="module" module-name="platform-api" />
<orderEntry type="module" module-name="lang-impl" />
<orderEntry type="library" name="Guava" level="project" />
<orderEntry type="module" module-name="spellchecker" />
</component>
</module>
@@ -0,0 +1,52 @@
package com.jetbrains.rest;
import com.intellij.openapi.components.*;
import com.intellij.openapi.project.Project;
import com.intellij.util.xmlb.XmlSerializerUtil;
/**
* User: catherine
*/
@State(name = "ReSTService",
storages = {
@Storage( file = StoragePathMacros.PROJECT_FILE),
@Storage( file = StoragePathMacros.PROJECT_CONFIG_DIR + "/rest.xml", scheme = StorageScheme.DIRECTORY_BASED)
}
)
public class ReSTService implements PersistentStateComponent<ReSTService> {
public String DOC_DIR = "";
public boolean TXT_IS_RST = false;
public ReSTService() {
}
@Override
public ReSTService getState() {
return this;
}
@Override
public void loadState(ReSTService state) {
XmlSerializerUtil.copyBean(state, this);
}
public void setWorkdir(String workDir) {
DOC_DIR = workDir;
}
public static ReSTService getInstance(Project project) {
return ServiceManager.getService(project, ReSTService.class);
}
public String getWorkdir() {
return DOC_DIR;
}
public boolean txtIsRst() {
return TXT_IS_RST;
}
public void setTxtIsRst(boolean isRst) {
TXT_IS_RST = isRst;
}
}
@@ -0,0 +1,39 @@
package com.jetbrains.rest;
import com.intellij.CommonBundle;
import com.intellij.reference.SoftReference;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.PropertyKey;
import java.lang.ref.Reference;
import java.util.ResourceBundle;
// A copy of Ruby's.
/**
* User : catherine
*/
public class RestBundle {
private static Reference<ResourceBundle> ourBundle;
@NonNls
private static final String BUNDLE = "com.jetbrains.rest.RestBundle";
private RestBundle() {
}
public static String message(@PropertyKey(resourceBundle = BUNDLE)String key, Object... params) {
return CommonBundle.message(getBundle(), key, params);
}
// Cached loading
private static ResourceBundle getBundle() {
ResourceBundle bundle = null;
if (ourBundle != null) bundle = ourBundle.get();
if (bundle == null) {
bundle = ResourceBundle.getBundle(BUNDLE);
ourBundle = new SoftReference<ResourceBundle>(bundle);
}
return bundle;
}
}
@@ -0,0 +1,22 @@
### Inspections: INSP ###
INSP.GROUP.rest=ReST
INSP.role.not.defined=Role is not defined
### Quick fixes ###
QFIX.ignore.role=Ignore undefined role ''{0}''
### Annotators ###
ANN.unknown.target=Unknown target name ''{0}''
ANN.duplicate.target=Duplicate explicit target name ''{0}''
ANN.unusable.anonymous.target=Anonymous hyperlink target has no reference
ANN.inline.block=Blank line is required after a literal block
### Run configurations ###
runcfg.docutils.display_name=Python docs
runcfg.docutils.description=Python documentation run configuration
runcfg.docutils.input=Input:
runcfg.docutils.output=Output:
runcfg.docutils.command=Command:
runcfg.docutils.options=Options:
runcfg.dlg.select.script.path=Select path:
@@ -0,0 +1,92 @@
package com.jetbrains.rest;
import com.intellij.openapi.editor.colors.TextAttributesKey;
import com.intellij.openapi.fileTypes.SyntaxHighlighter;
import com.intellij.openapi.options.colors.AttributesDescriptor;
import com.intellij.openapi.options.colors.ColorDescriptor;
import com.intellij.openapi.options.colors.ColorSettingsPage;
import com.intellij.util.containers.HashMap;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import javax.swing.*;
import java.util.Map;
/**
* User : catherine
*/
public class RestColorsPage implements ColorSettingsPage {
private static final AttributesDescriptor[] ATTRS = new AttributesDescriptor[]{
new AttributesDescriptor("Comment", RestSyntaxHighlighter.REST_COMMENT),
new AttributesDescriptor("Title", RestSyntaxHighlighter.REST_SECTION_HEADER),
new AttributesDescriptor("Explicit markup", RestSyntaxHighlighter.REST_EXPLICIT),
new AttributesDescriptor("Fields", RestSyntaxHighlighter.REST_FIELD),
new AttributesDescriptor("Reference name", RestSyntaxHighlighter.REST_REF_NAME),
new AttributesDescriptor("Inline literals", RestSyntaxHighlighter.REST_FIXED),
new AttributesDescriptor("Bold text", RestSyntaxHighlighter.REST_BOLD),
new AttributesDescriptor("Italic text", RestSyntaxHighlighter.REST_ITALIC),
new AttributesDescriptor("Interpreted text", RestSyntaxHighlighter.REST_INTERPRETED),
new AttributesDescriptor("Literal and line blocks", RestSyntaxHighlighter.REST_INLINE),
};
@NonNls private static final HashMap<String, TextAttributesKey> ourTagToDescriptorMap = new HashMap<String, TextAttributesKey>();
@NotNull
public String getDisplayName() {
return "ReST file";
}
public Icon getIcon() {
return RestFileType.INSTANCE.getIcon();
}
@NotNull
public AttributesDescriptor[] getAttributeDescriptors() {
return ATTRS;
}
@NotNull
public ColorDescriptor[] getColorDescriptors() {
return ColorDescriptor.EMPTY_ARRAY;
}
@NotNull
public SyntaxHighlighter getHighlighter() {
final SyntaxHighlighter highlighter = SyntaxHighlighter.PROVIDER.create(RestFileType.INSTANCE, null, null);
assert highlighter != null;
return highlighter;
}
@NotNull
public String getDemoText() {
return
".. comment for documentation master file\n\n" +
"===============\n" +
" Section Title\n" +
"===============\n\n" +
".. toctree::\n" +
" :maxdepth: 2\n\n" +
"There is *some italics text*\n" +
"and **bold one** " +
"and ``inline literals``\n\n" +
"A link_ in citation style.\n" +
"\n" +
".. _link: http://www.google.com\n\n" +
".. rubric:: Footnotes\n" +
".. [*] footnote.\n" +
".. [REL09] Citation\n\n" +
":ref:`builders`\n\n" +
"\n" +
"::\n" +
"\n" +
" Whitespace, newlines, blank lines, and\n" +
" all kinds of markup (like *this* or\n" +
" \\this) is preserved by literal blocks.\n\n" +
"It was literal block.";
}
public Map<String, TextAttributesKey> getAdditionalHighlightingTagToDescriptorMap() {
return ourTagToDescriptorMap;
}
}
@@ -0,0 +1,14 @@
package com.jetbrains.rest;
import com.intellij.psi.tree.IElementType;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
/**
* User : catherine
*/
public class RestElementType extends IElementType {
public RestElementType(@NotNull @NonNls String s) {
super(s, RestLanguage.INSTANCE);
}
}
@@ -0,0 +1,13 @@
package com.jetbrains.rest;
import com.intellij.psi.tree.IFileElementType;
/**
* User : catherine
*/
public interface RestElementTypes {
IFileElementType REST_FILE = new IFileElementType("REST_FILE", RestLanguage.INSTANCE);
RestElementType REFERENCE_TARGET = new RestElementType("REFERENCE");
RestElementType DIRECTIVE_BLOCK = new RestElementType("DIRECTIVE_BLOCK");
}
@@ -0,0 +1,32 @@
package com.jetbrains.rest;
import com.intellij.openapi.fileTypes.FileType;
import com.intellij.psi.FileViewProvider;
import com.intellij.psi.PsiElementVisitor;
import com.intellij.psi.impl.source.PsiFileImpl;
import org.jetbrains.annotations.NotNull;
/**
* User : catherine
*/
public class RestFile extends PsiFileImpl {
public RestFile(FileViewProvider viewProvider) {
super(RestElementTypes.REST_FILE, RestElementTypes.REST_FILE, viewProvider);
}
@NotNull
public FileType getFileType() {
return RestFileType.INSTANCE;
}
@Override
public void accept(@NotNull PsiElementVisitor visitor) {
visitor.visitFile(this);
}
@Override
public String toString() {
return "rest file";
}
}
@@ -0,0 +1,46 @@
package com.jetbrains.rest;
import com.intellij.openapi.fileTypes.LanguageFileType;
import com.intellij.openapi.util.IconLoader;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
/**
* User : catherine
*
* file type for restructured text files
*/
public class RestFileType extends LanguageFileType {
public static final RestFileType INSTANCE = new RestFileType();
@NonNls public static final String DEFAULT_EXTENSION = "rst";
@NonNls private static final String NAME = "ReST";
@NonNls private static final String DESCRIPTION = "reStructuredText files";
private RestFileType() {
super(RestLanguage.INSTANCE);
}
@NotNull
public String getName() {
return NAME;
}
@NotNull
public String getDescription() {
return DESCRIPTION;
}
@NotNull
public String getDefaultExtension() {
return DEFAULT_EXTENSION;
}
@Nullable
public Icon getIcon() {
return IconLoader.getIcon("/com/jetbrains/rest/res/rst.png", RestFileType.class);
}
}
@@ -0,0 +1,15 @@
package com.jetbrains.rest;
import com.intellij.openapi.fileTypes.FileTypeConsumer;
import com.intellij.openapi.fileTypes.FileTypeFactory;
import org.jetbrains.annotations.NotNull;
/**
* User : catherine
*/
public class RestFileTypeFactory extends FileTypeFactory {
@Override
public void createFileTypes(final @NotNull FileTypeConsumer consumer) {
consumer.consume(RestFileType.INSTANCE, RestFileType.DEFAULT_EXTENSION);
}
}
@@ -0,0 +1,23 @@
package com.jetbrains.rest;
import com.intellij.codeInsight.navigation.actions.GotoDeclarationHandlerBase;
import com.intellij.openapi.editor.Editor;
import com.intellij.psi.PsiElement;
import com.intellij.psi.util.PsiTreeUtil;
import com.jetbrains.rest.psi.RestReference;
/**
* User : catherine
*/
public class RestGotoProvider extends GotoDeclarationHandlerBase {
public PsiElement getGotoDeclarationTarget(PsiElement source, Editor editor) {
if (source != null && source.getLanguage() instanceof RestLanguage) {
RestReference ref = PsiTreeUtil.getParentOfType(source, RestReference.class);
if (ref != null) {
return ref.resolve();
}
}
return null;
}
}
@@ -0,0 +1,19 @@
package com.jetbrains.rest;
import com.intellij.openapi.fileTypes.SyntaxHighlighter;
import com.intellij.openapi.fileTypes.SyntaxHighlighterFactory;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.vfs.VirtualFile;
import org.jetbrains.annotations.NotNull;
/**
* User : catherine
*/
public class RestHighlighterFactory extends SyntaxHighlighterFactory {
@NotNull
@Override
public SyntaxHighlighter getSyntaxHighlighter(Project project, VirtualFile virtualFile) {
return new RestSyntaxHighlighter();
}
}
@@ -0,0 +1,41 @@
package com.jetbrains.rest;
import com.intellij.lang.Language;
import com.intellij.psi.templateLanguages.TemplateLanguage;
import com.jetbrains.rest.validation.RestAnnotator;
import com.jetbrains.rest.validation.RestHyperlinksAnnotator;
import com.jetbrains.rest.validation.RestInlineBlockAnnotator;
import com.jetbrains.rest.validation.RestReferenceTargetAnnotator;
import java.util.Set;
import java.util.concurrent.CopyOnWriteArraySet;
/**
* User : catherine
*/
public class RestLanguage extends Language implements TemplateLanguage {
public static final RestLanguage INSTANCE = new RestLanguage();
private final Set<Class<? extends RestAnnotator>> _annotators = new CopyOnWriteArraySet<Class<? extends RestAnnotator>>();
private RestLanguage() {
super("ReST");
}
@Override
public String getDisplayName() {
return "Rest language";
}
@Override
public RestFileType getAssociatedFileType() {
return RestFileType.INSTANCE;
}
{
_annotators.add(RestHyperlinksAnnotator.class);
_annotators.add(RestReferenceTargetAnnotator.class);
_annotators.add(RestInlineBlockAnnotator.class);
}
public Set<Class<? extends RestAnnotator>> getAnnotators() {
return _annotators;
}
}
@@ -0,0 +1,20 @@
package com.jetbrains.rest;
import com.intellij.lang.Language;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.LanguageSubstitutor;
import org.jetbrains.annotations.NotNull;
/**
* User : catherine
*/
public class RestLanguageSubstitutor extends LanguageSubstitutor {
@Override
public Language getLanguage(@NotNull final VirtualFile vFile, @NotNull final Project project) {
boolean txtIsRst = ReSTService.getInstance(project).txtIsRst();
if (txtIsRst)
return RestLanguage.INSTANCE;
return null;
}
}
@@ -0,0 +1,117 @@
/*
* Copyright 2000-2008 JetBrains s.r.o.
*
* 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.jetbrains.rest;
import com.google.common.collect.Maps;
import com.intellij.lexer.Lexer;
import com.intellij.openapi.editor.SyntaxHighlighterColors;
import com.intellij.openapi.editor.colors.TextAttributesKey;
import com.intellij.openapi.editor.markup.TextAttributes;
import com.intellij.openapi.fileTypes.SyntaxHighlighterBase;
import com.intellij.psi.tree.IElementType;
import com.jetbrains.rest.lexer.RestFlexLexer;
import org.jetbrains.annotations.NotNull;
import java.awt.*;
import java.util.Map;
/**
* User : catherine
*/
public class RestSyntaxHighlighter extends SyntaxHighlighterBase implements RestTokenTypes {
public static final TextAttributesKey REST_COMMENT = TextAttributesKey.createTextAttributesKey(
"REST.LINE_COMMENT",
SyntaxHighlighterColors.LINE_COMMENT.getDefaultAttributes()
);
public static final TextAttributesKey REST_SECTION_HEADER = TextAttributesKey.createTextAttributesKey(
"REST.SECTION.HEADER",
SyntaxHighlighterColors.NUMBER.getDefaultAttributes()
);
public static final TextAttributesKey REST_BOLD = TextAttributesKey.createTextAttributesKey(
"REST.BOLD",
new TextAttributes(Color.black, null, null, null, Font.BOLD)
);
public static final TextAttributesKey REST_ITALIC = TextAttributesKey.createTextAttributesKey(
"REST.ITALIC",
new TextAttributes(Color.black, null, null, null, Font.ITALIC)
);
public static final TextAttributesKey REST_FIXED = TextAttributesKey.createTextAttributesKey(
"REST.FIXED",
new TextAttributes(Color.black, new Color(217, 217, 240), null, null, Font.PLAIN)
);
public static final TextAttributesKey REST_INTERPRETED = TextAttributesKey.createTextAttributesKey(
"REST.INTERPRETED",
new TextAttributes(Color.black, new Color(202, 218, 186), null, null, Font.PLAIN)
);
public static final TextAttributesKey REST_REF_NAME = TextAttributesKey.createTextAttributesKey(
"REST.REF.NAME",
SyntaxHighlighterColors.STRING.getDefaultAttributes()
);
public static final TextAttributesKey REST_EXPLICIT= TextAttributesKey.createTextAttributesKey(
"REST.EXPLICIT",
SyntaxHighlighterColors.KEYWORD.getDefaultAttributes()
);
public static final TextAttributesKey REST_FIELD = TextAttributesKey.createTextAttributesKey(
"REST.FIELD",
SyntaxHighlighterColors.KEYWORD.getDefaultAttributes()
);
public static final TextAttributesKey REST_INLINE = TextAttributesKey.createTextAttributesKey(
"REST.INLINE",
new TextAttributes(null, new Color(237, 252, 237), null, null, Font.PLAIN)
);
private static final Map<IElementType, TextAttributesKey> ATTRIBUTES = Maps.newHashMap();
static {
ATTRIBUTES.put(REFERENCE_NAME, REST_REF_NAME);
ATTRIBUTES.put(DIRECT_HYPERLINK, REST_REF_NAME);
ATTRIBUTES.put(TITLE, REST_SECTION_HEADER);
ATTRIBUTES.put(TITLE_TEXT, REST_SECTION_HEADER);
ATTRIBUTES.put(FOOTNOTE, REST_EXPLICIT);
ATTRIBUTES.put(CITATION, REST_EXPLICIT);
ATTRIBUTES.put(HYPERLINK, REST_REF_NAME);
ATTRIBUTES.put(ANONYMOUS_HYPERLINK, REST_REF_NAME);
ATTRIBUTES.put(DIRECTIVE, REST_EXPLICIT);
ATTRIBUTES.put(CUSTOM_DIRECTIVE, REST_EXPLICIT);
ATTRIBUTES.put(SUBSTITUTION, REST_EXPLICIT);
ATTRIBUTES.put(COMMENT, REST_COMMENT);
ATTRIBUTES.put(FIELD, REST_FIELD);
ATTRIBUTES.put(BOLD, REST_BOLD);
ATTRIBUTES.put(ITALIC, REST_ITALIC);
ATTRIBUTES.put(FIXED, REST_FIXED);
ATTRIBUTES.put(INTERPRETED, REST_INTERPRETED);
ATTRIBUTES.put(INLINE_LINE, REST_INLINE);
ATTRIBUTES.put(PYTHON_LINE, REST_INLINE);
ATTRIBUTES.put(DJANGO_LINE, REST_INLINE);
}
@NotNull
public TextAttributesKey[] getTokenHighlights(IElementType tokenType) {
return SyntaxHighlighterBase.pack(ATTRIBUTES.get(tokenType));
}
@NotNull
public Lexer getHighlightingLexer() {
return new RestFlexLexer();
}
}
@@ -0,0 +1,44 @@
package com.jetbrains.rest;
/**
* User : catherine
*/
public interface RestTokenTypes {
RestElementType WHITESPACE = new RestElementType("WHITESPACE");
RestElementType TITLE = new RestElementType("TITLE");
RestElementType TITLE_TEXT = new RestElementType("TITLETEXT");
RestElementType EXPLISIT_MARKUP_START = new RestElementType("EXPLISIT_MARKUP_START");
RestElementType FOOTNOTE = new RestElementType("FOOTNOTE");
RestElementType CITATION = new RestElementType("CITATION");
RestElementType HYPERLINK = new RestElementType("HYPERLINK");
RestElementType ANONYMOUS_HYPERLINK = new RestElementType("ANONYMOUS_HYPERLINK");
RestElementType DIRECTIVE = new RestElementType("DIRECTIVE");
RestElementType CUSTOM_DIRECTIVE = new RestElementType("CUSTOM_DIRECTIVE");
RestElementType SUBSTITUTION = new RestElementType("SUBSTITUTION");
RestElementType LINE = new RestElementType("LINE");
RestElementType INLINE_LINE = new RestElementType("INLINE_LINE");
RestElementType SPEC_SYMBOL = new RestElementType("SPEC_SYMBOL");
RestElementType COMMENT = new RestElementType("COMMENT");
RestElementType REFERENCE_NAME = new RestElementType("REFERENCE_NAME");
RestElementType FIELD = new RestElementType("FIELD");
RestElementType BOLD = new RestElementType("BOLD");
RestElementType ITALIC = new RestElementType("ITALIC");
RestElementType FIXED = new RestElementType("FIXED");
RestElementType LITERAL_BLOCK_START = new RestElementType("LITERAL_BLOCK_START");
RestElementType INTERPRETED = new RestElementType("INTERPRETED");
RestElementType ERROR = new RestElementType("ERROR");
RestElementType REST_INJECTION = new RestElementType("REST_INJECTION");
RestElementType REST_DJANGO_INJECTION = new RestElementType("REST_DJANGO_INJECTION");
RestElementType DJANGO_LINE = new RestElementType("DJANGO_LINE");
RestElementType PYTHON_LINE = new RestElementType("PYTHON_LINE");
RestElementType JAVASCRIPT_LINE = new RestElementType("JAVASCRIPT_LINE");
RestElementType DIRECT_HYPERLINK = new RestElementType("DIRECT_HYPERLINK");
}
@@ -0,0 +1,165 @@
package com.jetbrains.rest;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
import com.intellij.openapi.vfs.LocalFileSystem;
import org.jetbrains.annotations.Nullable;
import java.io.File;
import java.util.Map;
import java.util.Set;
/**
* User : catherine
*/
public class RestUtil {
private RestUtil() {}
@Nullable
public static String findRunner(final String sdkHome, String runnerName) {
String shortRunner = null;
if (runnerName.endsWith(".py")) shortRunner = runnerName.substring(0, runnerName.length()-3);
File bin_path = new File(sdkHome);
File bin_dir = bin_path.getParentFile();
if (bin_dir == null) return null;
File runner = new File(bin_dir, runnerName);
if (runner.exists()) return LocalFileSystem.getInstance().extractPresentableUrl(runner.getPath());
runner = new File(new File(bin_dir, "scripts"), runnerName);
if (runner.exists()) return LocalFileSystem.getInstance().extractPresentableUrl(runner.getPath());
runner = new File(new File(bin_dir.getParentFile(), "scripts"), runnerName);
if (runner.exists()) return LocalFileSystem.getInstance().extractPresentableUrl(runner.getPath());
runner = new File(new File(bin_dir.getParentFile(), "local"), runnerName);
if (runner.exists()) return LocalFileSystem.getInstance().extractPresentableUrl(runner.getPath());
runner = new File(new File (new File(bin_dir.getParentFile(), "local"), "bin"), runnerName);
if (runner.exists()) return LocalFileSystem.getInstance().extractPresentableUrl(runner.getPath());
if (shortRunner != null) return findRunner(sdkHome, shortRunner);
return null;
}
public static String[] SPHINX_DIRECTIVES = new String[] {
"module::" , "automodule::" , "autoclass::" , "toctree::" , "glossary::" , "code-block::", "versionadded::",
"versionchanged::", "deprecated::", "seealso::", "centered::", "hlist::", "index::", "productionlist::", "highlight::",
"literalinclude::", "sectionauthor::", "codeauthor::", "only::", "tabularcolumns::", "py:function::", "default-domain::",
"py:module::", "py:currentmodule::", "py:data::", "py:exception::", "py:function::", "py:class::", "py:attribute::",
"py:method::", "py:staticmethod::", "py:classmethod::", "c:function::", "c:member::", "c:macro::", "c:type::", "c:var::",
"cpp:class::", "cpp:function::", "cpp:member::", "cpp:type::", "option::", "envvar::", "program::", "describe::", "object::",
"js:function::", "js:class::", "js:data::", "js:attribute::", "rst:directive::", "rst:role::"
};
public static final Set<String> PREDEFINED_ROLES = Sets.newHashSet();
public static final Set<String> SPHINX_ROLES = Sets.newHashSet();
private static final Map<String, String[]> DIRECTIVES = Maps.newHashMap();
static {
PREDEFINED_ROLES.add(":emphasis:");
PREDEFINED_ROLES.add(":literal:");
PREDEFINED_ROLES.add(":pep-reference:");
PREDEFINED_ROLES.add(":PEP:");
PREDEFINED_ROLES.add(":rfc-reference:");
PREDEFINED_ROLES.add(":RFC:");
PREDEFINED_ROLES.add(":strong:");
PREDEFINED_ROLES.add(":subscript:");
PREDEFINED_ROLES.add(":sub:");
PREDEFINED_ROLES.add(":superscript:");
PREDEFINED_ROLES.add(":sup:");
PREDEFINED_ROLES.add(":title-reference:");
PREDEFINED_ROLES.add(":title:");
PREDEFINED_ROLES.add(":t:");
PREDEFINED_ROLES.add(":raw:");
SPHINX_ROLES.add(":py:mod:");
SPHINX_ROLES.add(":py:func:");
SPHINX_ROLES.add(":py:data:");
SPHINX_ROLES.add(":py:const:");
SPHINX_ROLES.add(":py:class:");
SPHINX_ROLES.add(":py:meth:");
SPHINX_ROLES.add(":py:attr:");
SPHINX_ROLES.add(":py:exc:");
SPHINX_ROLES.add(":py:obj:");
SPHINX_ROLES.add(":ref:");
SPHINX_ROLES.add(":doc:");
SPHINX_ROLES.add(":download:");
SPHINX_ROLES.add(":envvar:");
SPHINX_ROLES.add(":token:");
SPHINX_ROLES.add(":keyword:");
SPHINX_ROLES.add(":option:");
SPHINX_ROLES.add(":term:");
SPHINX_ROLES.add(":abbr:");
SPHINX_ROLES.add(":command:");
SPHINX_ROLES.add(":dfn:");
SPHINX_ROLES.add(":file:");
SPHINX_ROLES.add(":guilabel:");
SPHINX_ROLES.add(":kbd:");
SPHINX_ROLES.add(":mailheader:");
SPHINX_ROLES.add(":makevar:");
SPHINX_ROLES.add(":manpage:");
SPHINX_ROLES.add(":menuselection:");
SPHINX_ROLES.add(":mimetype:");
SPHINX_ROLES.add(":newsgroup:");
SPHINX_ROLES.add(":program:");
SPHINX_ROLES.add(":regexp:");
SPHINX_ROLES.add(":samp:");
SPHINX_ROLES.add(":pep:");
SPHINX_ROLES.add(":rfc:");
DIRECTIVES.put("attention::", new String[] {});
DIRECTIVES.put("caution::", new String[] {});
DIRECTIVES.put("danger::", new String[] {});
DIRECTIVES.put("error::", new String[] {});
DIRECTIVES.put("hint::", new String[] {});
DIRECTIVES.put("important::", new String[] {});
DIRECTIVES.put("note::", new String[] {});
DIRECTIVES.put("tip::", new String[] {});
DIRECTIVES.put("warning::", new String[] {});
DIRECTIVES.put("admonition::", new String[] {":class:"});
DIRECTIVES.put("image::", new String[] {":alt:", ":height:", ":width:", ":scale:", ":align:", ":target:", ":class:"});
DIRECTIVES.put("figure::", new String[] {":alt:", ":height:", ":width:", ":scale:", ":align:", ":target:", ":class:", ":figwidth:", ":figclass:"});
DIRECTIVES.put("topic::", new String[] {":class:"});
DIRECTIVES.put("sidebar::", new String[] {":subtitle:", ":class:"});
DIRECTIVES.put("line-block::", new String[] {":class:"});
DIRECTIVES.put("parsed-literal::", new String[] {":class:"});
DIRECTIVES.put("rubric::", new String[] {":class:"});
DIRECTIVES.put("epigraph::", new String[] {});
DIRECTIVES.put("highlights::", new String[] {});
DIRECTIVES.put("pull-quote::", new String[] {});
DIRECTIVES.put("compound::", new String[] {":class:"});
DIRECTIVES.put("container::", new String[] {});
DIRECTIVES.put("table::", new String[] {":class:"});
DIRECTIVES.put("csv-table::", new String[] {":class:", ":widths:", ":header-rows:", ":stub-columns:", ":header:", ":file:", ":url:", ":encoding:",
":delim:", ":quote:", ":keepspace:", ":escape:"});
DIRECTIVES.put("list-table::", new String[] {":class:", ":widths:", ":header-rows:", ":stub-columns:"});
DIRECTIVES.put("contents::", new String[] {":class:", ":depth:", ":local:", ":backlinks:"});
DIRECTIVES.put("sectnum::", new String[] {":depth:", ":prefix:", ":suffix:", ":start:"});
DIRECTIVES.put("section-autonumbering::", new String[] {":depth:", ":prefix:", ":suffix:", ":start:"});
DIRECTIVES.put("header::", new String[] {});
DIRECTIVES.put("footer::", new String[] {});
DIRECTIVES.put("target-notes::", new String[] {"class"});
DIRECTIVES.put("footnotes::", new String[] {});
DIRECTIVES.put("citations::", new String[] {});
DIRECTIVES.put("meta::", new String[] {});
DIRECTIVES.put("replace::", new String[] {});
DIRECTIVES.put("unicode::", new String[] {":ltrim:", ":rtrim:", ":trim:"});
DIRECTIVES.put("date::", new String[] {});
DIRECTIVES.put("include::", new String[] {":start-line:", ":end-line:", ":start-after:", ":end-before:", ":literal:", ":encoding:", ":tab-width:"});
DIRECTIVES.put("raw::", new String[] {":file:", ":url:", ":encoding:"});
DIRECTIVES.put("class::", new String[] {});
DIRECTIVES.put("role::", new String[] {":class:", ":format:"});
DIRECTIVES.put("default-role::", new String[] {});
DIRECTIVES.put("title::", new String[] {});
DIRECTIVES.put("restructuredtext-test-directive::", new String[] {});
}
static public String[] getDirectiveOptions(String directive) {
if (DIRECTIVES.containsKey(directive))
return DIRECTIVES.get(directive);
return new String[]{};
}
static public Set<String> getDirectives() {
return DIRECTIVES.keySet();
}
}
@@ -0,0 +1,50 @@
package com.jetbrains.rest.completion;
import com.intellij.codeInsight.completion.*;
import com.intellij.codeInsight.lookup.LookupElementBuilder;
import com.intellij.openapi.projectRoots.Sdk;
import com.intellij.openapi.roots.ProjectRootManager;
import com.intellij.openapi.util.SystemInfo;
import com.intellij.patterns.PsiElementPattern;
import com.intellij.psi.PsiElement;
import com.intellij.util.ProcessingContext;
import com.jetbrains.rest.RestTokenTypes;
import com.jetbrains.rest.RestUtil;
import com.jetbrains.rest.psi.RestReferenceTarget;
import org.jetbrains.annotations.NotNull;
import static com.intellij.patterns.PlatformPatterns.psiElement;
import static com.intellij.patterns.StandardPatterns.or;
/**
* User : catherine
*/
public class DirectiveCompletionContributor extends CompletionContributor {
public static final PsiElementPattern.Capture<PsiElement> DIRECTIVE_PATTERN = psiElement().afterSibling(or(psiElement().
withElementType(RestTokenTypes.WHITESPACE).afterSibling(psiElement(RestReferenceTarget.class)),
psiElement().withElementType(RestTokenTypes.EXPLISIT_MARKUP_START)));
public DirectiveCompletionContributor() {
extend(CompletionType.BASIC, DIRECTIVE_PATTERN,
new CompletionProvider<CompletionParameters>() {
@Override
protected void addCompletions(@NotNull CompletionParameters parameters,
ProcessingContext context,
@NotNull CompletionResultSet result) {
for (String tag : RestUtil.getDirectives()) {
result.addElement(LookupElementBuilder.create(tag));
}
Sdk sdk = ProjectRootManager.getInstance(parameters.getPosition().getProject()).getProjectSdk();
if (sdk != null) {
String sphinx = RestUtil.findRunner(sdk.getHomePath(), "sphinx-quickstart"+ (SystemInfo.isWindows ? ".exe" : ""));
if (sphinx != null && !sphinx.isEmpty()) {
for (String tag : RestUtil.SPHINX_DIRECTIVES) {
result.addElement(LookupElementBuilder.create(tag));
}
}
}
}
}
);
}
}
@@ -0,0 +1,65 @@
package com.jetbrains.rest.completion;
import com.intellij.codeInsight.completion.*;
import com.intellij.codeInsight.lookup.LookupElementBuilder;
import com.intellij.patterns.PsiElementPattern;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFile;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.util.ProcessingContext;
import com.jetbrains.rest.RestUtil;
import com.jetbrains.rest.psi.RestDirectiveBlock;
import org.jetbrains.annotations.NotNull;
import static com.intellij.patterns.PlatformPatterns.psiElement;
/**
* User : catherine
*/
public class OptionCompletionContributor extends CompletionContributor {
public static final PsiElementPattern.Capture<PsiElement> OPTION_PATTERN = psiElement().withParent(RestDirectiveBlock.class);
public OptionCompletionContributor() {
extend(CompletionType.BASIC, OPTION_PATTERN,
new CompletionProvider<CompletionParameters>() {
@Override
protected void addCompletions(@NotNull CompletionParameters parameters,
ProcessingContext context,
@NotNull CompletionResultSet result) {
RestDirectiveBlock original = PsiTreeUtil.getParentOfType(parameters.getOriginalPosition(), RestDirectiveBlock.class);
if (original != null) {
int offset = parameters.getOffset();
final PsiFile file = parameters.getOriginalFile();
String prefix = getPrefix(offset, file);
if (prefix.length() > 0) {
result = result.withPrefixMatcher(prefix);
}
for (String tag : RestUtil.getDirectiveOptions(original.getDirectiveName())) {
result.addElement(LookupElementBuilder.create(tag + " "));
}
}
}
private String getPrefix(int offset, PsiFile file) {
if (offset > 0) {
offset--;
}
final String text = file.getText();
StringBuilder prefixBuilder = new StringBuilder();
while(offset > 0 && (Character.isLetterOrDigit(text.charAt(offset)) || text.charAt(offset) == ':')) {
prefixBuilder.insert(0, text.charAt(offset));
if (text.charAt(offset) == ':') {
break;
}
offset--;
}
return prefixBuilder.toString();
}
}
);
}
}
@@ -0,0 +1,91 @@
package com.jetbrains.rest.completion;
import com.intellij.codeInsight.completion.*;
import com.intellij.codeInsight.lookup.LookupElementBuilder;
import com.intellij.patterns.PsiElementPattern;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFile;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.util.ProcessingContext;
import com.jetbrains.rest.RestTokenTypes;
import com.jetbrains.rest.psi.RestReference;
import com.jetbrains.rest.psi.RestReferenceTarget;
import org.jetbrains.annotations.NotNull;
import java.util.HashSet;
import java.util.Set;
import static com.intellij.patterns.PlatformPatterns.psiElement;
/**
* User : catherine
*/
public class ReferenceCompletionContributor extends CompletionContributor {
public static final PsiElementPattern.Capture<PsiElement> REFERENCE_PATTERN =
psiElement().afterSibling(psiElement().withElementType(RestTokenTypes.EXPLISIT_MARKUP_START));
public static final PsiElementPattern.Capture<PsiElement> PATTERN =
psiElement().andOr(psiElement().withParent(REFERENCE_PATTERN), REFERENCE_PATTERN);
public ReferenceCompletionContributor() {
extend(CompletionType.BASIC, PATTERN,
new CompletionProvider<CompletionParameters>() {
@Override
protected void addCompletions(@NotNull CompletionParameters parameters,
ProcessingContext context,
@NotNull CompletionResultSet result) {
PsiElement original = parameters.getPosition();
PsiFile file = original.getContainingFile();
int offset = parameters.getOffset();
String prefix = getPrefix(offset, file);
if (prefix.length() > 0) {
result = result.withPrefixMatcher(prefix);
}
RestReference[] elements = PsiTreeUtil.getChildrenOfType(file, RestReference.class);
RestReferenceTarget[] targets = PsiTreeUtil.getChildrenOfType(file, RestReferenceTarget.class);
Set<String> names = new HashSet<String>();
if (targets != null) {
for (RestReferenceTarget t : targets) {
names.add(t.getReferenceName());
}
}
if (elements != null) {
for (RestReference e : elements) {
String name = e.getReferenceText();
if (! names.contains(name)) {
if ((name.startsWith("[") && name.endsWith("]")) ||
(name.startsWith("|") && name.endsWith("|")))
result.addElement(LookupElementBuilder.create(name));
else if (name.equals("__"))
result.addElement(LookupElementBuilder.create(name + ":"));
else {
if (name.startsWith("_")) name = "\\"+name;
result.addElement(LookupElementBuilder.create("_" + name + ":"));
}
}
}
}
}
private String getPrefix(int offset, PsiFile file) {
if (offset > 0) {
offset--;
}
final String text = file.getText();
StringBuilder prefixBuilder = new StringBuilder();
while(offset > 0 && (Character.isLetterOrDigit(text.charAt(offset)) || text.charAt(offset) == '_'
|| text.charAt(offset) == '[') || text.charAt(offset) == '|') {
prefixBuilder.insert(0, text.charAt(offset));
if (text.charAt(offset) == '_' || text.charAt(offset) == '[' || text.charAt(offset) == '|') {
break;
}
offset--;
}
return prefixBuilder.toString();
}
}
);
}
}
@@ -0,0 +1,20 @@
package com.jetbrains.rest.lexer;
import com.intellij.lexer.FlexAdapter;
import com.intellij.lexer.MergingLexerAdapter;
import com.intellij.psi.tree.TokenSet;
import com.jetbrains.rest.RestTokenTypes;
import java.io.Reader;
/**
* User : catherine
*/
public class RestFlexLexer extends MergingLexerAdapter {
public static final TokenSet TOKENS_TO_MERGE = TokenSet.create(RestTokenTypes.ITALIC, RestTokenTypes.BOLD, RestTokenTypes.FIXED,
RestTokenTypes.LINE, RestTokenTypes.PYTHON_LINE,
RestTokenTypes.COMMENT);
public RestFlexLexer() {
super(new FlexAdapter(new _RestFlexLexer((Reader) null)), TOKENS_TO_MERGE);
}
}
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,219 @@
package com.jetbrains.rest.lexer;
import com.intellij.lexer.FlexLexer;
import com.intellij.psi.tree.IElementType;
import com.jetbrains.rest.RestTokenTypes;
/* Auto generated File */
%%
%class _RestFlexLexer
%implements FlexLexer, RestTokenTypes
%unicode
%public
%ignorecase
%function advance
%type IElementType
%eof{ return;
%eof}
CRLF= \n|\r|\r\n
SPACE=[\ \t]
ADORNMENT_SYMBOL="="|"-"|"`"|":"|"."|"'"|\"|"~"|"^"|"_"|"*"|"+"|"#"|">"
ADORNMENT=("="{4, 80}|"-"{4, 80}|"`"{4, 80}|":"{4, 80}|"."{4, 80}|"'"{4, 80}|\"{4, 80}|"~"{4, 80}|"^"{4, 80}|"_"{4, 80}|"*"{4, 80}|"+"{4, 80}|"#"{4, 80}){CRLF}
SEPARATOR=[\n .:,()\{\}\[\]\-]
USUAL_TYPES="attention"|"caution"|"danger"|"error"|"hint"|"important"|"note"|"tip"|"warning"|"admonition"|"image"|"figure"|"topic"|"sidebar"|"parsed-literal"|"rubric"|"epigraph"|"highlights"|"pull-quote"|"compound"|"container"|"table"|"csv-table"|"list-table"|"contents"|"sectnum"|"section-autonumbering"|"header"|"footer"|"target-notes"|"footnotes"|"citations"|"meta"|"replace"|"unicode"|"date"|"include"|"raw"|"class"|"role"|"default-role"|"title"|"restructuredtext-test-directive"
HIGHLIGHT_TYPES= "highlight" | "sourcecode" | "code-block"
ANY_CHAR = [^\t`\ \n]
NOT_BACKQUOTE = [^`]
ANY= .|\n
%state IN_EXPLISIT_MARKUP
%state IN_COMMENT
%state IN_TITLE_TEXT
%state IN_BODY
%state IN_INLINE
%state HYPERLINK_TEXT
%state INDENTED
%state PRE_INDENTED
%state QUOTED
%state PRE_QUOTED
%state IN_LINE
%state IN_HIGHLIGHT
%state IN_VALUE
%state IN_FOOTNOTE
%state IN_LINEBEGIN
%state INIT
%{
int myState = 0; //python=1;django=2;initial=0;
int myIndent = 0;
private IElementType chooseType () {if (myState == 2)
return DJANGO_LINE;
else if (myState == 3)
return JAVASCRIPT_LINE;
else if (myState == 1)
return PYTHON_LINE;
else
return INLINE_LINE;
}
%}
%%
<YYINITIAL> {
":"[^:\n\r ]([^:\n\r] | "\\:")*[^:\n\r ]":"[ `\n] { yypushback(1); return FIELD;}
. { yypushback(1); yybegin(INIT); }
}
<INIT> {
//TITLES
^{ADORNMENT}?.*{CRLF}{ADORNMENT} { return TITLE;}
{CRLF}{2,5}{ADORNMENT}{CRLF}+ { return TITLE;}
//EXPLICIT MARKUP
".."" "+ { yybegin(IN_EXPLISIT_MARKUP); return EXPLISIT_MARKUP_START;}
"::"{CRLF}{CRLF} { yybegin(IN_INLINE);return LITERAL_BLOCK_START;}
// ESCAPING
"\\" { yybegin(IN_LINE); return SPEC_SYMBOL;}
// IMPLICIT MARKUP
"``"[^`\n\r ][^`\n\r]*[^`\n\r ]"``" { return FIXED;}
"**"[^*\n\r ][^*\n\r]*[^*\n\r ]"**" { return BOLD;}
"*"[^*\n\r ][^*\n\r]*[^*\n\r ]"*" { return ITALIC;}
"|"[^*|\n\r ][^*|\n\r]*[^*|\n\r ]"|" { return SUBSTITUTION;}
"http://"[^\n\r ]+ {return DIRECT_HYPERLINK;}
"`"[^`\n\r ][^`\n\r]*[^`\n\r ]"`" { return INTERPRETED;}
"`"{NOT_BACKQUOTE}+"`_""_"?{SEPARATOR} {yypushback(1); return REFERENCE_NAME;}
[0-9A-Za-z][0-9A-Za-z\-:+_]*"_""_"?{SEPARATOR} {yypushback(1); return REFERENCE_NAME;}
//"["([0-9]* | #?[0-9A-Za-z]* | "*")"]_"{SEPARATOR} {yypushback(1); return REFERENCE_NAME;}
":"[^:\n\r ]([^:\n\r] | "\\:")*[^:\n\r ]":"[`] { yypushback(1); yybegin(INIT); return FIELD;}
{CRLF} { yybegin(IN_LINEBEGIN); return WHITESPACE;}
. { yypushback(1); yybegin(IN_LINE); }
{SPACE}+ { yybegin(IN_LINEBEGIN); return WHITESPACE;}
}
<IN_LINEBEGIN> {
"["([0-9]* | #?[0-9A-Za-z]* | "*")"]_"{SEPARATOR} { yypushback(1); yybegin(INIT); return REFERENCE_NAME;}
{SPACE} { return LINE;}
{CRLF} { return WHITESPACE;}
"__" { yybegin(IN_VALUE); return ANONYMOUS_HYPERLINK;}
":"[^:\n\r ]([^:\n\r] | "\\:")*[^:\n\r ]":"[ `\n] { yypushback(1); yybegin(INIT); return FIELD;}
. { yypushback(1); yybegin(INIT);}
}
<IN_FOOTNOTE> {
"["([0-9]* | #?[0-9A-Za-z]* | "*")"]_"{SEPARATOR} { yypushback(1); yybegin(INIT); return REFERENCE_NAME;}
{SPACE} { return LINE;}
{CRLF} { return WHITESPACE;}
. { yypushback(1); yybegin(INIT);}
}
<IN_LINE> {
{CRLF} { return WHITESPACE;}
[^`*:\n\r\[ |({]* { yybegin(INIT); return LINE;}
{SPACE} { yybegin(IN_FOOTNOTE); return LINE;}
"(" | "[" | "{" { yybegin(IN_FOOTNOTE); return LINE;}
"`" | "_" | ":" | "*" | "[" | "|" { yybegin(INIT); return LINE;}
}
<IN_INLINE> {
//Two posibilities -- quoted-block, indented block
{CRLF} { return WHITESPACE;}
{SPACE}+ { yybegin(PRE_INDENTED); myIndent = yylength(); return chooseType();}
{ADORNMENT_SYMBOL} { yybegin(PRE_QUOTED); return SPEC_SYMBOL;}
//{CRLF}{2}~{CRLF}{2} { yybegin(INIT); return LINE;}
}
<PRE_QUOTED> {
.* { return chooseType();}
{CRLF} { yybegin(QUOTED); return chooseType();}
}
<QUOTED> {
{ADORNMENT_SYMBOL} { yybegin(PRE_QUOTED); return chooseType();}
. { yypushback(1); myState = 0; yybegin(INIT);}
}
<PRE_INDENTED> {
.* { yybegin(INDENTED); return chooseType();}
{CRLF} { return chooseType();}
}
<INDENTED> {
{SPACE}+ { if (yylength() >= myIndent) {
yybegin(PRE_INDENTED); return chooseType();}
else {
myIndent = 0; yypushback(yylength()); yybegin(INIT);
} }
{SPACE}*{CRLF}+ { return chooseType();}
{CRLF}+ { return chooseType();}
. { yypushback(1); myIndent = 0; myState = 0; yybegin(INIT);}
}
<IN_EXPLISIT_MARKUP> {
"["([0-9]* | #[0-9A-Za-z]* | "*")"]" { yybegin(INIT); return FOOTNOTE;}
"["[0-9A-Za-z]*"]" { yybegin(INIT); return CITATION;}
"__" { yybegin(IN_VALUE); return ANONYMOUS_HYPERLINK;}
"_"[^_\n\r:][^\n\r:]+":" { yybegin(INIT); return HYPERLINK;}
{USUAL_TYPES}"::" { yybegin(IN_VALUE); return DIRECTIVE;}
{HIGHLIGHT_TYPES}"::" { yybegin(IN_HIGHLIGHT); return CUSTOM_DIRECTIVE;}
[0-9A-Za-z\-:]*"::" { yybegin(IN_VALUE); return CUSTOM_DIRECTIVE;}
"|"[0-9A-Za-z]*"|" { return SUBSTITUTION;}
[0-9A-Za-z_\[|.]* { yybegin(IN_COMMENT); return COMMENT;}
{CRLF}{2} { yybegin(INIT); return COMMENT;}
{SPACE}*{CRLF}+ { return WHITESPACE; }
{SPACE}+ { return WHITESPACE;}
}
<IN_VALUE> {
[^\n\r]+ { return LINE;}
{CRLF} { yybegin(INIT); return WHITESPACE; }
}
<IN_HIGHLIGHT> {
{SPACE}+ { return WHITESPACE;}
{CRLF} { yybegin(INIT); return WHITESPACE; }
[A-Za-z+]+{CRLF}{CRLF} { String value = yytext().toString().trim();
if ("python".equalsIgnoreCase(value)) {
myState = 1;
yybegin(IN_INLINE);
}
else if ("django".equalsIgnoreCase(value) ||
"html+django".equalsIgnoreCase(value)) {
myState = 2;
yybegin(IN_INLINE);
}
else if ("javascript".equalsIgnoreCase(value)) {
myState = 3;
yybegin(IN_INLINE);
}
else {
yybegin(INIT);
}
return LINE;
}
. { yypushback(1); yybegin(INIT);}
}
<IN_COMMENT> {
{CRLF}".. " { yybegin(IN_EXPLISIT_MARKUP); return EXPLISIT_MARKUP_START;}
{SPACE}+ { return WHITESPACE;}
{CRLF}{2} { yybegin(INIT); return COMMENT;}
. { return COMMENT;}
{CRLF} { return WHITESPACE;}
}
{CRLF} { yybegin(INIT); return WHITESPACE; }
. { yybegin(INIT); return ERROR;}
@@ -0,0 +1,141 @@
/*
* Copyright 2000-2009 JetBrains s.r.o.
*
* 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.jetbrains.rest.parsing;
import com.intellij.lang.ASTNode;
import com.intellij.lang.PsiBuilder;
import com.intellij.lang.PsiParser;
import com.intellij.psi.tree.IElementType;
import com.jetbrains.rest.RestElementTypes;
import com.jetbrains.rest.RestTokenTypes;
import org.jetbrains.annotations.NotNull;
/**
* User : catherine
*/
public class RestParser implements PsiParser {
@NotNull
public ASTNode parse(IElementType root, PsiBuilder builder) {
final PsiBuilder.Marker rootMarker = builder.mark();
while (!builder.eof()) {
IElementType type = builder.getTokenType();
if (type == RestTokenTypes.EXPLISIT_MARKUP_START) {
builder.advanceLexer();
parseMarkup(builder);
}
else if (type == RestTokenTypes.REFERENCE_NAME || type == RestTokenTypes.SUBSTITUTION) {
PsiBuilder.Marker marker = builder.mark();
builder.advanceLexer();
marker.done(RestTokenTypes.REFERENCE_NAME);
}
else if (type == RestTokenTypes.TITLE) {
PsiBuilder.Marker marker = builder.mark();
builder.advanceLexer();
marker.done(RestTokenTypes.TITLE);
}
else if (type == RestTokenTypes.FIELD) {
PsiBuilder.Marker marker = builder.mark();
builder.advanceLexer();
marker.done(RestTokenTypes.FIELD);
}
else if (type == RestTokenTypes.INLINE_LINE) {
PsiBuilder.Marker marker = builder.mark();
builder.advanceLexer();
type = builder.getTokenType();
while (type == RestTokenTypes.INLINE_LINE) {
builder.advanceLexer();
type = builder.getTokenType();
}
marker.done(RestTokenTypes.INLINE_LINE);
}
else if (type == RestTokenTypes.ANONYMOUS_HYPERLINK) {
PsiBuilder.Marker marker = builder.mark();
builder.advanceLexer();
marker.done(RestElementTypes.REFERENCE_TARGET);
}
else
builder.advanceLexer();
}
rootMarker.done(root);
return builder.getTreeBuilt();
}
private void parseMarkup(PsiBuilder builder) {
PsiBuilder.Marker marker = builder.mark();
IElementType type = builder.getTokenType();
if (type == RestTokenTypes.SUBSTITUTION) {
builder.advanceLexer();
marker.done(RestElementTypes.REFERENCE_TARGET);
builder.advanceLexer();
marker = builder.mark();
type = builder.getTokenType();
}
if (type == RestTokenTypes.DIRECTIVE) {
gotoNextWhiteSpaces(builder);
if (builder.getTokenType() != RestTokenTypes.WHITESPACE) {
builder.advanceLexer();
marker.done(RestElementTypes.DIRECTIVE_BLOCK);
return;
}
skipBlankLines(builder);
if (builder.getTokenType() != RestTokenTypes.WHITESPACE || "\n".equals(builder.getTokenText())) {
marker.done(RestElementTypes.DIRECTIVE_BLOCK);
return;
}
String white = builder.getTokenText();
parseDirective(builder, white, marker);
}
else if (type == RestTokenTypes.FOOTNOTE || type == RestTokenTypes.CITATION ||
type == RestTokenTypes.HYPERLINK || type == RestTokenTypes.ANONYMOUS_HYPERLINK) {
builder.advanceLexer();
marker.done(RestElementTypes.REFERENCE_TARGET);
}
else {
builder.advanceLexer();
marker.drop();
}
}
private void gotoNextWhiteSpaces(PsiBuilder builder) {
while(!"\n".equals(builder.getTokenText()) && !(builder.getTokenType() == RestTokenTypes.TITLE) && !builder.eof() && (builder.getTokenType() != null)) {
builder.advanceLexer();
}
}
private void skipBlankLines(PsiBuilder builder) {
while("\n".equals(builder.getTokenText()) && !builder.eof() && (builder.getTokenType() != null)) {
builder.advanceLexer();
}
}
private void parseDirective(PsiBuilder builder, String white, PsiBuilder.Marker marker) {
gotoNextWhiteSpaces(builder);
if (builder.getTokenType() != RestTokenTypes.WHITESPACE) {
builder.advanceLexer();
marker.done(RestElementTypes.DIRECTIVE_BLOCK);
return;
}
skipBlankLines(builder);
if (white.equals(builder.getTokenText())) {
builder.advanceLexer();
parseDirective(builder, white, marker);
}
else {
marker.done(RestElementTypes.DIRECTIVE_BLOCK);
return;
}
}
}
@@ -0,0 +1,77 @@
package com.jetbrains.rest.parsing;
import com.intellij.lang.ASTNode;
import com.intellij.lang.ParserDefinition;
import com.intellij.lang.PsiParser;
import com.intellij.lexer.Lexer;
import com.intellij.openapi.project.Project;
import com.intellij.psi.FileViewProvider;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFile;
import com.intellij.psi.tree.IFileElementType;
import com.intellij.psi.tree.TokenSet;
import com.jetbrains.rest.RestFile;
import com.jetbrains.rest.RestLanguage;
import com.jetbrains.rest.RestTokenTypes;
import com.jetbrains.rest.lexer.RestFlexLexer;
import com.jetbrains.rest.psi.RestASTFactory;
import org.jetbrains.annotations.NotNull;
/**
* User : catherine
*/
public class RestParserDefinition implements ParserDefinition, RestTokenTypes {
private static final IFileElementType FILE_ELEMENT_TYPE = new IFileElementType(RestLanguage.INSTANCE);
private final RestASTFactory astFactory = new RestASTFactory();
@NotNull
@Override
public Lexer createLexer(Project project) {
return new RestFlexLexer();
}
@Override
public PsiParser createParser(Project project) {
return new RestParser();
}
@Override
public IFileElementType getFileNodeType() {
return FILE_ELEMENT_TYPE;
}
@NotNull
@Override
public TokenSet getWhitespaceTokens() {
return TokenSet.EMPTY;
}
@NotNull
@Override
public TokenSet getCommentTokens() {
return TokenSet.EMPTY;
}
@NotNull
@Override
public TokenSet getStringLiteralElements() {
return TokenSet.EMPTY;
}
@NotNull
@Override
public PsiElement createElement(ASTNode node) {
return astFactory.create(node);
}
@Override
public PsiFile createFile(FileViewProvider viewProvider) {
return new RestFile(viewProvider);
}
@Override
public SpaceRequirements spaceExistanceTypeBetweenTokens(ASTNode left, ASTNode right) {
return SpaceRequirements.MAY;
}
}
@@ -0,0 +1,38 @@
package com.jetbrains.rest.psi;
import com.intellij.extapi.psi.ASTWrapperPsiElement;
import com.intellij.lang.ASTNode;
import com.intellij.psi.PsiElement;
import com.intellij.psi.tree.IElementType;
import com.jetbrains.rest.RestElementTypes;
import com.jetbrains.rest.RestTokenTypes;
/**
* User : catherine
*/
public class RestASTFactory implements RestTokenTypes, RestElementTypes {
public PsiElement create(ASTNode node) {
IElementType type = node.getElementType();
if (type == DIRECTIVE_BLOCK) {
return new RestDirectiveBlock(node);
}
if (type == REFERENCE_NAME) {
return new RestReference(node);
}
if (type == REFERENCE_TARGET) {
return new RestReferenceTarget(node);
}
if (type == TITLE) {
return new RestTitle(node);
}
if (type == FIELD) {
return new RestRole(node);
}
if (type == INLINE_LINE) {
return new RestInlineBlock(node);
}
return new ASTWrapperPsiElement(node);
}
}
@@ -0,0 +1,28 @@
package com.jetbrains.rest.psi;
import com.intellij.lang.ASTNode;
import com.intellij.psi.PsiElement;
import org.jetbrains.annotations.NotNull;
/**
* User : catherine
*/
public class RestDirectiveBlock extends RestElement {
public RestDirectiveBlock(@NotNull final ASTNode node) {
super(node);
}
@Override
public String toString() {
return "RestDirective:" + getNode().getElementType().toString();
}
@NotNull
public String getDirectiveName() {
PsiElement child = this.getFirstChild();
if (child != null)
return child.getText();
else
return "";
}
}
@@ -0,0 +1,34 @@
package com.jetbrains.rest.psi;
import com.intellij.extapi.psi.ASTWrapperPsiElement;
import com.intellij.lang.ASTNode;
import com.intellij.psi.NavigatablePsiElement;
import com.intellij.psi.PsiElementVisitor;
import com.jetbrains.rest.validation.RestElementVisitor;
import org.jetbrains.annotations.NotNull;
public class RestElement extends ASTWrapperPsiElement implements NavigatablePsiElement {
public RestElement(@NotNull final ASTNode node) {
super(node);
}
@Override
public String toString() {
return "RestElement:" + getNode().getElementType().toString();
}
protected void acceptRestVisitor(RestElementVisitor visitor) {
visitor.visitRestElement(this);
}
public void accept(@NotNull PsiElementVisitor visitor) {
if (visitor instanceof RestElementVisitor) {
acceptRestVisitor(((RestElementVisitor)visitor));
}
else {
super.accept(visitor);
}
}
}
@@ -0,0 +1,27 @@
package com.jetbrains.rest.psi;
import com.intellij.lang.ASTNode;
import com.jetbrains.rest.validation.RestElementVisitor;
import org.jetbrains.annotations.NotNull;
/**
* User : catherine
*/
public class RestInlineBlock extends RestElement {
public RestInlineBlock(@NotNull final ASTNode node) {
super(node);
}
@Override
public String toString() {
return "RestInlineBlock";
}
public boolean isValid() {
return getText().matches("(.|\n)*\n *\n");
}
@Override
protected void acceptRestVisitor(RestElementVisitor visitor) {
visitor.visitInlineBlock(this);
}
}
@@ -0,0 +1,88 @@
package com.jetbrains.rest.psi;
import com.intellij.lang.ASTNode;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.psi.PsiFile;
import com.intellij.psi.util.PsiTreeUtil;
import com.jetbrains.rest.validation.RestElementVisitor;
import org.jetbrains.annotations.NotNull;
/**
* User : catherine
*/
public class RestReference extends RestElement {
public RestReference(@NotNull final ASTNode node) {
super(node);
}
@Override
public String toString() {
return "RestReference:" + getNode().getElementType().toString();
}
public String getReferenceText() {
String text = getNode().getText();
text = StringUtil.replace(text, "\n", " ");
text = text.replaceAll("\\\\([^\\\\]+)", "$1");
if (text.startsWith("`") && text.endsWith("`_"))
return text.substring(1, text.length()-2);
if (text.endsWith("__"))
return "__";
if (text.startsWith("|") && text.endsWith("|"))
return text;
return text.substring(0, text.length()-1);
}
@Override
protected void acceptRestVisitor(RestElementVisitor visitor) {
visitor.visitReference(this);
}
public RestElement resolve() {
String name = getReferenceText();
PsiFile file = getContainingFile();
RestReferenceTarget[] elements = PsiTreeUtil.getChildrenOfType(file, RestReferenceTarget.class);
if (elements != null) {
if (name.equals("__") || name.equals("[*]") || name.equals("[#]"))
return findAnonimousTarget(file, elements);
for (RestReferenceTarget element : elements) {
if (element.getReferenceName().equalsIgnoreCase(name) || element.getReferenceName(false).equalsIgnoreCase(name)) {
return element;
}
}
}
//TODO[catherine]: targets are not better than titles for resolving
// they should have the same ancestor
RestTitle[] titles = PsiTreeUtil.getChildrenOfType(file, RestTitle.class);
if (titles != null) {
for (RestTitle element : titles) {
if (name.equalsIgnoreCase(element.getName())) {
return element;
}
}
}
return null;
}
private RestReferenceTarget findAnonimousTarget(PsiFile file, RestReferenceTarget[] targets) {
String name = getReferenceText();
RestReference[] references = PsiTreeUtil.getChildrenOfType(file, RestReference.class);
int refIndex = 1;
int i = 0;
while (!references[i].equals(this)) {
if (references[i].getReferenceText().equals(name))
++refIndex;
++i;
}
int targetIndex = 0;
for (int j = 0; j != targets.length; ++j) {
if (targets[j].getReferenceName().equals(name))
++targetIndex;
if (targetIndex == refIndex)
return targets[j];
}
return null;
}
}
@@ -0,0 +1,67 @@
package com.jetbrains.rest.psi;
import com.intellij.lang.ASTNode;
import com.intellij.psi.PsiFile;
import com.intellij.psi.util.PsiTreeUtil;
import com.jetbrains.rest.validation.RestElementVisitor;
import org.jetbrains.annotations.NotNull;
/**
* User : catherine
*/
public class RestReferenceTarget extends RestElement {
public RestReferenceTarget(@NotNull final ASTNode node) {
super(node);
}
@Override
public String toString() {
return "RestReferenceTarget:" + getNode().getElementType().toString();
}
public String getReferenceName(boolean quoted) {
String text = getNode().getText();
if ("__".equals(text))
return text;
text = text.replaceAll("\\\\([^\\\\]+)", "$1");
if (text.startsWith("_`") && !quoted)
return text.substring(2, text.length()-2);
if (text.startsWith("_"))
return text.substring(1, text.length()-1);
if (text.startsWith("[#") && !quoted && text.length()>3)
return text.substring(2, text.length()-1);
if (text.startsWith("[") && !quoted)
return text.substring(1, text.length()-1);
return text;
}
public String getReferenceName() {
return getReferenceName(true);
}
public boolean hasReference() {
String text = getNode().getText();
PsiFile file = getContainingFile();
if ("__".equals(text)) {
RestReference[] references = PsiTreeUtil.getChildrenOfType(file, RestReference.class);
if (references != null) {
for (RestReference ref : references) {
if (ref.resolve() == this)
return true;
}
}
return false;
}
return true;
}
@Override
protected void acceptRestVisitor(RestElementVisitor visitor) {
visitor.visitReferenceTarget(this);
}
}
@@ -0,0 +1,29 @@
package com.jetbrains.rest.psi;
import com.intellij.lang.ASTNode;
import com.jetbrains.rest.validation.RestElementVisitor;
import org.jetbrains.annotations.NotNull;
/**
* User : catherine
*/
public class RestRole extends RestElement {
public RestRole(@NotNull final ASTNode node) {
super(node);
}
@Override
public String toString() {
return "RestRole:" + getNode().getElementType().toString();
}
public String getRoleName() {
String text = getNode().getText();
return text.substring(1, text.length()-1);
}
@Override
protected void acceptRestVisitor(RestElementVisitor visitor) {
visitor.visitRole(this);
}
}
@@ -0,0 +1,51 @@
package com.jetbrains.rest.psi;
import com.intellij.lang.ASTNode;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.text.CharacterIterator;
import java.text.StringCharacterIterator;
/**
* User : catherine
*/
public class RestTitle extends RestElement {
public RestTitle(@NotNull final ASTNode node) {
super(node);
}
@Override
public String toString() {
return "RestTitle:" + getNode().getElementType().toString();
}
@Nullable
public String getName() {
final String text = getNode().getText();
if (text.length() == 0) return null;
final char adorn = text.charAt(text.length()-2);
final CharacterIterator it = new StringCharacterIterator(text);
int finish = 0;
for (char ch = it.last(); ch != CharacterIterator.DONE; ch = it.previous()) {
if (finish == 0)
finish++;
else if (ch != adorn) {
finish = it.getIndex();
break;
}
}
int start = 0;
if (text.charAt(0) == adorn) {
for (char ch = it.first(); ch != CharacterIterator.DONE; ch = it.next()) {
if (ch != adorn) {
start = it.getIndex() + 1;
break;
}
}
}
if (finish <= 0 || start < 0)
return null;
return text.substring(start, finish).trim();
}
}
@@ -1,6 +1,5 @@
package com.jetbrains.python.spellchecker;
package com.jetbrains.rest.spellchecker;
import com.intellij.lang.Language;
import com.intellij.psi.PsiElement;
import com.intellij.psi.impl.source.tree.LeafPsiElement;
import com.intellij.psi.tree.IElementType;
@@ -0,0 +1,81 @@
package com.jetbrains.rest.structureView;
import com.intellij.ide.structureView.StructureViewTreeElement;
import com.intellij.navigation.ItemPresentation;
import com.intellij.psi.NavigatablePsiElement;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiElementVisitor;
import com.jetbrains.rest.psi.RestElement;
import com.jetbrains.rest.psi.RestTitle;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
import java.util.LinkedHashSet;
import java.util.Set;
/**
* Handles nodes in ReST Structure View.
* User : catherine
*/
public class RestStructureViewElement implements StructureViewTreeElement {
private NavigatablePsiElement myElement;
public RestStructureViewElement(NavigatablePsiElement element) {
myElement = element;
}
public NavigatablePsiElement getValue() {
return myElement;
}
public void navigate(boolean requestFocus) {
myElement.navigate(requestFocus);
}
public boolean canNavigate() {
return myElement.canNavigate();
}
public boolean canNavigateToSource() {
return myElement.canNavigateToSource();
}
public StructureViewTreeElement[] getChildren() {
final Set<RestElement> childrenElements = new LinkedHashSet<RestElement>();
myElement.acceptChildren(new PsiElementVisitor() {
@Override
public void visitElement(PsiElement element) {
if (element instanceof RestTitle && ((RestTitle)element).getName() != null)
childrenElements.add((RestElement)element);
else
element.acceptChildren(this);
}
});
StructureViewTreeElement[] children = new StructureViewTreeElement[childrenElements.size()];
int i = 0;
for (RestElement element : childrenElements) {
children[i] = new RestStructureViewElement(element);
i += 1;
}
return children;
}
public ItemPresentation getPresentation() {
return new ItemPresentation() {
public String getPresentableText() {
return myElement.getName();
}
@Nullable
public String getLocationString() {
return null;
}
public Icon getIcon(boolean open) {
return null;
}
};
}
}
@@ -0,0 +1,23 @@
package com.jetbrains.rest.structureView;
import com.intellij.ide.structureView.StructureViewBuilder;
import com.intellij.ide.structureView.StructureViewModel;
import com.intellij.ide.structureView.TreeBasedStructureViewBuilder;
import com.intellij.lang.PsiStructureViewFactory;
import com.intellij.psi.PsiFile;
import org.jetbrains.annotations.NotNull;
/**
* User : catherine
*/
public class RestStructureViewFactory implements PsiStructureViewFactory {
public StructureViewBuilder getStructureViewBuilder(final PsiFile psiFile) {
return new TreeBasedStructureViewBuilder() {
@NotNull
public StructureViewModel createStructureViewModel() {
return new RestStructureViewModel(psiFile);
}
};
}
}
@@ -0,0 +1,42 @@
package com.jetbrains.rest.structureView;
import com.intellij.ide.structureView.StructureViewModel;
import com.intellij.ide.structureView.StructureViewModelBase;
import com.intellij.ide.structureView.StructureViewTreeElement;
import com.intellij.ide.util.treeView.smartTree.Sorter;
import com.intellij.psi.PsiFile;
import com.jetbrains.rest.RestFile;
import com.jetbrains.rest.psi.RestTitle;
import org.jetbrains.annotations.NotNull;
/**
* User : catherine
*/
public class RestStructureViewModel extends StructureViewModelBase implements StructureViewModel.ElementInfoProvider, StructureViewModel.ExpandInfoProvider {
public RestStructureViewModel(@NotNull PsiFile psiFile) {
super(psiFile, new RestStructureViewElement(psiFile));
withSorters(Sorter.ALPHA_SORTER);
withSuitableClasses(RestTitle.class);
}
@Override
public boolean isAlwaysShowsPlus(StructureViewTreeElement element) {
final Object value = element.getValue();
return value instanceof RestFile;
}
@Override
public boolean isAlwaysLeaf(StructureViewTreeElement element) {
return element.getValue() instanceof RestTitle;
}
@Override
public boolean isAutoExpand(StructureViewTreeElement element) {
return element.getValue() instanceof PsiFile;
}
@Override
public boolean isSmartExpand() {
return false;
}
}
@@ -0,0 +1,44 @@
package com.jetbrains.rest.validation;
import com.intellij.lang.annotation.AnnotationHolder;
import com.intellij.lang.annotation.Annotator;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.psi.PsiElement;
import com.jetbrains.rest.RestFileType;
import com.jetbrains.rest.RestLanguage;
import org.jetbrains.annotations.NotNull;
import java.util.ArrayList;
import java.util.List;
/**
* User : catherine
*/
public class RestAnnotatingVisitor implements Annotator {
private static final Logger LOGGER = Logger.getInstance(RestAnnotatingVisitor.class.getName());
private final List<RestAnnotator> myAnnotators = new ArrayList<RestAnnotator>();
public RestAnnotatingVisitor() {
for (Class<? extends RestAnnotator> cls : ((RestLanguage)RestFileType.INSTANCE.getLanguage()).getAnnotators()) {
RestAnnotator annotator;
try {
annotator = cls.newInstance();
}
catch (InstantiationException e) {
LOGGER.error(e);
continue;
}
catch (IllegalAccessException e) {
LOGGER.error(e);
continue;
}
myAnnotators.add(annotator);
}
}
public void annotate(@NotNull PsiElement psiElement, @NotNull AnnotationHolder holder) {
for(RestAnnotator annotator: myAnnotators) {
annotator.annotateElement(psiElement, holder);
}
}
}
@@ -0,0 +1,33 @@
package com.jetbrains.rest.validation;
import com.intellij.lang.annotation.AnnotationHolder;
import com.intellij.psi.PsiElement;
/**
* User : catherine
*/
public abstract class RestAnnotator extends RestElementVisitor {
private AnnotationHolder _holder;
public AnnotationHolder getHolder() {
return _holder;
}
public void setHolder(AnnotationHolder holder) {
_holder = holder;
}
public synchronized void annotateElement(final PsiElement psiElement, final AnnotationHolder holder) {
setHolder(holder);
try {
psiElement.accept(this);
}
finally {
setHolder(null);
}
}
protected void markError(PsiElement element, String message) {
getHolder().createErrorAnnotation(element, message);
}
}
@@ -0,0 +1,38 @@
package com.jetbrains.rest.validation;
import com.intellij.psi.PsiElementVisitor;
import com.jetbrains.rest.psi.*;
/**
* User : catherine
* Visitor for rest-specific nodes.
*/
public class RestElementVisitor extends PsiElementVisitor {
public void visitRestElement(final RestElement node) {
visitElement(node);
}
public void visitReference(final RestReference node) {
visitRestElement(node);
}
public void visitReferenceTarget(final RestReferenceTarget node) {
visitRestElement(node);
}
public void visitRole(final RestRole node) {
visitRestElement(node);
}
public void visitTitle(final RestTitle node) {
visitRestElement(node);
}
public void visitDirectiveBlock(final RestDirectiveBlock node) {
visitRestElement(node);
}
public void visitInlineBlock(final RestInlineBlock node) {
visitRestElement(node);
}
}
@@ -0,0 +1,21 @@
package com.jetbrains.rest.validation;
import com.jetbrains.rest.RestBundle;
import com.jetbrains.rest.psi.RestReference;
/**
* Looks for not defined hyperlinks
*
* User : catherine
*/
public class RestHyperlinksAnnotator extends RestAnnotator {
@Override
public void visitReference(final RestReference node) {
if (node.getText().matches("`[^`]*<[^`]+>`_(_)?"))
return;
if (node.resolve() == null)
getHolder().createWarningAnnotation(node, RestBundle.message("ANN.unknown.target", node.getReferenceText()));
}
}
@@ -0,0 +1,25 @@
package com.jetbrains.rest.validation;
import com.intellij.psi.PsiElement;
import com.jetbrains.rest.RestBundle;
import com.jetbrains.rest.psi.RestInlineBlock;
/**
* Looks for invalid inline block
*
* User : catherine
*/
public class RestInlineBlockAnnotator extends RestAnnotator {
@Override
public void visitInlineBlock(final RestInlineBlock node) {
if (!node.isValid()) {
PsiElement el = node.getLastChild();
if (el != null) {
if (el.getText().equals("\n") && el.getPrevSibling() != null)
el = el.getPrevSibling();
markError(el, RestBundle.message("ANN.inline.block"));
}
}
}
}
@@ -0,0 +1,34 @@
package com.jetbrains.rest.validation;
import com.intellij.psi.util.PsiTreeUtil;
import com.jetbrains.rest.RestBundle;
import com.jetbrains.rest.RestFile;
import com.jetbrains.rest.psi.RestReferenceTarget;
/**
* Looks for double defined hyperlinks
*
* User : catherine
*/
public class RestReferenceTargetAnnotator extends RestAnnotator {
@Override
public void visitReferenceTarget(final RestReferenceTarget node) {
RestFile file = (RestFile)node.getContainingFile();
RestReferenceTarget[] targets = PsiTreeUtil.getChildrenOfType(file, RestReferenceTarget.class);
String quotedName = node.getReferenceName();
String name = node.getReferenceName(false);
if (targets != null) {
if ("__".equals(name) && !node.hasReference()) {
getHolder().createWarningAnnotation(node, RestBundle.message("ANN.unusable.anonymous.target"));
}
for (RestReferenceTarget element : targets) {
if ((element.getReferenceName().equalsIgnoreCase(name) || element.getReferenceName(false).equalsIgnoreCase(name) ||
element.getReferenceName().equalsIgnoreCase(quotedName) || element.getReferenceName(false).equalsIgnoreCase(quotedName)) &&
!element.equals(node) && ! "__".equals(name) && !"[#]".equals(quotedName) && !"[*]".equals(quotedName)) {
getHolder().createWarningAnnotation(element, RestBundle.message("ANN.duplicate.target", name));
}
}
}
}
}
+1 -17
View File
@@ -652,29 +652,14 @@
<!-- ReST files -->
<fileTypeFactory implementation="com.jetbrains.rest.RestFileTypeFactory"/>
<lang.syntaxHighlighterFactory key="ReST"
implementationClass="com.jetbrains.rest.RestHighlighterFactory"/>
<lang.parserDefinition language="ReST" implementationClass="com.jetbrains.rest.parsing.RestParserDefinition"/>
<colorSettingsPage implementation="com.jetbrains.rest.RestColorsPage"/>
<projectService serviceInterface="com.jetbrains.rest.ReSTService"
serviceImplementation="com.jetbrains.rest.ReSTService"/>
<completion.contributor language="ReST" implementationClass="com.jetbrains.rest.completion.DirectiveCompletionContributor"/>
<completion.contributor language="ReST" implementationClass="com.jetbrains.rest.completion.OptionCompletionContributor"/>
<completion.contributor language="ReST" implementationClass="com.jetbrains.rest.completion.ReferenceCompletionContributor"/>
<gotoDeclarationHandler implementation="com.jetbrains.rest.RestGotoProvider" order="FIRST"/>
<lang.fileViewProviderFactory language="ReST"
implementationClass="com.jetbrains.rest.RestFileProviderFactory"/>
<lang.psiStructureViewFactory language="ReST"
implementationClass="com.jetbrains.rest.structureView.RestStructureViewFactory"/>
<annotator language="ReST" implementationClass="com.jetbrains.rest.validation.RestAnnotatingVisitor"/>
<editorHighlighterProvider filetype="ReST" implementationClass="com.jetbrains.rest.RestEditorHighlighterProvider"/>
<localInspection language="ReST" shortName="RestRoleInspection" bundle="com.jetbrains.rest.RestBundle" key="INSP.role.not.defined"
groupKey="INSP.GROUP.rest" enabledByDefault="false" level="WARNING"
implementationClass="com.jetbrains.rest.inspections.RestRoleInspection"/>
<lang.substitutor language="TEXT" implementationClass="com.jetbrains.rest.RestLanguageSubstitutor"/>
<configurationType implementation="com.jetbrains.rest.run.RestRunConfigurationType"/>
<configurationProducer implementation="com.jetbrains.rest.run.docutils.DocutilsConfigurationProducer"/>
<configurationProducer implementation="com.jetbrains.rest.run.sphinx.SphinxConfigurationProducer"/>
@@ -965,7 +950,6 @@
<extensions defaultExtensionNs="com.intellij.spellchecker">
<support language="Python" implementationClass="com.jetbrains.python.spellchecker.PythonSpellcheckerStrategy"/>
<support language="ReST" implementationClass="com.jetbrains.python.spellchecker.RestSpellcheckerStrategy"/>
<bundledDictionaryProvider implementation="com.jetbrains.python.spellchecker.PythonBundledDictionaryProvider"/>
</extensions>