mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
bundle relax-ng plugin
This commit is contained in:
Generated
+1
@@ -11,6 +11,7 @@
|
||||
<module fileurl="file://$PROJECT_DIR$/RegExpSupport/RegExpSupport.iml" filepath="$PROJECT_DIR$/RegExpSupport/RegExpSupport.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/platform/annotations/annotations.iml" filepath="$PROJECT_DIR$/platform/annotations/annotations.iml" group="platform" />
|
||||
<module fileurl="file://$PROJECT_DIR$/plugins/ant/ant.iml" filepath="$PROJECT_DIR$/plugins/ant/ant.iml" group="plugins" />
|
||||
<module fileurl="file://$PROJECT_DIR$/plugins/relaxng/relaxng.iml" filepath="$PROJECT_DIR$/plugins/relaxng/relaxng.iml" group="plugins" />
|
||||
<module fileurl="file://$PROJECT_DIR$/platform/boot/boot.iml" filepath="$PROJECT_DIR$/platform/boot/boot.iml" group="platform" />
|
||||
<module fileurl="file://$PROJECT_DIR$/platform/bootstrap/bootstrap.iml" filepath="$PROJECT_DIR$/platform/bootstrap/bootstrap.iml" group="platform" />
|
||||
<module fileurl="file://$PROJECT_DIR$/build/build.iml" filepath="$PROJECT_DIR$/build/build.iml" />
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,31 @@
|
||||
Copyright (c) 2002, 2003 Thai Open Source Software Center Ltd
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are
|
||||
met:
|
||||
|
||||
Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in
|
||||
the documentation and/or other materials provided with the
|
||||
distribution.
|
||||
|
||||
Neither the name of the Thai Open Source Software Center Ltd nor
|
||||
the names of its contributors may be used to endorse or promote
|
||||
products derived from this software without specific prior written
|
||||
permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR
|
||||
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
Binary file not shown.
@@ -0,0 +1,56 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<module relativePaths="true" 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$/test" isTestSource="true" />
|
||||
</content>
|
||||
<orderEntry type="inheritedJdk" />
|
||||
<orderEntry type="sourceFolder" forTests="false" />
|
||||
<orderEntry type="module" module-name="lang-api" />
|
||||
<orderEntry type="module" module-name="xml" />
|
||||
<orderEntry type="module" module-name="dom-openapi" />
|
||||
<orderEntry type="module" module-name="lang-impl" />
|
||||
<orderEntry type="module" module-name="testFramework" scope="TEST" />
|
||||
<orderEntry type="module-library">
|
||||
<library>
|
||||
<CLASSES>
|
||||
<root url="jar://$MODULE_DIR$/lib/rngom-20051226-patched.jar!/" />
|
||||
</CLASSES>
|
||||
<JAVADOC />
|
||||
<SOURCES>
|
||||
<root url="jar://$MODULE_DIR$/lib/rngom-src.zip!/src" />
|
||||
</SOURCES>
|
||||
</library>
|
||||
</orderEntry>
|
||||
<orderEntry type="module-library">
|
||||
<library>
|
||||
<CLASSES>
|
||||
<root url="jar://$MODULE_DIR$/lib/isorelax.jar!/" />
|
||||
</CLASSES>
|
||||
<JAVADOC />
|
||||
<SOURCES />
|
||||
</library>
|
||||
</orderEntry>
|
||||
<orderEntry type="module-library">
|
||||
<library>
|
||||
<CLASSES>
|
||||
<root url="jar://$MODULE_DIR$/lib/trang-core.jar!/" />
|
||||
</CLASSES>
|
||||
<JAVADOC />
|
||||
<SOURCES />
|
||||
</library>
|
||||
</orderEntry>
|
||||
<orderEntry type="module-library">
|
||||
<library>
|
||||
<CLASSES>
|
||||
<root url="jar://$MODULE_DIR$/lib/jing.jar!/" />
|
||||
</CLASSES>
|
||||
<JAVADOC />
|
||||
<SOURCES />
|
||||
</library>
|
||||
</orderEntry>
|
||||
</component>
|
||||
</module>
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
Copyright 2007 Sascha Weinreuter
|
||||
|
||||
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.
|
||||
@@ -0,0 +1,73 @@
|
||||
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||
<head>
|
||||
<title>Jing Copying Conditions</title>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<h1>Jing Copying Conditions</h1>
|
||||
|
||||
<p>Copyright (c) 2001-2003 Thai Open Source Software Center Ltd<br />
|
||||
All rights reserved.</p>
|
||||
|
||||
<p>Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are
|
||||
met:</p>
|
||||
|
||||
<ul>
|
||||
<li>Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.</li>
|
||||
|
||||
<li>Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in
|
||||
the documentation and/or other materials provided with the
|
||||
distribution.</li>
|
||||
|
||||
<li>Neither the name of the Thai Open Source Software Center Ltd nor
|
||||
the names of its contributors may be used to endorse or promote
|
||||
products derived from this software without specific prior written
|
||||
permission.</li>
|
||||
</ul>
|
||||
|
||||
<p>THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR
|
||||
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.</p>
|
||||
|
||||
<h2>Third-party JARs</h2>
|
||||
|
||||
<p>This distribution includes some additional JAR files, which have
|
||||
their own copying conditions:</p>
|
||||
|
||||
<dl>
|
||||
|
||||
<dt><code>isorelax.jar</code></dt>
|
||||
<dd>Comes from <a href="http://sourceforge.net/projects/iso-relax/">ISO RELAX</a>
|
||||
2003/01/08 distribution and is covered by the following license:
|
||||
|
||||
<p>Copyright (c) 2001-2002, SourceForge ISO-RELAX Project (ASAMI Tomoharu, Daisuke
|
||||
Okajima, Kohsuke Kawaguchi, and MURATA Makoto)</p>
|
||||
|
||||
<p>Permission is hereby granted, free of charge, to any person obtaining a copy of
|
||||
this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use,
|
||||
copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the
|
||||
Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:</p>
|
||||
|
||||
<p>The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.</p>
|
||||
|
||||
<p>THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR
|
||||
A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
||||
ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.</p>
|
||||
</dd>
|
||||
|
||||
</dl>
|
||||
|
||||
</body>
|
||||
|
||||
</html>
|
||||
@@ -0,0 +1,93 @@
|
||||
<idea-plugin version="2" url="http://www.jetbrains.net/confluence/display/CONTEST/RELAX-NG+Support">
|
||||
<id>RelaxNG-Support</id>
|
||||
<name>RELAX-NG Support</name>
|
||||
<depends>com.intellij.modules.xml</depends>
|
||||
|
||||
<description><![CDATA[
|
||||
Support for RELAX-NG XML schemas. See <a href="http://relaxng.org/">relaxng.org</a> and the corresponding
|
||||
IntelliJ IDEA feature request: <a href="http://www.jetbrains.net/jira/browse/IDEA-13734">IDEA-13734</a>.
|
||||
<p>
|
||||
The plugin provides the following features:
|
||||
</p>
|
||||
<ul>
|
||||
<li> Completion and validation of XML documents associated with RELAX-NG schemas</li>
|
||||
<li> Editing RELAX-NG files in XML and compact syntax, including on-the-fly error checking, completion,
|
||||
documentation lookup and more.</li>
|
||||
<li> Conversion between different schema formats (including W3C XML Schema/XML 1.0 DTDs) using
|
||||
<a href="http://www.thaiopensource.com/relaxng/trang.html">Trang</a></li>
|
||||
</ul>
|
||||
]]></description>
|
||||
<version>1.5.5</version>
|
||||
|
||||
<change-notes><![CDATA[
|
||||
<ul>
|
||||
<li>extreme index optimization</li>
|
||||
<li>renameable xml prefixes</li>
|
||||
<li>IDEA 9.x compatibility bugfixes</li>
|
||||
</ul>
|
||||
<p>
|
||||
The complete list of changes in earlier versions is available
|
||||
<a href="http://www.jetbrains.net/confluence/display/CONTEST/RELAX-NG+Support#RELAX-NGSupport-VersionHistory">here</a>
|
||||
</p>
|
||||
]]></change-notes>
|
||||
|
||||
<vendor email="sascha.weinreuter@cit.de">Sascha Weinreuter</vendor>
|
||||
<idea-version since-build="95.4" /><!-- 9.x -->
|
||||
|
||||
<extensions defaultExtensionNs="com.intellij">
|
||||
<errorHandler implementation="org.intellij.plugins.relaxNG.SimpleErrorReportSubmitter" />
|
||||
<gotoSymbolContributor implementation="org.intellij.plugins.relaxNG.GotoSymbolContributor" />
|
||||
<xml.schemaProvider implementation="org.intellij.plugins.relaxNG.config.NoNamespaceSchemaProvider" />
|
||||
<hectorComponentProvider implementation="org.intellij.plugins.relaxNG.config.NoNamespaceConfigImpl$HectorProvider" />
|
||||
|
||||
<fileTypeFactory implementation="org.intellij.plugins.relaxNG.compact.RncFileType$Factory" />
|
||||
<completionData fileType="RNG Compact" className="org.intellij.plugins.relaxNG.compact.RncCompletionData" />
|
||||
<standardResourceProvider implementation="org.intellij.plugins.relaxNG.ApplicationLoader$ResourceProvider" />
|
||||
|
||||
<annotator language="RELAX-NG" implementationClass="org.intellij.plugins.relaxNG.compact.ReferenceAnnotator" />
|
||||
<annotator language="RELAX-NG" implementationClass="org.intellij.plugins.relaxNG.model.annotation.ModelAnnotator" />
|
||||
<externalAnnotator language="RELAX-NG" implementationClass="org.intellij.plugins.relaxNG.validation.RngSchemaValidator" />
|
||||
|
||||
<lang.parserDefinition language="RELAX-NG" implementationClass="org.intellij.plugins.relaxNG.compact.RncParserDefinition" />
|
||||
<lang.braceMatcher language="RELAX-NG" implementationClass="org.intellij.plugins.relaxNG.compact.RngCompactLanguage$MyPairedBraceMatcher" />
|
||||
<lang.commenter language="RELAX-NG" implementationClass="org.intellij.plugins.relaxNG.compact.RngCompactLanguage$MyCommenter" />
|
||||
<lang.foldingBuilder language="RELAX-NG" implementationClass="org.intellij.plugins.relaxNG.compact.folding.RncFoldingBuilder" />
|
||||
<lang.formatter language="RELAX-NG" implementationClass="org.intellij.plugins.relaxNG.compact.formatting.RncFormattingModelBuilder" />
|
||||
<lang.namesValidator language="RELAX-NG" implementationClass="org.intellij.plugins.relaxNG.compact.RngCompactLanguage$MyNamesValidator" />
|
||||
<lang.syntaxHighlighterFactory key="RELAX-NG" implementationClass="org.intellij.plugins.relaxNG.compact.RngCompactLanguage$MySyntaxHighlighterFactory" />
|
||||
|
||||
<lang.elementManipulator forClass="org.intellij.plugins.relaxNG.compact.psi.RncFileReference" implementationClass="org.intellij.plugins.relaxNG.ProjectLoader$RncFileReferenceManipulator" />
|
||||
|
||||
<lang.documentationProvider language="RELAX-NG" implementationClass="org.intellij.plugins.relaxNG.compact.RngCompactLanguage$MyDocumentationProvider" />
|
||||
|
||||
<fileBasedIndex implementation="org.intellij.plugins.relaxNG.model.resolve.RelaxSymbolIndex" />
|
||||
<include.provider implementation="org.intellij.plugins.relaxNG.model.resolve.RelaxIncludeProvider"/>
|
||||
|
||||
<externalAnnotator language="XML" implementationClass="org.intellij.plugins.relaxNG.validation.RngSchemaValidator" />
|
||||
<lang.documentationProvider language="XML" implementationClass="org.intellij.plugins.relaxNG.RngDocumentationProvider" />
|
||||
</extensions>
|
||||
|
||||
<project-components>
|
||||
<component>
|
||||
<implementation-class>org.intellij.plugins.relaxNG.ProjectLoader</implementation-class>
|
||||
</component>
|
||||
<component>
|
||||
<interface-class>org.intellij.plugins.relaxNG.config.NoNamespaceConfig</interface-class>
|
||||
<implementation-class>org.intellij.plugins.relaxNG.config.NoNamespaceConfigImpl</implementation-class>
|
||||
</component>
|
||||
</project-components>
|
||||
|
||||
<application-components>
|
||||
<component>
|
||||
<implementation-class>org.intellij.plugins.relaxNG.ApplicationLoader</implementation-class>
|
||||
</component>
|
||||
</application-components>
|
||||
|
||||
<actions>
|
||||
<action id="ConvertSchemaAction" class="org.intellij.plugins.relaxNG.convert.ConvertSchemaAction"
|
||||
text="Convert Schema..."
|
||||
description="Converts the selected Schema document (RNG, RNC, XSD, DTD) into another format">
|
||||
<add-to-group group-id="ToolsXmlGroup" anchor="after" relative-to-action="GenerateDTD" />
|
||||
</action>
|
||||
</actions>
|
||||
</idea-plugin>
|
||||
@@ -0,0 +1,25 @@
|
||||
<html>
|
||||
<head>
|
||||
<style type="text/css">
|
||||
body, table {
|
||||
font-family: Verdana, sans-serif;
|
||||
font-size: 100%;
|
||||
padding-left: 2mm;
|
||||
}
|
||||
|
||||
#footer {
|
||||
font-size: 95%;
|
||||
padding-top: 10px;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<p>
|
||||
This inspections checks for any unresolved references to named patterns ("define") in a RELAX-NG file in XML Syntax.
|
||||
For unresolved references, a QuickFix is offered to create a corresponding define-element.
|
||||
</p>
|
||||
|
||||
<p id="footer">Powered by RELAX-NG Support</p>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,26 @@
|
||||
<html>
|
||||
<head>
|
||||
<style type="text/css">
|
||||
body, table {
|
||||
font-family: Verdana, sans-serif;
|
||||
font-size: 100%;
|
||||
padding-left: 2mm;
|
||||
}
|
||||
|
||||
#footer {
|
||||
font-size: 95%;
|
||||
padding-top: 10px;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<p>
|
||||
This inspections checks for any unused named patterns ("define") in a RELAX-NG file (XML or Compact Syntax) and
|
||||
highlights them as unused symbols. This is done with respect to includes from other files, i.e. a define is not
|
||||
marked as unused if is is used through an include in another file.
|
||||
</p>
|
||||
|
||||
<p id="footer">Powered by RELAX-NG Support</p>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,124 @@
|
||||
/*
|
||||
* Copyright 2007 Sascha Weinreuter
|
||||
*
|
||||
* 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 org.intellij.plugins.relaxNG;
|
||||
|
||||
import org.intellij.plugins.relaxNG.compact.psi.impl.RncDocument;
|
||||
import org.intellij.plugins.relaxNG.inspections.RngDomInspection;
|
||||
import org.intellij.plugins.relaxNG.inspections.UnusedDefineInspection;
|
||||
import org.intellij.plugins.relaxNG.model.descriptors.RngNsDescriptor;
|
||||
import org.intellij.plugins.relaxNG.validation.ValidateAction;
|
||||
import org.intellij.plugins.relaxNG.xml.dom.RngDefine;
|
||||
import org.intellij.plugins.relaxNG.xml.dom.impl.RngDefineMetaData;
|
||||
|
||||
import com.intellij.codeInspection.InspectionToolProvider;
|
||||
import com.intellij.javaee.ResourceRegistrar;
|
||||
import com.intellij.javaee.StandardResourceProvider;
|
||||
import com.intellij.openapi.actionSystem.ActionManager;
|
||||
import com.intellij.openapi.actionSystem.AnAction;
|
||||
import com.intellij.openapi.components.ApplicationComponent;
|
||||
import com.intellij.openapi.fileTypes.FileTypeManager;
|
||||
import com.intellij.openapi.fileTypes.StdFileTypes;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.filters.AndFilter;
|
||||
import com.intellij.psi.filters.ClassFilter;
|
||||
import com.intellij.psi.filters.ElementFilter;
|
||||
import com.intellij.psi.filters.position.NamespaceFilter;
|
||||
import com.intellij.psi.meta.MetaDataRegistrar;
|
||||
import com.intellij.psi.xml.XmlDocument;
|
||||
import com.intellij.psi.xml.XmlTag;
|
||||
import com.intellij.util.xml.DomElement;
|
||||
import com.intellij.util.xml.DomManager;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
* Created by IntelliJ IDEA.
|
||||
* User: sweinreuter
|
||||
* Date: 18.07.2007
|
||||
*/
|
||||
public class ApplicationLoader implements ApplicationComponent, InspectionToolProvider {
|
||||
private static final String RNG_EXT = "rng";
|
||||
private static final String VALIDATE_XML = "ValidateXml";
|
||||
|
||||
@NonNls
|
||||
@NotNull
|
||||
public String getComponentName() {
|
||||
return "Relax-NG";
|
||||
}
|
||||
|
||||
public void initComponent() {
|
||||
registerMetaData();
|
||||
|
||||
final FileTypeManager ftm = FileTypeManager.getInstance();
|
||||
ftm.registerFileType(StdFileTypes.XML, RNG_EXT);
|
||||
|
||||
installValidateXmlAction();
|
||||
}
|
||||
|
||||
private static void installValidateXmlAction() {
|
||||
final ActionManager mgr = ActionManager.getInstance();
|
||||
final AnAction validateAction = mgr.getAction(VALIDATE_XML);
|
||||
mgr.unregisterAction(VALIDATE_XML);
|
||||
mgr.registerAction(VALIDATE_XML, new ValidateAction(validateAction));
|
||||
}
|
||||
|
||||
private static void registerMetaData() {
|
||||
final MetaDataRegistrar registrar = MetaDataRegistrar.getInstance();
|
||||
registrar.registerMetaData(
|
||||
new AndFilter(
|
||||
new NamespaceFilter(ProjectLoader.RNG_NAMESPACE),
|
||||
new ClassFilter(XmlDocument.class)
|
||||
),
|
||||
RngNsDescriptor.class);
|
||||
|
||||
registrar.registerMetaData(
|
||||
new ClassFilter(RncDocument.class),
|
||||
RngNsDescriptor.class);
|
||||
|
||||
registrar.registerMetaData(new ElementFilter() {
|
||||
public boolean isAcceptable(Object element, PsiElement context) {
|
||||
if (element instanceof XmlTag) {
|
||||
final XmlTag tag = (XmlTag)element;
|
||||
final DomElement domElement = DomManager.getDomManager(tag.getProject()).getDomElement(tag);
|
||||
return domElement instanceof RngDefine;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean isClassAcceptable(Class hintClass) {
|
||||
return XmlTag.class.isAssignableFrom(hintClass);
|
||||
}
|
||||
}, RngDefineMetaData.class);
|
||||
}
|
||||
|
||||
public void disposeComponent() {
|
||||
}
|
||||
|
||||
public Class[] getInspectionClasses() {
|
||||
return new Class[]{
|
||||
RngDomInspection.class,
|
||||
UnusedDefineInspection.class
|
||||
};
|
||||
}
|
||||
|
||||
public class ResourceProvider implements StandardResourceProvider {
|
||||
public void registerResources(ResourceRegistrar registrar) {
|
||||
registrar.addStdResource(ProjectLoader.RNG_NAMESPACE, "resources/relaxng.rng", getClass());
|
||||
registrar.addIgnoredResource("http://relaxng.org/ns/compatibility/annotations/1.0");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
/*
|
||||
* Copyright 2007 Sascha Weinreuter
|
||||
*
|
||||
* 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 org.intellij.plugins.relaxNG;
|
||||
|
||||
import org.intellij.plugins.relaxNG.model.resolve.RelaxSymbolIndex;
|
||||
|
||||
import com.intellij.navigation.ChooseByNameContributor;
|
||||
import com.intellij.navigation.NavigationItem;
|
||||
import com.intellij.openapi.project.Project;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
/*
|
||||
* Created by IntelliJ IDEA.
|
||||
* User: sweinreuter
|
||||
* Date: 24.10.2007
|
||||
*/
|
||||
public class GotoSymbolContributor implements ChooseByNameContributor {
|
||||
|
||||
public NavigationItem[] getItemsByName(String name, String pattern, Project project, boolean includeNonProjectItems) {
|
||||
return RelaxSymbolIndex.getSymbolsByName(name, project, includeNonProjectItems);
|
||||
}
|
||||
|
||||
public String[] getNames(Project project, boolean includeNonProjectItems) {
|
||||
final Collection<String> names = RelaxSymbolIndex.getSymbolNames(project);
|
||||
return names.toArray(new String[names.size()]);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,152 @@
|
||||
/*
|
||||
* Copyright 2007 Sascha Weinreuter
|
||||
*
|
||||
* 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 org.intellij.plugins.relaxNG;
|
||||
|
||||
import com.intellij.lang.ASTNode;
|
||||
import com.intellij.openapi.components.ProjectComponent;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.TextRange;
|
||||
import com.intellij.patterns.StringPattern;
|
||||
import com.intellij.patterns.XmlNamedElementPattern;
|
||||
import com.intellij.psi.AbstractElementManipulator;
|
||||
import com.intellij.psi.PsiManager;
|
||||
import com.intellij.psi.filters.position.PatternFilter;
|
||||
import com.intellij.psi.impl.source.resolve.reference.ReferenceProvidersRegistry;
|
||||
import com.intellij.util.IncorrectOperationException;
|
||||
import com.intellij.util.xml.DomFileDescription;
|
||||
import com.intellij.util.xml.DomManager;
|
||||
import com.intellij.util.xml.highlighting.DomElementsAnnotator;
|
||||
import com.intellij.xml.util.XmlUtil;
|
||||
import org.intellij.plugins.relaxNG.compact.RncTokenTypes;
|
||||
import org.intellij.plugins.relaxNG.compact.psi.RncFileReference;
|
||||
import org.intellij.plugins.relaxNG.compact.psi.util.RenameUtil;
|
||||
import org.intellij.plugins.relaxNG.model.annotation.ModelAnnotator;
|
||||
import org.intellij.plugins.relaxNG.references.PrefixReferenceProvider;
|
||||
import org.intellij.plugins.relaxNG.xml.dom.*;
|
||||
import org.intellij.plugins.relaxNG.xml.dom.impl.RngDefineImpl;
|
||||
import org.intellij.plugins.relaxNG.xml.dom.impl.RngGrammarImpl;
|
||||
import org.intellij.plugins.relaxNG.xml.dom.impl.RngIncludeImpl;
|
||||
import org.intellij.plugins.relaxNG.xml.dom.impl.RngRefImpl;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import static com.intellij.patterns.StandardPatterns.string;
|
||||
import static com.intellij.patterns.XmlPatterns.*;
|
||||
|
||||
/**
|
||||
* Created by IntelliJ IDEA.
|
||||
* User: sweinreuter
|
||||
* Date: 16.07.2007
|
||||
*/
|
||||
public class ProjectLoader implements ProjectComponent {
|
||||
public static final String RNG_NAMESPACE = "http://relaxng.org/ns/structure/1.0";
|
||||
|
||||
private static final XmlNamedElementPattern RNG_TAG_PATTERN = xmlTag().withNamespace(string().equalTo(RNG_NAMESPACE));
|
||||
|
||||
private static final XmlNamedElementPattern.XmlAttributePattern NAME_ATTR_PATTERN = xmlAttribute("name");
|
||||
private static final StringPattern ELEMENT_OR_ATTRIBUTE_PATTERN = string().oneOf("element", "attribute");
|
||||
private static final XmlNamedElementPattern.XmlAttributePattern NAME_PATTERN = NAME_ATTR_PATTERN.withParent(
|
||||
RNG_TAG_PATTERN.withLocalName(ELEMENT_OR_ATTRIBUTE_PATTERN));
|
||||
|
||||
private final Project myProject;
|
||||
|
||||
public ProjectLoader(Project project) {
|
||||
myProject = project;
|
||||
}
|
||||
|
||||
@NonNls
|
||||
@NotNull
|
||||
public String getComponentName() {
|
||||
return "RELAX-NG";
|
||||
}
|
||||
|
||||
public void initComponent() {
|
||||
registerFileDescriptions();
|
||||
|
||||
registerReferences();
|
||||
}
|
||||
|
||||
private void registerReferences() {
|
||||
final ReferenceProvidersRegistry registry = ReferenceProvidersRegistry.getInstance(myProject);
|
||||
XmlUtil.registerXmlAttributeValueReferenceProvider(registry, new String[]{
|
||||
"name"
|
||||
}, new PatternFilter(xmlAttributeValue().withParent(NAME_PATTERN)), true, new PrefixReferenceProvider());
|
||||
|
||||
// final XmlAttributeValuePattern id = xmlAttributeValue().withParent(xmlAttribute()).with(IdRefProvider.HAS_ID_REF_TYPE);
|
||||
// final XmlAttributeValuePattern idref = xmlAttributeValue().withParent(xmlAttribute()).with(IdRefProvider.HAS_ID_TYPE);
|
||||
// registry.registerXmlAttributeValueReferenceProvider(null, new PatternFilter(or(id, idref)), false, new IdRefProvider());
|
||||
}
|
||||
|
||||
@SuppressWarnings({ "deprecation" })
|
||||
private void registerFileDescriptions() {
|
||||
final DomManager mgr = DomManager.getDomManager(myProject);
|
||||
mgr.registerFileDescription(new MyFileDescription<RngGrammar>(RngGrammar.class, "grammar"));
|
||||
mgr.registerFileDescription(new MyFileDescription<RngElement>(RngElement.class, "element"));
|
||||
mgr.registerFileDescription(new MyFileDescription<RngChoice>(RngChoice.class, "choice"));
|
||||
mgr.registerFileDescription(new MyFileDescription<RngGroup>(RngGroup.class, "group"));
|
||||
mgr.registerFileDescription(new MyFileDescription<RngInterleave>(RngInterleave.class, "interleave"));
|
||||
}
|
||||
|
||||
public void disposeComponent() {
|
||||
}
|
||||
|
||||
public void projectOpened() {
|
||||
}
|
||||
|
||||
public void projectClosed() {
|
||||
}
|
||||
|
||||
private static class MyFileDescription<T> extends DomFileDescription<T> {
|
||||
public MyFileDescription(Class<T> elementClass, String rootTagName) {
|
||||
super(elementClass, rootTagName);
|
||||
registerNamespacePolicy("RELAX-NG", RNG_NAMESPACE);
|
||||
registerImplementation(RngDefine.class, RngDefineImpl.class);
|
||||
registerImplementation(RngGrammar.class, RngGrammarImpl.class);
|
||||
registerImplementation(RngInclude.class, RngIncludeImpl.class);
|
||||
registerImplementation(RngRef.class, RngRefImpl.class);
|
||||
}
|
||||
|
||||
public boolean isAutomaticHighlightingEnabled() {
|
||||
return true;
|
||||
}
|
||||
|
||||
public DomElementsAnnotator createAnnotator() {
|
||||
return new ModelAnnotator();
|
||||
}
|
||||
}
|
||||
|
||||
public static class RncFileReferenceManipulator extends AbstractElementManipulator<RncFileReference> {
|
||||
public RncFileReference handleContentChange(RncFileReference element, TextRange range, String newContent) throws IncorrectOperationException {
|
||||
final ASTNode node = element.getNode();
|
||||
assert node != null;
|
||||
|
||||
final ASTNode literal = node.findChildByType(RncTokenTypes.LITERAL);
|
||||
if (literal != null) {
|
||||
assert range.equals(element.getReferenceRange());
|
||||
final PsiManager manager = PsiManager.getInstance(element.getProject());
|
||||
final ASTNode newChild = RenameUtil.createLiteralNode(manager, newContent);
|
||||
literal.getTreeParent().replaceChild(literal, newChild);
|
||||
}
|
||||
return element;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TextRange getRangeInElement(RncFileReference element) {
|
||||
return element.getReferenceRange();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,148 @@
|
||||
/*
|
||||
* Copyright 2007 Sascha Weinreuter
|
||||
*
|
||||
* 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 org.intellij.plugins.relaxNG;
|
||||
|
||||
import org.intellij.plugins.relaxNG.model.descriptors.CompositeDescriptor;
|
||||
import org.intellij.plugins.relaxNG.model.descriptors.RngElementDescriptor;
|
||||
import org.intellij.plugins.relaxNG.model.descriptors.RngXmlAttributeDescriptor;
|
||||
|
||||
import com.intellij.lang.documentation.DocumentationProvider;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.PsiManager;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import com.intellij.psi.xml.XmlAttribute;
|
||||
import com.intellij.psi.xml.XmlElement;
|
||||
import com.intellij.psi.xml.XmlTag;
|
||||
import com.intellij.xml.XmlAttributeDescriptor;
|
||||
import com.intellij.xml.XmlElementDescriptor;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import org.kohsuke.rngom.digested.DElementPattern;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
/*
|
||||
* Created by IntelliJ IDEA.
|
||||
* User: sweinreuter
|
||||
* Date: 19.11.2007
|
||||
*/
|
||||
public class RngDocumentationProvider implements DocumentationProvider {
|
||||
@NonNls
|
||||
private static final String COMPATIBILITY_ANNOTATIONS_1_0 = "http://relaxng.org/ns/compatibility/annotations/1.0";
|
||||
|
||||
@Nullable
|
||||
public String generateDoc(PsiElement element, PsiElement originalElement) {
|
||||
final XmlElement c = PsiTreeUtil.getParentOfType(originalElement, XmlTag.class, XmlAttribute.class);
|
||||
if (c instanceof XmlTag) {
|
||||
final XmlTag xmlElement = (XmlTag)c;
|
||||
final XmlElementDescriptor descriptor = xmlElement.getDescriptor();
|
||||
if (descriptor instanceof CompositeDescriptor) {
|
||||
final StringBuilder sb = new StringBuilder();
|
||||
final CompositeDescriptor d = (CompositeDescriptor)descriptor;
|
||||
final DElementPattern[] patterns = d.getElementPatterns();
|
||||
for (DElementPattern pattern : patterns) {
|
||||
final PsiElement psiElement = d.getDeclaration(pattern.getLocation());
|
||||
if (psiElement instanceof XmlTag) {
|
||||
if (sb.length() > 0) {
|
||||
sb.append("<hr>");
|
||||
}
|
||||
sb.append(getDocumentationFromTag((XmlTag)psiElement, xmlElement.getLocalName(), "Element"));
|
||||
}
|
||||
}
|
||||
return makeDocumentation(sb);
|
||||
} else if (descriptor instanceof RngElementDescriptor) {
|
||||
final RngElementDescriptor d = (RngElementDescriptor)descriptor;
|
||||
final PsiElement declaration = d.getDeclaration();
|
||||
if (declaration instanceof XmlTag) {
|
||||
return makeDocumentation(getDocumentationFromTag((XmlTag)declaration, xmlElement.getLocalName(), "Element"));
|
||||
}
|
||||
}
|
||||
} else if (c instanceof XmlAttribute) {
|
||||
final XmlAttribute attribute = (XmlAttribute)c;
|
||||
final XmlAttributeDescriptor descriptor = attribute.getDescriptor();
|
||||
if (descriptor instanceof RngXmlAttributeDescriptor) {
|
||||
final RngXmlAttributeDescriptor d = (RngXmlAttributeDescriptor)descriptor;
|
||||
final StringBuilder sb = new StringBuilder();
|
||||
final Collection<PsiElement> declaration = d.getDeclarations();
|
||||
for (PsiElement psiElement : declaration) {
|
||||
if (psiElement instanceof XmlTag) {
|
||||
if (sb.length() > 0) {
|
||||
sb.append("<hr>");
|
||||
}
|
||||
sb.append(getDocumentationFromTag((XmlTag)element, d.getName(), "Attribute"));
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (element instanceof XmlTag) {
|
||||
return makeDocumentation(getDocumentationFromTag((XmlTag)element, ((XmlTag)element).getLocalName(), "Element"));
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private static String makeDocumentation(StringBuilder sb) {
|
||||
if (!sb.toString().startsWith("<html>")) {
|
||||
sb.insert(0, "<html>");
|
||||
sb.append("</html>");
|
||||
}
|
||||
return sb.toString().replaceAll("\n", "<br>");
|
||||
}
|
||||
|
||||
private static StringBuilder getDocumentationFromTag(XmlTag tag, String localName, String kind) {
|
||||
if (tag.getNamespace().equals(ProjectLoader.RNG_NAMESPACE)) {
|
||||
final StringBuilder sb = new StringBuilder();
|
||||
sb.append(kind).append(": <b>").append(localName).append("</b><br>");
|
||||
final XmlTag[] docTags = tag.findSubTags("documentation", COMPATIBILITY_ANNOTATIONS_1_0);
|
||||
for (XmlTag docTag : docTags) {
|
||||
sb.append(docTag.getValue().getTrimmedText());
|
||||
sb.append("\n");
|
||||
}
|
||||
final XmlTag nextTag = PsiTreeUtil.getNextSiblingOfType(tag, XmlTag.class);
|
||||
if (nextTag != null) {
|
||||
if ("documentation".equals(nextTag.getLocalName()) && COMPATIBILITY_ANNOTATIONS_1_0.equals(nextTag.getNamespace())) {
|
||||
sb.append(nextTag.getValue().getTrimmedText());
|
||||
}
|
||||
}
|
||||
return sb;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public PsiElement getDocumentationElementForLink(PsiManager psiManager, String link, PsiElement context) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public PsiElement getDocumentationElementForLookupItem(PsiManager psiManager, Object object, PsiElement element) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public String getQuickNavigateInfo(PsiElement element) {
|
||||
return null;
|
||||
}
|
||||
|
||||
public List<String> getUrlFor(PsiElement element, PsiElement originalElement) {
|
||||
return null;
|
||||
}
|
||||
|
||||
public int hashCode() {
|
||||
return 0; // CompositeDocumentationProvider uses a HashSet that doesn't preserve order. We want to be the first one.
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,135 @@
|
||||
/*
|
||||
* Copyright 2006 Sascha Weinreuter
|
||||
*
|
||||
* 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 org.intellij.plugins.relaxNG;
|
||||
|
||||
import com.intellij.ide.BrowserUtil;
|
||||
import com.intellij.ide.plugins.IdeaPluginDescriptor;
|
||||
import com.intellij.ide.plugins.PluginManager;
|
||||
import com.intellij.openapi.diagnostic.ErrorReportSubmitter;
|
||||
import com.intellij.openapi.diagnostic.IdeaLoggingEvent;
|
||||
import com.intellij.openapi.diagnostic.SubmittedReportInfo;
|
||||
import com.intellij.openapi.ui.DialogWrapper;
|
||||
import com.intellij.openapi.ui.Messages;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import javax.swing.*;
|
||||
import javax.swing.event.HyperlinkEvent;
|
||||
import javax.swing.event.HyperlinkListener;
|
||||
import java.awt.*;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.net.URLEncoder;
|
||||
|
||||
public class SimpleErrorReportSubmitter extends ErrorReportSubmitter {
|
||||
public String getReportActionText() {
|
||||
return "Error Report Information";
|
||||
}
|
||||
|
||||
public SubmittedReportInfo submit(IdeaLoggingEvent[] events, Component parentComponent) {
|
||||
final IdeaPluginDescriptor plugin = PluginManager.getPlugin(getPluginDescriptor().getPluginId());
|
||||
|
||||
assert plugin != null;
|
||||
final String title = plugin.getName() + " - " + plugin.getVersion();
|
||||
|
||||
final String vendorEmail = plugin.getVendorEmail();
|
||||
final String subject = title + " Exception";
|
||||
final String mailto = "mailto:" + encode(vendorEmail) + "?Subject=" + encode(subject) /*+
|
||||
"&body=" + encode("Stacktrace:\n" + events[0].getThrowableText())*/;
|
||||
|
||||
final String weblink = "http://www.intellij.net/forums/forum.jsp?forum=18";
|
||||
final String website = plugin.getUrl();
|
||||
|
||||
final String font = new JLabel().getFont().getName();
|
||||
|
||||
String message = "<html><span style='font: " + font + "; font-size:smaller'>" +
|
||||
"To report an exception, please post the exception stacktrace and a short description " +
|
||||
"of how it can be reproduced to the IntelliJ " +
|
||||
"<a href='" + weblink + "'>plugin web forum</a> or the corresponding newsgroup, " +
|
||||
"and/or send an email containing that information to " +
|
||||
"<a href='" + mailto + "'>" + vendorEmail + "</a>." +
|
||||
(website != null ? "<br><br>Please also check the plugin's <a href='" + website + "'>website</a> for more information." : "") +
|
||||
"</span></html>";
|
||||
|
||||
final JEditorPane pane = new JEditorPane("text/html", message);
|
||||
pane.setEditable(false);
|
||||
pane.setPreferredSize(new Dimension(410, website != null ? 110 : 80));
|
||||
pane.addHyperlinkListener(new HyperlinkListener() {
|
||||
public void hyperlinkUpdate(HyperlinkEvent e) {
|
||||
if (e.getEventType() == HyperlinkEvent.EventType.ACTIVATED) {
|
||||
BrowserUtil.launchBrowser(e.getURL().toExternalForm());
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
new MyMessageDialog(parentComponent, title, Messages.getErrorIcon(), pane).show();
|
||||
|
||||
return new SubmittedReportInfo(null, null, SubmittedReportInfo.SubmissionStatus.FAILED);
|
||||
}
|
||||
|
||||
private String encode(String link) {
|
||||
final String enc = System.getProperty("file.encoding");
|
||||
try {
|
||||
return URLEncoder.encode(link, enc).replaceAll("\\+", "%20");
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
throw new Error(e);
|
||||
}
|
||||
}
|
||||
|
||||
private static class MyMessageDialog extends DialogWrapper {
|
||||
protected JComponent myMessage;
|
||||
protected Icon myIcon;
|
||||
|
||||
public MyMessageDialog(Component parent, String title, Icon icon, JComponent message) {
|
||||
super(parent, false);
|
||||
_init(title, message, icon);
|
||||
}
|
||||
|
||||
private void _init(String title, JComponent message, Icon icon) {
|
||||
setTitle(title);
|
||||
myMessage = message;
|
||||
myIcon = icon;
|
||||
setButtonsAlignment(SwingUtilities.CENTER);
|
||||
init();
|
||||
|
||||
myMessage.setBackground(getContentPane().getBackground());
|
||||
}
|
||||
|
||||
protected Action[] createActions() {
|
||||
return new Action[]{ getOKAction() };
|
||||
}
|
||||
|
||||
protected JComponent createNorthPanel() {
|
||||
JPanel panel = new JPanel(new BorderLayout(15, 0));
|
||||
if (myIcon != null) {
|
||||
JLabel iconLabel = new JLabel(myIcon);
|
||||
Container container = new Container();
|
||||
container.setLayout(new BorderLayout());
|
||||
container.add(iconLabel, BorderLayout.NORTH);
|
||||
panel.add(container, BorderLayout.WEST);
|
||||
}
|
||||
|
||||
if (myMessage != null) {
|
||||
panel.add(myMessage, BorderLayout.CENTER);
|
||||
}
|
||||
return panel;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
protected JComponent createCenterPanel() {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,126 @@
|
||||
/*
|
||||
* Copyright 2007 Sascha Weinreuter
|
||||
*
|
||||
* 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 org.intellij.plugins.relaxNG.compact;
|
||||
|
||||
import org.intellij.plugins.relaxNG.compact.psi.*;
|
||||
|
||||
import com.intellij.codeInsight.daemon.EmptyResolveMessageProvider;
|
||||
import com.intellij.codeInsight.daemon.QuickFixProvider;
|
||||
import com.intellij.codeInsight.daemon.impl.HighlightInfo;
|
||||
import com.intellij.codeInsight.daemon.impl.HighlightInfoType;
|
||||
import com.intellij.codeInspection.ProblemHighlightType;
|
||||
import com.intellij.lang.annotation.Annotation;
|
||||
import com.intellij.lang.annotation.AnnotationHolder;
|
||||
import com.intellij.lang.annotation.Annotator;
|
||||
import com.intellij.openapi.util.Pair;
|
||||
import com.intellij.openapi.util.TextRange;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.PsiPolyVariantReference;
|
||||
import com.intellij.psi.PsiReference;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.text.MessageFormat;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Created by IntelliJ IDEA.
|
||||
* User: sweinreuter
|
||||
* Date: 10.08.2007
|
||||
*/
|
||||
public class ReferenceAnnotator extends RncElementVisitor implements Annotator {
|
||||
private AnnotationHolder myHolder;
|
||||
|
||||
public synchronized void annotate(@NotNull PsiElement psiElement, @NotNull AnnotationHolder holder) {
|
||||
myHolder = holder;
|
||||
try {
|
||||
psiElement.accept(this);
|
||||
} finally {
|
||||
myHolder = null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitInclude(RncInclude include) {
|
||||
checkReferences(include.getReferences());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitExternalRef(RncExternalRef ref) {
|
||||
checkReferences(ref.getReferences());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitRef(RncRef pattern) {
|
||||
checkReferences(pattern.getReferences());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitParentRef(RncParentRef pattern) {
|
||||
checkReferences(pattern.getReferences());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitName(RncName name) {
|
||||
checkReferences(name.getReferences());
|
||||
}
|
||||
|
||||
private void checkReferences(PsiReference[] references) {
|
||||
for (PsiReference reference : references) {
|
||||
if (!reference.isSoft()) {
|
||||
if (reference.resolve() == null) {
|
||||
if (reference instanceof PsiPolyVariantReference) {
|
||||
final PsiPolyVariantReference pvr = (PsiPolyVariantReference)reference;
|
||||
if (pvr.multiResolve(false).length == 0) {
|
||||
addError(reference);
|
||||
}
|
||||
} else {
|
||||
addError(reference);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void addError(PsiReference reference) {
|
||||
final TextRange rangeInElement = reference.getRangeInElement();
|
||||
final TextRange range = TextRange.from(reference.getElement().getTextRange().getStartOffset()
|
||||
+ rangeInElement.getStartOffset(), rangeInElement.getLength());
|
||||
|
||||
final Annotation annotation;
|
||||
if (reference instanceof EmptyResolveMessageProvider) {
|
||||
final String s = ((EmptyResolveMessageProvider)reference).getUnresolvedMessagePattern();
|
||||
annotation = myHolder.createErrorAnnotation(range, s != null ?
|
||||
MessageFormat.format(s, reference.getCanonicalText())
|
||||
: "Cannot resolve symbol");
|
||||
} else {
|
||||
annotation = myHolder.createErrorAnnotation(range, "Cannot resolve symbol");
|
||||
}
|
||||
annotation.setHighlightType(ProblemHighlightType.LIKE_UNKNOWN_SYMBOL);
|
||||
|
||||
if (reference instanceof QuickFixProvider) {
|
||||
final HighlightInfo info = new HighlightInfo(HighlightInfoType.WRONG_REF, annotation.getStartOffset(), annotation.getEndOffset(), "", null);
|
||||
((QuickFixProvider)reference).registerQuickfix(info, reference);
|
||||
|
||||
final List<Pair<HighlightInfo.IntentionActionDescriptor,TextRange>> ranges = info.quickFixActionRanges;
|
||||
if (ranges != null) {
|
||||
for (Pair<HighlightInfo.IntentionActionDescriptor, TextRange> pair : ranges) {
|
||||
annotation.registerFix(pair.first.getAction(), pair.second);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,137 @@
|
||||
/*
|
||||
* Copyright 2007 Sascha Weinreuter
|
||||
*
|
||||
* 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 org.intellij.plugins.relaxNG.compact;
|
||||
|
||||
import com.intellij.codeInsight.TailType;
|
||||
import com.intellij.codeInsight.completion.CompletionContext;
|
||||
import com.intellij.codeInsight.completion.CompletionData;
|
||||
import com.intellij.codeInsight.completion.CompletionVariant;
|
||||
import com.intellij.codeInsight.lookup.LookupElement;
|
||||
import com.intellij.codeInsight.lookup.LookupElementFactory;
|
||||
import com.intellij.patterns.ElementPattern;
|
||||
import com.intellij.patterns.PsiElementPattern;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.PsiWhiteSpace;
|
||||
import com.intellij.psi.filters.AndFilter;
|
||||
import com.intellij.psi.filters.ContextGetter;
|
||||
import com.intellij.psi.filters.ElementFilter;
|
||||
import com.intellij.psi.filters.position.PatternFilter;
|
||||
import com.intellij.psi.impl.source.tree.LeafPsiElement;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import com.intellij.util.ArrayUtil;
|
||||
import com.intellij.util.Function;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import org.intellij.plugins.relaxNG.compact.psi.RncDecl;
|
||||
import org.intellij.plugins.relaxNG.compact.psi.RncDefine;
|
||||
import org.intellij.plugins.relaxNG.compact.psi.RncElement;
|
||||
import org.intellij.plugins.relaxNG.compact.psi.RncGrammar;
|
||||
import org.intellij.plugins.relaxNG.compact.psi.util.EscapeUtil;
|
||||
|
||||
import static com.intellij.patterns.PlatformPatterns.psiElement;
|
||||
import static com.intellij.patterns.StandardPatterns.*;
|
||||
|
||||
public class RncCompletionData extends CompletionData {
|
||||
|
||||
public RncCompletionData() {
|
||||
declareFinalScope(RncElement.class);
|
||||
|
||||
final CompletionVariant variant = new CompletionVariant(new AndFilter(
|
||||
new ElementFilter() {
|
||||
public boolean isAcceptable(Object element, PsiElement context) {
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean isClassAcceptable(Class hintClass) {
|
||||
return PsiElement.class.isAssignableFrom(hintClass);
|
||||
}
|
||||
},
|
||||
new PatternFilter(or(
|
||||
psiElement().afterLeaf(psiElement(RncTokenTypes.KEYWORD_DEFAULT)),
|
||||
not(
|
||||
or(
|
||||
psiElement().inside(psiElement(RncTokenTypes.LITERAL)),
|
||||
psiElement().afterLeaf(psiElement().withElementType(RncTokenTypes.KEYWORDS))
|
||||
)
|
||||
)
|
||||
))
|
||||
));
|
||||
|
||||
variant.includeScopeClass(LeafPsiElement.class, true);
|
||||
|
||||
variant.addCompletion(new KeywordGetter());
|
||||
|
||||
registerVariant(variant);
|
||||
}
|
||||
|
||||
private static class KeywordGetter implements ContextGetter {
|
||||
private static final ElementPattern TOP_LEVEL =
|
||||
not(psiElement().inside(psiElement(RncGrammar.class)
|
||||
.inside(true, psiElement(RncGrammar.class))));
|
||||
|
||||
private static final PsiElementPattern DECL_PATTERN =
|
||||
psiElement().inside(psiElement(RncDecl.class));
|
||||
|
||||
private static final PsiElementPattern DEFAULT_PATTERN =
|
||||
DECL_PATTERN.afterLeaf(psiElement().withText("default"));
|
||||
|
||||
private static final ElementPattern DEFINE_PATTERN =
|
||||
and(psiElement().withParent(RncDefine.class), psiElement().afterLeafSkipping(psiElement(PsiWhiteSpace.class), psiElement().withText("=")));
|
||||
|
||||
private static final String[] DECL_KEYWORDS = new String[]{ "default", "namespace", "datatypes" };
|
||||
private static final String[] GRAMMAR_CONTENT_KEYWORDS = new String[]{ "include", "div", "start" };
|
||||
private static final String[] PATTERN_KEYWORDS = new String[]{ "attribute", "element", "grammar",
|
||||
"notAllowed", "text", "empty", "external", "parent", "list", "mixed" };
|
||||
|
||||
public Object[] get(PsiElement context, CompletionContext completionContext) {
|
||||
return ContainerUtil.map2Array(doGetKeywords(context), LookupElement.class, new Function<String, LookupElement>() {
|
||||
public LookupElement fun(String s) {
|
||||
return LookupElementFactory.getInstance().createLookupElement(s).setTailType(TailType.SPACE).setBold();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private String[] doGetKeywords(PsiElement context) {
|
||||
final PsiElement next = PsiTreeUtil.skipSiblingsForward(context, PsiWhiteSpace.class);
|
||||
if (next != null && EscapeUtil.unescapeText(next).equals("=")) {
|
||||
return new String[]{ "start" };
|
||||
}
|
||||
|
||||
if (DEFAULT_PATTERN.accepts(context)) {
|
||||
return new String[]{ "namespace" };
|
||||
} else if (DECL_PATTERN.accepts(context)) {
|
||||
return ArrayUtil.EMPTY_STRING_ARRAY;
|
||||
} else if (context.getParent() instanceof RncDefine && context.getParent().getFirstChild() == context) {
|
||||
if (DEFINE_PATTERN.accepts(context)) {
|
||||
return ArrayUtil.EMPTY_STRING_ARRAY;
|
||||
}
|
||||
if (TOP_LEVEL.accepts(context)) {
|
||||
if (!afterPattern(context)) {
|
||||
return ArrayUtil.mergeArrays(DECL_KEYWORDS,
|
||||
ArrayUtil.mergeArrays(GRAMMAR_CONTENT_KEYWORDS, PATTERN_KEYWORDS, String.class), String.class);
|
||||
}
|
||||
}
|
||||
return GRAMMAR_CONTENT_KEYWORDS;
|
||||
}
|
||||
return PATTERN_KEYWORDS;
|
||||
}
|
||||
|
||||
private boolean afterPattern(PsiElement context) {
|
||||
// TODO: recognize all patterns
|
||||
return PsiTreeUtil.getPrevSiblingOfType(context.getParent(), RncDefine.class) != null;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
/*
|
||||
* Copyright 2007 Sascha Weinreuter
|
||||
*
|
||||
* 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 org.intellij.plugins.relaxNG.compact;
|
||||
|
||||
import org.intellij.plugins.relaxNG.compact.psi.RncElement;
|
||||
|
||||
import com.intellij.lang.ASTNode;
|
||||
import com.intellij.psi.tree.IElementType;
|
||||
import com.intellij.util.NotNullFunction;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.lang.reflect.Modifier;
|
||||
|
||||
public class RncElementType extends IElementType {
|
||||
public RncElementType(String name) {
|
||||
super(name, RngCompactLanguage.INSTANCE);
|
||||
}
|
||||
}
|
||||
|
||||
class RncElementTypeEx<C extends RncElement> extends RncElementType implements NotNullFunction<ASTNode, C> {
|
||||
private final Constructor<? extends C> myConstructor;
|
||||
|
||||
RncElementTypeEx(String name, Class<? extends C> clazz) {
|
||||
super(name);
|
||||
assert !clazz.isInterface() && !Modifier.isAbstract(clazz.getModifiers());
|
||||
try {
|
||||
myConstructor = clazz.getConstructor(ASTNode.class);
|
||||
} catch (NoSuchMethodException e) {
|
||||
throw new Error(e);
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public final C fun(ASTNode node) {
|
||||
try {
|
||||
return myConstructor.newInstance(node);
|
||||
} catch (Exception e) {
|
||||
throw new Error(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,74 @@
|
||||
/*
|
||||
* Copyright 2007 Sascha Weinreuter
|
||||
*
|
||||
* 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 org.intellij.plugins.relaxNG.compact;
|
||||
|
||||
import org.intellij.plugins.relaxNG.compact.psi.*;
|
||||
import org.intellij.plugins.relaxNG.compact.psi.impl.*;
|
||||
|
||||
import com.intellij.psi.tree.IElementType;
|
||||
import com.intellij.psi.tree.IFileElementType;
|
||||
|
||||
/*
|
||||
* Created by IntelliJ IDEA.
|
||||
* User: sweinreuter
|
||||
* Date: 01.08.2007
|
||||
*/
|
||||
public class RncElementTypes {
|
||||
public static final IFileElementType FILE_ELEMENT_TYPE = new IFileElementType(RngCompactLanguage.INSTANCE);
|
||||
|
||||
public static final IElementType DOCUMENT = new RncElementTypeEx<RncDocument>("DOCUMENT", RncDocument.class);
|
||||
|
||||
public static final IElementType NS_DECL = new RncElementTypeEx<RncNsDecl>("NS_DECL", RncNsDeclImpl.class);
|
||||
public static final IElementType DATATYPES_DECL = new RncElementTypeEx<RncDecl>("DATATYPES_DECL", RncDeclImpl.class);
|
||||
|
||||
public static final IElementType START = new RncElementType("START");
|
||||
public static final IElementType DIV = new RncElementTypeEx<RncDiv>("DIV", RncDivImpl.class);
|
||||
public static final IElementType INCLUDE = new RncElementTypeEx<RncInclude>("INCLUDE", RncIncludeImpl.class);
|
||||
|
||||
public static final IElementType NAME_CLASS = new RncElementType("NAME_CLASS");
|
||||
public static final IElementType NAME_CLASS_CHOICE = new RncElementType("NAME_CLASS_CHOICE");
|
||||
public static final IElementType EXCEPT_NAME_CLASS = new RncElementType("EXCEPT_NAME_CLASS");
|
||||
|
||||
public static final IElementType DEFINE = new RncElementTypeEx<RncDefine>("DEFINE", RncDefineImpl.class);
|
||||
public static final IElementType PATTERN = new RncElementType("PATTERN");
|
||||
public static final IElementType GROUP_PATTERN = new RncElementType("GROUP_PATTERN");
|
||||
public static final IElementType GRAMMAR_PATTERN = new RncElementTypeEx<RncGrammar>("GRAMMAR_PATTERN", RncGrammarImpl.class);
|
||||
public static final IElementType EMPTY_PATTERN = new RncElementType("EMPTY_PATTERN");
|
||||
public static final IElementType TEXT_PATTERN = new RncElementType("TEXT_PATTERN");
|
||||
public static final IElementType NOT_ALLOWED_PATTERN = new RncElementType("NOT_ALLOWED_PATTERN");
|
||||
public static final IElementType EXTERNAL_REF = new RncElementTypeEx<RncExternalRef>("EXTERNAL_REF", RncExternalRefImpl.class);
|
||||
public static final IElementType PARENT_REF = new RncElementTypeEx<RncParentRef>("PARENT_REF", RncParentRefImpl.class);
|
||||
public static final IElementType REF_PATTERN = new RncElementTypeEx<RncRef>("REF_PATTERN", RncRefImpl.class);
|
||||
public static final IElementType LIST_PATTERN = new RncElementType("LIST_PATTERN");
|
||||
public static final IElementType MIXED_PATTERN = new RncElementType("MIXED_PATTERN");
|
||||
|
||||
public static final IElementType DATATYPE_PATTERN = new RncElementType("DATATYPE_PATTERN");
|
||||
public static final IElementType PARAM = new RncElementType("PARAM");
|
||||
|
||||
public static final IElementType SEQUENCE = new RncElementType("SEQUENCE");
|
||||
public static final IElementType INTERLEAVE = new RncElementType("INTERLEAVE");
|
||||
public static final IElementType CHOICE = new RncElementType("CHOICE");
|
||||
public static final IElementType OPTIONAL = new RncElementType("OPTIONAL");
|
||||
public static final IElementType ZERO_OR_MORE = new RncElementType("ZERO_OR_MORE");
|
||||
public static final IElementType ONE_OR_MORE = new RncElementType("ONE_OR_MORE");
|
||||
|
||||
public static final IElementType NAME = new RncElementTypeEx<RncName>("NAME", RncNameImpl.class);
|
||||
|
||||
public static final IElementType ANNOTATION = new RncElementTypeEx<RncAnnotation>("ANNOTATION", RncAnnotationImpl.class);
|
||||
public static final IElementType ANNOTATION_ELEMENT = new RncElementTypeEx<RncAnnotation>("ANNOTATION_ELEMENT", RncAnnotationImpl.class);
|
||||
public static final IElementType FORWARD_ANNOTATION = new RncElementTypeEx<RncAnnotation>("FORWARD_ANNOTATION", RncAnnotationImpl.class);
|
||||
}
|
||||
@@ -0,0 +1,83 @@
|
||||
/*
|
||||
* Copyright 2007 Sascha Weinreuter
|
||||
*
|
||||
* 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 org.intellij.plugins.relaxNG.compact;
|
||||
|
||||
import com.intellij.openapi.fileTypes.FileType;
|
||||
import com.intellij.openapi.fileTypes.FileTypeConsumer;
|
||||
import com.intellij.openapi.fileTypes.FileTypeFactory;
|
||||
import com.intellij.openapi.fileTypes.LanguageFileType;
|
||||
import com.intellij.openapi.util.IconLoader;
|
||||
import com.intellij.util.PairConsumer;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import javax.swing.*;
|
||||
|
||||
/*
|
||||
* Created by IntelliJ IDEA.
|
||||
* User: sweinreuter
|
||||
* Date: 01.08.2007
|
||||
*/
|
||||
public class RncFileType extends LanguageFileType {
|
||||
public static final String RNC_EXT = "rnc";
|
||||
|
||||
private static FileType INSTANCE;
|
||||
|
||||
private RncFileType() {
|
||||
super(RngCompactLanguage.INSTANCE);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@NonNls
|
||||
public String getName() {
|
||||
return "RNG Compact";
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public String getDescription() {
|
||||
return "RELAX NG Compact Syntax";
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@NonNls
|
||||
public String getDefaultExtension() {
|
||||
return "rnc";
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public Icon getIcon() {
|
||||
return IconLoader.findIcon("/fileTypes/text.png");
|
||||
}
|
||||
|
||||
public static synchronized FileType getInstance() {
|
||||
if (INSTANCE == null) {
|
||||
INSTANCE = new RncFileType();
|
||||
}
|
||||
return INSTANCE;
|
||||
}
|
||||
|
||||
public static class Factory extends FileTypeFactory {
|
||||
public void createFileTypes(@NotNull FileTypeConsumer fileTypeConsumer) {
|
||||
fileTypeConsumer.consume(getInstance(), RNC_EXT);
|
||||
}
|
||||
|
||||
public void createFileTypes(@NotNull PairConsumer<FileType, String> consumer) {
|
||||
consumer.consume(getInstance(), RNC_EXT);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,77 @@
|
||||
/*
|
||||
* Copyright 2007 Sascha Weinreuter
|
||||
*
|
||||
* 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 org.intellij.plugins.relaxNG.compact;
|
||||
|
||||
import org.intellij.plugins.relaxNG.compact.lexer.CompactSyntaxLexerAdapter;
|
||||
|
||||
import com.intellij.lexer.Lexer;
|
||||
import com.intellij.openapi.editor.HighlighterColors;
|
||||
import com.intellij.openapi.editor.SyntaxHighlighterColors;
|
||||
import com.intellij.openapi.editor.colors.CodeInsightColors;
|
||||
import com.intellij.openapi.editor.colors.TextAttributesKey;
|
||||
import com.intellij.openapi.fileTypes.SyntaxHighlighterBase;
|
||||
import com.intellij.psi.tree.IElementType;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Created by IntelliJ IDEA.
|
||||
* User: sweinreuter
|
||||
* Date: 04.08.2007
|
||||
*/
|
||||
public class RncHighlighter extends SyntaxHighlighterBase {
|
||||
@NotNull
|
||||
public Lexer getHighlightingLexer() {
|
||||
return new CompactSyntaxLexerAdapter();
|
||||
}
|
||||
|
||||
private static final Map<IElementType, TextAttributesKey> ourMap1;
|
||||
|
||||
static {
|
||||
ourMap1 = new HashMap<IElementType, TextAttributesKey>();
|
||||
|
||||
fillMap(ourMap1, RncTokenTypes.KEYWORDS, SyntaxHighlighterColors.KEYWORD);
|
||||
fillMap(ourMap1, RncTokenTypes.OPERATORS, SyntaxHighlighterColors.OPERATION_SIGN);
|
||||
|
||||
fillMap(ourMap1, RncTokenTypes.STRINGS, SyntaxHighlighterColors.STRING);
|
||||
|
||||
ourMap1.put(RncTokenTypes.LBRACE, SyntaxHighlighterColors.BRACES);
|
||||
ourMap1.put(RncTokenTypes.RBRACE, SyntaxHighlighterColors.BRACES);
|
||||
|
||||
ourMap1.put(RncTokenTypes.LBRACKET, SyntaxHighlighterColors.BRACKETS);
|
||||
ourMap1.put(RncTokenTypes.RBRACKET, SyntaxHighlighterColors.BRACKETS);
|
||||
|
||||
ourMap1.put(RncTokenTypes.LPAREN, SyntaxHighlighterColors.PARENTHS);
|
||||
ourMap1.put(RncTokenTypes.RPAREN, SyntaxHighlighterColors.PARENTHS);
|
||||
|
||||
ourMap1.put(RncTokenTypes.COMMA, SyntaxHighlighterColors.COMMA);
|
||||
|
||||
fillMap(ourMap1, RncTokenTypes.DOC_TOKENS, SyntaxHighlighterColors.DOC_COMMENT);
|
||||
fillMap(ourMap1, RncTokenTypes.COMMENTS, SyntaxHighlighterColors.LINE_COMMENT);
|
||||
|
||||
fillMap(ourMap1, RncTokenTypes.IDENTIFIERS, CodeInsightColors.LOCAL_VARIABLE_ATTRIBUTES);
|
||||
|
||||
ourMap1.put(RncTokenTypes.ILLEGAL_CHAR, HighlighterColors.BAD_CHARACTER);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public TextAttributesKey[] getTokenHighlights(IElementType tokenType) {
|
||||
return pack(ourMap1.get(tokenType));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,103 @@
|
||||
/*
|
||||
* Copyright 2007 Sascha Weinreuter
|
||||
*
|
||||
* 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 org.intellij.plugins.relaxNG.compact;
|
||||
|
||||
import org.intellij.plugins.relaxNG.compact.lexer.CompactSyntaxLexerAdapter;
|
||||
import org.intellij.plugins.relaxNG.compact.parser.RncParser;
|
||||
import org.intellij.plugins.relaxNG.compact.psi.RncElementVisitor;
|
||||
import org.intellij.plugins.relaxNG.compact.psi.impl.RncElementImpl;
|
||||
import org.intellij.plugins.relaxNG.compact.psi.impl.RncFileImpl;
|
||||
|
||||
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.TokenType;
|
||||
import com.intellij.psi.tree.IElementType;
|
||||
import com.intellij.psi.tree.IFileElementType;
|
||||
import com.intellij.psi.tree.TokenSet;
|
||||
import com.intellij.util.NotNullFunction;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
* Created by IntelliJ IDEA.
|
||||
* User: sweinreuter
|
||||
* Date: 10.08.2007
|
||||
*/
|
||||
public class RncParserDefinition implements ParserDefinition {
|
||||
@NotNull
|
||||
public Lexer createLexer(Project project) {
|
||||
return new CompactSyntaxLexerAdapter();
|
||||
}
|
||||
|
||||
public PsiParser createParser(Project project) {
|
||||
return new RncParser();
|
||||
}
|
||||
|
||||
public IFileElementType getFileNodeType() {
|
||||
return RncElementTypes.FILE_ELEMENT_TYPE;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public TokenSet getWhitespaceTokens() {
|
||||
return TokenSet.create(TokenType.WHITE_SPACE);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public TokenSet getCommentTokens() {
|
||||
return TokenSet.orSet(RncTokenTypes.COMMENTS, RncTokenTypes.DOC_TOKENS);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public TokenSet getStringLiteralElements() {
|
||||
return TokenSet.create(RncTokenTypes.LITERAL);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@SuppressWarnings({ "unchecked" })
|
||||
public PsiElement createElement(ASTNode node) {
|
||||
final IElementType type = node.getElementType();
|
||||
|
||||
if (type instanceof NotNullFunction) {
|
||||
return ((NotNullFunction<ASTNode, PsiElement>)type).fun(node);
|
||||
}
|
||||
|
||||
return new MyRncElement(node);
|
||||
}
|
||||
|
||||
public PsiFile createFile(FileViewProvider viewProvider) {
|
||||
return new RncFileImpl(viewProvider);
|
||||
}
|
||||
|
||||
public SpaceRequirements spaceExistanceTypeBetweenTokens(ASTNode left, ASTNode right) {
|
||||
return SpaceRequirements.MAY;
|
||||
}
|
||||
|
||||
private static class MyRncElement extends RncElementImpl {
|
||||
public MyRncElement(ASTNode node) {
|
||||
super(node);
|
||||
}
|
||||
|
||||
public void accept(@NotNull RncElementVisitor visitor) {
|
||||
visitor.visitElement(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,205 @@
|
||||
/*
|
||||
* Copyright 2007 Sascha Weinreuter
|
||||
*
|
||||
* 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 org.intellij.plugins.relaxNG.compact;
|
||||
|
||||
import com.intellij.openapi.util.Ref;
|
||||
import com.intellij.psi.tree.IElementType;
|
||||
import com.intellij.psi.tree.TokenSet;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import gnu.trove.TIntObjectHashMap;
|
||||
import gnu.trove.TObjectProcedure;
|
||||
import org.kohsuke.rngom.parse.compact.CompactSyntaxConstants;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
|
||||
/**
|
||||
* Created by IntelliJ IDEA.
|
||||
* User: sweinreuter
|
||||
* Date: 04.08.2007
|
||||
*/
|
||||
public class RncTokenTypes {
|
||||
private static final TIntObjectHashMap<IElementType> ourTokenTypes = new TIntObjectHashMap<IElementType>();
|
||||
|
||||
static {
|
||||
assert RngCompactLanguage.INSTANCE != null;
|
||||
try {
|
||||
final Field[] fields = CompactSyntaxConstants.class.getFields();
|
||||
for (Field field : fields) {
|
||||
final String name = field.getName();
|
||||
if (name.equals("DEFAULT")) break;
|
||||
|
||||
if (int.class.isAssignableFrom(field.getType())) {
|
||||
Integer i = (Integer)field.get(null);
|
||||
ourTokenTypes.put(i, new RncElementType(name));
|
||||
}
|
||||
}
|
||||
|
||||
final String[] tokens = CompactSyntaxConstants.tokenImage;
|
||||
for (int i = 0; i < tokens.length; i++) {
|
||||
String token = tokens[i];
|
||||
if (token.matches("\"\\w*\"")) {
|
||||
token = "KEYWORD_" + token.substring(1, token.length() - 1).toUpperCase();
|
||||
} else if (token.matches("\".*\"")) {
|
||||
token = token.substring(1, token.length() - 1);
|
||||
}
|
||||
if (ourTokenTypes.get(i) == null) {
|
||||
ourTokenTypes.put(i, new RncElementType(token));
|
||||
}
|
||||
}
|
||||
} catch (IllegalAccessException e) {
|
||||
throw new Error(e);
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static IElementType get(int i) {
|
||||
assert !ourTokenTypes.isEmpty();
|
||||
final IElementType type = ourTokenTypes.get(i);
|
||||
assert type != null : "Unknown token kind: " + i;
|
||||
return type;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static IElementType get(final String name) {
|
||||
assert !ourTokenTypes.isEmpty();
|
||||
final Ref<IElementType> ref = new Ref<IElementType>();
|
||||
ourTokenTypes.forEachValue(new TObjectProcedure<IElementType>() {
|
||||
public boolean execute(IElementType iElementType) {
|
||||
if (iElementType.toString().equals(name)) {
|
||||
ref.set(iElementType);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
});
|
||||
return ref.get();
|
||||
}
|
||||
|
||||
private static final IElementType WS = get(CompactSyntaxConstants.WS);
|
||||
public static final TokenSet WHITESPACE = TokenSet.create(WS);
|
||||
|
||||
public static final IElementType ILLEGAL_CHAR = get(CompactSyntaxConstants.ILLEGAL_CHAR);
|
||||
|
||||
public static final IElementType LBRACE = get("{");
|
||||
public static final IElementType RBRACE = get("}");
|
||||
public static final IElementType LBRACKET = get("[");
|
||||
public static final IElementType RBRACKET = get("]");
|
||||
public static final IElementType LPAREN = get("(");
|
||||
public static final IElementType RPAREN = get(")");
|
||||
|
||||
public static final IElementType GTGT = get(CompactSyntaxConstants.FANNOTATE);
|
||||
|
||||
public static final TokenSet BRACES = TokenSet.create(LBRACE, RBRACE);
|
||||
|
||||
public static final IElementType EQ = get("=");
|
||||
public static final IElementType PLUS = get("+");
|
||||
public static final IElementType MINUS = get("-");
|
||||
public static final IElementType STAR = get("*");
|
||||
public static final IElementType AND = get("&");
|
||||
public static final IElementType PIPE = get("|");
|
||||
public static final IElementType QUEST = get("?");
|
||||
|
||||
public static final IElementType PREFIXED_NAME = get(CompactSyntaxConstants.PREFIXED_NAME);
|
||||
public static final IElementType PREFIXED_STAR = get(CompactSyntaxConstants.PREFIX_STAR);
|
||||
|
||||
public static final IElementType CHOICE_EQ = get("|=");
|
||||
public static final IElementType INTERLEAVE_EQ = get("&=");
|
||||
|
||||
public static final IElementType COMMA = get(",");
|
||||
|
||||
public static final TokenSet BINARY_OPS = TokenSet.create(
|
||||
COMMA, PIPE, AND
|
||||
);
|
||||
|
||||
public static final TokenSet QUANTIFIER_OPS = TokenSet.create(
|
||||
PLUS, STAR, QUEST
|
||||
);
|
||||
|
||||
public static final IElementType DOC = get(CompactSyntaxConstants.DOCUMENTATION);
|
||||
public static final TokenSet DOC_TOKENS = TokenSet.create(
|
||||
DOC,
|
||||
get(CompactSyntaxConstants.DOCUMENTATION_AFTER_SINGLE_LINE_COMMENT),
|
||||
get(CompactSyntaxConstants.DOCUMENTATION_CONTINUE)
|
||||
);
|
||||
|
||||
public static final IElementType COMMENT = get(CompactSyntaxConstants.SINGLE_LINE_COMMENT);
|
||||
public static final TokenSet COMMENTS = TokenSet.create(
|
||||
COMMENT,
|
||||
get(CompactSyntaxConstants.SINGLE_LINE_COMMENT_CONTINUE)
|
||||
);
|
||||
|
||||
public static final IElementType ESCAPED_IDENTIFIER = get(CompactSyntaxConstants.ESCAPED_IDENTIFIER);
|
||||
public static final TokenSet IDENTIFIERS = TokenSet.create(
|
||||
get(CompactSyntaxConstants.IDENTIFIER),
|
||||
ESCAPED_IDENTIFIER
|
||||
);
|
||||
|
||||
public static final TokenSet OPERATORS = TokenSet.orSet(TokenSet.create(
|
||||
CHOICE_EQ, INTERLEAVE_EQ), BINARY_OPS, QUANTIFIER_OPS);
|
||||
|
||||
public static final IElementType LITERAL = get(CompactSyntaxConstants.LITERAL);
|
||||
public static final TokenSet STRINGS = TokenSet.create(LITERAL);
|
||||
|
||||
static final TokenSet READABLE_TEXT = TokenSet.orSet(
|
||||
DOC_TOKENS, COMMENTS,
|
||||
TokenSet.create(LITERAL));
|
||||
|
||||
public static final IElementType KEYWORD_ElEMENT = get("KEYWORD_ELEMENT");
|
||||
public static final IElementType KEYWORD_ATTRIBUTE = get("KEYWORD_ATTRIBUTE");
|
||||
public static final IElementType KEYWORD_NAMESPACE = get("KEYWORD_NAMESPACE");
|
||||
public static final IElementType KEYWORD_LIST = get("KEYWORD_LIST");
|
||||
public static final IElementType KEYWORD_MIXED = get("KEYWORD_MIXED");
|
||||
public static final IElementType KEYWORD_EMPTY = get("KEYWORD_EMPTY");
|
||||
public static final IElementType KEYWORD_GRAMMAR = get("KEYWORD_GRAMMAR");
|
||||
public static final IElementType KEYWORD_TEXT = get("KEYWORD_TEXT");
|
||||
public static final IElementType KEYWORD_PARENT = get("KEYWORD_PARENT");
|
||||
public static final IElementType KEYWORD_EXTERNAL = get("KEYWORD_LIST");
|
||||
public static final IElementType KEYWORD_NOT_ALLOWED = get("KEYWORD_NOTALLOWED");
|
||||
public static final IElementType KEYWORD_START = get("KEYWORD_START");
|
||||
public static final IElementType KEYWORD_INCLUDE = get("KEYWORD_INCLUDE");
|
||||
public static final IElementType KEYWORD_DEFAULT = get("KEYWORD_DEFAULT");
|
||||
public static final IElementType KEYWORD_INHERIT = get("KEYWORD_INHERIT");
|
||||
public static final IElementType KEYWORD_STRING = get("KEYWORD_STRING");
|
||||
public static final IElementType KEYWORD_TOKEN = get("KEYWORD_TOKEN");
|
||||
public static final IElementType KEYWORD_DATATYPES = get("KEYWORD_DATATYPES");
|
||||
public static final IElementType KEYWORD_DIV = get("KEYWORD_DIV");
|
||||
|
||||
public static final TokenSet KEYWORDS = TokenSet.create(
|
||||
KEYWORD_ATTRIBUTE,
|
||||
KEYWORD_DATATYPES,
|
||||
KEYWORD_DEFAULT,
|
||||
KEYWORD_DIV,
|
||||
KEYWORD_ElEMENT,
|
||||
KEYWORD_EMPTY,
|
||||
KEYWORD_EXTERNAL,
|
||||
KEYWORD_GRAMMAR,
|
||||
KEYWORD_INCLUDE,
|
||||
KEYWORD_INHERIT,
|
||||
KEYWORD_LIST,
|
||||
KEYWORD_MIXED,
|
||||
KEYWORD_NAMESPACE,
|
||||
KEYWORD_NOT_ALLOWED,
|
||||
KEYWORD_PARENT,
|
||||
KEYWORD_START,
|
||||
KEYWORD_STRING,
|
||||
KEYWORD_TEXT,
|
||||
KEYWORD_TOKEN
|
||||
);
|
||||
|
||||
public static final TokenSet IDENTIFIER_OR_KEYWORD = TokenSet.orSet(KEYWORDS, IDENTIFIERS);
|
||||
}
|
||||
@@ -0,0 +1,164 @@
|
||||
/*
|
||||
* Copyright 2007 Sascha Weinreuter
|
||||
*
|
||||
* 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 org.intellij.plugins.relaxNG.compact;
|
||||
|
||||
import org.intellij.plugins.relaxNG.compact.psi.RncDefine;
|
||||
import org.intellij.plugins.relaxNG.compact.psi.RncElement;
|
||||
import org.intellij.plugins.relaxNG.compact.psi.util.EscapeUtil;
|
||||
import org.intellij.plugins.relaxNG.compact.psi.util.RenameUtil;
|
||||
|
||||
import com.intellij.lang.BracePair;
|
||||
import com.intellij.lang.Commenter;
|
||||
import com.intellij.lang.Language;
|
||||
import com.intellij.lang.PairedBraceMatcher;
|
||||
import com.intellij.lang.documentation.DocumentationProvider;
|
||||
import com.intellij.lang.refactoring.NamesValidator;
|
||||
import com.intellij.openapi.fileTypes.SingleLazyInstanceSyntaxHighlighterFactory;
|
||||
import com.intellij.openapi.fileTypes.SyntaxHighlighter;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.tree.IElementType;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/*
|
||||
* Created by IntelliJ IDEA.
|
||||
* User: sweinreuter
|
||||
* Date: 01.08.2007
|
||||
*/
|
||||
public class RngCompactLanguage extends Language {
|
||||
public static final String ID = "RELAX-NG";
|
||||
|
||||
public static final RngCompactLanguage INSTANCE = new RngCompactLanguage();
|
||||
|
||||
private RngCompactLanguage() {
|
||||
super(ID);
|
||||
}
|
||||
|
||||
public static class MyCommenter implements Commenter {
|
||||
@Nullable
|
||||
public String getLineCommentPrefix() {
|
||||
return "#";
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public String getBlockCommentPrefix() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public String getBlockCommentSuffix() {
|
||||
return null;
|
||||
}
|
||||
|
||||
public String getCommentedBlockCommentPrefix() {
|
||||
return null;
|
||||
}
|
||||
|
||||
public String getCommentedBlockCommentSuffix() {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public static class MyPairedBraceMatcher implements PairedBraceMatcher {
|
||||
private BracePair[] myBracePairs;
|
||||
|
||||
public BracePair[] getPairs() {
|
||||
if (myBracePairs == null) {
|
||||
myBracePairs = new BracePair[]{
|
||||
new BracePair(RncTokenTypes.LBRACE, RncTokenTypes.RBRACE, true),
|
||||
new BracePair(RncTokenTypes.LPAREN, RncTokenTypes.RPAREN, false),
|
||||
new BracePair(RncTokenTypes.LBRACKET, RncTokenTypes.RBRACKET, false),
|
||||
};
|
||||
}
|
||||
return myBracePairs;
|
||||
}
|
||||
|
||||
public boolean isPairedBracesAllowedBeforeType(@NotNull IElementType lbraceType, @Nullable IElementType contextType) {
|
||||
return false;
|
||||
}
|
||||
|
||||
public int getCodeConstructStart(PsiFile file, int openingBraceOffset) {
|
||||
// TODO
|
||||
return openingBraceOffset;
|
||||
}
|
||||
}
|
||||
|
||||
public static class MyNamesValidator implements NamesValidator {
|
||||
public boolean isKeyword(String name, Project project) {
|
||||
return RenameUtil.isKeyword(PsiManager.getInstance(project), name);
|
||||
}
|
||||
|
||||
public boolean isIdentifier(String name, Project project) {
|
||||
return RenameUtil.isIdentifier(PsiManager.getInstance(project), name);
|
||||
}
|
||||
}
|
||||
|
||||
public static class MyDocumentationProvider implements DocumentationProvider {
|
||||
@Nullable
|
||||
public String getQuickNavigateInfo(PsiElement element) {
|
||||
return null;
|
||||
}
|
||||
|
||||
public List<String> getUrlFor(PsiElement element, PsiElement originalElement) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public String generateDoc(PsiElement element, PsiElement originalElement) {
|
||||
if (element instanceof RncElement) {
|
||||
PsiElement comment = element.getPrevSibling();
|
||||
while (comment instanceof PsiWhiteSpace) {
|
||||
comment = comment.getPrevSibling();
|
||||
}
|
||||
if (comment instanceof PsiComment) {
|
||||
final StringBuilder sb = new StringBuilder();
|
||||
do {
|
||||
sb.insert(0, EscapeUtil.unescapeText(comment).replaceAll("\n?##?", "") + "<br>");
|
||||
comment = comment.getPrevSibling();
|
||||
} while (comment instanceof PsiComment);
|
||||
|
||||
if (element instanceof RncDefine) {
|
||||
sb.insert(0, "Define: <b>" + ((RncDefine)element).getName() + "</b><br>");
|
||||
}
|
||||
|
||||
return sb.toString();
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public PsiElement getDocumentationElementForLookupItem(PsiManager psiManager, Object object, PsiElement element) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public PsiElement getDocumentationElementForLink(PsiManager psiManager, String link, PsiElement context) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public static class MySyntaxHighlighterFactory extends SingleLazyInstanceSyntaxHighlighterFactory {
|
||||
@NotNull
|
||||
protected SyntaxHighlighter createHighlighter() {
|
||||
return new RncHighlighter();
|
||||
}
|
||||
}
|
||||
}
|
||||
+158
@@ -0,0 +1,158 @@
|
||||
/*
|
||||
* Copyright 2007 Sascha Weinreuter
|
||||
*
|
||||
* 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 org.intellij.plugins.relaxNG.compact.folding;
|
||||
|
||||
import org.intellij.plugins.relaxNG.compact.RncElementTypes;
|
||||
import org.intellij.plugins.relaxNG.compact.RncTokenTypes;
|
||||
import org.intellij.plugins.relaxNG.compact.psi.RncAnnotation;
|
||||
import org.intellij.plugins.relaxNG.compact.psi.RncName;
|
||||
import org.intellij.plugins.relaxNG.compact.psi.util.EscapeUtil;
|
||||
|
||||
import com.intellij.codeInsight.folding.CodeFoldingSettings;
|
||||
import com.intellij.lang.ASTNode;
|
||||
import com.intellij.lang.folding.FoldingBuilder;
|
||||
import com.intellij.lang.folding.FoldingDescriptor;
|
||||
import com.intellij.openapi.editor.Document;
|
||||
import com.intellij.openapi.util.TextRange;
|
||||
import com.intellij.psi.PsiWhiteSpace;
|
||||
import com.intellij.psi.tree.IElementType;
|
||||
import com.intellij.psi.tree.TokenSet;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
/**
|
||||
* Created by IntelliJ IDEA.
|
||||
* User: sweinreuter
|
||||
* Date: 10.08.2007
|
||||
*/
|
||||
public class RncFoldingBuilder implements FoldingBuilder {
|
||||
@NotNull
|
||||
public FoldingDescriptor[] buildFoldRegions(@NotNull ASTNode node, @NotNull Document document) {
|
||||
|
||||
final ArrayList<FoldingDescriptor> regions = new ArrayList<FoldingDescriptor>();
|
||||
process(node, document, regions);
|
||||
|
||||
return regions.size() > 0
|
||||
? regions.toArray(new FoldingDescriptor[regions.size()])
|
||||
: FoldingDescriptor.EMPTY;
|
||||
}
|
||||
|
||||
public String getPlaceholderText(@NotNull ASTNode node) {
|
||||
final IElementType type = node.getElementType();
|
||||
if (type == RncTokenTypes.LBRACE) {
|
||||
return "{ ... }";
|
||||
} else if (isCommentLike(type)) {
|
||||
return "# ...";
|
||||
} else if (isAnnotation(type)) {
|
||||
final RncName element = ((RncAnnotation)node.getPsi()).getNameElement();
|
||||
if (element != null) {
|
||||
final ASTNode n = element.getNode();
|
||||
assert n != null;
|
||||
return EscapeUtil.unescapeText(n) + " [ ... ]";
|
||||
}
|
||||
return "[ ... ]";
|
||||
} else {
|
||||
return "...";
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean isAnnotation(IElementType type) {
|
||||
return RncElementTypes.ANNOTATION == type || RncElementTypes.ANNOTATION_ELEMENT == type || RncElementTypes.FORWARD_ANNOTATION == type;
|
||||
}
|
||||
|
||||
private static boolean isCommentLike(IElementType type) {
|
||||
return RncTokenTypes.COMMENTS.contains(type) || RncTokenTypes.DOC_TOKENS.contains(type);
|
||||
}
|
||||
|
||||
public boolean isCollapsedByDefault(@NotNull ASTNode node) {
|
||||
return isCommentLike(node.getElementType()) && CodeFoldingSettings.getInstance().COLLAPSE_DOC_COMMENTS;
|
||||
}
|
||||
|
||||
private static void process(@Nullable ASTNode node, Document document, ArrayList<FoldingDescriptor> regions) {
|
||||
if (node == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
final ASTNode[] braces = node.getChildren(RncTokenTypes.BRACES);
|
||||
if (braces.length == 2) {
|
||||
final ASTNode lbrace = braces[0];
|
||||
final ASTNode rbrace = braces[1];
|
||||
if (shouldFold(lbrace, rbrace, document)) {
|
||||
final TextRange range = new TextRange(lbrace.getStartOffset(), rbrace.getTextRange().getEndOffset());
|
||||
regions.add(new FoldingDescriptor(lbrace, range));
|
||||
}
|
||||
} else if (isAnnotation(node.getElementType())) {
|
||||
if (isOnDifferentLine(node.getFirstChildNode(), node.getLastChildNode(), document)) {
|
||||
regions.add(new FoldingDescriptor(node, node.getTextRange()));
|
||||
}
|
||||
}
|
||||
|
||||
node = node.getFirstChildNode();
|
||||
while (node != null) {
|
||||
node = checkNodeAndSiblings(node, RncTokenTypes.DOC_TOKENS, regions, document);
|
||||
|
||||
node = checkNodeAndSiblings(node, RncTokenTypes.COMMENTS, regions, document);
|
||||
|
||||
process(node, document, regions);
|
||||
|
||||
if (node != null) {
|
||||
node = node.getTreeNext();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static ASTNode checkNodeAndSiblings(@Nullable ASTNode node, TokenSet tokens, ArrayList<FoldingDescriptor> regions, Document document) {
|
||||
if (node != null && tokens.contains(node.getElementType())) {
|
||||
final ASTNode start = node;
|
||||
ASTNode end = start;
|
||||
|
||||
node = node.getTreeNext();
|
||||
if (node != null) {
|
||||
do {
|
||||
end = node;
|
||||
node = node.getTreeNext();
|
||||
} while (node != null && tokens.contains(node.getElementType()));
|
||||
}
|
||||
if (end != start) {
|
||||
while (end.getPsi() instanceof PsiWhiteSpace) {
|
||||
end = end.getTreePrev();
|
||||
}
|
||||
if (isOnDifferentLine(start, end, document)) {
|
||||
regions.add(new FoldingDescriptor(start, new TextRange(start.getStartOffset(), end.getTextRange().getEndOffset())));
|
||||
}
|
||||
}
|
||||
}
|
||||
return node;
|
||||
}
|
||||
|
||||
private static boolean shouldFold(ASTNode first, ASTNode second, Document document) {
|
||||
if (first.getElementType() != RncTokenTypes.LBRACE) {
|
||||
return false;
|
||||
} else if (second.getElementType() != RncTokenTypes.RBRACE) {
|
||||
return false;
|
||||
} else {
|
||||
return isOnDifferentLine(first, second, document);
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean isOnDifferentLine(ASTNode first, ASTNode second, Document document) {
|
||||
return document.getLineNumber(first.getStartOffset()) != document.getLineNumber(second.getStartOffset());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,127 @@
|
||||
/*
|
||||
* Copyright 2007 Sascha Weinreuter
|
||||
*
|
||||
* 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 org.intellij.plugins.relaxNG.compact.formatting;
|
||||
|
||||
import org.intellij.plugins.relaxNG.compact.RncElementTypes;
|
||||
import org.intellij.plugins.relaxNG.compact.RncTokenTypes;
|
||||
import org.intellij.plugins.relaxNG.compact.psi.RncDecl;
|
||||
import org.intellij.plugins.relaxNG.compact.psi.RncDefine;
|
||||
import org.intellij.plugins.relaxNG.compact.psi.RncFile;
|
||||
import org.intellij.plugins.relaxNG.compact.psi.RncGrammar;
|
||||
import org.intellij.plugins.relaxNG.compact.psi.impl.RncDocument;
|
||||
|
||||
import com.intellij.formatting.*;
|
||||
import com.intellij.lang.ASTNode;
|
||||
import com.intellij.openapi.util.TextRange;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
class RncBlock implements Block {
|
||||
private final ASTNode myNode;
|
||||
|
||||
public RncBlock(ASTNode element) {
|
||||
myNode = element;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public TextRange getTextRange() {
|
||||
return myNode.getTextRange();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public List<Block> getSubBlocks() {
|
||||
final List<Block> list = new ArrayList<Block>();
|
||||
ASTNode node = myNode.getFirstChildNode();
|
||||
while (node != null) {
|
||||
if (!RncTokenTypes.WHITESPACE.contains(node.getElementType()) && node.getTextLength() > 0) {
|
||||
list.add(new RncBlock(node));
|
||||
}
|
||||
node = node.getTreeNext();
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public Wrap getWrap() {
|
||||
// TODO
|
||||
return null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public Indent getIndent() {
|
||||
if (isTopLevel()) {
|
||||
return Indent.getAbsoluteNoneIndent();
|
||||
} else if (myNode.getTreeParent().getPsi() instanceof RncGrammar && !RncTokenTypes.BRACES.contains(myNode.getElementType())) {
|
||||
// TODO: fix block psi
|
||||
return Indent.getNormalIndent();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private boolean isTopLevel() {
|
||||
final PsiElement parent = myNode.getTreeParent().getPsi();
|
||||
return parent instanceof RncDocument ||
|
||||
parent instanceof RncFile ||
|
||||
parent instanceof RncGrammar && parent.getParent() instanceof RncDocument;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public Alignment getAlignment() {
|
||||
// TODO
|
||||
return null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public Spacing getSpacing(Block child1, Block child2) {
|
||||
final ASTNode lnode = ((RncBlock)child1).myNode;
|
||||
final PsiElement lpsi = lnode.getPsi();
|
||||
final PsiElement rpsi = ((RncBlock)child2).myNode.getPsi();
|
||||
|
||||
if (lpsi instanceof RncDecl && rpsi instanceof RncDecl) {
|
||||
return makeNewline();
|
||||
}
|
||||
if ((lpsi instanceof RncDecl || lpsi instanceof RncDefine ||
|
||||
lnode.getElementType() == RncElementTypes.START) &&
|
||||
(rpsi instanceof RncDefine || rpsi instanceof RncGrammar)) {
|
||||
return makeNewline();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private static Spacing makeNewline() {
|
||||
return Spacing.createSpacing(0, Integer.MAX_VALUE, 1, true, 100);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public ChildAttributes getChildAttributes(int newChildIndex) {
|
||||
return new ChildAttributes(null, null);
|
||||
}
|
||||
|
||||
public boolean isIncomplete() {
|
||||
// TODO
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean isLeaf() {
|
||||
// TODO
|
||||
return false;
|
||||
}
|
||||
}
|
||||
+39
@@ -0,0 +1,39 @@
|
||||
/*
|
||||
* Copyright 2007 Sascha Weinreuter
|
||||
*
|
||||
* 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 org.intellij.plugins.relaxNG.compact.formatting;
|
||||
|
||||
import com.intellij.formatting.FormattingModel;
|
||||
import com.intellij.formatting.FormattingModelBuilder;
|
||||
import com.intellij.formatting.FormattingModelProvider;
|
||||
import com.intellij.lang.ASTNode;
|
||||
import com.intellij.openapi.util.TextRange;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.PsiFile;
|
||||
import com.intellij.psi.codeStyle.CodeStyleSettings;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public class RncFormattingModelBuilder implements FormattingModelBuilder {
|
||||
@NotNull
|
||||
public FormattingModel createModel(PsiElement element, CodeStyleSettings settings) {
|
||||
return FormattingModelProvider.createFormattingModelForPsiFile(element.getContainingFile(), new RncBlock(element.getNode()), settings);
|
||||
}
|
||||
|
||||
public TextRange getRangeAffectingIndent(PsiFile file, int offset, ASTNode elementAtOffset) {
|
||||
// TODO
|
||||
return null;
|
||||
}
|
||||
}
|
||||
+258
@@ -0,0 +1,258 @@
|
||||
/*
|
||||
* Copyright 2007 Sascha Weinreuter
|
||||
*
|
||||
* 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 org.intellij.plugins.relaxNG.compact.lexer;
|
||||
|
||||
import org.intellij.plugins.relaxNG.compact.RncTokenTypes;
|
||||
|
||||
import com.intellij.lexer.LexerBase;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.util.io.FileUtil;
|
||||
import com.intellij.psi.TokenType;
|
||||
import com.intellij.psi.tree.IElementType;
|
||||
import com.intellij.util.text.CharArrayCharSequence;
|
||||
import com.intellij.util.text.CharArrayUtil;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import gnu.trove.TIntIntHashMap;
|
||||
import org.kohsuke.rngom.parse.compact.CompactSyntaxConstants;
|
||||
import org.kohsuke.rngom.parse.compact.CompactSyntaxTokenManager;
|
||||
import org.kohsuke.rngom.parse.compact.Token;
|
||||
import org.kohsuke.rngom.parse.compact.TokenMgrError;
|
||||
|
||||
import java.io.CharArrayReader;
|
||||
import java.io.FileReader;
|
||||
import java.io.IOException;
|
||||
import java.io.Reader;
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.LinkedList;
|
||||
|
||||
/**
|
||||
* An adapter to use the lexer ("TokenManager") generated from a javacc grammar.
|
||||
*
|
||||
* Not sure if it was easier to write this than hacking my own lexer...
|
||||
*/
|
||||
public class CompactSyntaxLexerAdapter extends LexerBase {
|
||||
private static final Logger LOG = Logger.getInstance(CompactSyntaxLexerAdapter.class.getName());
|
||||
|
||||
private static final Field myStateField;
|
||||
|
||||
static {
|
||||
try {
|
||||
myStateField = CompactSyntaxTokenManager.class.getDeclaredField("curLexState");
|
||||
myStateField.setAccessible(true);
|
||||
} catch (NoSuchFieldException e) {
|
||||
throw new Error(e);
|
||||
}
|
||||
}
|
||||
|
||||
private static final Token START = new Token();
|
||||
|
||||
private CompactSyntaxTokenManager myLexer;
|
||||
private final LinkedList<Token> myTokenQueue = new LinkedList<Token>();
|
||||
private Token myCurrentToken;
|
||||
private int myCurrentOffset;
|
||||
private int myCurrentEnd;
|
||||
|
||||
private IElementType myCurrentTokenType;
|
||||
private CharSequence myBuffer;
|
||||
private int myEndOffset;
|
||||
private TIntIntHashMap myLengthMap;
|
||||
|
||||
public void advance() {
|
||||
try {
|
||||
myCurrentToken = nextToken();
|
||||
myCurrentOffset = myCurrentEnd;
|
||||
|
||||
if (myCurrentToken != null) {
|
||||
|
||||
myCurrentEnd = myCurrentOffset + myCurrentToken.image.length();
|
||||
for (int i = myCurrentOffset; i < myCurrentEnd; i++) {
|
||||
myCurrentEnd += myLengthMap.get(i);
|
||||
}
|
||||
|
||||
if (myCurrentToken.kind == CompactSyntaxConstants.EOF) {
|
||||
assert myCurrentOffset == myEndOffset : "actual: " + myCurrentOffset + ", expected: " + myEndOffset;
|
||||
myCurrentToken = null;
|
||||
}
|
||||
}
|
||||
|
||||
// if (myCurrentToken != null) {
|
||||
// System.out.println("token = <" + RncTokenTypes.get(myCurrentToken.kind).toString() + "> [" + myCurrentToken.image + "]");
|
||||
// }
|
||||
} catch (TokenMgrError e) {
|
||||
LOG.error(e);
|
||||
myCurrentToken = null;
|
||||
}
|
||||
|
||||
if (myCurrentToken == null) {
|
||||
myCurrentTokenType = null;
|
||||
} else {
|
||||
myCurrentTokenType = RncTokenTypes.get(myCurrentToken.kind);
|
||||
|
||||
// collapse whitespace tokens into TokenType.WHITE_SPACE [IDEA-12106]
|
||||
if (RncTokenTypes.WHITESPACE.contains(myCurrentTokenType)) {
|
||||
myCurrentTokenType = TokenType.WHITE_SPACE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private Token nextToken() {
|
||||
if (myTokenQueue.size() > 0) {
|
||||
return myTokenQueue.removeFirst();
|
||||
}
|
||||
|
||||
final Token t = myLexer.getNextToken();
|
||||
if (t.specialToken != null) {
|
||||
myTokenQueue.addFirst(t);
|
||||
for (Token s = t.specialToken; s != null; s = s.specialToken) {
|
||||
myTokenQueue.addFirst(s);
|
||||
}
|
||||
return myTokenQueue.removeFirst();
|
||||
} else {
|
||||
return t;
|
||||
}
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public char[] getBuffer() {
|
||||
return CharArrayUtil.fromSequence(myBuffer);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CharSequence getBufferSequence() {
|
||||
return myBuffer;
|
||||
}
|
||||
|
||||
public int getBufferEnd() {
|
||||
return myEndOffset;
|
||||
}
|
||||
|
||||
public int getState() {
|
||||
try {
|
||||
return (Integer)myStateField.get(myLexer);
|
||||
} catch (Exception e) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
public int getTokenEnd() {
|
||||
return myCurrentEnd;
|
||||
}
|
||||
|
||||
public int getTokenStart() {
|
||||
return myCurrentToken == null ? 0 : myCurrentOffset;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public IElementType getTokenType() {
|
||||
if (myCurrentToken == null) {
|
||||
return null;
|
||||
} else {
|
||||
return myCurrentTokenType;
|
||||
}
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public void start(char[] buffer, int startOffset, int endOffset, int initialState) {
|
||||
myBuffer = new CharArrayCharSequence(buffer, startOffset, endOffset);
|
||||
|
||||
final CharArrayReader reader = new CharArrayReader(buffer, startOffset, endOffset - startOffset);
|
||||
init(startOffset, endOffset, reader, initialState);
|
||||
}
|
||||
|
||||
public void start(CharSequence buffer, int startOffset, int endOffset, int initialState) {
|
||||
myBuffer = buffer;
|
||||
|
||||
final Reader reader = new CharSequenceReader(buffer, startOffset, endOffset);
|
||||
init(startOffset, endOffset, reader, initialState);
|
||||
}
|
||||
|
||||
private void init(int startOffset, int endOffset, Reader reader, int initialState) {
|
||||
myEndOffset = endOffset;
|
||||
myLengthMap = new TIntIntHashMap();
|
||||
|
||||
final EscapePreprocessor preprocessor = new EscapePreprocessor(reader, startOffset, myLengthMap);
|
||||
myLexer = new CompactSyntaxTokenManager(new SimpleCharStream(preprocessor, 1, 1), initialState);
|
||||
|
||||
myCurrentToken = START;
|
||||
myCurrentOffset = startOffset;
|
||||
myCurrentEnd = startOffset;
|
||||
myTokenQueue.clear();
|
||||
advance();
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws IOException {
|
||||
final CompactSyntaxLexerAdapter lexer = new CompactSyntaxLexerAdapter();
|
||||
lexer.start(new CharArrayCharSequence(FileUtil.adaptiveLoadText(new FileReader(args[0]))));
|
||||
while (lexer.getTokenType() != null) {
|
||||
System.out.println("token = " + lexer.getTokenType());
|
||||
final int start = lexer.getTokenStart();
|
||||
System.out.println("start = " + start);
|
||||
final int end = lexer.getTokenEnd();
|
||||
System.out.println("end = " + end);
|
||||
final CharSequence t = lexer.getBufferSequence().subSequence(start, end);
|
||||
System.out.println("t = " + t);
|
||||
lexer.advance();
|
||||
}
|
||||
}
|
||||
|
||||
// adapted from com.intellij.util.text.CharSequenceReader with start- and endOffset support
|
||||
static class CharSequenceReader extends Reader {
|
||||
private final CharSequence myText;
|
||||
private final int myEndOffset;
|
||||
private int myCurPos;
|
||||
|
||||
public CharSequenceReader(final CharSequence text, int startOffset, int endOffset) {
|
||||
myText = text;
|
||||
myEndOffset = endOffset;
|
||||
myCurPos = startOffset;
|
||||
}
|
||||
|
||||
public void close() {
|
||||
}
|
||||
|
||||
public int read(char[] cbuf, int off, int len) {
|
||||
if ((off < 0) || (off > cbuf.length) || (len < 0) || ((off + len) > cbuf.length) || ((off + len) < 0)) {
|
||||
throw new IndexOutOfBoundsException();
|
||||
} else if (len == 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (myText instanceof CharArrayCharSequence) { // Optimization
|
||||
final int readChars = ((CharArrayCharSequence)myText).readCharsTo(myCurPos, cbuf, off, len);
|
||||
if (readChars < 0) return -1;
|
||||
myCurPos += readChars;
|
||||
return readChars;
|
||||
}
|
||||
|
||||
int charsToCopy = Math.min(len, myEndOffset - myCurPos);
|
||||
if (charsToCopy <= 0) return -1;
|
||||
|
||||
for (int n = 0; n < charsToCopy; n++) {
|
||||
cbuf[n + off] = myText.charAt(n + myCurPos);
|
||||
}
|
||||
|
||||
myCurPos += charsToCopy;
|
||||
return charsToCopy;
|
||||
}
|
||||
|
||||
public int read() {
|
||||
if (myCurPos >= myEndOffset) return -1;
|
||||
return myText.charAt(myCurPos++);
|
||||
}
|
||||
}
|
||||
}
|
||||
+140
@@ -0,0 +1,140 @@
|
||||
/*
|
||||
* Copyright 2007 Sascha Weinreuter
|
||||
*
|
||||
* 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 org.intellij.plugins.relaxNG.compact.lexer;
|
||||
|
||||
import gnu.trove.TIntArrayList;
|
||||
import gnu.trove.TIntIntHashMap;
|
||||
import org.kohsuke.rngom.util.Utf16;
|
||||
|
||||
import java.io.FilterReader;
|
||||
import java.io.IOException;
|
||||
import java.io.Reader;
|
||||
|
||||
/**
|
||||
* A reader that deals with escape sequences in RNC files (\x{xx}) and keeps track of their positions to build correct
|
||||
* token ranges in the lexer.
|
||||
* <p/>
|
||||
* Created by IntelliJ IDEA.
|
||||
* User: sweinreuter
|
||||
* Date: 05.08.2007
|
||||
*/
|
||||
class EscapePreprocessor extends FilterReader {
|
||||
private final TIntArrayList myQueuedChars;
|
||||
private final TIntIntHashMap myLengthMap;
|
||||
|
||||
private int myOffset;
|
||||
|
||||
public EscapePreprocessor(Reader reader, int startOffset, TIntIntHashMap map) {
|
||||
super(reader);
|
||||
myOffset = startOffset;
|
||||
myQueuedChars = new TIntArrayList();
|
||||
myLengthMap = map;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int read(char cbuf[], int off, int len) throws IOException {
|
||||
final int i = read();
|
||||
if (i == -1) {
|
||||
return -1;
|
||||
}
|
||||
cbuf[off] = (char)i; // not really efficient, but acceptable since we're usually not having to deal with megabytes of RNC files...
|
||||
return 1;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int read() throws IOException {
|
||||
if (myQueuedChars.size() > 0) {
|
||||
return consume();
|
||||
}
|
||||
final int i = super.read();
|
||||
if (i == -1) {
|
||||
return -1;
|
||||
}
|
||||
myOffset++;
|
||||
|
||||
switch (i) {
|
||||
case '\r':
|
||||
assert false : "Unexpected newline character"; // IDEA document's are supposed to newlines normalized to \n
|
||||
if (peek() == '\n') {
|
||||
consume();
|
||||
myLengthMap.put(myOffset - 1, 2);
|
||||
}
|
||||
case '\n':
|
||||
return '\u0000';
|
||||
|
||||
case '\\':
|
||||
int n = 0;
|
||||
int x;
|
||||
while ((x = peek()) == 'x') {
|
||||
n++;
|
||||
}
|
||||
if (n > 0 && x == '{') {
|
||||
n++;
|
||||
} else {
|
||||
return i;
|
||||
}
|
||||
int value = 0;
|
||||
while (isHexChar((char)(x = peek()))) {
|
||||
n++;
|
||||
value <<= 4;
|
||||
value |= Character.digit(x, 16);
|
||||
}
|
||||
if (x == '}') {
|
||||
n++;
|
||||
}
|
||||
consume(n);
|
||||
|
||||
myLengthMap.put(myOffset - 1, n);
|
||||
myOffset += n;
|
||||
|
||||
if (value <= 0xFFFF) {
|
||||
return value;
|
||||
}
|
||||
|
||||
myQueuedChars.add(Utf16.surrogate2(value));
|
||||
return Utf16.surrogate1(value);
|
||||
}
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
private static boolean isHexChar(char i) {
|
||||
if (Character.isDigit(i)) return true;
|
||||
final char c = Character.toLowerCase(i);
|
||||
return c >= 'a' && c <= 'f';
|
||||
}
|
||||
|
||||
private int consume() {
|
||||
if (myQueuedChars.size() > 0) {
|
||||
return myQueuedChars.remove(0);
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
private void consume(int n) {
|
||||
myQueuedChars.remove(0, n);
|
||||
}
|
||||
|
||||
private int peek() throws IOException {
|
||||
final int i = super.read();
|
||||
if (i == -1) {
|
||||
return -1;
|
||||
}
|
||||
myQueuedChars.add(i);
|
||||
return i;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,420 @@
|
||||
/*
|
||||
* Copyright 2007 Sascha Weinreuter
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/* Generated By:JavaCC: Do not edit this line. SimpleCharStream.java Version 3.0 */
|
||||
package org.intellij.plugins.relaxNG.compact.lexer;
|
||||
|
||||
import org.kohsuke.rngom.parse.compact.CharStream;
|
||||
import org.kohsuke.rngom.parse.compact.EOFException;
|
||||
|
||||
/**
|
||||
* An implementation of interface CharStream, where the stream is assumed to
|
||||
* contain only ASCII characters (without unicode processing).
|
||||
*/
|
||||
|
||||
@SuppressWarnings({ "ALL" })
|
||||
public class SimpleCharStream implements CharStream
|
||||
{
|
||||
int bufsize;
|
||||
int available;
|
||||
int tokenBegin;
|
||||
public int bufpos = -1;
|
||||
protected int bufline[];
|
||||
protected int bufcolumn[];
|
||||
|
||||
protected int column = 0;
|
||||
protected int line = 1;
|
||||
|
||||
protected boolean prevCharIsCR = false;
|
||||
protected boolean prevCharIsLF = false;
|
||||
|
||||
protected java.io.Reader inputStream;
|
||||
|
||||
protected char[] buffer;
|
||||
protected int maxNextCharInd = 0;
|
||||
protected int inBuf = 0;
|
||||
|
||||
protected void ExpandBuff(boolean wrapAround)
|
||||
{
|
||||
char[] newbuffer = new char[bufsize + 2048];
|
||||
int newbufline[] = new int[bufsize + 2048];
|
||||
int newbufcolumn[] = new int[bufsize + 2048];
|
||||
|
||||
try
|
||||
{
|
||||
if (wrapAround)
|
||||
{
|
||||
System.arraycopy(buffer, tokenBegin, newbuffer, 0, bufsize - tokenBegin);
|
||||
System.arraycopy(buffer, 0, newbuffer,
|
||||
bufsize - tokenBegin, bufpos);
|
||||
buffer = newbuffer;
|
||||
|
||||
System.arraycopy(bufline, tokenBegin, newbufline, 0, bufsize - tokenBegin);
|
||||
System.arraycopy(bufline, 0, newbufline, bufsize - tokenBegin, bufpos);
|
||||
bufline = newbufline;
|
||||
|
||||
System.arraycopy(bufcolumn, tokenBegin, newbufcolumn, 0, bufsize - tokenBegin);
|
||||
System.arraycopy(bufcolumn, 0, newbufcolumn, bufsize - tokenBegin, bufpos);
|
||||
bufcolumn = newbufcolumn;
|
||||
|
||||
maxNextCharInd = (bufpos += (bufsize - tokenBegin));
|
||||
}
|
||||
else
|
||||
{
|
||||
System.arraycopy(buffer, tokenBegin, newbuffer, 0, bufsize - tokenBegin);
|
||||
buffer = newbuffer;
|
||||
|
||||
System.arraycopy(bufline, tokenBegin, newbufline, 0, bufsize - tokenBegin);
|
||||
bufline = newbufline;
|
||||
|
||||
System.arraycopy(bufcolumn, tokenBegin, newbufcolumn, 0, bufsize - tokenBegin);
|
||||
bufcolumn = newbufcolumn;
|
||||
|
||||
maxNextCharInd = (bufpos -= tokenBegin);
|
||||
}
|
||||
}
|
||||
catch (Throwable t)
|
||||
{
|
||||
throw new Error(t.getMessage());
|
||||
}
|
||||
|
||||
|
||||
bufsize += 2048;
|
||||
available = bufsize;
|
||||
tokenBegin = 0;
|
||||
}
|
||||
|
||||
protected void FillBuff() throws EOFException
|
||||
{
|
||||
if (maxNextCharInd == available)
|
||||
{
|
||||
if (available == bufsize)
|
||||
{
|
||||
if (tokenBegin > 2048)
|
||||
{
|
||||
bufpos = maxNextCharInd = 0;
|
||||
available = tokenBegin;
|
||||
}
|
||||
else if (tokenBegin < 0)
|
||||
bufpos = maxNextCharInd = 0;
|
||||
else
|
||||
ExpandBuff(false);
|
||||
}
|
||||
else if (available > tokenBegin)
|
||||
available = bufsize;
|
||||
else if ((tokenBegin - available) < 2048)
|
||||
ExpandBuff(true);
|
||||
else
|
||||
available = tokenBegin;
|
||||
}
|
||||
|
||||
int i;
|
||||
try {
|
||||
if ((i = inputStream.read(buffer, maxNextCharInd,
|
||||
available - maxNextCharInd)) == -1)
|
||||
{
|
||||
inputStream.close();
|
||||
throw new java.io.IOException();
|
||||
}
|
||||
else
|
||||
maxNextCharInd += i;
|
||||
return;
|
||||
}
|
||||
catch(java.io.IOException e) {
|
||||
--bufpos;
|
||||
backup(0);
|
||||
if (tokenBegin == -1)
|
||||
tokenBegin = bufpos;
|
||||
throw new EOFException();
|
||||
}
|
||||
}
|
||||
|
||||
public char BeginToken() throws EOFException
|
||||
{
|
||||
tokenBegin = -1;
|
||||
char c = readChar();
|
||||
tokenBegin = bufpos;
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
protected void UpdateLineColumn(char c)
|
||||
{
|
||||
column++;
|
||||
|
||||
if (prevCharIsLF)
|
||||
{
|
||||
prevCharIsLF = false;
|
||||
line += (column = 1);
|
||||
}
|
||||
else if (prevCharIsCR)
|
||||
{
|
||||
prevCharIsCR = false;
|
||||
if (c == '\n')
|
||||
{
|
||||
prevCharIsLF = true;
|
||||
}
|
||||
else
|
||||
line += (column = 1);
|
||||
}
|
||||
|
||||
switch (c)
|
||||
{
|
||||
case '\r' :
|
||||
prevCharIsCR = true;
|
||||
break;
|
||||
case '\n' :
|
||||
prevCharIsLF = true;
|
||||
break;
|
||||
case '\t' :
|
||||
column--;
|
||||
column += (8 - (column & 07));
|
||||
break;
|
||||
default :
|
||||
break;
|
||||
}
|
||||
|
||||
bufline[bufpos] = line;
|
||||
bufcolumn[bufpos] = column;
|
||||
}
|
||||
|
||||
public char readChar() throws EOFException
|
||||
{
|
||||
if (inBuf > 0)
|
||||
{
|
||||
--inBuf;
|
||||
|
||||
if (++bufpos == bufsize)
|
||||
bufpos = 0;
|
||||
|
||||
return buffer[bufpos];
|
||||
}
|
||||
|
||||
if (++bufpos >= maxNextCharInd)
|
||||
FillBuff();
|
||||
|
||||
char c = buffer[bufpos];
|
||||
|
||||
UpdateLineColumn(c);
|
||||
return (c);
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated
|
||||
* @see #getEndColumn
|
||||
*/
|
||||
|
||||
public int getColumn() {
|
||||
return bufcolumn[bufpos];
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated
|
||||
* @see #getEndLine
|
||||
*/
|
||||
|
||||
public int getLine() {
|
||||
return bufline[bufpos];
|
||||
}
|
||||
|
||||
public int getEndColumn() {
|
||||
return bufcolumn[bufpos];
|
||||
}
|
||||
|
||||
public int getEndLine() {
|
||||
return bufline[bufpos];
|
||||
}
|
||||
|
||||
public int getBeginColumn() {
|
||||
return bufcolumn[tokenBegin];
|
||||
}
|
||||
|
||||
public int getBeginLine() {
|
||||
return bufline[tokenBegin];
|
||||
}
|
||||
|
||||
public void backup(int amount) {
|
||||
|
||||
inBuf += amount;
|
||||
if ((bufpos -= amount) < 0)
|
||||
bufpos += bufsize;
|
||||
}
|
||||
|
||||
public SimpleCharStream(java.io.Reader dstream, int startline,
|
||||
int startcolumn, int buffersize)
|
||||
{
|
||||
inputStream = dstream;
|
||||
line = startline;
|
||||
column = startcolumn - 1;
|
||||
|
||||
available = bufsize = buffersize;
|
||||
buffer = new char[buffersize];
|
||||
bufline = new int[buffersize];
|
||||
bufcolumn = new int[buffersize];
|
||||
}
|
||||
|
||||
public SimpleCharStream(java.io.Reader dstream, int startline,
|
||||
int startcolumn)
|
||||
{
|
||||
this(dstream, startline, startcolumn, 4096);
|
||||
}
|
||||
|
||||
public SimpleCharStream(java.io.Reader dstream)
|
||||
{
|
||||
this(dstream, 1, 1, 4096);
|
||||
}
|
||||
public void ReInit(java.io.Reader dstream, int startline,
|
||||
int startcolumn, int buffersize)
|
||||
{
|
||||
inputStream = dstream;
|
||||
line = startline;
|
||||
column = startcolumn - 1;
|
||||
|
||||
if (buffer == null || buffersize != buffer.length)
|
||||
{
|
||||
available = bufsize = buffersize;
|
||||
buffer = new char[buffersize];
|
||||
bufline = new int[buffersize];
|
||||
bufcolumn = new int[buffersize];
|
||||
}
|
||||
prevCharIsLF = prevCharIsCR = false;
|
||||
tokenBegin = inBuf = maxNextCharInd = 0;
|
||||
bufpos = -1;
|
||||
}
|
||||
|
||||
public void ReInit(java.io.Reader dstream, int startline,
|
||||
int startcolumn)
|
||||
{
|
||||
ReInit(dstream, startline, startcolumn, 4096);
|
||||
}
|
||||
|
||||
public void ReInit(java.io.Reader dstream)
|
||||
{
|
||||
ReInit(dstream, 1, 1, 4096);
|
||||
}
|
||||
public SimpleCharStream(java.io.InputStream dstream, int startline,
|
||||
int startcolumn, int buffersize)
|
||||
{
|
||||
this(new java.io.InputStreamReader(dstream), startline, startcolumn, 4096);
|
||||
}
|
||||
|
||||
public SimpleCharStream(java.io.InputStream dstream, int startline,
|
||||
int startcolumn)
|
||||
{
|
||||
this(dstream, startline, startcolumn, 4096);
|
||||
}
|
||||
|
||||
public SimpleCharStream(java.io.InputStream dstream)
|
||||
{
|
||||
this(dstream, 1, 1, 4096);
|
||||
}
|
||||
|
||||
public void ReInit(java.io.InputStream dstream, int startline,
|
||||
int startcolumn, int buffersize)
|
||||
{
|
||||
ReInit(new java.io.InputStreamReader(dstream), startline, startcolumn, 4096);
|
||||
}
|
||||
|
||||
public void ReInit(java.io.InputStream dstream)
|
||||
{
|
||||
ReInit(dstream, 1, 1, 4096);
|
||||
}
|
||||
public void ReInit(java.io.InputStream dstream, int startline,
|
||||
int startcolumn)
|
||||
{
|
||||
ReInit(dstream, startline, startcolumn, 4096);
|
||||
}
|
||||
public String GetImage()
|
||||
{
|
||||
if (bufpos >= tokenBegin)
|
||||
return new String(buffer, tokenBegin, bufpos - tokenBegin + 1);
|
||||
else
|
||||
return new String(buffer, tokenBegin, bufsize - tokenBegin) +
|
||||
new String(buffer, 0, bufpos + 1);
|
||||
}
|
||||
|
||||
public char[] GetSuffix(int len)
|
||||
{
|
||||
char[] ret = new char[len];
|
||||
|
||||
if ((bufpos + 1) >= len)
|
||||
System.arraycopy(buffer, bufpos - len + 1, ret, 0, len);
|
||||
else
|
||||
{
|
||||
System.arraycopy(buffer, bufsize - (len - bufpos - 1), ret, 0,
|
||||
len - bufpos - 1);
|
||||
System.arraycopy(buffer, 0, ret, len - bufpos - 1, bufpos + 1);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
public void Done()
|
||||
{
|
||||
buffer = null;
|
||||
bufline = null;
|
||||
bufcolumn = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method to adjust line and column numbers for the start of a token.
|
||||
*/
|
||||
public void adjustBeginLineColumn(int newLine, int newCol)
|
||||
{
|
||||
int start = tokenBegin;
|
||||
int len;
|
||||
|
||||
if (bufpos >= tokenBegin)
|
||||
{
|
||||
len = bufpos - tokenBegin + inBuf + 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
len = bufsize - tokenBegin + bufpos + 1 + inBuf;
|
||||
}
|
||||
|
||||
int i = 0, j = 0, k = 0;
|
||||
int nextColDiff = 0, columnDiff = 0;
|
||||
|
||||
while (i < len &&
|
||||
bufline[j = start % bufsize] == bufline[k = ++start % bufsize])
|
||||
{
|
||||
bufline[j] = newLine;
|
||||
nextColDiff = columnDiff + bufcolumn[k] - bufcolumn[j];
|
||||
bufcolumn[j] = newCol + columnDiff;
|
||||
columnDiff = nextColDiff;
|
||||
i++;
|
||||
}
|
||||
|
||||
if (i < len)
|
||||
{
|
||||
bufline[j] = newLine++;
|
||||
bufcolumn[j] = newCol + columnDiff;
|
||||
|
||||
while (i++ < len)
|
||||
{
|
||||
if (bufline[j = start % bufsize] != bufline[++start % bufsize])
|
||||
bufline[j] = newLine++;
|
||||
else
|
||||
bufline[j] = newLine;
|
||||
}
|
||||
}
|
||||
|
||||
line = bufline[j];
|
||||
column = bufcolumn[j];
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,156 @@
|
||||
/*
|
||||
* Copyright 2007 Sascha Weinreuter
|
||||
*
|
||||
* 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 org.intellij.plugins.relaxNG.compact.parser;
|
||||
|
||||
import org.intellij.plugins.relaxNG.compact.RncElementTypes;
|
||||
import static org.intellij.plugins.relaxNG.compact.RncTokenTypes.*;
|
||||
|
||||
import com.intellij.lang.PsiBuilder;
|
||||
import com.intellij.psi.tree.IElementType;
|
||||
import com.intellij.psi.tree.TokenSet;
|
||||
|
||||
/**
|
||||
* Created by IntelliJ IDEA.
|
||||
* User: sweinreuter
|
||||
* Date: 09.08.2007
|
||||
*/
|
||||
public abstract class AbstractParsing {
|
||||
protected static final TokenSet LA_INCLUDE_CONTENT = TokenSet.orSet(TokenSet.create(
|
||||
KEYWORD_DIV, KEYWORD_START), IDENTIFIERS);
|
||||
|
||||
protected static final TokenSet LA_GRAMMAR_CONTENT = TokenSet.orSet(TokenSet.create(
|
||||
KEYWORD_INCLUDE), LA_INCLUDE_CONTENT);
|
||||
|
||||
protected static final TokenSet ATTR_OR_ELEMENT = TokenSet.create(
|
||||
KEYWORD_ATTRIBUTE, KEYWORD_ElEMENT);
|
||||
|
||||
protected static final TokenSet CONTENT = TokenSet.create(
|
||||
KEYWORD_LIST, KEYWORD_MIXED);
|
||||
|
||||
protected static final TokenSet LA_DATATYPE = TokenSet.create(
|
||||
KEYWORD_STRING, KEYWORD_TOKEN);
|
||||
|
||||
protected static final TokenSet LA_DECL = TokenSet.create(
|
||||
KEYWORD_DATATYPES, KEYWORD_NAMESPACE, KEYWORD_DEFAULT);
|
||||
|
||||
protected static final TokenSet NS_URI_LITERAL = TokenSet.create(KEYWORD_INHERIT, LITERAL);
|
||||
protected static final TokenSet ASSIGN_METHOD = TokenSet.create(EQ, CHOICE_EQ, INTERLEAVE_EQ);
|
||||
protected final PsiBuilder myBuilder;
|
||||
|
||||
public AbstractParsing(PsiBuilder builder) {
|
||||
myBuilder = builder;
|
||||
}
|
||||
|
||||
protected final PsiBuilder.Marker begin() {
|
||||
final PsiBuilder.Marker marker = myBuilder.mark();
|
||||
advance();
|
||||
return marker;
|
||||
}
|
||||
|
||||
protected final boolean matches(TokenSet set) {
|
||||
if (set.contains(currentToken())) {
|
||||
advance();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
protected final boolean matches(IElementType t) {
|
||||
if (t == currentToken()) {
|
||||
advance();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
protected final void match(IElementType token, String msg) {
|
||||
if (!matches(token)) {
|
||||
error(msg);
|
||||
advance();
|
||||
}
|
||||
}
|
||||
|
||||
protected final void match(TokenSet set, String msg) {
|
||||
if (!matches(set)) {
|
||||
error(msg);
|
||||
advance();
|
||||
}
|
||||
}
|
||||
|
||||
protected final void error(String s) {
|
||||
myBuilder.error(s);
|
||||
}
|
||||
|
||||
protected final void advance() {
|
||||
myBuilder.advanceLexer();
|
||||
}
|
||||
|
||||
protected final IElementType currentToken() {
|
||||
final IElementType token = myBuilder.getTokenType();
|
||||
if (isName(token)) {
|
||||
final PsiBuilder.Marker marker = myBuilder.mark();
|
||||
makeName();
|
||||
if (myBuilder.getTokenType() == LBRACKET) {
|
||||
skipAnnotation(marker, RncElementTypes.ANNOTATION_ELEMENT);
|
||||
return currentToken();
|
||||
} else {
|
||||
marker.rollbackTo();
|
||||
}
|
||||
} else if (token == LBRACKET) {
|
||||
final PsiBuilder.Marker marker = myBuilder.mark();
|
||||
skipAnnotation(marker, RncElementTypes.ANNOTATION);
|
||||
return currentToken();
|
||||
} else if (token == GTGT) {
|
||||
final PsiBuilder.Marker marker = myBuilder.mark();
|
||||
advance();
|
||||
if (isName(myBuilder.getTokenType())) {
|
||||
makeName();
|
||||
if (myBuilder.getTokenType() == LBRACKET) {
|
||||
skipAnnotation(marker, RncElementTypes.FORWARD_ANNOTATION);
|
||||
return currentToken();
|
||||
}
|
||||
}
|
||||
marker.done(RncElementTypes.FORWARD_ANNOTATION);
|
||||
return currentToken();
|
||||
}
|
||||
return token;
|
||||
}
|
||||
|
||||
protected static boolean isName(IElementType token) {
|
||||
return IDENTIFIER_OR_KEYWORD.contains(token) || token == PREFIXED_NAME;
|
||||
}
|
||||
|
||||
private void skipAnnotation(PsiBuilder.Marker marker, IElementType annotationType) {
|
||||
final boolean b = myBuilder.getTokenType() == LBRACKET;
|
||||
advance();
|
||||
assert b;
|
||||
|
||||
while (!myBuilder.eof() && currentToken() != RBRACKET) {
|
||||
advance();
|
||||
}
|
||||
if (myBuilder.getTokenType() == RBRACKET) {
|
||||
advance();
|
||||
}
|
||||
marker.done(annotationType);
|
||||
}
|
||||
|
||||
protected final void makeName() {
|
||||
final PsiBuilder.Marker name = myBuilder.mark();
|
||||
advance();
|
||||
name.done(RncElementTypes.NAME);
|
||||
}
|
||||
}
|
||||
+178
@@ -0,0 +1,178 @@
|
||||
/*
|
||||
* Copyright 2007 Sascha Weinreuter
|
||||
*
|
||||
* 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 org.intellij.plugins.relaxNG.compact.parser;
|
||||
|
||||
import org.intellij.plugins.relaxNG.compact.RncElementTypes;
|
||||
import static org.intellij.plugins.relaxNG.compact.RncTokenTypes.*;
|
||||
|
||||
import com.intellij.lang.PsiBuilder;
|
||||
import com.intellij.psi.tree.IElementType;
|
||||
|
||||
/**
|
||||
* Created by IntelliJ IDEA.
|
||||
* User: sweinreuter
|
||||
* Date: 09.08.2007
|
||||
*/
|
||||
public abstract class DeclarationParsing extends AbstractParsing {
|
||||
|
||||
public DeclarationParsing(PsiBuilder builder) {
|
||||
super(builder);
|
||||
}
|
||||
|
||||
protected void parseTopLevel() {
|
||||
while (!myBuilder.eof() && LA_DECL.contains(currentToken())) {
|
||||
parseDecl(myBuilder);
|
||||
}
|
||||
|
||||
if (LA_GRAMMAR_CONTENT.contains(currentToken())) {
|
||||
final PsiBuilder.Marker marker = myBuilder.mark();
|
||||
parseGrammarContents();
|
||||
marker.done(RncElementTypes.GRAMMAR_PATTERN);
|
||||
} else if (currentToken() == KEYWORD_GRAMMAR) {
|
||||
parsePattern();
|
||||
} else {
|
||||
final PsiBuilder.Marker marker = myBuilder.mark();
|
||||
while (!myBuilder.eof()) {
|
||||
if (!parsePattern()) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
marker.done(RncElementTypes.GRAMMAR_PATTERN);
|
||||
}
|
||||
}
|
||||
|
||||
protected abstract boolean parsePattern();
|
||||
|
||||
protected void parseGrammarContents() {
|
||||
while (LA_GRAMMAR_CONTENT.contains(currentToken())) {
|
||||
parseGrammarContent(true);
|
||||
}
|
||||
}
|
||||
|
||||
private void parseIncludeContents() {
|
||||
while (LA_INCLUDE_CONTENT.contains(currentToken())) {
|
||||
parseGrammarContent(false);
|
||||
}
|
||||
}
|
||||
|
||||
private void parseGrammarContent(boolean allowInclude) {
|
||||
final IElementType t = currentToken();
|
||||
if (t == KEYWORD_START) {
|
||||
parseStart();
|
||||
} else if (t == KEYWORD_DIV) {
|
||||
parseDiv();
|
||||
} else if (allowInclude && t == KEYWORD_INCLUDE) {
|
||||
parseInclude();
|
||||
} else if (IDENTIFIERS.contains(t)) {
|
||||
parseDefine();
|
||||
} else {
|
||||
error("Unexpected token");
|
||||
advance();
|
||||
}
|
||||
}
|
||||
|
||||
private void parseDefine() {
|
||||
final PsiBuilder.Marker marker = begin();
|
||||
match(ASSIGN_METHOD, "'=', '|=' or '&=' expected");
|
||||
if (!parsePattern()) {
|
||||
error("Pattern expected");
|
||||
}
|
||||
marker.done(RncElementTypes.DEFINE);
|
||||
}
|
||||
|
||||
private void parseInclude() {
|
||||
final PsiBuilder.Marker marker = begin();
|
||||
|
||||
parseAnyUriLiteral();
|
||||
|
||||
parseInherit();
|
||||
|
||||
if (matches(LBRACE)) {
|
||||
parseIncludeContents();
|
||||
match(RBRACE, "'}' expected");
|
||||
}
|
||||
marker.done(RncElementTypes.INCLUDE);
|
||||
}
|
||||
|
||||
protected final void parseAnyUriLiteral() {
|
||||
match(LITERAL, "URI literal expected");
|
||||
}
|
||||
|
||||
protected final void parseInherit() {
|
||||
if (matches(KEYWORD_INHERIT)) {
|
||||
match(EQ, "'=' expected");
|
||||
match(IDENTIFIER_OR_KEYWORD, "Identifier expected");
|
||||
}
|
||||
}
|
||||
|
||||
private void parseDiv() {
|
||||
final PsiBuilder.Marker marker = begin();
|
||||
parseBracedGrammarContents();
|
||||
marker.done(RncElementTypes.DIV);
|
||||
}
|
||||
|
||||
private void parseStart() {
|
||||
final PsiBuilder.Marker marker = begin();
|
||||
match(ASSIGN_METHOD, "'=', '|=' or '&=' expected");
|
||||
if (!parsePattern()) {
|
||||
error("Pattern expected");
|
||||
}
|
||||
marker.done(RncElementTypes.START);
|
||||
}
|
||||
|
||||
protected void parseBracedGrammarContents() {
|
||||
match(LBRACE, "'{' expected");
|
||||
parseGrammarContents();
|
||||
match(RBRACE, "'}' expected");
|
||||
}
|
||||
|
||||
protected void parseDecl(PsiBuilder builder) {
|
||||
final IElementType t = builder.getTokenType();
|
||||
if (t == KEYWORD_NAMESPACE) {
|
||||
parseNamespaceDecl(false);
|
||||
} else if (t == KEYWORD_DEFAULT) {
|
||||
parseNamespaceDecl(true);
|
||||
} else if (t == KEYWORD_DATATYPES) {
|
||||
parseDataTypesDecl();
|
||||
}
|
||||
}
|
||||
|
||||
private void parseDataTypesDecl() {
|
||||
final PsiBuilder.Marker marker = begin();
|
||||
match(IDENTIFIER_OR_KEYWORD, "Identifier expected");
|
||||
match(EQ, "'=' expected");
|
||||
parseNsUriLiteral();
|
||||
marker.done(RncElementTypes.DATATYPES_DECL);
|
||||
}
|
||||
|
||||
private void parseNamespaceDecl(boolean isDefault) {
|
||||
final PsiBuilder.Marker marker = begin();
|
||||
if (isDefault) {
|
||||
match(KEYWORD_NAMESPACE, "'namespace' expected");
|
||||
matches(IDENTIFIER_OR_KEYWORD);
|
||||
} else {
|
||||
match(IDENTIFIER_OR_KEYWORD, "Identifier expected");
|
||||
}
|
||||
match(EQ, "'=' expected");
|
||||
parseNsUriLiteral();
|
||||
marker.done(RncElementTypes.NS_DECL);
|
||||
}
|
||||
|
||||
private void parseNsUriLiteral() {
|
||||
match(NS_URI_LITERAL, "Namespace URI or 'inherit' expected");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,88 @@
|
||||
/*
|
||||
* Copyright 2007 Sascha Weinreuter
|
||||
*
|
||||
* 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 org.intellij.plugins.relaxNG.compact.parser;
|
||||
|
||||
import org.intellij.plugins.relaxNG.compact.RncElementTypes;
|
||||
import static org.intellij.plugins.relaxNG.compact.RncTokenTypes.*;
|
||||
|
||||
import com.intellij.lang.PsiBuilder;
|
||||
import com.intellij.psi.tree.IElementType;
|
||||
|
||||
public class NameClassParsing extends AbstractParsing {
|
||||
|
||||
public NameClassParsing(PsiBuilder builder) {
|
||||
super(builder);
|
||||
}
|
||||
|
||||
public boolean parseNameClass() {
|
||||
PsiBuilder.Marker marker = myBuilder.mark();
|
||||
|
||||
if (!parseNameClassPart()) {
|
||||
marker.drop();
|
||||
return false;
|
||||
}
|
||||
|
||||
if (currentToken() == PIPE) {
|
||||
do {
|
||||
advance();
|
||||
if (!parseNameClassPart()) {
|
||||
error("NameClass expected");
|
||||
}
|
||||
} while (currentToken() == PIPE);
|
||||
marker.done(RncElementTypes.NAME_CLASS_CHOICE);
|
||||
} else {
|
||||
marker.drop();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private boolean parseNameClassPart() {
|
||||
final IElementType t = currentToken();
|
||||
PsiBuilder.Marker marker = myBuilder.mark();
|
||||
if (IDENTIFIER_OR_KEYWORD.contains(t)) {
|
||||
advance();
|
||||
} else if (PREFIXED_NAME == t) { // CName
|
||||
makeName();
|
||||
} else if (STAR == t) { // anyName
|
||||
advance();
|
||||
parseExceptNameClass();
|
||||
} else if (PREFIXED_STAR == t) { // nsName
|
||||
makeName();
|
||||
parseExceptNameClass();
|
||||
} else if (LPAREN == t) {
|
||||
advance();
|
||||
if (parseNameClass()) {
|
||||
match(RPAREN, "')' expected");
|
||||
}
|
||||
} else {
|
||||
marker.drop();
|
||||
return false;
|
||||
}
|
||||
marker.done(RncElementTypes.NAME_CLASS);
|
||||
return true;
|
||||
}
|
||||
|
||||
private void parseExceptNameClass() {
|
||||
if (MINUS == currentToken()) {
|
||||
final PsiBuilder.Marker marker = begin();
|
||||
if (!parseNameClass()) {
|
||||
error("NameClass expected");
|
||||
}
|
||||
marker.done(RncElementTypes.EXCEPT_NAME_CLASS);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,191 @@
|
||||
/*
|
||||
* Copyright 2007 Sascha Weinreuter
|
||||
*
|
||||
* 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 org.intellij.plugins.relaxNG.compact.parser;
|
||||
|
||||
import org.intellij.plugins.relaxNG.compact.RncElementTypes;
|
||||
import static org.intellij.plugins.relaxNG.compact.RncTokenTypes.*;
|
||||
|
||||
import com.intellij.lang.PsiBuilder;
|
||||
import com.intellij.psi.tree.IElementType;
|
||||
|
||||
import gnu.trove.THashMap;
|
||||
import gnu.trove.TObjectHashingStrategy;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Created by IntelliJ IDEA.
|
||||
* User: sweinreuter
|
||||
* Date: 09.08.2007
|
||||
*/
|
||||
public class PatternParsing extends DeclarationParsing {
|
||||
|
||||
@SuppressWarnings({ "unchecked" })
|
||||
protected static final Map<IElementType, IElementType> TOKEN_MAP =
|
||||
new THashMap<IElementType, IElementType>(TObjectHashingStrategy.IDENTITY);
|
||||
|
||||
static {
|
||||
TOKEN_MAP.put(COMMA, RncElementTypes.SEQUENCE);
|
||||
TOKEN_MAP.put(PIPE, RncElementTypes.CHOICE);
|
||||
TOKEN_MAP.put(AND, RncElementTypes.INTERLEAVE);
|
||||
TOKEN_MAP.put(STAR, RncElementTypes.ZERO_OR_MORE);
|
||||
TOKEN_MAP.put(PLUS, RncElementTypes.ONE_OR_MORE);
|
||||
TOKEN_MAP.put(QUEST, RncElementTypes.OPTIONAL);
|
||||
}
|
||||
|
||||
private final NameClassParsing myNameClassParsing;
|
||||
|
||||
public PatternParsing(PsiBuilder builder) {
|
||||
super(builder);
|
||||
myNameClassParsing = new NameClassParsing(builder);
|
||||
}
|
||||
|
||||
public void parse() {
|
||||
parseTopLevel();
|
||||
}
|
||||
|
||||
protected boolean parsePattern() {
|
||||
PsiBuilder.Marker marker = myBuilder.mark();
|
||||
if (!parseQuantifiedPattern()) {
|
||||
marker.drop();
|
||||
return false;
|
||||
}
|
||||
|
||||
while (BINARY_OPS.contains(currentToken())) {
|
||||
IElementType t;
|
||||
if (BINARY_OPS.contains(t = currentToken())) {
|
||||
do {
|
||||
advance();
|
||||
if (!parseQuantifiedPattern()) {
|
||||
error("Pattern expected");
|
||||
}
|
||||
} while (currentToken() == t);
|
||||
marker.done(TOKEN_MAP.get(t));
|
||||
marker = marker.precede();
|
||||
}
|
||||
}
|
||||
marker.drop();
|
||||
return true;
|
||||
}
|
||||
|
||||
private boolean parseQuantifiedPattern() {
|
||||
final PsiBuilder.Marker marker = myBuilder.mark();
|
||||
if (!parseSinglePattern()) {
|
||||
marker.drop();
|
||||
return false;
|
||||
}
|
||||
|
||||
final IElementType t = currentToken();
|
||||
if (matches(QUANTIFIER_OPS)) {
|
||||
marker.done(TOKEN_MAP.get(t));
|
||||
} else {
|
||||
marker.drop();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private boolean parseSinglePattern() {
|
||||
final PsiBuilder.Marker marker = myBuilder.mark();
|
||||
if (matches(ATTR_OR_ELEMENT)) {
|
||||
if (!myNameClassParsing.parseNameClass()) {
|
||||
error("Name class expected");
|
||||
marker.drop();
|
||||
return false;
|
||||
}
|
||||
parseBracedPattern();
|
||||
marker.done(RncElementTypes.PATTERN);
|
||||
} else if (matches(KEYWORD_LIST)) {
|
||||
parseBracedPattern();
|
||||
marker.done(RncElementTypes.LIST_PATTERN);
|
||||
} else if (matches(KEYWORD_MIXED)) {
|
||||
parseBracedPattern();
|
||||
marker.done(RncElementTypes.MIXED_PATTERN);
|
||||
} else if (matches(KEYWORD_EXTERNAL)) {
|
||||
parseAnyUriLiteral();
|
||||
parseInherit();
|
||||
marker.done(RncElementTypes.EXTERNAL_REF);
|
||||
} else if (matches(KEYWORD_NOT_ALLOWED)) {
|
||||
marker.done(RncElementTypes.NOT_ALLOWED_PATTERN);
|
||||
} else if (matches(KEYWORD_TEXT)) {
|
||||
marker.done(RncElementTypes.TEXT_PATTERN);
|
||||
} else if (matches(KEYWORD_EMPTY)) {
|
||||
marker.done(RncElementTypes.EMPTY_PATTERN);
|
||||
} else if (matches(KEYWORD_PARENT)) {
|
||||
match(IDENTIFIERS, "Identifier expected");
|
||||
marker.done(RncElementTypes.PARENT_REF);
|
||||
} else if (matches(KEYWORD_GRAMMAR)) {
|
||||
parseBracedGrammarContents();
|
||||
marker.done(RncElementTypes.GRAMMAR_PATTERN);
|
||||
} else if (matches(LPAREN)) {
|
||||
if (!parsePattern()) {
|
||||
error("Pattern expected");
|
||||
}
|
||||
match(RPAREN, "')' expected");
|
||||
marker.done(RncElementTypes.GROUP_PATTERN);
|
||||
} else if (matches(IDENTIFIERS)) {
|
||||
marker.done(RncElementTypes.REF_PATTERN);
|
||||
} else if (matches(LA_DATATYPE)) {
|
||||
parseDatatype();
|
||||
marker.done(RncElementTypes.DATATYPE_PATTERN);
|
||||
} else if (currentToken() == PREFIXED_NAME) {
|
||||
makeName();
|
||||
parseDatatype();
|
||||
marker.done(RncElementTypes.DATATYPE_PATTERN);
|
||||
} else if (matches(LITERAL)) {
|
||||
marker.done(RncElementTypes.DATATYPE_PATTERN);
|
||||
} else {
|
||||
marker.drop();
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private void parseDatatype() {
|
||||
if (currentToken() == LITERAL) {
|
||||
advance();
|
||||
} else if (matches(LBRACE)) {
|
||||
parseParams();
|
||||
if (matches(MINUS)) {
|
||||
if (!parsePattern()) {
|
||||
error("Pattern expected");
|
||||
}
|
||||
}
|
||||
match(RBRACE, "'}' expected");
|
||||
}
|
||||
}
|
||||
|
||||
private void parseBracedPattern() {
|
||||
match(LBRACE, "'{' expected");
|
||||
if (!parsePattern()) {
|
||||
error("Pattern expected");
|
||||
}
|
||||
match(RBRACE, "'}' expected");
|
||||
}
|
||||
|
||||
private void parseParams() {
|
||||
final IElementType t = currentToken();
|
||||
if (t != RBRACE) {
|
||||
do {
|
||||
final PsiBuilder.Marker marker = myBuilder.mark();
|
||||
match(IDENTIFIER_OR_KEYWORD, "Identifier expected");
|
||||
match(EQ, "'=' expected");
|
||||
match(LITERAL, "Literal expected");
|
||||
marker.done(RncElementTypes.PARAM);
|
||||
} while (IDENTIFIER_OR_KEYWORD.contains(currentToken()));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
/*
|
||||
* Copyright 2007 Sascha Weinreuter
|
||||
*
|
||||
* 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 org.intellij.plugins.relaxNG.compact.parser;
|
||||
|
||||
import org.intellij.plugins.relaxNG.compact.RncElementTypes;
|
||||
|
||||
import com.intellij.lang.ASTNode;
|
||||
import com.intellij.lang.PsiBuilder;
|
||||
import com.intellij.lang.PsiParser;
|
||||
import com.intellij.psi.tree.IElementType;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
* Created by IntelliJ IDEA.
|
||||
* User: sweinreuter
|
||||
* Date: 07.08.2007
|
||||
*/
|
||||
public class RncParser implements PsiParser {
|
||||
|
||||
@NotNull
|
||||
public ASTNode parse(IElementType root, PsiBuilder builder) {
|
||||
final PsiBuilder.Marker fileMarker = builder.mark();
|
||||
final PsiBuilder.Marker docMarker = builder.mark();
|
||||
|
||||
new PatternParsing(builder).parse();
|
||||
|
||||
while (!builder.eof()) {
|
||||
builder.error("Unexpected token");
|
||||
builder.advanceLexer();
|
||||
}
|
||||
|
||||
docMarker.done(RncElementTypes.DOCUMENT);
|
||||
fileMarker.done(root);
|
||||
return builder.getTreeBuilt();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
/*
|
||||
* Copyright 2007 Sascha Weinreuter
|
||||
*
|
||||
* 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 org.intellij.plugins.relaxNG.compact.psi;
|
||||
|
||||
import com.intellij.psi.PsiComment;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
/*
|
||||
* Created by IntelliJ IDEA.
|
||||
* User: sweinreuter
|
||||
* Date: 24.08.2007
|
||||
*/
|
||||
public interface RncAnnotation extends RncElement, PsiComment {
|
||||
@Nullable
|
||||
RncName getNameElement();
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
/*
|
||||
* Copyright 2007 Sascha Weinreuter
|
||||
*
|
||||
* 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 org.intellij.plugins.relaxNG.compact.psi;
|
||||
|
||||
import com.intellij.psi.PsiNamedElement;
|
||||
|
||||
/**
|
||||
* Created by IntelliJ IDEA.
|
||||
* User: sweinreuter
|
||||
* Date: 16.08.2007
|
||||
*/
|
||||
public interface RncDecl extends RncElement, PsiNamedElement {
|
||||
String getPrefix();
|
||||
|
||||
String getDeclaredNamespace();
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
/*
|
||||
* Copyright 2007 Sascha Weinreuter
|
||||
*
|
||||
* 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 org.intellij.plugins.relaxNG.compact.psi;
|
||||
|
||||
import org.intellij.plugins.relaxNG.model.Define;
|
||||
|
||||
import com.intellij.psi.PsiNamedElement;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
/**
|
||||
* Created by IntelliJ IDEA.
|
||||
* User: sweinreuter
|
||||
* Date: 13.08.2007
|
||||
*/
|
||||
public interface RncDefine extends RncPattern, PsiNamedElement, Define<RncPattern, RncElement> {
|
||||
@Nullable
|
||||
RncPattern getPattern();
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
/*
|
||||
* Copyright 2007 Sascha Weinreuter
|
||||
*
|
||||
* 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 org.intellij.plugins.relaxNG.compact.psi;
|
||||
|
||||
import org.intellij.plugins.relaxNG.model.Div;
|
||||
|
||||
/*
|
||||
* Created by IntelliJ IDEA.
|
||||
* User: sweinreuter
|
||||
* Date: 24.08.2007
|
||||
*/
|
||||
public interface RncDiv extends RncElement, Div<RncElement> {
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
/*
|
||||
* Copyright 2007 Sascha Weinreuter
|
||||
*
|
||||
* 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 org.intellij.plugins.relaxNG.compact.psi;
|
||||
|
||||
import com.intellij.psi.PsiElement;
|
||||
|
||||
/**
|
||||
* Created by IntelliJ IDEA.
|
||||
* User: sweinreuter
|
||||
* Date: 10.08.2007
|
||||
*/
|
||||
public interface RncElement extends PsiElement {
|
||||
}
|
||||
@@ -0,0 +1,76 @@
|
||||
/*
|
||||
* Copyright 2007 Sascha Weinreuter
|
||||
*
|
||||
* 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 org.intellij.plugins.relaxNG.compact.psi;
|
||||
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.PsiElementVisitor;
|
||||
|
||||
public class RncElementVisitor extends PsiElementVisitor {
|
||||
|
||||
@Override
|
||||
public final void visitElement(PsiElement element) {
|
||||
if (element instanceof RncElement) {
|
||||
visitElement((RncElement)element);
|
||||
} else {
|
||||
superVisitElement(element);
|
||||
}
|
||||
}
|
||||
|
||||
protected void superVisitElement(PsiElement element) {
|
||||
super.visitElement(element);
|
||||
}
|
||||
|
||||
public void visitElement(RncElement element) {
|
||||
super.visitElement(element);
|
||||
}
|
||||
|
||||
public void visitInclude(RncInclude include) {
|
||||
visitElement(include);
|
||||
}
|
||||
|
||||
public void visitDiv(RncDiv div) {
|
||||
visitElement(div);
|
||||
}
|
||||
|
||||
public void visitRef(RncRef pattern) {
|
||||
visitElement(pattern);
|
||||
}
|
||||
|
||||
public void visitParentRef(RncParentRef pattern) {
|
||||
visitElement(pattern);
|
||||
}
|
||||
|
||||
public void visitDefine(RncDefine pattern) {
|
||||
visitElement(pattern);
|
||||
}
|
||||
|
||||
public void visitGrammar(RncGrammar pattern) {
|
||||
visitElement(pattern);
|
||||
}
|
||||
|
||||
public void visitName(RncName name) {
|
||||
visitElement(name);
|
||||
}
|
||||
|
||||
public void visitAnnotation(RncAnnotation annotation) {
|
||||
visitElement(annotation);
|
||||
}
|
||||
|
||||
public void visitExternalRef(RncExternalRef ref) {
|
||||
visitElement(ref);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
/*
|
||||
* Copyright 2007 Sascha Weinreuter
|
||||
*
|
||||
* 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 org.intellij.plugins.relaxNG.compact.psi;
|
||||
|
||||
/**
|
||||
* Created by IntelliJ IDEA.
|
||||
* User: sweinreuter
|
||||
* Date: 11.08.2007
|
||||
*/
|
||||
public interface RncExternalRef extends RncFileReference {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
/*
|
||||
* Copyright 2007 Sascha Weinreuter
|
||||
*
|
||||
* 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 org.intellij.plugins.relaxNG.compact.psi;
|
||||
|
||||
import com.intellij.psi.PsiFile;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
/**
|
||||
* Created by IntelliJ IDEA.
|
||||
* User: sweinreuter
|
||||
* Date: 11.08.2007
|
||||
*/
|
||||
public interface RncFile extends PsiFile {
|
||||
RncDecl[] getDeclarations();
|
||||
|
||||
@Nullable
|
||||
RncGrammar getGrammar();
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
/*
|
||||
* Copyright 2007 Sascha Weinreuter
|
||||
*
|
||||
* 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 org.intellij.plugins.relaxNG.compact.psi;
|
||||
|
||||
import com.intellij.openapi.util.TextRange;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
/**
|
||||
* Created by IntelliJ IDEA.
|
||||
* User: sweinreuter
|
||||
* Date: 29.08.2007
|
||||
*/
|
||||
public interface RncFileReference extends RncElement {
|
||||
@Nullable
|
||||
RncFile getReferencedFile();
|
||||
|
||||
@Nullable
|
||||
String getFileReference();
|
||||
|
||||
TextRange getReferenceRange();
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
/*
|
||||
* Copyright 2007 Sascha Weinreuter
|
||||
*
|
||||
* 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 org.intellij.plugins.relaxNG.compact.psi;
|
||||
|
||||
import org.intellij.plugins.relaxNG.model.Grammar;
|
||||
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
/**
|
||||
* Created by IntelliJ IDEA.
|
||||
* User: sweinreuter
|
||||
* Date: 13.08.2007
|
||||
*/
|
||||
public interface RncGrammar extends RncElement, Grammar<RncPattern, RncElement> {
|
||||
@Nullable
|
||||
RncPattern getStart();
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
/*
|
||||
* Copyright 2007 Sascha Weinreuter
|
||||
*
|
||||
* 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 org.intellij.plugins.relaxNG.compact.psi;
|
||||
|
||||
import org.intellij.plugins.relaxNG.model.Include;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
* Created by IntelliJ IDEA.
|
||||
* User: sweinreuter
|
||||
* Date: 11.08.2007
|
||||
*/
|
||||
public interface RncInclude extends RncFileReference, Include<RncElement, RncDefine> {
|
||||
@NotNull
|
||||
RncDefine[] getOverrides();
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
/*
|
||||
* Copyright 2007 Sascha Weinreuter
|
||||
*
|
||||
* 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 org.intellij.plugins.relaxNG.compact.psi;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
/**
|
||||
* Created by IntelliJ IDEA.
|
||||
* User: sweinreuter
|
||||
* Date: 14.08.2007
|
||||
*/
|
||||
public interface RncName extends RncElement {
|
||||
@Nullable
|
||||
String getPrefix();
|
||||
|
||||
@NotNull
|
||||
String getLocalPart();
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
/*
|
||||
* Copyright 2007 Sascha Weinreuter
|
||||
*
|
||||
* 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 org.intellij.plugins.relaxNG.compact.psi;
|
||||
|
||||
/**
|
||||
* Created by IntelliJ IDEA.
|
||||
* User: sweinreuter
|
||||
* Date: 14.08.2007
|
||||
*/
|
||||
public interface RncNsDecl extends RncDecl {
|
||||
boolean isDefault();
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
/*
|
||||
* Copyright 2007 Sascha Weinreuter
|
||||
*
|
||||
* 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 org.intellij.plugins.relaxNG.compact.psi;
|
||||
|
||||
/**
|
||||
* Created by IntelliJ IDEA.
|
||||
* User: sweinreuter
|
||||
* Date: 13.08.2007
|
||||
*/
|
||||
public interface RncParentRef extends RncRef {
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
/*
|
||||
* Copyright 2007 Sascha Weinreuter
|
||||
*
|
||||
* 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 org.intellij.plugins.relaxNG.compact.psi;
|
||||
|
||||
import org.intellij.plugins.relaxNG.model.Pattern;
|
||||
|
||||
/**
|
||||
* Created by IntelliJ IDEA.
|
||||
* User: sweinreuter
|
||||
* Date: 05.09.2007
|
||||
*/
|
||||
public interface RncPattern extends RncElement, Pattern<RncElement> {
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
/*
|
||||
* Copyright 2007 Sascha Weinreuter
|
||||
*
|
||||
* 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 org.intellij.plugins.relaxNG.compact.psi;
|
||||
|
||||
import org.intellij.plugins.relaxNG.model.Ref;
|
||||
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
/**
|
||||
* Created by IntelliJ IDEA.
|
||||
* User: sweinreuter
|
||||
* Date: 11.08.2007
|
||||
*/
|
||||
public interface RncRef extends RncPattern, Ref<RncDefine, RncElement> {
|
||||
@Nullable
|
||||
RncDefine getPattern();
|
||||
|
||||
@Nullable
|
||||
String getReferencedName();
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
/*
|
||||
* Copyright 2007 Sascha Weinreuter
|
||||
*
|
||||
* 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 org.intellij.plugins.relaxNG.compact.psi.impl;
|
||||
|
||||
import org.intellij.plugins.relaxNG.compact.psi.RncFile;
|
||||
|
||||
import com.intellij.openapi.util.Key;
|
||||
|
||||
/**
|
||||
* Created by IntelliJ IDEA.
|
||||
* User: sweinreuter
|
||||
* Date: 13.08.2007
|
||||
*/
|
||||
public interface FollowFileHint {
|
||||
Key<FollowFileHint> KEY = Key.create("FollowFileHint");
|
||||
|
||||
public boolean doFollow(RncFile file);
|
||||
}
|
||||
+227
@@ -0,0 +1,227 @@
|
||||
/*
|
||||
* Copyright 2007 Sascha Weinreuter
|
||||
*
|
||||
* 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 org.intellij.plugins.relaxNG.compact.psi.impl;
|
||||
|
||||
import org.intellij.plugins.relaxNG.compact.RncFileType;
|
||||
import org.intellij.plugins.relaxNG.compact.RncTokenTypes;
|
||||
import org.intellij.plugins.relaxNG.compact.psi.*;
|
||||
import org.intellij.plugins.relaxNG.compact.psi.util.EscapeUtil;
|
||||
import org.intellij.plugins.relaxNG.compact.psi.util.RenameUtil;
|
||||
import org.intellij.plugins.relaxNG.model.Define;
|
||||
import org.intellij.plugins.relaxNG.model.resolve.DefinitionResolver;
|
||||
|
||||
import com.intellij.codeInsight.daemon.EmptyResolveMessageProvider;
|
||||
import com.intellij.codeInsight.daemon.QuickFixProvider;
|
||||
import com.intellij.codeInsight.daemon.impl.HighlightInfo;
|
||||
import com.intellij.codeInsight.daemon.impl.quickfix.QuickFixAction;
|
||||
import com.intellij.codeInsight.intention.IntentionAction;
|
||||
import com.intellij.lang.ASTNode;
|
||||
import com.intellij.openapi.editor.Editor;
|
||||
import com.intellij.openapi.editor.ScrollType;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.TextRange;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import com.intellij.util.ArrayUtil;
|
||||
import com.intellij.util.Function;
|
||||
import com.intellij.util.IncorrectOperationException;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* Created by IntelliJ IDEA.
|
||||
* User: sweinreuter
|
||||
* Date: 13.08.2007
|
||||
*/
|
||||
class PatternReference extends PsiReferenceBase.Poly<RncRef> implements Function<Define, ResolveResult>,
|
||||
QuickFixProvider<PatternReference>, EmptyResolveMessageProvider {
|
||||
|
||||
public PatternReference(RncRef ref) {
|
||||
super(ref);
|
||||
}
|
||||
|
||||
public TextRange getRangeInElement() {
|
||||
final ASTNode node = findNameNode();
|
||||
if (node == null) return TextRange.from(0, 0);
|
||||
final int offset = myElement.getTextOffset();
|
||||
return TextRange.from(offset - myElement.getTextRange().getStartOffset(), node.getTextLength());
|
||||
}
|
||||
|
||||
private ASTNode findNameNode() {
|
||||
final ASTNode node = myElement.getNode();
|
||||
assert node != null;
|
||||
return node.findChildByType(RncTokenTypes.IDENTIFIERS);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public PsiElement resolve() {
|
||||
final ResolveResult[] results = multiResolve(false);
|
||||
return results.length == 1 ? results[0].getElement() : null;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public ResolveResult[] multiResolve(boolean incompleteCode) {
|
||||
final RncGrammar scope = getScope();
|
||||
if (scope == null) {
|
||||
return ResolveResult.EMPTY_ARRAY;
|
||||
}
|
||||
|
||||
final Set<Define> set = DefinitionResolver.resolve(scope, getCanonicalText());
|
||||
if (set == null || set.size() == 0) return ResolveResult.EMPTY_ARRAY;
|
||||
|
||||
return ContainerUtil.map2Array(set, ResolveResult.class, this);
|
||||
}
|
||||
|
||||
public ResolveResult fun(Define rncDefine) {
|
||||
final PsiElement element = rncDefine.getPsiElement();
|
||||
return element != null ? new PsiElementResolveResult(element) : new ResolveResult() {
|
||||
@Nullable
|
||||
public PsiElement getElement() {
|
||||
return null;
|
||||
}
|
||||
public boolean isValidResult() {
|
||||
return false;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Nullable
|
||||
protected RncGrammar getScope() {
|
||||
return PsiTreeUtil.getParentOfType(myElement, RncGrammar.class, true, PsiFile.class);
|
||||
}
|
||||
|
||||
public String getCanonicalText() {
|
||||
final ASTNode node = findNameNode();
|
||||
return node != null ? EscapeUtil.unescapeText(node) : "";
|
||||
}
|
||||
|
||||
public PsiElement handleElementRename(String newElementName) throws IncorrectOperationException {
|
||||
final ASTNode newNode = RenameUtil.createIdentifierNode(getElement().getManager(), newElementName);
|
||||
|
||||
final ASTNode nameNode = findNameNode();
|
||||
nameNode.getTreeParent().replaceChild(nameNode, newNode);
|
||||
return getElement();
|
||||
}
|
||||
|
||||
public PsiElement bindToElement(@NotNull PsiElement element) throws IncorrectOperationException {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public Object[] getVariants() {
|
||||
final RncGrammar scope = getScope();
|
||||
if (scope == null) {
|
||||
return ResolveResult.EMPTY_ARRAY;
|
||||
}
|
||||
|
||||
final Map<String, Set<Define>> map = DefinitionResolver.getAllVariants(scope);
|
||||
if (map == null || map.size() == 0) return ArrayUtil.EMPTY_OBJECT_ARRAY;
|
||||
|
||||
return ContainerUtil.mapNotNull(map.values(), new Function<Set<Define>, Object>() {
|
||||
public Object fun(Set<Define> defines) {
|
||||
return defines.size() == 0 ? null : defines.iterator().next().getPsiElement();
|
||||
}
|
||||
}).toArray();
|
||||
}
|
||||
|
||||
public boolean isSoft() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public String getUnresolvedMessagePattern() {
|
||||
return "Unresolved pattern reference ''{0}''";
|
||||
}
|
||||
|
||||
public void registerQuickfix(HighlightInfo info, final PatternReference reference) {
|
||||
if (reference.getScope() == null) {
|
||||
return;
|
||||
}
|
||||
QuickFixAction.registerQuickFixAction(info, new CreatePatternFix(reference));
|
||||
}
|
||||
|
||||
static class CreatePatternFix implements IntentionAction {
|
||||
private final PatternReference myReference;
|
||||
|
||||
public CreatePatternFix(PatternReference reference) {
|
||||
myReference = reference;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public String getText() {
|
||||
return "Create Pattern '" + myReference.getCanonicalText() + "'";
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public String getFamilyName() {
|
||||
return "Create Pattern";
|
||||
}
|
||||
|
||||
public boolean isAvailable(@NotNull Project project, Editor editor, PsiFile file) {
|
||||
return myReference.getElement().isValid() && myReference.getScope() != null;
|
||||
}
|
||||
|
||||
public void invoke(@NotNull Project project, Editor editor, PsiFile file) throws IncorrectOperationException {
|
||||
final RncFile rncfile = (RncFile)PsiFileFactory.getInstance(myReference.getElement().getProject()).createFileFromText("dummy.rnc", RncFileType.getInstance(), "dummy = xxx");
|
||||
|
||||
final RncGrammar grammar = rncfile.getGrammar();
|
||||
assert grammar != null;
|
||||
|
||||
final RncDefine def = (RncDefine)grammar.getFirstChild();
|
||||
|
||||
final RncGrammar scope = myReference.getScope();
|
||||
assert scope != null;
|
||||
|
||||
assert def != null;
|
||||
final RncDefine e = (RncDefine)scope.add(def);
|
||||
|
||||
// ensures proper escaping (start -> \start)
|
||||
def.setName(myReference.getCanonicalText());
|
||||
|
||||
final SmartPsiElementPointer<RncDefine> p = SmartPointerManager.getInstance(project).createSmartPsiElementPointer(e);
|
||||
|
||||
final ASTNode blockNode = e.getParent().getNode();
|
||||
assert blockNode != null;
|
||||
|
||||
final ASTNode newNode = e.getNode();
|
||||
assert newNode != null;
|
||||
|
||||
e.getManager().getCodeStyleManager().reformatNewlyAddedElement(blockNode, newNode);
|
||||
|
||||
PsiDocumentManager.getInstance(project).doPostponedOperationsAndUnblockDocument(editor.getDocument());
|
||||
|
||||
final RncDefine d = p.getElement();
|
||||
assert d != null;
|
||||
|
||||
final RncElement definition = d.getPattern();
|
||||
assert definition != null;
|
||||
|
||||
final int offset = definition.getTextRange().getStartOffset();
|
||||
|
||||
editor.getCaretModel().moveToOffset(offset);
|
||||
editor.getScrollingModel().scrollToCaret(ScrollType.MAKE_VISIBLE);
|
||||
editor.getDocument().deleteString(offset, definition.getTextRange().getEndOffset());
|
||||
}
|
||||
|
||||
public boolean startInWriteAction() {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
+50
@@ -0,0 +1,50 @@
|
||||
/*
|
||||
* Copyright 2007 Sascha Weinreuter
|
||||
*
|
||||
* 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 org.intellij.plugins.relaxNG.compact.psi.impl;
|
||||
|
||||
import org.intellij.plugins.relaxNG.compact.psi.RncAnnotation;
|
||||
import org.intellij.plugins.relaxNG.compact.psi.RncElementVisitor;
|
||||
import org.intellij.plugins.relaxNG.compact.psi.RncName;
|
||||
|
||||
import com.intellij.lang.ASTNode;
|
||||
import com.intellij.psi.tree.IElementType;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
/*
|
||||
* Created by IntelliJ IDEA.
|
||||
* User: sweinreuter
|
||||
* Date: 24.08.2007
|
||||
*/
|
||||
public class RncAnnotationImpl extends RncElementImpl implements RncAnnotation {
|
||||
public RncAnnotationImpl(ASTNode node) {
|
||||
super(node);
|
||||
}
|
||||
|
||||
public void accept(@NotNull RncElementVisitor visitor) {
|
||||
visitor.visitAnnotation(this);
|
||||
}
|
||||
|
||||
public IElementType getTokenType() {
|
||||
return getNode().getElementType();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public RncName getNameElement() {
|
||||
return findChildByClass(RncName.class);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,88 @@
|
||||
/*
|
||||
* Copyright 2007 Sascha Weinreuter
|
||||
*
|
||||
* 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 org.intellij.plugins.relaxNG.compact.psi.impl;
|
||||
|
||||
import org.intellij.plugins.relaxNG.compact.RncTokenTypes;
|
||||
import org.intellij.plugins.relaxNG.compact.psi.RncDecl;
|
||||
import org.intellij.plugins.relaxNG.compact.psi.RncElementVisitor;
|
||||
import org.intellij.plugins.relaxNG.compact.psi.util.EscapeUtil;
|
||||
import org.intellij.plugins.relaxNG.compact.psi.util.RenameUtil;
|
||||
|
||||
import com.intellij.lang.ASTNode;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.util.IncorrectOperationException;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
* Created by IntelliJ IDEA.
|
||||
* User: sweinreuter
|
||||
* Date: 16.08.2007
|
||||
*/
|
||||
public class RncDeclImpl extends RncElementImpl implements RncDecl {
|
||||
public RncDeclImpl(ASTNode node) {
|
||||
super(node);
|
||||
}
|
||||
|
||||
public String getPrefix() {
|
||||
final ASTNode ns = findIdentifierNode();
|
||||
return ns != null ? EscapeUtil.unescapeText(ns) : null;
|
||||
}
|
||||
|
||||
public String getDeclaredNamespace() {
|
||||
final ASTNode ns = getNode().findChildByType(RncTokenTypes.LITERAL);
|
||||
return ns != null ? EscapeUtil.parseLiteralValue(ns) : null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getTextOffset() {
|
||||
final ASTNode ns = findIdentifierNode();
|
||||
if (ns != null) {
|
||||
return ns.getStartOffset();
|
||||
}
|
||||
return super.getTextOffset();
|
||||
}
|
||||
|
||||
private ASTNode findIdentifierNode() {
|
||||
// namespace text = "..." is valid - "text" is parsed as a keyword though
|
||||
final ASTNode node = getNode().findChildByType(RncTokenTypes.IDENTIFIERS);
|
||||
if (node == null) {
|
||||
final ASTNode[] nodes = getNode().getChildren(RncTokenTypes.KEYWORDS);
|
||||
if (nodes.length > 1) {
|
||||
return nodes[1];
|
||||
}
|
||||
}
|
||||
return node;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
final String s = getPrefix();
|
||||
return s != null ? s : "";
|
||||
}
|
||||
|
||||
public PsiElement setName(@NonNls @NotNull String name) throws IncorrectOperationException {
|
||||
final ASTNode node = findIdentifierNode();
|
||||
if (node == null) return this;
|
||||
node.getTreeParent().replaceChild(node, RenameUtil.createIdentifierNode(getManager(), name));
|
||||
return this;
|
||||
}
|
||||
|
||||
public void accept(@NotNull RncElementVisitor visitor) {
|
||||
visitor.visitElement(this);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,171 @@
|
||||
/*
|
||||
* Copyright 2007 Sascha Weinreuter
|
||||
*
|
||||
* 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 org.intellij.plugins.relaxNG.compact.psi.impl;
|
||||
|
||||
import com.intellij.lang.ASTNode;
|
||||
import com.intellij.openapi.util.IconLoader;
|
||||
import com.intellij.openapi.util.Iconable;
|
||||
import com.intellij.openapi.util.TextRange;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.PsiReference;
|
||||
import com.intellij.psi.PsiReferenceBase;
|
||||
import com.intellij.psi.meta.PsiMetaData;
|
||||
import com.intellij.psi.meta.PsiMetaOwner;
|
||||
import com.intellij.psi.meta.PsiPresentableMetaData;
|
||||
import com.intellij.util.ArrayUtil;
|
||||
import com.intellij.util.IncorrectOperationException;
|
||||
import org.intellij.plugins.relaxNG.compact.RncTokenTypes;
|
||||
import org.intellij.plugins.relaxNG.compact.psi.*;
|
||||
import org.intellij.plugins.relaxNG.compact.psi.util.EscapeUtil;
|
||||
import org.intellij.plugins.relaxNG.compact.psi.util.RenameUtil;
|
||||
import org.intellij.plugins.relaxNG.model.Define;
|
||||
import org.intellij.plugins.relaxNG.model.resolve.DefinitionResolver;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* Created by IntelliJ IDEA.
|
||||
* User: sweinreuter
|
||||
* Date: 13.08.2007
|
||||
*/
|
||||
public class RncDefineImpl extends RncElementImpl implements RncDefine, PsiMetaOwner {
|
||||
public RncDefineImpl(ASTNode node) {
|
||||
super(node);
|
||||
}
|
||||
|
||||
public void accept(@NotNull RncElementVisitor visitor) {
|
||||
visitor.visitDefine(this);
|
||||
}
|
||||
|
||||
public void accept(Visitor visitor) {
|
||||
visitor.visitDefine(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
final ASTNode node = getNameNode();
|
||||
return EscapeUtil.unescapeText(node);
|
||||
}
|
||||
|
||||
public PsiElement getNameElement() {
|
||||
return getNameNode().getPsi();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public ASTNode getNameNode() {
|
||||
final ASTNode node = getNode().findChildByType(RncTokenTypes.IDENTIFIERS);
|
||||
assert node != null;
|
||||
return node;
|
||||
}
|
||||
|
||||
public PsiElement setName(@NonNls @NotNull String name) throws IncorrectOperationException {
|
||||
final ASTNode node = getNameNode();
|
||||
node.getTreeParent().replaceChild(node, RenameUtil.createIdentifierNode(getManager(), name));
|
||||
return this;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public RncPattern getPattern() {
|
||||
return findChildByClass(RncPattern.class);
|
||||
}
|
||||
|
||||
public PsiReference getReference() {
|
||||
if (getParent() instanceof RncInclude) {
|
||||
final TextRange range = TextRange.from(0, getNameNode().getTextLength());
|
||||
return new PsiReferenceBase<RncDefine>(this, range, true) {
|
||||
public PsiElement resolve() {
|
||||
return RncDefineImpl.this;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public Object[] getVariants() {
|
||||
final RncInclude parent = (RncInclude)getParent();
|
||||
final RncFile referencedFile = parent.getReferencedFile();
|
||||
if (referencedFile == null) {
|
||||
return EMPTY_ARRAY;
|
||||
}
|
||||
final RncGrammar grammar = referencedFile.getGrammar();
|
||||
if (grammar == null) {
|
||||
return EMPTY_ARRAY;
|
||||
}
|
||||
|
||||
final Map<String, Set<Define>> map = DefinitionResolver.getAllVariants(grammar);
|
||||
if (map != null) {
|
||||
return map.keySet().toArray();
|
||||
}
|
||||
return EMPTY_ARRAY;
|
||||
}
|
||||
};
|
||||
}
|
||||
return super.getReference();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public Icon getIcon(int flags) {
|
||||
return IconLoader.findIcon("/nodes/property.png");
|
||||
}
|
||||
|
||||
public boolean isMetaEnough() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public PsiMetaData getMetaData() {
|
||||
return new MyMetaData();
|
||||
}
|
||||
|
||||
private class MyMetaData implements PsiMetaData, PsiPresentableMetaData {
|
||||
/*public boolean processDeclarations(PsiElement context, PsiScopeProcessor processor, PsiSubstitutor substitutor, PsiElement lastElement, PsiElement place) {
|
||||
return false;
|
||||
}*/
|
||||
|
||||
@Nullable
|
||||
public Icon getIcon() {
|
||||
return RncDefineImpl.this.getIcon(Iconable.ICON_FLAG_CLOSED);
|
||||
}
|
||||
|
||||
public String getTypeName() {
|
||||
return "Pattern Definition";
|
||||
}
|
||||
|
||||
public PsiElement getDeclaration() {
|
||||
return RncDefineImpl.this;
|
||||
}
|
||||
|
||||
@NonNls
|
||||
public String getName(PsiElement context) {
|
||||
return RncDefineImpl.this.getName();
|
||||
}
|
||||
|
||||
@NonNls
|
||||
public String getName() {
|
||||
return RncDefineImpl.this.getName();
|
||||
}
|
||||
|
||||
public void init(PsiElement element) {
|
||||
}
|
||||
|
||||
public Object[] getDependences() {
|
||||
return ArrayUtil.EMPTY_OBJECT_ARRAY;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
/*
|
||||
* Copyright 2007 Sascha Weinreuter
|
||||
*
|
||||
* 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 org.intellij.plugins.relaxNG.compact.psi.impl;
|
||||
|
||||
import org.intellij.plugins.relaxNG.compact.psi.RncDiv;
|
||||
import org.intellij.plugins.relaxNG.compact.psi.RncElementVisitor;
|
||||
|
||||
import com.intellij.lang.ASTNode;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/*
|
||||
* Created by IntelliJ IDEA.
|
||||
* User: sweinreuter
|
||||
* Date: 24.08.2007
|
||||
*/
|
||||
public class RncDivImpl extends RncElementImpl implements RncDiv {
|
||||
public RncDivImpl(ASTNode node) {
|
||||
super(node);
|
||||
}
|
||||
|
||||
public void accept(@NotNull RncElementVisitor visitor) {
|
||||
visitor.visitDiv(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void accept(Visitor visitor) {
|
||||
visitor.visitDiv(this);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,82 @@
|
||||
/*
|
||||
* Copyright 2007 Sascha Weinreuter
|
||||
*
|
||||
* 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 org.intellij.plugins.relaxNG.compact.psi.impl;
|
||||
|
||||
import org.intellij.plugins.relaxNG.compact.psi.RncElementVisitor;
|
||||
import org.intellij.plugins.relaxNG.compact.psi.RncGrammar;
|
||||
|
||||
import com.intellij.lang.ASTNode;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.impl.meta.MetaRegistry;
|
||||
import com.intellij.psi.meta.PsiMetaData;
|
||||
import com.intellij.psi.search.PsiElementProcessor;
|
||||
import com.intellij.psi.xml.XmlDocument;
|
||||
import com.intellij.psi.xml.XmlProlog;
|
||||
import com.intellij.psi.xml.XmlTag;
|
||||
import com.intellij.xml.XmlNSDescriptor;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
public class RncDocument extends RncElementImpl implements XmlDocument {
|
||||
public RncDocument(ASTNode node) {
|
||||
super(node);
|
||||
}
|
||||
|
||||
public XmlNSDescriptor getDefaultNSDescriptor(String namespace, boolean strict) {
|
||||
return null;
|
||||
}
|
||||
|
||||
public XmlProlog getProlog() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public XmlTag getRootTag() {
|
||||
return null;
|
||||
}
|
||||
|
||||
public XmlNSDescriptor getRootTagNSDescriptor() {
|
||||
return null;
|
||||
}
|
||||
|
||||
public boolean processElements(PsiElementProcessor processor, PsiElement place) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public PsiMetaData getMetaData() {
|
||||
return MetaRegistry.getMeta(this);
|
||||
}
|
||||
|
||||
public boolean isMetaEnough() {
|
||||
return true;
|
||||
}
|
||||
|
||||
public RncGrammar getGrammar() {
|
||||
return findChildByClass(RncGrammar.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
protected <T> T[] findChildrenByClass(Class<T> aClass) {
|
||||
return super.findChildrenByClass(aClass);
|
||||
}
|
||||
|
||||
public void accept(@NotNull RncElementVisitor visitor) {
|
||||
visitor.visitElement(this);
|
||||
}
|
||||
}
|
||||
+138
@@ -0,0 +1,138 @@
|
||||
/*
|
||||
* Copyright 2007 Sascha Weinreuter
|
||||
*
|
||||
* 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 org.intellij.plugins.relaxNG.compact.psi.impl;
|
||||
|
||||
import org.intellij.plugins.relaxNG.compact.RncElementTypes;
|
||||
import org.intellij.plugins.relaxNG.compact.psi.RncElement;
|
||||
import org.intellij.plugins.relaxNG.compact.psi.RncElementVisitor;
|
||||
import org.intellij.plugins.relaxNG.model.CommonElement;
|
||||
|
||||
import com.intellij.extapi.psi.ASTWrapperPsiElement;
|
||||
import com.intellij.lang.ASTNode;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.PsiElementVisitor;
|
||||
import com.intellij.psi.ResolveState;
|
||||
import com.intellij.psi.scope.PsiScopeProcessor;
|
||||
import com.intellij.psi.tree.TokenSet;
|
||||
import com.intellij.util.IncorrectOperationException;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public abstract class RncElementImpl extends ASTWrapperPsiElement implements RncElement, CommonElement<RncElement> {
|
||||
private static final TokenSet GRAMMAR_CONTENT = TokenSet.create(
|
||||
RncElementTypes.START,
|
||||
RncElementTypes.DEFINE, RncElementTypes.DIV,
|
||||
RncElementTypes.GRAMMAR_PATTERN, RncElementTypes.PATTERN,
|
||||
RncElementTypes.INCLUDE
|
||||
);
|
||||
|
||||
public RncElementImpl(ASTNode node) {
|
||||
super(node);
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return getNode().getElementType().toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void delete() throws IncorrectOperationException {
|
||||
getNode().getTreeParent().removeChild(getNode());
|
||||
}
|
||||
|
||||
@Override
|
||||
public PsiElement add(@NotNull PsiElement psiElement) throws IncorrectOperationException {
|
||||
final ASTNode astNode = psiElement.getNode();
|
||||
assert astNode != null;
|
||||
|
||||
getNode().addChild(astNode);
|
||||
final PsiElement r = getNode().getLastChildNode().getPsi();
|
||||
|
||||
assert r.getClass() == psiElement.getClass();
|
||||
return r;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PsiElement addBefore(@NotNull PsiElement psiElement, PsiElement anchor) throws IncorrectOperationException {
|
||||
final ASTNode child = psiElement.getNode();
|
||||
assert child != null;
|
||||
|
||||
final ASTNode anchorNode = anchor.getNode();
|
||||
assert anchorNode != null;
|
||||
|
||||
getNode().addChild(child, anchorNode);
|
||||
final PsiElement r = anchorNode.getTreePrev().getPsi();
|
||||
|
||||
assert r.getClass() == psiElement.getClass();
|
||||
return r;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PsiElement addAfter(@NotNull PsiElement element, PsiElement anchor) throws IncorrectOperationException {
|
||||
final ASTNode astNode = anchor.getNode();
|
||||
assert astNode != null;
|
||||
|
||||
final ASTNode node = astNode.getTreeNext();
|
||||
if (node == null) {
|
||||
return add(element);
|
||||
} else {
|
||||
return addBefore(element, node.getPsi());
|
||||
}
|
||||
}
|
||||
|
||||
public final void accept(@NotNull PsiElementVisitor visitor) {
|
||||
if (visitor instanceof RncElementVisitor) {
|
||||
accept((RncElementVisitor)visitor);
|
||||
} else {
|
||||
visitor.visitElement(this);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean processDeclarations(@NotNull PsiScopeProcessor processor, @NotNull ResolveState substitutor, PsiElement lastParent, @NotNull PsiElement place) {
|
||||
final ASTNode astNode = getNode();
|
||||
|
||||
final ASTNode[] children = astNode.getChildren(GRAMMAR_CONTENT);
|
||||
processor.handleEvent(PsiScopeProcessor.Event.SET_DECLARATION_HOLDER, this);
|
||||
for (ASTNode element : children) {
|
||||
if (!processor.execute(element.getPsi(), substitutor)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
processor.handleEvent(PsiScopeProcessor.Event.SET_DECLARATION_HOLDER, null);
|
||||
return true;
|
||||
}
|
||||
|
||||
public abstract void accept(@NotNull RncElementVisitor visitor);
|
||||
|
||||
public void accept(Visitor visitor) {
|
||||
visitor.visitElement(this);
|
||||
}
|
||||
|
||||
public void acceptChildren(Visitor visitor) {
|
||||
final PsiElement[] elements = getChildren();
|
||||
//noinspection ForLoopReplaceableByForEach
|
||||
for (int i = 0; i < elements.length; i++) {
|
||||
PsiElement element = elements[i];
|
||||
if (element instanceof CommonElement) {
|
||||
((CommonElement)element).accept(visitor);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public RncElement getPsiElement() {
|
||||
return this;
|
||||
}
|
||||
}
|
||||
+38
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
* Copyright 2007 Sascha Weinreuter
|
||||
*
|
||||
* 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 org.intellij.plugins.relaxNG.compact.psi.impl;
|
||||
|
||||
import org.intellij.plugins.relaxNG.compact.psi.RncElementVisitor;
|
||||
import org.intellij.plugins.relaxNG.compact.psi.RncExternalRef;
|
||||
|
||||
import com.intellij.lang.ASTNode;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
* Created by IntelliJ IDEA.
|
||||
* User: sweinreuter
|
||||
* Date: 10.08.2007
|
||||
*/
|
||||
public class RncExternalRefImpl extends RncFileReferenceImpl implements RncExternalRef {
|
||||
public RncExternalRefImpl(ASTNode node) {
|
||||
super(node);
|
||||
}
|
||||
|
||||
public void accept(@NotNull RncElementVisitor visitor) {
|
||||
visitor.visitExternalRef(this);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,126 @@
|
||||
/*
|
||||
* Copyright 2007 Sascha Weinreuter
|
||||
*
|
||||
* 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 org.intellij.plugins.relaxNG.compact.psi.impl;
|
||||
|
||||
import com.intellij.extapi.psi.PsiFileBase;
|
||||
import com.intellij.lang.ASTNode;
|
||||
import com.intellij.openapi.fileTypes.FileType;
|
||||
import com.intellij.psi.FileViewProvider;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.ResolveState;
|
||||
import com.intellij.psi.scope.PsiScopeProcessor;
|
||||
import com.intellij.psi.search.GlobalSearchScope;
|
||||
import com.intellij.psi.search.ProjectScope;
|
||||
import com.intellij.psi.search.PsiElementProcessor;
|
||||
import com.intellij.psi.tree.TokenSet;
|
||||
import com.intellij.psi.xml.XmlDocument;
|
||||
import com.intellij.psi.xml.XmlFile;
|
||||
import com.intellij.util.IncorrectOperationException;
|
||||
import org.intellij.plugins.relaxNG.compact.RncElementTypes;
|
||||
import org.intellij.plugins.relaxNG.compact.RncFileType;
|
||||
import org.intellij.plugins.relaxNG.compact.RngCompactLanguage;
|
||||
import org.intellij.plugins.relaxNG.compact.psi.RncDecl;
|
||||
import org.intellij.plugins.relaxNG.compact.psi.RncFile;
|
||||
import org.intellij.plugins.relaxNG.compact.psi.RncGrammar;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/*
|
||||
* Created by IntelliJ IDEA.
|
||||
* User: sweinreuter
|
||||
* Date: 01.08.2007
|
||||
*/
|
||||
public class RncFileImpl extends PsiFileBase implements RncFile, XmlFile {
|
||||
private static final TokenSet DECLS = TokenSet.create(RncElementTypes.NS_DECL, RncElementTypes.DATATYPES_DECL);
|
||||
|
||||
public RncFileImpl(FileViewProvider viewProvider) {
|
||||
super(viewProvider, RngCompactLanguage.INSTANCE);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public FileType getFileType() {
|
||||
return RncFileType.getInstance();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public XmlDocument getDocument() {
|
||||
// this needs to be a seperate child element because of com.intellij.util.xml.impl.ExternalChangeProcessor.visitDocumentChanged()
|
||||
final XmlDocument document = findChildByClass(XmlDocument.class);
|
||||
assert document != null;
|
||||
return document;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean processDeclarations(@NotNull PsiScopeProcessor processor, @NotNull ResolveState substitutor, PsiElement lastParent, @NotNull PsiElement place) {
|
||||
//processor.handleEvent(JavaScopeProcessorEvent.SET_CURRENT_FILE_CONTEXT, this);
|
||||
try {
|
||||
final ASTNode docNode = getDocument().getNode();
|
||||
assert docNode != null;
|
||||
final ASTNode[] nodes = docNode.getChildren(DECLS);
|
||||
for (ASTNode node : nodes) {
|
||||
if (!processor.execute(node.getPsi(), substitutor)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
final RncGrammar grammar = getGrammar();
|
||||
if (grammar != null) {
|
||||
return grammar.processDeclarations(processor, substitutor, lastParent, place);
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
} finally {
|
||||
//processor.handleEvent(JavaScopeProcessorEvent.SET_CURRENT_FILE_CONTEXT, null);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public PsiElement add(@NotNull PsiElement element) throws IncorrectOperationException {
|
||||
return getDocument().add(element);
|
||||
}
|
||||
|
||||
@Override
|
||||
public PsiElement addAfter(@NotNull PsiElement element, PsiElement anchor) throws IncorrectOperationException {
|
||||
return getDocument().addAfter(element, anchor);
|
||||
}
|
||||
|
||||
@Override
|
||||
public PsiElement addBefore(@NotNull PsiElement element, PsiElement anchor) throws IncorrectOperationException {
|
||||
return getDocument().addBefore(element, anchor);
|
||||
}
|
||||
|
||||
public boolean processElements(PsiElementProcessor processor, PsiElement place) {
|
||||
return false;
|
||||
}
|
||||
|
||||
public GlobalSearchScope getFileResolveScope() {
|
||||
return ProjectScope.getAllScope(getProject());
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return getClass().getSimpleName() + ":" + getName();
|
||||
}
|
||||
|
||||
public RncDecl[] getDeclarations() {
|
||||
return ((RncDocument)getDocument()).findChildrenByClass(RncDecl.class);
|
||||
}
|
||||
|
||||
public RncGrammar getGrammar() {
|
||||
final XmlDocument document = getDocument();
|
||||
return ((RncDocument)document).getGrammar();
|
||||
}
|
||||
}
|
||||
+99
@@ -0,0 +1,99 @@
|
||||
/*
|
||||
* Copyright 2007 Sascha Weinreuter
|
||||
*
|
||||
* 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 org.intellij.plugins.relaxNG.compact.psi.impl;
|
||||
|
||||
import org.intellij.plugins.relaxNG.compact.RncFileType;
|
||||
import org.intellij.plugins.relaxNG.compact.RncTokenTypes;
|
||||
import org.intellij.plugins.relaxNG.compact.psi.RncFile;
|
||||
import org.intellij.plugins.relaxNG.compact.psi.RncFileReference;
|
||||
import org.intellij.plugins.relaxNG.compact.psi.util.EscapeUtil;
|
||||
import org.intellij.plugins.relaxNG.references.FileReferenceUtil;
|
||||
|
||||
import com.intellij.lang.ASTNode;
|
||||
import com.intellij.openapi.util.TextRange;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.PsiFile;
|
||||
import com.intellij.psi.PsiReference;
|
||||
import com.intellij.psi.ResolveState;
|
||||
import com.intellij.psi.impl.source.resolve.reference.impl.providers.FileReferenceSet;
|
||||
import com.intellij.psi.scope.PsiScopeProcessor;
|
||||
import com.intellij.xml.util.XmlUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
/**
|
||||
* Created by IntelliJ IDEA.
|
||||
* User: sweinreuter
|
||||
* Date: 29.08.2007
|
||||
*/
|
||||
abstract class RncFileReferenceImpl extends RncElementImpl implements RncFileReference {
|
||||
public RncFileReferenceImpl(ASTNode node) {
|
||||
super(node);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
@SuppressWarnings({ "SSBasedInspection" })
|
||||
public PsiReference[] getReferences() {
|
||||
final ASTNode literal = getNode().findChildByType(RncTokenTypes.LITERAL);
|
||||
if (literal == null) return PsiReference.EMPTY_ARRAY;
|
||||
|
||||
final String s = literal.getText();
|
||||
final FileReferenceSet set =
|
||||
new FileReferenceSet(s.substring(1, s.length() - 1), this,
|
||||
getReferenceRange().getStartOffset(),
|
||||
null, true, false);
|
||||
|
||||
return FileReferenceUtil.restrict(set, FileReferenceUtil.byType(RncFileType.getInstance()));
|
||||
}
|
||||
|
||||
public RncFile getReferencedFile() {
|
||||
final String href = getFileReference();
|
||||
if (href != null) {
|
||||
final PsiFile file = XmlUtil.findRelativeFile(href, getContainingFile());
|
||||
if (file instanceof RncFile) {
|
||||
return (RncFile)file;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public String getFileReference() {
|
||||
final ASTNode element = getNode().findChildByType(RncTokenTypes.LITERAL);
|
||||
if (element == null) return null;
|
||||
final String s = EscapeUtil.unescapeText(element);
|
||||
return s.substring(1, s.length() - 1);
|
||||
}
|
||||
|
||||
public TextRange getReferenceRange() {
|
||||
final ASTNode literal = getNode().findChildByType(RncTokenTypes.LITERAL);
|
||||
if (literal == null) return TextRange.from(0, 0);
|
||||
final int startInElement = literal.getStartOffset() - getTextOffset() + 1;
|
||||
return TextRange.from(startInElement, literal.getTextLength() - 2);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean processDeclarations(@NotNull PsiScopeProcessor processor, @NotNull ResolveState substitutor, PsiElement lastParent, @NotNull PsiElement place) {
|
||||
final FollowFileHint hint = processor.getHint(FollowFileHint.KEY);
|
||||
final RncFile file = getReferencedFile();
|
||||
if (file != null && hint != null && hint.doFollow(file)) {
|
||||
file.processDeclarations(processor, substitutor, lastParent, place);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
/*
|
||||
* Copyright 2007 Sascha Weinreuter
|
||||
*
|
||||
* 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 org.intellij.plugins.relaxNG.compact.psi.impl;
|
||||
|
||||
import org.intellij.plugins.relaxNG.compact.RncElementTypes;
|
||||
import org.intellij.plugins.relaxNG.compact.RncTokenTypes;
|
||||
import org.intellij.plugins.relaxNG.compact.psi.RncElementVisitor;
|
||||
import org.intellij.plugins.relaxNG.compact.psi.RncGrammar;
|
||||
import org.intellij.plugins.relaxNG.compact.psi.RncPattern;
|
||||
|
||||
import com.intellij.lang.ASTNode;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.util.IncorrectOperationException;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
* Created by IntelliJ IDEA.
|
||||
* User: sweinreuter
|
||||
* Date: 13.08.2007
|
||||
*/
|
||||
public class RncGrammarImpl extends RncElementImpl implements RncGrammar {
|
||||
public RncGrammarImpl(ASTNode node) {
|
||||
super(node);
|
||||
}
|
||||
|
||||
public void accept(@NotNull RncElementVisitor visitor) {
|
||||
visitor.visitGrammar(this);
|
||||
}
|
||||
|
||||
public void accept(Visitor visitor) {
|
||||
visitor.visitGrammar(this);
|
||||
}
|
||||
|
||||
public RncPattern getStart() {
|
||||
final ASTNode node = getNode().findChildByType(RncElementTypes.START);
|
||||
return node != null ? (RncPattern)node.getPsi() : null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PsiElement add(@NotNull PsiElement psiElement) throws IncorrectOperationException {
|
||||
final PsiElement rbrace = findChildByType(RncTokenTypes.RBRACE);
|
||||
// TODO: fix block psi
|
||||
if (rbrace != null) {
|
||||
return addBefore(psiElement, rbrace);
|
||||
}
|
||||
return super.add(psiElement);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,69 @@
|
||||
/*
|
||||
* Copyright 2007 Sascha Weinreuter
|
||||
*
|
||||
* 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 org.intellij.plugins.relaxNG.compact.psi.impl;
|
||||
|
||||
import org.intellij.plugins.relaxNG.compact.psi.RncDefine;
|
||||
import org.intellij.plugins.relaxNG.compact.psi.RncElementVisitor;
|
||||
import org.intellij.plugins.relaxNG.compact.psi.RncInclude;
|
||||
|
||||
import com.intellij.lang.ASTNode;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.PsiFile;
|
||||
import com.intellij.psi.ResolveState;
|
||||
import com.intellij.psi.scope.PsiScopeProcessor;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
* Created by IntelliJ IDEA.
|
||||
* User: sweinreuter
|
||||
* Date: 10.08.2007
|
||||
*/
|
||||
public class RncIncludeImpl extends RncFileReferenceImpl implements RncInclude {
|
||||
public RncIncludeImpl(ASTNode node) {
|
||||
super(node);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean processDeclarations(@NotNull PsiScopeProcessor processor, @NotNull ResolveState substitutor, PsiElement lastParent, @NotNull PsiElement place) {
|
||||
final PsiElement[] children = getChildren();
|
||||
for (PsiElement child : children) {
|
||||
if (!processor.execute(child, substitutor)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return super.processDeclarations(processor, substitutor, lastParent, place);
|
||||
}
|
||||
|
||||
public void accept(@NotNull RncElementVisitor visitor) {
|
||||
visitor.visitInclude(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void accept(Visitor visitor) {
|
||||
visitor.visitInclude(this);
|
||||
}
|
||||
|
||||
public PsiFile getInclude() {
|
||||
return getReferencedFile();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public RncDefine[] getOverrides() {
|
||||
// TODO: DIVs?
|
||||
return findChildrenByClass(RncDefine.class);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,277 @@
|
||||
/*
|
||||
* Copyright 2007 Sascha Weinreuter
|
||||
*
|
||||
* 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 org.intellij.plugins.relaxNG.compact.psi.impl;
|
||||
|
||||
import org.intellij.plugins.relaxNG.compact.RncElementTypes;
|
||||
import org.intellij.plugins.relaxNG.compact.RncTokenTypes;
|
||||
import org.intellij.plugins.relaxNG.compact.psi.*;
|
||||
import org.intellij.plugins.relaxNG.compact.psi.util.EscapeUtil;
|
||||
import org.intellij.plugins.relaxNG.compact.psi.util.RenameUtil;
|
||||
|
||||
import com.intellij.codeInsight.daemon.EmptyResolveMessageProvider;
|
||||
import com.intellij.codeInsight.daemon.QuickFixProvider;
|
||||
import com.intellij.codeInsight.daemon.impl.HighlightInfo;
|
||||
import com.intellij.codeInsight.daemon.impl.quickfix.QuickFixAction;
|
||||
import com.intellij.codeInsight.intention.IntentionAction;
|
||||
import com.intellij.codeInsight.lookup.LookupItem;
|
||||
import com.intellij.codeInsight.template.*;
|
||||
import com.intellij.lang.ASTNode;
|
||||
import com.intellij.openapi.editor.Editor;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.Comparing;
|
||||
import com.intellij.openapi.util.TextRange;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.scope.BaseScopeProcessor;
|
||||
import com.intellij.psi.tree.IElementType;
|
||||
import com.intellij.util.ArrayUtil;
|
||||
import com.intellij.util.IncorrectOperationException;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
/**
|
||||
* Created by IntelliJ IDEA.
|
||||
* User: sweinreuter
|
||||
* Date: 14.08.2007
|
||||
*/
|
||||
public class RncNameImpl extends RncElementImpl implements RncName, PsiReference,
|
||||
EmptyResolveMessageProvider, QuickFixProvider<RncNameImpl> {
|
||||
private enum Kind {
|
||||
NAMESPACE, DATATYPES
|
||||
}
|
||||
private final Kind myKind;
|
||||
|
||||
public RncNameImpl(ASTNode node) {
|
||||
super(node);
|
||||
|
||||
final IElementType parent = node.getTreeParent().getElementType();
|
||||
if (parent == RncElementTypes.DATATYPE_PATTERN) {
|
||||
myKind = Kind.DATATYPES;
|
||||
} else {
|
||||
myKind = Kind.NAMESPACE;
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public String getPrefix() {
|
||||
final String[] parts = EscapeUtil.unescapeText(getNode()).split(":", 2);
|
||||
return parts.length == 2 ? parts[0] : null;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public String getLocalPart() {
|
||||
final String[] parts = EscapeUtil.unescapeText(getNode()).split(":", 2);
|
||||
return parts.length == 1 ? parts[0] : parts[1];
|
||||
}
|
||||
|
||||
@Override
|
||||
public void accept(@NotNull RncElementVisitor visitor) {
|
||||
visitor.visitName(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public PsiReference getReference() {
|
||||
return getPrefix() == null ? null : this;
|
||||
}
|
||||
|
||||
public PsiElement getElement() {
|
||||
return this;
|
||||
}
|
||||
|
||||
public TextRange getRangeInElement() {
|
||||
return TextRange.from(0, getText().indexOf(':'));
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public PsiElement resolve() {
|
||||
final MyResolver resolver = new MyResolver(getPrefix(), myKind);
|
||||
getContainingFile().processDeclarations(resolver, ResolveState.initial(), this, this);
|
||||
return resolver.getResult();
|
||||
}
|
||||
|
||||
public String getCanonicalText() {
|
||||
return getRangeInElement().substring(getText());
|
||||
}
|
||||
|
||||
public PsiElement handleElementRename(String newElementName) throws IncorrectOperationException {
|
||||
final ASTNode node = getNode();
|
||||
final ASTNode child = RenameUtil.createPrefixedNode(getManager(), newElementName, getLocalPart());
|
||||
node.getTreeParent().replaceChild(node, child);
|
||||
return child.getPsi();
|
||||
}
|
||||
|
||||
public PsiElement bindToElement(@NotNull PsiElement element) throws IncorrectOperationException {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
public boolean isReferenceTo(PsiElement element) {
|
||||
return element instanceof RncElement && Comparing.equal(resolve(), element);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public Object[] getVariants() {
|
||||
return ArrayUtil.EMPTY_OBJECT_ARRAY;
|
||||
}
|
||||
|
||||
public boolean isSoft() {
|
||||
final String prefix = getPrefix();
|
||||
return "xsd".equals(prefix) || "xml".equals(prefix);
|
||||
}
|
||||
|
||||
public String getUnresolvedMessagePattern() {
|
||||
return "Unresolved namespace prefix ''{0}''";
|
||||
}
|
||||
|
||||
public void registerQuickfix(HighlightInfo info, final RncNameImpl reference) {
|
||||
if (reference.getPrefix() == null) return; // huh?
|
||||
|
||||
QuickFixAction.registerQuickFixAction(info, new CreateDeclFix(reference));
|
||||
}
|
||||
|
||||
private static class MyResolver extends BaseScopeProcessor {
|
||||
private final String myPrefix;
|
||||
private final Kind myKind;
|
||||
private PsiElement myResult;
|
||||
|
||||
public MyResolver(String prefix, Kind kind) {
|
||||
myPrefix = prefix;
|
||||
myKind = kind;
|
||||
}
|
||||
|
||||
public boolean execute(PsiElement element, ResolveState substitutor) {
|
||||
final ASTNode node = element.getNode();
|
||||
if (node == null) return true;
|
||||
|
||||
if (!(element instanceof RncDecl)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
final IElementType type = node.getElementType();
|
||||
if (myKind == Kind.NAMESPACE && type == RncElementTypes.NS_DECL) {
|
||||
if (checkDecl(element)) return false;
|
||||
} else if (myKind == Kind.DATATYPES && type == RncElementTypes.DATATYPES_DECL) {
|
||||
if (checkDecl(element)) return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private boolean checkDecl(PsiElement element) {
|
||||
if (myPrefix.equals(((RncDecl)element).getPrefix())) {
|
||||
myResult = element;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public PsiElement getResult() {
|
||||
return myResult;
|
||||
}
|
||||
}
|
||||
|
||||
public static class CreateDeclFix implements IntentionAction {
|
||||
private final RncNameImpl myReference;
|
||||
|
||||
public CreateDeclFix(RncNameImpl reference) {
|
||||
myReference = reference;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public String getText() {
|
||||
return getFamilyName() + " '" + myReference.getPrefix() + "'";
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public String getFamilyName() {
|
||||
return "Create " + myReference.myKind.name().toLowerCase() + " declaration";
|
||||
}
|
||||
|
||||
public boolean isAvailable(@NotNull Project project, Editor editor, PsiFile file) {
|
||||
return myReference.isValid();
|
||||
}
|
||||
|
||||
public void invoke(@NotNull Project project, Editor editor, PsiFile file) throws IncorrectOperationException {
|
||||
final String prefix = myReference.getPrefix();
|
||||
final RncFile psiFile = (RncFile)PsiFileFactory.getInstance(myReference.getProject()).createFileFromText("dummy.rnc", myReference.myKind.name().toLowerCase() + " " + prefix + " = \"###\"");
|
||||
final RncFile rncFile = (RncFile)myReference.getContainingFile();
|
||||
final RncDecl[] declarations = rncFile.getDeclarations();
|
||||
final RncDecl decl = psiFile.getDeclarations()[0];
|
||||
final RncDecl e;
|
||||
if (declarations.length > 0) {
|
||||
e = (RncDecl)rncFile.addAfter(decl, declarations[declarations.length - 1]);
|
||||
} else {
|
||||
final RncGrammar rncGrammar = rncFile.getGrammar();
|
||||
if (rncGrammar != null) {
|
||||
e = (RncDecl)rncFile.addBefore(decl, rncGrammar);
|
||||
} else {
|
||||
e = (RncDecl)rncFile.add(decl);
|
||||
}
|
||||
}
|
||||
|
||||
final ASTNode blockNode = e.getParent().getNode();
|
||||
assert blockNode != null;
|
||||
|
||||
final ASTNode newNode = e.getNode();
|
||||
assert newNode != null;
|
||||
|
||||
e.getManager().getCodeStyleManager().reformatNewlyAddedElement(blockNode, newNode);
|
||||
|
||||
final SmartPsiElementPointer<RncDecl> p = SmartPointerManager.getInstance(project).createLazyPointer(e);
|
||||
PsiDocumentManager.getInstance(project).doPostponedOperationsAndUnblockDocument(editor.getDocument());
|
||||
|
||||
final RncDecl d = p.getElement();
|
||||
assert d != null;
|
||||
|
||||
final PsiElement literal = d.getLastChild();
|
||||
assert literal != null;
|
||||
|
||||
final ASTNode literalNode = literal.getNode();
|
||||
assert literalNode != null;
|
||||
|
||||
assert literalNode.getElementType() == RncTokenTypes.LITERAL;
|
||||
|
||||
final int offset = literal.getTextRange().getStartOffset();
|
||||
editor.getDocument().deleteString(literal.getTextRange().getStartOffset(), literal.getTextRange().getEndOffset());
|
||||
|
||||
final TemplateManager manager = TemplateManager.getInstance(project);
|
||||
final Template t = manager.createTemplate("", "");
|
||||
t.addTextSegment("\"");
|
||||
final Expression expression = new Expression() {
|
||||
public Result calculateResult(ExpressionContext context) {
|
||||
return new TextResult("");
|
||||
}
|
||||
|
||||
public Result calculateQuickResult(ExpressionContext context) {
|
||||
return calculateResult(context);
|
||||
}
|
||||
|
||||
public LookupItem[] calculateLookupItems(ExpressionContext context) {
|
||||
return LookupItem.EMPTY_ARRAY;
|
||||
}
|
||||
};
|
||||
t.addVariable("uri", expression, expression, true);
|
||||
t.addTextSegment("\"");
|
||||
t.addEndVariable();
|
||||
|
||||
editor.getCaretModel().moveToOffset(offset);
|
||||
manager.startTemplate(editor, t);
|
||||
}
|
||||
|
||||
public boolean startInWriteAction() {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
/*
|
||||
* Copyright 2007 Sascha Weinreuter
|
||||
*
|
||||
* 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 org.intellij.plugins.relaxNG.compact.psi.impl;
|
||||
|
||||
import org.intellij.plugins.relaxNG.compact.RncTokenTypes;
|
||||
import org.intellij.plugins.relaxNG.compact.psi.RncNsDecl;
|
||||
|
||||
import com.intellij.lang.ASTNode;
|
||||
|
||||
/**
|
||||
* Created by IntelliJ IDEA.
|
||||
* User: sweinreuter
|
||||
* Date: 14.08.2007
|
||||
*/
|
||||
public class RncNsDeclImpl extends RncDeclImpl implements RncNsDecl {
|
||||
public RncNsDeclImpl(ASTNode node) {
|
||||
super(node);
|
||||
}
|
||||
|
||||
public boolean isDefault() {
|
||||
return getNode().findChildByType(RncTokenTypes.KEYWORD_DEFAULT) != null;
|
||||
}
|
||||
}
|
||||
+72
@@ -0,0 +1,72 @@
|
||||
/*
|
||||
* Copyright 2007 Sascha Weinreuter
|
||||
*
|
||||
* 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 org.intellij.plugins.relaxNG.compact.psi.impl;
|
||||
|
||||
import org.intellij.plugins.relaxNG.compact.psi.RncElementVisitor;
|
||||
import org.intellij.plugins.relaxNG.compact.psi.RncGrammar;
|
||||
import org.intellij.plugins.relaxNG.compact.psi.RncParentRef;
|
||||
|
||||
import com.intellij.lang.ASTNode;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.PsiFile;
|
||||
import com.intellij.psi.PsiReference;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
/**
|
||||
* Created by IntelliJ IDEA.
|
||||
* User: sweinreuter
|
||||
* Date: 11.08.2007
|
||||
*/
|
||||
public class RncParentRefImpl extends RncRefImpl implements RncParentRef {
|
||||
public RncParentRefImpl(ASTNode node) {
|
||||
super(node);
|
||||
}
|
||||
|
||||
@Override // super asserts nameNode != null
|
||||
public String getReferencedName() {
|
||||
final ASTNode node = findNameNode();
|
||||
return node == null ? null : super.getReferencedName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void accept(@NotNull RncElementVisitor visitor) {
|
||||
visitor.visitParentRef(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getTextOffset() {
|
||||
final ASTNode astNode = findNameNode();
|
||||
return astNode != null ? astNode.getStartOffset() : getTextRange().getStartOffset();
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public PsiReference getReference() {
|
||||
return new PatternReference(this) {
|
||||
@Override
|
||||
protected RncGrammar getScope() {
|
||||
final PsiElement scope = PsiTreeUtil.getParentOfType(getElement(), RncGrammar.class, true, PsiFile.class);
|
||||
if (scope == null) {
|
||||
return null;
|
||||
}
|
||||
return PsiTreeUtil.getParentOfType(scope, RncGrammar.class, true, PsiFile.class);
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,70 @@
|
||||
/*
|
||||
* Copyright 2007 Sascha Weinreuter
|
||||
*
|
||||
* 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 org.intellij.plugins.relaxNG.compact.psi.impl;
|
||||
|
||||
import org.intellij.plugins.relaxNG.compact.RncTokenTypes;
|
||||
import org.intellij.plugins.relaxNG.compact.psi.RncDefine;
|
||||
import org.intellij.plugins.relaxNG.compact.psi.RncElementVisitor;
|
||||
import org.intellij.plugins.relaxNG.compact.psi.RncRef;
|
||||
import org.intellij.plugins.relaxNG.compact.psi.util.EscapeUtil;
|
||||
|
||||
import com.intellij.lang.ASTNode;
|
||||
import com.intellij.psi.PsiReference;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
/**
|
||||
* Created by IntelliJ IDEA.
|
||||
* User: sweinreuter
|
||||
* Date: 11.08.2007
|
||||
*/
|
||||
public class RncRefImpl extends RncElementImpl implements RncRef {
|
||||
public RncRefImpl(ASTNode node) {
|
||||
super(node);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public RncDefine getPattern() {
|
||||
final PsiReference ref = getReference();
|
||||
// TODO: honor combine & return virtual element if multiResolve().length > 0
|
||||
return ref instanceof PatternReference ? (RncDefine)ref.resolve() : null;
|
||||
}
|
||||
|
||||
public String getReferencedName() {
|
||||
final ASTNode node = findNameNode();
|
||||
assert node != null;
|
||||
return EscapeUtil.unescapeText(node);
|
||||
}
|
||||
|
||||
protected ASTNode findNameNode() {
|
||||
return getNode().findChildByType(RncTokenTypes.IDENTIFIERS);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void accept(@NotNull RncElementVisitor visitor) {
|
||||
visitor.visitRef(this);
|
||||
}
|
||||
|
||||
public void accept(Visitor visitor) {
|
||||
visitor.visitRef(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public PsiReference getReference() {
|
||||
return new PatternReference(this);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,67 @@
|
||||
/*
|
||||
* Copyright 2007 Sascha Weinreuter
|
||||
*
|
||||
* 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 org.intellij.plugins.relaxNG.compact.psi.util;
|
||||
|
||||
import org.intellij.plugins.relaxNG.compact.RncTokenTypes;
|
||||
|
||||
import com.intellij.lang.ASTNode;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
* Created by IntelliJ IDEA.
|
||||
* User: sweinreuter
|
||||
* Date: 13.08.2007
|
||||
*/
|
||||
public class EscapeUtil {
|
||||
@SuppressWarnings({ "SSBasedInspection" })
|
||||
public static String unescapeText(@NotNull PsiElement element) {
|
||||
final ASTNode node = element.getNode();
|
||||
if (node != null) {
|
||||
return unescapeText(node);
|
||||
} else {
|
||||
return element.getText();
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings({ "SSBasedInspection" })
|
||||
public static String unescapeText(@NotNull ASTNode node) {
|
||||
final String text = node.getText();
|
||||
|
||||
// TODO: unescape \x{xx} sequences
|
||||
|
||||
if (node.getElementType() == RncTokenTypes.ESCAPED_IDENTIFIER) {
|
||||
assert text.charAt(0) == '\\';
|
||||
return text.length() > 1 ? text.substring(1) : "";
|
||||
} else {
|
||||
return text;
|
||||
}
|
||||
}
|
||||
|
||||
public static String parseLiteralValue(ASTNode ns) {
|
||||
return unquote(unescapeText(ns));
|
||||
}
|
||||
|
||||
private static String unquote(String s) {
|
||||
if (s.length() >= 6 && s.charAt(0) == s.charAt(1)) {
|
||||
s = s.replace('\u0000', '\n');
|
||||
return s.substring(3, s.length() - 3);
|
||||
} else {
|
||||
return s.substring(1, s.length() - 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
/*
|
||||
* Copyright 2007 Sascha Weinreuter
|
||||
*
|
||||
* 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 org.intellij.plugins.relaxNG.compact.psi.util;
|
||||
|
||||
import com.intellij.lang.ASTNode;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.util.NotNullFunction;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
* Created by IntelliJ IDEA.
|
||||
* User: sweinreuter
|
||||
* Date: 13.08.2007
|
||||
*/
|
||||
public final class PsiFunction implements NotNullFunction<ASTNode, PsiElement> {
|
||||
public static final PsiFunction INSTANCE = new PsiFunction();
|
||||
|
||||
@NotNull
|
||||
public PsiElement fun(ASTNode astNode) {
|
||||
return astNode.getPsi();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,111 @@
|
||||
/*
|
||||
* Copyright 2007 Sascha Weinreuter
|
||||
*
|
||||
* 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 org.intellij.plugins.relaxNG.compact.psi.util;
|
||||
|
||||
import org.intellij.plugins.relaxNG.compact.RncElementTypes;
|
||||
import org.intellij.plugins.relaxNG.compact.RncFileType;
|
||||
import org.intellij.plugins.relaxNG.compact.RncTokenTypes;
|
||||
import org.intellij.plugins.relaxNG.compact.RngCompactLanguage;
|
||||
import org.intellij.plugins.relaxNG.compact.psi.RncFile;
|
||||
import org.intellij.plugins.relaxNG.compact.psi.RncGrammar;
|
||||
|
||||
import com.intellij.lang.ASTNode;
|
||||
import com.intellij.lang.LanguageParserDefinitions;
|
||||
import com.intellij.lang.ParserDefinition;
|
||||
import com.intellij.lexer.Lexer;
|
||||
import com.intellij.psi.PsiFileFactory;
|
||||
import com.intellij.psi.PsiManager;
|
||||
import com.intellij.psi.tree.IElementType;
|
||||
import com.intellij.psi.tree.TokenSet;
|
||||
import com.intellij.util.IncorrectOperationException;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
* Created by IntelliJ IDEA.
|
||||
* User: sweinreuter
|
||||
* Date: 14.08.2007
|
||||
*/
|
||||
public class RenameUtil {
|
||||
@NotNull
|
||||
public static ASTNode createIdentifierNode(PsiManager manager, String name) throws IncorrectOperationException {
|
||||
if (isKeyword(manager, name)) {
|
||||
name = "\\" + name;
|
||||
} else if (!isIdentifier(manager, name)) {
|
||||
throw new IncorrectOperationException("Illegal identifier: " + name);
|
||||
}
|
||||
|
||||
final PsiFileFactory f = PsiFileFactory.getInstance(manager.getProject());
|
||||
final RncFile file = (RncFile)f.createFileFromText("dummy.rnc", RncFileType.getInstance(), name + " = bar");
|
||||
final ASTNode astNode = findFirstGrammarNode(file);
|
||||
final ASTNode newNode = astNode.findChildByType(RncTokenTypes.IDENTIFIERS);
|
||||
assert newNode != null;
|
||||
return newNode;
|
||||
}
|
||||
|
||||
public static boolean isIdentifier(PsiManager manager, String name) {
|
||||
return isTokenOfType(manager, name, RncTokenTypes.IDENTIFIER_OR_KEYWORD);
|
||||
}
|
||||
|
||||
public static boolean isKeyword(PsiManager manager, String name) {
|
||||
return isTokenOfType(manager, name, RncTokenTypes.KEYWORDS);
|
||||
}
|
||||
|
||||
private static boolean isTokenOfType(PsiManager manager, String name, TokenSet set) {
|
||||
final ParserDefinition definition = LanguageParserDefinitions.INSTANCE.forLanguage(RngCompactLanguage.INSTANCE);
|
||||
assert definition != null;
|
||||
final Lexer lexer = definition.createLexer(manager.getProject());
|
||||
|
||||
lexer.start(name, 0, name.length(), 0);
|
||||
final IElementType t = lexer.getTokenType();
|
||||
lexer.advance();
|
||||
return lexer.getTokenType() == null && set.contains(t);
|
||||
}
|
||||
|
||||
public static ASTNode createPrefixedNode(PsiManager manager, String prefix, String localPart) {
|
||||
final PsiFileFactory f = PsiFileFactory.getInstance(manager.getProject());
|
||||
final RncFile file = (RncFile)f.createFileFromText("dummy.rnc", RncFileType.getInstance(), "element " + prefix + ":" + localPart + " { text }");
|
||||
|
||||
final ASTNode node = findFirstGrammarNode(file);
|
||||
final ASTNode nameClassNode = node.findChildByType(RncElementTypes.NAME_CLASS);
|
||||
assert nameClassNode != null;
|
||||
|
||||
final ASTNode astNode = nameClassNode.findChildByType(RncElementTypes.NAME);
|
||||
assert astNode != null;
|
||||
return astNode;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static ASTNode findFirstGrammarNode(RncFile file) {
|
||||
final RncGrammar grammar = file.getGrammar();
|
||||
assert grammar != null;
|
||||
final ASTNode grammarNode = grammar.getNode();
|
||||
assert grammarNode != null;
|
||||
final ASTNode astNode = grammarNode.getFirstChildNode();
|
||||
assert astNode != null;
|
||||
return astNode;
|
||||
}
|
||||
|
||||
public static ASTNode createLiteralNode(PsiManager manager, String content) {
|
||||
final PsiFileFactory f = PsiFileFactory.getInstance(manager.getProject());
|
||||
final RncFile file = (RncFile)f.createFileFromText("dummy.rnc", RncFileType.getInstance(), "include \"" + content + "\"");
|
||||
|
||||
final ASTNode include = findFirstGrammarNode(file);
|
||||
final ASTNode literal = include.findChildByType(RncTokenTypes.LITERAL);
|
||||
assert literal != null;
|
||||
return literal;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
/*
|
||||
* Copyright 2007 Sascha Weinreuter
|
||||
*
|
||||
* 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 org.intellij.plugins.relaxNG.config;
|
||||
|
||||
import com.intellij.openapi.components.ProjectComponent;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.psi.PsiFile;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
/**
|
||||
* Created by IntelliJ IDEA.
|
||||
* User: sweinreuter
|
||||
* Date: 26.11.2007
|
||||
*/
|
||||
public abstract class NoNamespaceConfig implements ProjectComponent {
|
||||
@Nullable
|
||||
public abstract String getMapping(@NotNull PsiFile file);
|
||||
public abstract VirtualFile getMappedFile(@NotNull PsiFile file);
|
||||
|
||||
public abstract void setMapping(@NotNull PsiFile file, @Nullable String location);
|
||||
|
||||
public static NoNamespaceConfig getInstance(@NotNull Project project) {
|
||||
return project.getComponent(NoNamespaceConfig.class);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,175 @@
|
||||
/*
|
||||
* Copyright 2007 Sascha Weinreuter
|
||||
*
|
||||
* 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 org.intellij.plugins.relaxNG.config;
|
||||
|
||||
import com.intellij.openapi.components.PersistentStateComponent;
|
||||
import com.intellij.openapi.components.State;
|
||||
import com.intellij.openapi.components.Storage;
|
||||
import com.intellij.openapi.editor.HectorComponentPanel;
|
||||
import com.intellij.openapi.editor.HectorComponentPanelsProvider;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.openapi.vfs.pointers.VirtualFilePointer;
|
||||
import com.intellij.openapi.vfs.pointers.VirtualFilePointerManager;
|
||||
import com.intellij.psi.PsiFile;
|
||||
import com.intellij.psi.xml.XmlFile;
|
||||
import com.intellij.psi.xml.XmlTag;
|
||||
import com.intellij.util.xmlb.annotations.MapAnnotation;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Created by IntelliJ IDEA.
|
||||
* User: sweinreuter
|
||||
* Date: 25.11.2007
|
||||
*/
|
||||
@State(
|
||||
name = "NoNamespaceConfig.Mappings",
|
||||
storages = { @Storage(
|
||||
id = "other",
|
||||
file = "$WORKSPACE_FILE$") })
|
||||
class NoNamespaceConfigImpl extends NoNamespaceConfig implements PersistentStateComponent<NoNamespaceConfigImpl.Mappings> {
|
||||
|
||||
private final Map<VirtualFilePointer, VirtualFilePointer> myMappings = new HashMap<VirtualFilePointer, VirtualFilePointer>();
|
||||
private final Project myProject;
|
||||
|
||||
NoNamespaceConfigImpl(Project project) {
|
||||
myProject = project;
|
||||
}
|
||||
|
||||
private VirtualFilePointer getMappedPointer(@NotNull PsiFile file) {
|
||||
final VirtualFile virtualFile = file.getVirtualFile();
|
||||
if (virtualFile == null) return null;
|
||||
|
||||
final String url = virtualFile.getUrl();
|
||||
for (VirtualFilePointer pointer : myMappings.keySet()) {
|
||||
if (url.equals(pointer.getUrl())) {
|
||||
return myMappings.get(pointer);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public String getMapping(@NotNull PsiFile file) {
|
||||
final VirtualFilePointer pointer = getMappedPointer(file);
|
||||
return pointer != null ? pointer.getUrl() : null;
|
||||
}
|
||||
|
||||
public VirtualFile getMappedFile(@NotNull PsiFile file) {
|
||||
final VirtualFilePointer url = getMappedPointer(file);
|
||||
return url != null ? url.getFile() : null;
|
||||
}
|
||||
|
||||
public void setMapping(@NotNull PsiFile file, String location) {
|
||||
final VirtualFile virtualFile = file.getVirtualFile();
|
||||
assert virtualFile != null;
|
||||
|
||||
final String url = virtualFile.getUrl();
|
||||
final VirtualFilePointerManager manager = VirtualFilePointerManager.getInstance();
|
||||
for (VirtualFilePointer pointer : myMappings.keySet()) {
|
||||
if (url.equals(pointer.getUrl())) {
|
||||
if (location == null) {
|
||||
myMappings.remove(pointer);
|
||||
return;
|
||||
} else if (!location.equals(myMappings.get(pointer).getUrl())) {
|
||||
myMappings.remove(pointer);
|
||||
myMappings.put(pointer, manager.create(location, myProject, null));
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (location != null) {
|
||||
myMappings.put(manager.create(url, myProject, null), manager.create(location, myProject, null));
|
||||
}
|
||||
}
|
||||
|
||||
public void initComponent() {
|
||||
}
|
||||
|
||||
public void disposeComponent() {
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public String getComponentName() {
|
||||
return "RELAX-NG.NoNamespaceConfig";
|
||||
}
|
||||
|
||||
public void projectOpened() {
|
||||
}
|
||||
|
||||
public void projectClosed() {
|
||||
reset();
|
||||
}
|
||||
|
||||
public Mappings getState() {
|
||||
final HashMap<String, String> map = new HashMap<String, String>();
|
||||
for (Map.Entry<VirtualFilePointer, VirtualFilePointer> entry : myMappings.entrySet()) {
|
||||
map.put(entry.getKey().getUrl(), entry.getValue().getUrl());
|
||||
}
|
||||
return new Mappings(map);
|
||||
}
|
||||
|
||||
public void loadState(Mappings state) {
|
||||
reset();
|
||||
|
||||
final VirtualFilePointerManager manager = VirtualFilePointerManager.getInstance();
|
||||
final Map<String, String> map = state.myMappings;
|
||||
for (String file : map.keySet()) {
|
||||
myMappings.put(manager.create(file, myProject, null), manager.create(map.get(file), myProject, null));
|
||||
}
|
||||
}
|
||||
|
||||
private void reset() {
|
||||
myMappings.clear();
|
||||
}
|
||||
|
||||
@SuppressWarnings({ "CanBeFinal", "UnusedDeclaration" })
|
||||
public static class Mappings {
|
||||
@MapAnnotation(surroundWithTag = false, entryTagName = "mapping", keyAttributeName = "file", valueAttributeName = "schema")
|
||||
public Map<String, String> myMappings;
|
||||
|
||||
public Mappings() {
|
||||
myMappings = new HashMap<String, String>();
|
||||
}
|
||||
|
||||
Mappings(Map<String, String> map) {
|
||||
myMappings = map;
|
||||
}
|
||||
}
|
||||
|
||||
public static class HectorProvider implements HectorComponentPanelsProvider {
|
||||
@Nullable
|
||||
public HectorComponentPanel createConfigurable(@NotNull PsiFile file) {
|
||||
if (file instanceof XmlFile) {
|
||||
try {
|
||||
final XmlTag rootTag = ((XmlFile)file).getDocument().getRootTag();
|
||||
if (rootTag.getNamespace().length() == 0) {
|
||||
return new NoNamespaceConfigPanel(NoNamespaceConfig.getInstance(file.getProject()), file);
|
||||
}
|
||||
} catch (NullPointerException e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<form xmlns="http://www.intellij.com/uidesigner/form/" version="1" bind-to-class="org.intellij.plugins.relaxNG.config.NoNamespaceConfigPanel">
|
||||
<grid id="27dc6" binding="myRoot" layout-manager="GridLayoutManager" row-count="2" column-count="1" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
|
||||
<margin top="0" left="0" bottom="0" right="0"/>
|
||||
<constraints>
|
||||
<xy x="20" y="20" width="687" height="96"/>
|
||||
</constraints>
|
||||
<properties/>
|
||||
<border type="none" title="RELAX-NG Schema Association"/>
|
||||
<children>
|
||||
<component id="9c3ce" class="com.intellij.openapi.ui.TextFieldWithBrowseButton" binding="mySchemaFile">
|
||||
<constraints>
|
||||
<grid row="0" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="7" anchor="0" fill="1" indent="0" use-parent-layout="false">
|
||||
<minimum-size width="160" height="-1"/>
|
||||
</grid>
|
||||
</constraints>
|
||||
<properties/>
|
||||
</component>
|
||||
<vspacer id="e4455">
|
||||
<constraints>
|
||||
<grid row="1" column="0" row-span="1" col-span="1" vsize-policy="6" hsize-policy="1" anchor="0" fill="2" indent="0" use-parent-layout="false"/>
|
||||
</constraints>
|
||||
</vspacer>
|
||||
</children>
|
||||
</grid>
|
||||
<inspectionSuppressions>
|
||||
<suppress inspection="NoLabelFor" id="9c3ce"/>
|
||||
</inspectionSuppressions>
|
||||
</form>
|
||||
@@ -0,0 +1,133 @@
|
||||
/*
|
||||
* Copyright 2007 Sascha Weinreuter
|
||||
*
|
||||
* 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 org.intellij.plugins.relaxNG.config;
|
||||
|
||||
import com.intellij.openapi.actionSystem.LangDataKeys;
|
||||
import com.intellij.openapi.editor.HectorComponentPanel;
|
||||
import com.intellij.openapi.fileChooser.FileChooserDescriptor;
|
||||
import com.intellij.openapi.fileTypes.FileType;
|
||||
import com.intellij.openapi.fileTypes.StdFileTypes;
|
||||
import com.intellij.openapi.module.Module;
|
||||
import com.intellij.openapi.options.ConfigurationException;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.roots.ProjectRootManager;
|
||||
import com.intellij.openapi.ui.ComponentWithBrowseButton;
|
||||
import com.intellij.openapi.ui.TextComponentAccessor;
|
||||
import com.intellij.openapi.ui.TextFieldWithBrowseButton;
|
||||
import com.intellij.openapi.vfs.VfsUtil;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.psi.PsiFile;
|
||||
import org.intellij.plugins.relaxNG.compact.RncFileType;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.io.File;
|
||||
|
||||
/**
|
||||
* Created by IntelliJ IDEA.
|
||||
* User: sweinreuter
|
||||
* Date: 25.11.2007
|
||||
*/
|
||||
class NoNamespaceConfigPanel extends HectorComponentPanel {
|
||||
private final NoNamespaceConfig myConfig;
|
||||
private final PsiFile myFile;
|
||||
private final String myMapping;
|
||||
|
||||
private TextFieldWithBrowseButton mySchemaFile;
|
||||
private JPanel myRoot;
|
||||
private boolean myDialogOpen;
|
||||
|
||||
NoNamespaceConfigPanel(NoNamespaceConfig noNamespaceConfig, PsiFile file) {
|
||||
myConfig = noNamespaceConfig;
|
||||
myFile = file;
|
||||
myMapping = myConfig.getMapping(file);
|
||||
|
||||
final FileChooserDescriptor descriptor = new FileChooserDescriptor(true, false, false, false, false, false) {
|
||||
public boolean isFileSelectable(VirtualFile file) {
|
||||
final boolean b = super.isFileSelectable(file);
|
||||
if (b) {
|
||||
final FileType type = file.getFileType();
|
||||
if (type != StdFileTypes.XML) {
|
||||
return type == RncFileType.getInstance();
|
||||
}
|
||||
}
|
||||
return b;
|
||||
}
|
||||
};
|
||||
|
||||
final Project project = file.getProject();
|
||||
final VirtualFile virtualFile = file.getVirtualFile();
|
||||
if (virtualFile != null) {
|
||||
final Module module = ProjectRootManager.getInstance(project).getFileIndex().getModuleForFile(virtualFile);
|
||||
descriptor.putUserData(LangDataKeys.MODULE_CONTEXT, module);
|
||||
}
|
||||
|
||||
// that's kind of a hack that ensures the Hector Panel stays open when selecting a file. otherwise it will close
|
||||
// as soon as a file selected.
|
||||
final ComponentWithBrowseButton.BrowseFolderActionListener<JTextField> actionListener =
|
||||
new ComponentWithBrowseButton.BrowseFolderActionListener<JTextField>("Select Schema", "Select a RELAX-NG file to associate with the document",
|
||||
mySchemaFile, project, descriptor, TextComponentAccessor.TEXT_FIELD_WHOLE_TEXT) {
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
myDialogOpen = true;
|
||||
try {
|
||||
super.actionPerformed(e);
|
||||
} finally {
|
||||
myDialogOpen = false;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
mySchemaFile.addActionListener(actionListener);
|
||||
}
|
||||
|
||||
public boolean canClose() {
|
||||
return super.canClose() && !myDialogOpen;
|
||||
}
|
||||
|
||||
public JComponent createComponent() {
|
||||
return myRoot;
|
||||
}
|
||||
|
||||
public boolean isModified() {
|
||||
final String s = mySchemaFile.getText();
|
||||
final String m = myMapping != null ? myMapping : "";
|
||||
return !s.equals(m);
|
||||
}
|
||||
|
||||
public void apply() throws ConfigurationException {
|
||||
final String s = getMapping();
|
||||
if (s != null) {
|
||||
myConfig.setMapping(myFile, s);
|
||||
} else {
|
||||
myConfig.setMapping(myFile, null);
|
||||
}
|
||||
}
|
||||
|
||||
private String getMapping() {
|
||||
final String s = mySchemaFile.getText().trim();
|
||||
return s.length() > 0 ? VfsUtil.pathToUrl(s.replace(File.separatorChar, '/')) : null;
|
||||
}
|
||||
|
||||
public void reset() {
|
||||
mySchemaFile.setText(myMapping != null ? VfsUtil.urlToPath(myMapping).replace('/', File.separatorChar) : "");
|
||||
}
|
||||
|
||||
public void disposeUIResources() {
|
||||
// doesn't help - updating the validation needs a hard modification
|
||||
// DaemonCodeAnalyzer.getInstance(myFile.getProject()).restart();
|
||||
}
|
||||
}
|
||||
+55
@@ -0,0 +1,55 @@
|
||||
/*
|
||||
* Copyright 2007 Sascha Weinreuter
|
||||
*
|
||||
* 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 org.intellij.plugins.relaxNG.config;
|
||||
|
||||
import com.intellij.ide.highlighter.XmlFileType;
|
||||
import com.intellij.openapi.module.Module;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.psi.PsiFile;
|
||||
import com.intellij.psi.PsiManager;
|
||||
import com.intellij.psi.xml.XmlFile;
|
||||
import com.intellij.xml.XmlSchemaProvider;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
/*
|
||||
* Created by IntelliJ IDEA.
|
||||
* User: sweinreuter
|
||||
* Date: 22.11.2007
|
||||
*/
|
||||
public class NoNamespaceSchemaProvider extends XmlSchemaProvider {
|
||||
@Nullable
|
||||
public XmlFile getSchema(@NotNull @NonNls String url, @Nullable Module module, @NotNull PsiFile baseFile) {
|
||||
if ("".equals(url)) {
|
||||
final Project project = baseFile.getProject();
|
||||
final VirtualFile file = NoNamespaceConfig.getInstance(project).getMappedFile(baseFile);
|
||||
if (file == null) return null;
|
||||
final PsiFile f = PsiManager.getInstance(project).findFile(file);
|
||||
if (f instanceof XmlFile) {
|
||||
return (XmlFile)f;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAvailable(@NotNull XmlFile file) {
|
||||
return file.getFileType() == XmlFileType.INSTANCE;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,191 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<form xmlns="http://www.intellij.com/uidesigner/form/" version="1" bind-to-class="org.intellij.plugins.relaxNG.convert.AdvancedDtdOptions">
|
||||
<grid id="27dc6" binding="myRoot" layout-manager="GridLayoutManager" row-count="9" column-count="2" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
|
||||
<margin top="0" left="0" bottom="0" right="0"/>
|
||||
<constraints>
|
||||
<xy x="20" y="20" width="529" height="392"/>
|
||||
</constraints>
|
||||
<properties/>
|
||||
<border type="none" title="DTD Input"/>
|
||||
<children>
|
||||
<component id="60570" class="javax.swing.JCheckBox" binding="myInlineAttlistCheckBox" default-binding="true">
|
||||
<constraints>
|
||||
<grid row="2" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
|
||||
</constraints>
|
||||
<properties>
|
||||
<text value="&inline-attlist"/>
|
||||
<toolTipText value="Specifies not to generate definitions for attribute list declarations and instead move attributes declared in attribute list declarations into the definitions generated for element declarations. This is the default behavior when the output module is xsd. Otherwise, the default behaviour is as described in the -i no-inline-attlist parameter. "/>
|
||||
</properties>
|
||||
</component>
|
||||
<component id="ee970" class="javax.swing.JLabel">
|
||||
<constraints>
|
||||
<grid row="0" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
|
||||
</constraints>
|
||||
<properties>
|
||||
<labelFor value="4bcfc"/>
|
||||
<text value="&colon-replacement:"/>
|
||||
<toolTipText value="Replaces colons in element names by chars when constructing the names of definitions used to represent the element declarations and attribute list declarations in the DTD. Trang generates a definition for each element declaration and attlist declaration in the DTD. The name of the definition is based on the name of the element. In RELAX NG, the names of definitions cannot contain colons. However, in the DTD, the element name may contain a colon. By default, Trang will first try to use the element names without prefixes. If this causes a conflict, it will instead replace the colon by a legal name character (it try first to use a period). "/>
|
||||
</properties>
|
||||
</component>
|
||||
<component id="4bcfc" class="javax.swing.JTextField" binding="myColonReplacement">
|
||||
<constraints>
|
||||
<grid row="0" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="6" anchor="8" fill="1" indent="0" use-parent-layout="false">
|
||||
<preferred-size width="150" height="-1"/>
|
||||
</grid>
|
||||
</constraints>
|
||||
<properties/>
|
||||
</component>
|
||||
<component id="c69bb" class="javax.swing.JLabel">
|
||||
<constraints>
|
||||
<grid row="1" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
|
||||
</constraints>
|
||||
<properties>
|
||||
<labelFor value="12ad0"/>
|
||||
<text value="&element-define:"/>
|
||||
<toolTipText value="Specifies how to construct the name of the definition representing an element declaration from the name of the element. The name-pattern must contain exactly one percent character. This percent character is replaced by the name of element (after colon replacement) and the result is used as the name of the definition"/>
|
||||
</properties>
|
||||
</component>
|
||||
<component id="12ad0" class="javax.swing.JTextField" binding="myElementDefine">
|
||||
<constraints>
|
||||
<grid row="1" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="6" anchor="8" fill="1" indent="0" use-parent-layout="false">
|
||||
<preferred-size width="150" height="-1"/>
|
||||
</grid>
|
||||
</constraints>
|
||||
<properties/>
|
||||
</component>
|
||||
<component id="b63cc" class="javax.swing.JLabel">
|
||||
<constraints>
|
||||
<grid row="3" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="1" use-parent-layout="false"/>
|
||||
</constraints>
|
||||
<properties>
|
||||
<labelFor value="5576"/>
|
||||
<text value="&attlist-define:"/>
|
||||
<toolTipText value="This specifies how to construct the name of the definition representing an attribute list declaration from the name of the element. The name-pattern must contain exactly one percent character. This percent character is replaced by the name of element (after colon replacement) and the result is used as the name of the definition. "/>
|
||||
</properties>
|
||||
</component>
|
||||
<component id="5576" class="javax.swing.JTextField" binding="myAttlistDefine">
|
||||
<constraints>
|
||||
<grid row="3" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="6" anchor="8" fill="1" indent="0" use-parent-layout="false">
|
||||
<preferred-size width="150" height="-1"/>
|
||||
</grid>
|
||||
</constraints>
|
||||
<properties/>
|
||||
</component>
|
||||
<component id="32a4e" class="javax.swing.JLabel">
|
||||
<constraints>
|
||||
<grid row="4" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
|
||||
</constraints>
|
||||
<properties>
|
||||
<labelFor value="bbb31"/>
|
||||
<text value="a&ny-name:"/>
|
||||
<toolTipText value="Specifies the name of the definition generated for the content of elements declared in the DTD as having a content model of ANY."/>
|
||||
</properties>
|
||||
</component>
|
||||
<component id="bbb31" class="javax.swing.JTextField" binding="myAnyName">
|
||||
<constraints>
|
||||
<grid row="4" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="6" anchor="8" fill="1" indent="0" use-parent-layout="false">
|
||||
<preferred-size width="150" height="-1"/>
|
||||
</grid>
|
||||
</constraints>
|
||||
<properties/>
|
||||
</component>
|
||||
<component id="62d5d" class="javax.swing.JCheckBox" binding="myStrictAnyCheckBox" default-binding="true">
|
||||
<constraints>
|
||||
<grid row="5" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
|
||||
</constraints>
|
||||
<properties>
|
||||
<text value="&strict-any"/>
|
||||
<toolTipText value="Preserves the exact semantics of ANY content models by using an explicit choice of references to all declared elements. By default, Trang uses a wildcard that allows any element. "/>
|
||||
</properties>
|
||||
</component>
|
||||
<component id="b1561" class="javax.swing.JLabel">
|
||||
<constraints>
|
||||
<grid row="6" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
|
||||
</constraints>
|
||||
<properties>
|
||||
<labelFor value="79c45"/>
|
||||
<text value="ann&otation-prefix:"/>
|
||||
<toolTipText value="Default values are represented using an annotation attribute prefix:defaultValue where prefix is bound to http://relaxng.org/ns/compatibility/annotations/1.0 as defined by the RELAX NG DTD Compatibility Committee Specification. By default, Trang will use a for prefix unless that conflicts with a prefix used in the DTD. "/>
|
||||
</properties>
|
||||
</component>
|
||||
<component id="79c45" class="javax.swing.JTextField" binding="myAnnotationPrefix">
|
||||
<constraints>
|
||||
<grid row="6" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="6" anchor="8" fill="1" indent="0" use-parent-layout="false">
|
||||
<preferred-size width="150" height="-1"/>
|
||||
</grid>
|
||||
</constraints>
|
||||
<properties/>
|
||||
</component>
|
||||
<component id="d14ca" class="javax.swing.JCheckBox" binding="myGenerateStartCheckBox" default-binding="true">
|
||||
<constraints>
|
||||
<grid row="7" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
|
||||
</constraints>
|
||||
<properties>
|
||||
<text value="&generate-start"/>
|
||||
<toolTipText value="Specifies whether Trang should generate a start element. DTDs do not indicate what elements are allowed as document elements. Trang assumes that all elements that are defined but never referenced are allowed as document elements. "/>
|
||||
</properties>
|
||||
</component>
|
||||
<grid id="c0da2" layout-manager="GridLayoutManager" row-count="2" column-count="3" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
|
||||
<margin top="0" left="0" bottom="0" right="0"/>
|
||||
<constraints>
|
||||
<grid row="8" column="0" row-span="1" col-span="2" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
|
||||
</constraints>
|
||||
<properties/>
|
||||
<border type="none" title="Namespace Settings"/>
|
||||
<children>
|
||||
<component id="3e6e" class="javax.swing.JLabel">
|
||||
<constraints>
|
||||
<grid row="0" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
|
||||
</constraints>
|
||||
<properties>
|
||||
<labelFor value="577de"/>
|
||||
<text value="&Default:"/>
|
||||
</properties>
|
||||
</component>
|
||||
<vspacer id="827e3">
|
||||
<constraints>
|
||||
<grid row="1" column="0" row-span="1" col-span="1" vsize-policy="6" hsize-policy="1" anchor="0" fill="2" indent="0" use-parent-layout="false"/>
|
||||
</constraints>
|
||||
</vspacer>
|
||||
<component id="577de" class="javax.swing.JTextField" binding="myDefaultNS">
|
||||
<constraints>
|
||||
<grid row="0" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="6" anchor="8" fill="1" indent="0" use-parent-layout="false">
|
||||
<preferred-size width="150" height="-1"/>
|
||||
</grid>
|
||||
</constraints>
|
||||
<properties/>
|
||||
</component>
|
||||
<scrollpane id="66236">
|
||||
<constraints>
|
||||
<grid row="1" column="1" row-span="1" col-span="1" vsize-policy="7" hsize-policy="7" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
|
||||
</constraints>
|
||||
<properties/>
|
||||
<border type="none"/>
|
||||
<children>
|
||||
<component id="18116" class="javax.swing.JTable" binding="myNamespaceMap">
|
||||
<constraints/>
|
||||
<properties>
|
||||
<preferredScrollableViewportSize width="250" height="70"/>
|
||||
</properties>
|
||||
<clientProperties>
|
||||
<terminateEditOnFocusLost class="java.lang.Boolean" value="true"/>
|
||||
</clientProperties>
|
||||
</component>
|
||||
</children>
|
||||
</scrollpane>
|
||||
<grid id="f0444" binding="myToolbar" layout-manager="BorderLayout" hgap="0" vgap="0">
|
||||
<constraints>
|
||||
<grid row="1" column="2" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="8" fill="2" indent="0" use-parent-layout="false"/>
|
||||
</constraints>
|
||||
<properties/>
|
||||
<border type="none"/>
|
||||
<children/>
|
||||
</grid>
|
||||
</children>
|
||||
</grid>
|
||||
</children>
|
||||
</grid>
|
||||
<inspectionSuppressions>
|
||||
<suppress inspection="NoLabelFor" id="66236"/>
|
||||
</inspectionSuppressions>
|
||||
</form>
|
||||
@@ -0,0 +1,258 @@
|
||||
/*
|
||||
* Copyright 2007 Sascha Weinreuter
|
||||
*
|
||||
* 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 org.intellij.plugins.relaxNG.convert;
|
||||
|
||||
import com.intellij.openapi.actionSystem.*;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.IconLoader;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.PsiFile;
|
||||
import com.intellij.psi.PsiManager;
|
||||
import com.intellij.psi.PsiRecursiveElementVisitor;
|
||||
import com.intellij.psi.xml.XmlAttributeDecl;
|
||||
import com.intellij.psi.xml.XmlElementDecl;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
|
||||
import javax.swing.*;
|
||||
import javax.swing.table.AbstractTableModel;
|
||||
import java.awt.event.ItemEvent;
|
||||
import java.awt.event.ItemListener;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* Created by IntelliJ IDEA.
|
||||
* User: sweinreuter
|
||||
* Date: 18.11.2007
|
||||
*/
|
||||
public class AdvancedDtdOptions implements AdvancedOptions {
|
||||
@NonNls
|
||||
private static final String COLON_REPLACEMENT = "colon-replacement";
|
||||
@NonNls
|
||||
private static final String ELEMENT_DEFINE = "element-define";
|
||||
@NonNls
|
||||
private static final String ATTLIST_DEFINE = "attlist-define";
|
||||
@NonNls
|
||||
private static final String INLINE_ATTLIST = "inline-attlist";
|
||||
@NonNls
|
||||
private static final String ANY_NAME = "any-name";
|
||||
@NonNls
|
||||
private static final String STRICT_ANY = "strict-any";
|
||||
@NonNls
|
||||
private static final String ANNOTATION_PREFIX = "annotation-prefix";
|
||||
@NonNls
|
||||
private static final String GENERATE_START = "generate-start";
|
||||
@NonNls
|
||||
private static final String XMLNS = "xmlns";
|
||||
|
||||
private JComponent myRoot;
|
||||
|
||||
private JCheckBox myInlineAttlistCheckBox;
|
||||
private JTextField myColonReplacement;
|
||||
private JTextField myElementDefine;
|
||||
private JTextField myAttlistDefine;
|
||||
private JTextField myAnyName;
|
||||
private JCheckBox myStrictAnyCheckBox;
|
||||
private JTextField myAnnotationPrefix;
|
||||
private JCheckBox myGenerateStartCheckBox;
|
||||
private JTextField myDefaultNS;
|
||||
private JTable myNamespaceMap;
|
||||
|
||||
private JPanel myToolbar;
|
||||
|
||||
public AdvancedDtdOptions() {
|
||||
myInlineAttlistCheckBox.addItemListener(new ItemListener() {
|
||||
public void itemStateChanged(ItemEvent e) {
|
||||
if (e.getStateChange() == ItemEvent.SELECTED) {
|
||||
myAttlistDefine.setEnabled(false);
|
||||
} else {
|
||||
myAttlistDefine.setEnabled(true);
|
||||
}
|
||||
}
|
||||
});
|
||||
myNamespaceMap.setModel(new NamespaceMapModel());
|
||||
myNamespaceMap.getColumnModel().getColumn(0).setMaxWidth((int)(new JLabel("Prefix").getPreferredSize().width * 1.2));
|
||||
|
||||
final DefaultActionGroup group = new DefaultActionGroup();
|
||||
group.add(new AnAction(null, "Remove Entry", IconLoader.findIcon("/general/remove.png")) {
|
||||
public void update(AnActionEvent e) {
|
||||
if (myNamespaceMap.getModel().getRowCount() == 0 || myNamespaceMap.getSelectedRow() == -1) {
|
||||
e.getPresentation().setEnabled(false);
|
||||
} else {
|
||||
e.getPresentation().setEnabled(true);
|
||||
}
|
||||
}
|
||||
|
||||
public void actionPerformed(AnActionEvent e) {
|
||||
((NamespaceMapModel)myNamespaceMap.getModel()).removeRow(myNamespaceMap.getSelectedRow());
|
||||
}
|
||||
});
|
||||
|
||||
final ActionToolbar toolbar = ActionManager.getInstance().createActionToolbar(ActionPlaces.UNKNOWN, group, false);
|
||||
myToolbar.add(toolbar.getComponent());
|
||||
}
|
||||
|
||||
public JComponent getRoot() {
|
||||
return myRoot;
|
||||
}
|
||||
|
||||
public Map<String, ?> getOptions() {
|
||||
final HashMap<String, Object> map = new LinkedHashMap<String, Object>();
|
||||
|
||||
map.put(INLINE_ATTLIST, myInlineAttlistCheckBox.isSelected());
|
||||
|
||||
setText(map, COLON_REPLACEMENT, myColonReplacement);
|
||||
setText(map, ELEMENT_DEFINE, myElementDefine);
|
||||
setText(map, ATTLIST_DEFINE, myAttlistDefine);
|
||||
setText(map, ANY_NAME, myAnyName);
|
||||
|
||||
if (myStrictAnyCheckBox.isSelected()) {
|
||||
map.put(STRICT_ANY, Boolean.TRUE);
|
||||
}
|
||||
|
||||
setText(map, ANNOTATION_PREFIX, myAnnotationPrefix);
|
||||
|
||||
map.put(GENERATE_START, myGenerateStartCheckBox.isSelected());
|
||||
|
||||
if (myDefaultNS.getText().trim().length() > 0) {
|
||||
map.put(XMLNS, myDefaultNS.getText() );
|
||||
}
|
||||
|
||||
final List<String[]> data = ((NamespaceMapModel)myNamespaceMap.getModel()).getData();
|
||||
for (String[] parts : data) {
|
||||
map.put(XMLNS + ":" + parts[0], parts[1]);
|
||||
}
|
||||
|
||||
return map;
|
||||
}
|
||||
|
||||
private static void setText(HashMap<String, Object> map, String option, JTextField field) {
|
||||
final String colonReplacement = field.getText();
|
||||
if (colonReplacement != null && colonReplacement.trim().length() > 0) {
|
||||
map.put(option, colonReplacement);
|
||||
}
|
||||
}
|
||||
|
||||
public void setOptions(Map<String, ?> inputOptions) {
|
||||
if (inputOptions.containsKey(COLON_REPLACEMENT)) {
|
||||
myColonReplacement.setText((String)inputOptions.get(COLON_REPLACEMENT));
|
||||
}
|
||||
myInlineAttlistCheckBox.setSelected(inputOptions.get(INLINE_ATTLIST) == Boolean.TRUE);
|
||||
|
||||
if (inputOptions.containsKey(ELEMENT_DEFINE)) {
|
||||
myElementDefine.setText((String)inputOptions.get(ELEMENT_DEFINE));
|
||||
}
|
||||
if (inputOptions.containsKey(ATTLIST_DEFINE)) {
|
||||
myAttlistDefine.setText((String)inputOptions.get(ATTLIST_DEFINE));
|
||||
}
|
||||
if (inputOptions.containsKey(ANY_NAME)) {
|
||||
myAnyName.setText((String)inputOptions.get(ANY_NAME));
|
||||
}
|
||||
myStrictAnyCheckBox.setSelected(inputOptions.get(STRICT_ANY) == Boolean.TRUE);
|
||||
if (inputOptions.containsKey(ANNOTATION_PREFIX)) {
|
||||
myAnnotationPrefix.setText((String)inputOptions.get(ANNOTATION_PREFIX));
|
||||
}
|
||||
myGenerateStartCheckBox.setSelected(inputOptions.get(GENERATE_START) == Boolean.TRUE);
|
||||
if (inputOptions.containsKey(XMLNS)) {
|
||||
myDefaultNS.setText((String)inputOptions.get(XMLNS));
|
||||
}
|
||||
|
||||
final NamespaceMapModel model = (NamespaceMapModel)myNamespaceMap.getModel();
|
||||
final Set<String> set = inputOptions.keySet();
|
||||
final String prefix = XMLNS + ":";
|
||||
for (String s : set) {
|
||||
if (s.startsWith(prefix)) {
|
||||
model.addMapping(s.substring(prefix.length()), (String)inputOptions.get(s));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static Map<String, ?> prepareNamespaceMap(Project project, VirtualFile firstFile) {
|
||||
final PsiFile file = PsiManager.getInstance(project).findFile(firstFile);
|
||||
if (file == null) {
|
||||
return Collections.emptyMap();
|
||||
}
|
||||
|
||||
final HashMap<String, Object> map = new LinkedHashMap<String, Object>();
|
||||
file.accept(new PsiRecursiveElementVisitor() {
|
||||
public void visitElement(PsiElement element) {
|
||||
if (element instanceof XmlElementDecl) {
|
||||
final String s = ((XmlElementDecl)element).getName();
|
||||
if (s != null) {
|
||||
final String[] parts = s.split(":");
|
||||
if (parts.length > 1) {
|
||||
map.put(XMLNS + ":" + parts[0], null);
|
||||
}
|
||||
}
|
||||
} else if (element instanceof XmlAttributeDecl) {
|
||||
final String s = ((XmlAttributeDecl)element).getName();
|
||||
if (s != null) {
|
||||
final String[] parts = s.split(":");
|
||||
if (parts.length > 1) {
|
||||
map.put(XMLNS + ":" + parts[0], null);
|
||||
}
|
||||
}
|
||||
}
|
||||
super.visitElement(element);
|
||||
}
|
||||
});
|
||||
|
||||
return map;
|
||||
}
|
||||
|
||||
private static class NamespaceMapModel extends AbstractTableModel {
|
||||
private final List<String[]> myList = new ArrayList<String[]>();
|
||||
|
||||
public String getColumnName(int column) {
|
||||
return column == 0 ? "Prefix" : "URI";
|
||||
}
|
||||
|
||||
public int getRowCount() {
|
||||
return myList.size();
|
||||
}
|
||||
|
||||
public int getColumnCount() {
|
||||
return 2;
|
||||
}
|
||||
|
||||
public boolean isCellEditable(int rowIndex, int columnIndex) {
|
||||
return columnIndex == 1;
|
||||
}
|
||||
|
||||
public void setValueAt(Object aValue, int rowIndex, int columnIndex) {
|
||||
myList.get(rowIndex)[columnIndex] = (String)aValue;
|
||||
}
|
||||
|
||||
public Object getValueAt(int rowIndex, int columnIndex) {
|
||||
return myList.get(rowIndex)[columnIndex];
|
||||
}
|
||||
|
||||
public void addMapping(String prefix, String uri) {
|
||||
myList.add(new String[]{ prefix, uri });
|
||||
fireTableRowsInserted(myList.size() - 1, myList.size() - 1);
|
||||
}
|
||||
|
||||
public void removeRow(int row) {
|
||||
myList.remove(row);
|
||||
fireTableRowsDeleted(row - 1, row - 1);
|
||||
}
|
||||
|
||||
public List<String[]> getData() {
|
||||
return myList;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
/*
|
||||
* Copyright 2007 Sascha Weinreuter
|
||||
*
|
||||
* 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 org.intellij.plugins.relaxNG.convert;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.util.Map;
|
||||
|
||||
/*
|
||||
* Created by IntelliJ IDEA.
|
||||
* User: sweinreuter
|
||||
* Date: 19.11.2007
|
||||
*/
|
||||
public interface AdvancedOptions {
|
||||
JComponent getRoot();
|
||||
|
||||
Map<String, ?> getOptions();
|
||||
|
||||
void setOptions(Map<String, ?> options);
|
||||
}
|
||||
@@ -0,0 +1,95 @@
|
||||
/*
|
||||
* Copyright 2007 Sascha Weinreuter
|
||||
*
|
||||
* 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 org.intellij.plugins.relaxNG.convert;
|
||||
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.ui.DialogWrapper;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.util.Map;
|
||||
|
||||
/*
|
||||
* Created by IntelliJ IDEA.
|
||||
* User: sweinreuter
|
||||
* Date: 16.11.2007
|
||||
*/
|
||||
public class AdvancedOptionsDialog extends DialogWrapper {
|
||||
private AdvancedOptions myInputOptions;
|
||||
private AdvancedOptions myOutputOptions;
|
||||
|
||||
private Map<String,?> myInputOptions_;
|
||||
private Map<String,?> myOutputOptions_;
|
||||
|
||||
protected AdvancedOptionsDialog(Project project, SchemaType inputType, SchemaType outputType) {
|
||||
super(project, false);
|
||||
setTitle("Advanced Conversion Options");
|
||||
|
||||
if (inputType == SchemaType.DTD) {
|
||||
myInputOptions = new AdvancedDtdOptions();
|
||||
}
|
||||
if (outputType == SchemaType.XSD) {
|
||||
myOutputOptions = new AdvancedXsdOptions();
|
||||
}
|
||||
|
||||
init();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
protected JComponent createCenterPanel() {
|
||||
JComponent root;
|
||||
if (myInputOptions != null && myOutputOptions != null) {
|
||||
root = new JTabbedPane();
|
||||
((JTabbedPane)root).addTab("Input", myInputOptions.getRoot());
|
||||
((JTabbedPane)root).addTab("Output", myOutputOptions.getRoot());
|
||||
} else if (myInputOptions != null) {
|
||||
root = myInputOptions.getRoot();
|
||||
} else {
|
||||
root = myOutputOptions.getRoot();
|
||||
}
|
||||
return root;
|
||||
}
|
||||
|
||||
public Map<String, ?> getInputOptions() {
|
||||
if (myInputOptions != null) {
|
||||
return myInputOptions.getOptions();
|
||||
} else {
|
||||
return myInputOptions_;
|
||||
}
|
||||
}
|
||||
|
||||
public Map<String, ?> getOutputOptions() {
|
||||
if (myOutputOptions != null) {
|
||||
return myOutputOptions.getOptions();
|
||||
} else {
|
||||
return myOutputOptions_;
|
||||
}
|
||||
}
|
||||
|
||||
public void setOptions(Map<String, ?> inputOptions, Map<String, ?> outputOptions) {
|
||||
if (myInputOptions != null) {
|
||||
myInputOptions.setOptions(inputOptions);
|
||||
} else {
|
||||
myInputOptions_ = inputOptions;
|
||||
}
|
||||
if (myOutputOptions != null) {
|
||||
myOutputOptions.setOptions(outputOptions);
|
||||
} else {
|
||||
myOutputOptions_ = outputOptions;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,71 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<form xmlns="http://www.intellij.com/uidesigner/form/" version="1" bind-to-class="org.intellij.plugins.relaxNG.convert.AdvancedXsdOptions">
|
||||
<grid id="27dc6" binding="myRoot" layout-manager="GridLayoutManager" row-count="4" column-count="2" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
|
||||
<margin top="0" left="0" bottom="0" right="0"/>
|
||||
<constraints>
|
||||
<xy x="20" y="20" width="335" height="128"/>
|
||||
</constraints>
|
||||
<properties/>
|
||||
<border type="none" title="W3C XML Schema Output"/>
|
||||
<children>
|
||||
<vspacer id="bb5e1">
|
||||
<constraints>
|
||||
<grid row="3" column="0" row-span="1" col-span="1" vsize-policy="6" hsize-policy="1" anchor="0" fill="2" indent="0" use-parent-layout="false"/>
|
||||
</constraints>
|
||||
</vspacer>
|
||||
<component id="d49de" class="javax.swing.JLabel">
|
||||
<constraints>
|
||||
<grid row="1" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
|
||||
</constraints>
|
||||
<properties>
|
||||
<labelFor value="480bc"/>
|
||||
<text value="&any-process-contents"/>
|
||||
<toolTipText value="Specifies the value for the processContents attribute of any elements. The default is skip (corresponding to RELAX NG semantics) unless the input format is dtd, in which case the default is strict (corresponding to DTD semantics). "/>
|
||||
</properties>
|
||||
</component>
|
||||
<component id="272a3" class="javax.swing.JLabel">
|
||||
<constraints>
|
||||
<grid row="2" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
|
||||
</constraints>
|
||||
<properties>
|
||||
<labelFor value="6d96a"/>
|
||||
<text value="a&ny-attribute-process-contents"/>
|
||||
<toolTipText value="Specifies the value for the processContents attribute of any Attribute elements. The default is skip (corresponding to RELAX NG semantics). "/>
|
||||
</properties>
|
||||
</component>
|
||||
<component id="480bc" class="com.intellij.openapi.ui.ComboBox" binding="myAnyProcessContents">
|
||||
<constraints>
|
||||
<grid row="1" column="1" row-span="1" col-span="1" vsize-policy="3" hsize-policy="7" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
|
||||
</constraints>
|
||||
<properties>
|
||||
<model>
|
||||
<item value="strict"/>
|
||||
<item value="lax"/>
|
||||
<item value="skip"/>
|
||||
</model>
|
||||
</properties>
|
||||
</component>
|
||||
<component id="6d96a" class="com.intellij.openapi.ui.ComboBox" binding="myAnyAttributeProcessContents">
|
||||
<constraints>
|
||||
<grid row="2" column="1" row-span="1" col-span="1" vsize-policy="3" hsize-policy="7" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
|
||||
</constraints>
|
||||
<properties>
|
||||
<model>
|
||||
<item value="strict"/>
|
||||
<item value="lax"/>
|
||||
<item value="skip"/>
|
||||
</model>
|
||||
</properties>
|
||||
</component>
|
||||
<component id="1cd5c" class="javax.swing.JCheckBox" binding="myDisableAbstractElements" default-binding="true">
|
||||
<constraints>
|
||||
<grid row="0" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
|
||||
</constraints>
|
||||
<properties>
|
||||
<text value="&disable-abstract-elements"/>
|
||||
<toolTipText value="Disables the use of abstract elements and subsitution groups in the generated XML Schema. This can also be controlled using an annotation attribute."/>
|
||||
</properties>
|
||||
</component>
|
||||
</children>
|
||||
</grid>
|
||||
</form>
|
||||
@@ -0,0 +1,70 @@
|
||||
/*
|
||||
* Copyright 2007 Sascha Weinreuter
|
||||
*
|
||||
* 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 org.intellij.plugins.relaxNG.convert;
|
||||
|
||||
import com.intellij.openapi.ui.ComboBox;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Created by IntelliJ IDEA.
|
||||
* User: sweinreuter
|
||||
* Date: 18.11.2007
|
||||
*/
|
||||
public class AdvancedXsdOptions implements AdvancedOptions {
|
||||
@NonNls
|
||||
private static final String DISABLE_ABSTRACT_ELEMENTS = "disable-abstract-elements";
|
||||
@NonNls
|
||||
private static final String ANY_PROCESS_CONTENTS = "any-process-contents";
|
||||
@NonNls
|
||||
private static final String ANY_ATTRIBUTE_PROCESS_CONTENTS = "any-attribute-process-contents";
|
||||
|
||||
private JComponent myRoot;
|
||||
|
||||
private JCheckBox myDisableAbstractElements;
|
||||
private ComboBox myAnyProcessContents;
|
||||
private ComboBox myAnyAttributeProcessContents;
|
||||
|
||||
public JComponent getRoot() {
|
||||
return myRoot;
|
||||
}
|
||||
|
||||
public Map<String, ?> getOptions() {
|
||||
final Map<String, Object> strings = new HashMap<String, Object>();
|
||||
if (myDisableAbstractElements.isSelected()) {
|
||||
strings.put(DISABLE_ABSTRACT_ELEMENTS, Boolean.TRUE);
|
||||
}
|
||||
strings.put(ANY_PROCESS_CONTENTS, myAnyProcessContents.getSelectedItem());
|
||||
strings.put(ANY_ATTRIBUTE_PROCESS_CONTENTS, myAnyAttributeProcessContents.getSelectedItem());
|
||||
return strings;
|
||||
}
|
||||
|
||||
public void setOptions(Map<String, ?> inputOptions) {
|
||||
myDisableAbstractElements.setSelected(inputOptions.get(DISABLE_ABSTRACT_ELEMENTS) == Boolean.TRUE);
|
||||
final Object o = inputOptions.get(ANY_PROCESS_CONTENTS);
|
||||
if (o != null) {
|
||||
myAnyProcessContents.setSelectedItem(o);
|
||||
}
|
||||
final Object o2 = inputOptions.get(ANY_ATTRIBUTE_PROCESS_CONTENTS);
|
||||
if (o2 != null) {
|
||||
myAnyAttributeProcessContents.setSelectedItem(o2);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,121 @@
|
||||
/*
|
||||
* Copyright 2007 Sascha Weinreuter
|
||||
*
|
||||
* 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 org.intellij.plugins.relaxNG.convert;
|
||||
|
||||
import com.intellij.openapi.actionSystem.AnAction;
|
||||
import com.intellij.openapi.actionSystem.AnActionEvent;
|
||||
import com.intellij.openapi.actionSystem.PlatformDataKeys;
|
||||
import com.intellij.openapi.fileTypes.FileType;
|
||||
import com.intellij.openapi.fileTypes.StdFileTypes;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.vfs.LocalFileSystem;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.psi.PsiFile;
|
||||
import com.intellij.psi.PsiManager;
|
||||
import com.intellij.psi.xml.XmlDocument;
|
||||
import com.intellij.psi.xml.XmlFile;
|
||||
import com.intellij.psi.xml.XmlTag;
|
||||
import org.intellij.plugins.relaxNG.ProjectLoader;
|
||||
import org.intellij.plugins.relaxNG.compact.RncFileType;
|
||||
import org.intellij.plugins.relaxNG.validation.ValidateAction;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
/*
|
||||
* Created by IntelliJ IDEA.
|
||||
* User: sweinreuter
|
||||
* Date: 16.11.2007
|
||||
*/
|
||||
public class ConvertSchemaAction extends AnAction {
|
||||
|
||||
public void update(AnActionEvent e) {
|
||||
final VirtualFile[] files = e.getData(PlatformDataKeys.VIRTUAL_FILE_ARRAY);
|
||||
final Project project = e.getData(PlatformDataKeys.PROJECT);
|
||||
if (files != null && project != null) {
|
||||
final SchemaType type = getInputType(project, files);
|
||||
e.getPresentation().setEnabled(type != null);
|
||||
if (type == SchemaType.XML) {
|
||||
e.getPresentation().setText("Generate Schema from XML file" + (files.length > 1 ? "s" : "") + "...");
|
||||
} else {
|
||||
e.getPresentation().setText("Convert Schema...");
|
||||
}
|
||||
} else {
|
||||
e.getPresentation().setEnabled(false);
|
||||
}
|
||||
}
|
||||
|
||||
private static SchemaType getInputType(Project project, VirtualFile... files) {
|
||||
if (files.length == 0) return null;
|
||||
|
||||
final VirtualFile file = files[0];
|
||||
final FileType type = file.getFileType();
|
||||
if (type == StdFileTypes.XML) {
|
||||
final PsiFile psiFile = PsiManager.getInstance(project).findFile(file);
|
||||
if (psiFile instanceof XmlFile) {
|
||||
final XmlDocument document = ((XmlFile)psiFile).getDocument();
|
||||
if (document != null && document.getRootTag() != null) {
|
||||
final XmlTag rootTag = document.getRootTag();
|
||||
assert rootTag != null;
|
||||
final String uri = rootTag.getNamespace();
|
||||
if (ProjectLoader.RNG_NAMESPACE.equals(uri) && files.length == 1) {
|
||||
return SchemaType.RNG;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (files.length > 1) {
|
||||
for (VirtualFile virtualFile : files) {
|
||||
if (virtualFile.getFileType() != StdFileTypes.XML || getInputType(project, virtualFile) != null) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
return SchemaType.XML;
|
||||
} else if (type == StdFileTypes.DTD && files.length == 1) {
|
||||
return SchemaType.DTD;
|
||||
} else if (type == RncFileType.getInstance() && files.length == 1) {
|
||||
return SchemaType.RNC;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public void actionPerformed(AnActionEvent e) {
|
||||
final VirtualFile file = e.getData(PlatformDataKeys.VIRTUAL_FILE);
|
||||
final Project project = e.getData(PlatformDataKeys.PROJECT);
|
||||
if (file != null && project != null) {
|
||||
final VirtualFile[] files = e.getData(PlatformDataKeys.VIRTUAL_FILE_ARRAY);
|
||||
assert files != null;
|
||||
|
||||
final SchemaType type = getInputType(project, files);
|
||||
final ConvertSchemaDialog dialog = new ConvertSchemaDialog(project, type, file);
|
||||
dialog.show();
|
||||
if (!dialog.isOK()) {
|
||||
return;
|
||||
}
|
||||
|
||||
ValidateAction.saveFiles(files);
|
||||
|
||||
final ConvertSchemaSettings settings = dialog.getSettings();
|
||||
final IdeaErrorHandler errorHandler = new IdeaErrorHandler(project);
|
||||
new IdeaDriver(settings, project).convert(type, errorHandler, files);
|
||||
|
||||
final VirtualFile output = LocalFileSystem.getInstance().findFileByIoFile(new File(settings.getOutputDestination()));
|
||||
if (output != null) {
|
||||
output.refresh(false, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,86 @@
|
||||
/*
|
||||
* Copyright 2007 Sascha Weinreuter
|
||||
*
|
||||
* 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 org.intellij.plugins.relaxNG.convert;
|
||||
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.ui.DialogWrapper;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.beans.PropertyChangeEvent;
|
||||
import java.beans.PropertyChangeListener;
|
||||
|
||||
/*
|
||||
* Created by IntelliJ IDEA.
|
||||
* User: sweinreuter
|
||||
* Date: 16.11.2007
|
||||
*/
|
||||
public class ConvertSchemaDialog extends DialogWrapper implements PropertyChangeListener {
|
||||
private final ConvertSchemaSettingsImpl mySettings;
|
||||
private final AbstractAction myAdvancedAction;
|
||||
|
||||
protected ConvertSchemaDialog(Project project, SchemaType input, VirtualFile firstFile) {
|
||||
super(project, false);
|
||||
setTitle("Convert Schema File");
|
||||
|
||||
mySettings = new ConvertSchemaSettingsImpl(project, input, firstFile);
|
||||
mySettings.addPropertyChangeListener(ConvertSchemaSettingsImpl.OUTPUT_TYPE, this);
|
||||
mySettings.addPropertyChangeListener(ConvertSchemaSettingsImpl.OUTPUT_PATH, this);
|
||||
|
||||
myAdvancedAction = new AbstractAction("Advanced...") {
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
mySettings.showAdvancedSettings();
|
||||
}
|
||||
};
|
||||
myAdvancedAction.setEnabled(mySettings.hasAdvancedSettings());
|
||||
|
||||
init();
|
||||
|
||||
getOKAction().setEnabled(mySettings.getOutputDestination().trim().length() > 0);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Action[] createLeftSideActions() {
|
||||
return new Action[]{
|
||||
myAdvancedAction
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public JComponent getPreferredFocusedComponent() {
|
||||
return mySettings.getPreferredFocusedComponent();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
protected JComponent createCenterPanel() {
|
||||
return mySettings.getRoot();
|
||||
}
|
||||
|
||||
public ConvertSchemaSettings getSettings() {
|
||||
return mySettings;
|
||||
}
|
||||
|
||||
public void propertyChange(PropertyChangeEvent evt) {
|
||||
if (ConvertSchemaSettingsImpl.OUTPUT_TYPE.equals(evt.getPropertyName())) {
|
||||
myAdvancedAction.setEnabled(mySettings.hasAdvancedSettings());
|
||||
} else if (ConvertSchemaSettingsImpl.OUTPUT_PATH.equals(evt.getPropertyName())) {
|
||||
getOKAction().setEnabled(((String)evt.getNewValue()).trim().length() > 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
/*
|
||||
* Copyright 2007 Sascha Weinreuter
|
||||
*
|
||||
* 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 org.intellij.plugins.relaxNG.convert;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Created by IntelliJ IDEA.
|
||||
* User: sweinreuter
|
||||
* Date: 17.11.2007
|
||||
*/
|
||||
public interface ConvertSchemaSettings {
|
||||
@NotNull
|
||||
SchemaType getOutputType();
|
||||
|
||||
String getOutputEncoding();
|
||||
|
||||
int getIndent();
|
||||
|
||||
int getLineLength();
|
||||
|
||||
String getOutputDestination();
|
||||
|
||||
void addAdvancedSettings(List<String> inputParams, List<String> outputParams);
|
||||
}
|
||||
+152
@@ -0,0 +1,152 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<form xmlns="http://www.intellij.com/uidesigner/form/" version="1" bind-to-class="org.intellij.plugins.relaxNG.convert.ConvertSchemaSettingsImpl">
|
||||
<grid id="27dc6" binding="myRoot" layout-manager="GridLayoutManager" row-count="3" column-count="2" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
|
||||
<margin top="0" left="0" bottom="0" right="0"/>
|
||||
<constraints>
|
||||
<xy x="20" y="20" width="496" height="223"/>
|
||||
</constraints>
|
||||
<properties/>
|
||||
<border type="none"/>
|
||||
<children>
|
||||
<vspacer id="954f0">
|
||||
<constraints>
|
||||
<grid row="2" column="0" row-span="1" col-span="1" vsize-policy="6" hsize-policy="1" anchor="0" fill="2" indent="0" use-parent-layout="false"/>
|
||||
</constraints>
|
||||
</vspacer>
|
||||
<grid id="ba28d" layout-manager="GridLayoutManager" row-count="4" column-count="1" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
|
||||
<margin top="0" left="0" bottom="0" right="0"/>
|
||||
<constraints>
|
||||
<grid row="0" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="8" fill="2" indent="0" use-parent-layout="false"/>
|
||||
</constraints>
|
||||
<properties/>
|
||||
<border type="none" title="Output Type"/>
|
||||
<children>
|
||||
<component id="ae717" class="javax.swing.JRadioButton" binding="myOutputRnc">
|
||||
<constraints>
|
||||
<grid row="1" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
|
||||
</constraints>
|
||||
<properties>
|
||||
<text value="RELAX NG - &Compact Syntax"/>
|
||||
</properties>
|
||||
</component>
|
||||
<component id="42e64" class="javax.swing.JRadioButton" binding="myOutputXsd">
|
||||
<constraints>
|
||||
<grid row="2" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
|
||||
</constraints>
|
||||
<properties>
|
||||
<text value="W3C XML &Schema"/>
|
||||
</properties>
|
||||
</component>
|
||||
<component id="68cdd" class="javax.swing.JRadioButton" binding="myOutputDtd">
|
||||
<constraints>
|
||||
<grid row="3" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
|
||||
</constraints>
|
||||
<properties>
|
||||
<text value="&DTD"/>
|
||||
</properties>
|
||||
</component>
|
||||
<component id="a174f" class="javax.swing.JRadioButton" binding="myOutputRng">
|
||||
<constraints>
|
||||
<grid row="0" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
|
||||
</constraints>
|
||||
<properties>
|
||||
<text value="&RELAX NG - XML Syntax"/>
|
||||
</properties>
|
||||
</component>
|
||||
</children>
|
||||
</grid>
|
||||
<grid id="a8d13" layout-manager="GridLayoutManager" row-count="4" column-count="2" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
|
||||
<margin top="0" left="0" bottom="0" right="0"/>
|
||||
<constraints>
|
||||
<grid row="0" column="1" row-span="1" col-span="1" vsize-policy="3" hsize-policy="7" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
|
||||
</constraints>
|
||||
<properties/>
|
||||
<border type="none" title="Output Options"/>
|
||||
<children>
|
||||
<component id="a450" class="javax.swing.JLabel">
|
||||
<constraints>
|
||||
<grid row="0" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
|
||||
</constraints>
|
||||
<properties>
|
||||
<labelFor value="2ab32"/>
|
||||
<text value="&Encoding:"/>
|
||||
</properties>
|
||||
</component>
|
||||
<vspacer id="deedc">
|
||||
<constraints>
|
||||
<grid row="3" column="0" row-span="1" col-span="1" vsize-policy="6" hsize-policy="1" anchor="0" fill="2" indent="0" use-parent-layout="false"/>
|
||||
</constraints>
|
||||
</vspacer>
|
||||
<component id="2ab32" class="com.intellij.openapi.ui.ComboBox" binding="myEncoding">
|
||||
<constraints>
|
||||
<grid row="0" column="1" row-span="1" col-span="1" vsize-policy="3" hsize-policy="7" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
|
||||
</constraints>
|
||||
<properties/>
|
||||
</component>
|
||||
<component id="b3b11" class="javax.swing.JTextField" binding="myIndent">
|
||||
<constraints>
|
||||
<grid row="1" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="6" anchor="8" fill="1" indent="0" use-parent-layout="false">
|
||||
<preferred-size width="150" height="-1"/>
|
||||
</grid>
|
||||
</constraints>
|
||||
<properties/>
|
||||
</component>
|
||||
<component id="ce882" class="javax.swing.JLabel">
|
||||
<constraints>
|
||||
<grid row="1" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
|
||||
</constraints>
|
||||
<properties>
|
||||
<labelFor value="b3b11"/>
|
||||
<text value="&Indent:"/>
|
||||
</properties>
|
||||
</component>
|
||||
<component id="42a61" class="javax.swing.JLabel">
|
||||
<constraints>
|
||||
<grid row="2" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
|
||||
</constraints>
|
||||
<properties>
|
||||
<labelFor value="9a106"/>
|
||||
<text value="&Line Length:"/>
|
||||
</properties>
|
||||
</component>
|
||||
<component id="9a106" class="javax.swing.JTextField" binding="myLineLength">
|
||||
<constraints>
|
||||
<grid row="2" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="6" anchor="8" fill="1" indent="0" use-parent-layout="false">
|
||||
<preferred-size width="150" height="-1"/>
|
||||
</grid>
|
||||
</constraints>
|
||||
<properties/>
|
||||
</component>
|
||||
</children>
|
||||
</grid>
|
||||
<grid id="816e7" layout-manager="GridLayoutManager" row-count="1" column-count="1" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
|
||||
<margin top="0" left="0" bottom="0" right="0"/>
|
||||
<constraints>
|
||||
<grid row="1" column="0" row-span="1" col-span="2" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
|
||||
</constraints>
|
||||
<properties/>
|
||||
<border type="none" title="Output Destination"/>
|
||||
<children>
|
||||
<component id="5b279" class="com.intellij.openapi.ui.TextFieldWithBrowseButton" binding="myOutputDestination">
|
||||
<constraints>
|
||||
<grid row="0" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="7" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
|
||||
</constraints>
|
||||
<properties/>
|
||||
</component>
|
||||
</children>
|
||||
</grid>
|
||||
</children>
|
||||
</grid>
|
||||
<buttonGroups>
|
||||
<group name="outputType">
|
||||
<member id="ae717"/>
|
||||
<member id="ae717"/>
|
||||
<member id="42e64"/>
|
||||
<member id="68cdd"/>
|
||||
<member id="a174f"/>
|
||||
</group>
|
||||
</buttonGroups>
|
||||
<inspectionSuppressions>
|
||||
<suppress inspection="NoLabelFor" id="5b279"/>
|
||||
</inspectionSuppressions>
|
||||
</form>
|
||||
+257
@@ -0,0 +1,257 @@
|
||||
/*
|
||||
* Copyright 2007 Sascha Weinreuter
|
||||
*
|
||||
* 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 org.intellij.plugins.relaxNG.convert;
|
||||
|
||||
import com.intellij.openapi.actionSystem.LangDataKeys;
|
||||
import com.intellij.openapi.fileChooser.FileChooserDescriptor;
|
||||
import com.intellij.openapi.fileTypes.FileType;
|
||||
import com.intellij.openapi.fileTypes.StdFileTypes;
|
||||
import com.intellij.openapi.module.Module;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.roots.ProjectRootManager;
|
||||
import com.intellij.openapi.ui.ComboBox;
|
||||
import com.intellij.openapi.ui.TextFieldWithBrowseButton;
|
||||
import com.intellij.openapi.vfs.CharsetToolkit;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.openapi.vfs.encoding.EncodingManager;
|
||||
import com.intellij.psi.codeStyle.CodeStyleSettings;
|
||||
import com.intellij.psi.codeStyle.CodeStyleSettingsManager;
|
||||
import com.intellij.ui.DocumentAdapter;
|
||||
import org.intellij.plugins.relaxNG.compact.RncFileType;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import javax.swing.*;
|
||||
import javax.swing.event.DocumentEvent;
|
||||
import java.awt.event.ItemEvent;
|
||||
import java.awt.event.ItemListener;
|
||||
import java.beans.PropertyChangeListener;
|
||||
import java.beans.PropertyChangeSupport;
|
||||
import java.io.File;
|
||||
import java.nio.charset.Charset;
|
||||
import java.util.*;
|
||||
|
||||
/*
|
||||
* Created by IntelliJ IDEA.
|
||||
* User: sweinreuter
|
||||
* Date: 16.11.2007
|
||||
*/
|
||||
public class ConvertSchemaSettingsImpl implements ConvertSchemaSettings {
|
||||
static final String OUTPUT_TYPE = "output-type";
|
||||
static final String OUTPUT_PATH = "output-path";
|
||||
|
||||
private final PropertyChangeSupport myPropertyChangeSupport = new PropertyChangeSupport(this);
|
||||
private final Project myProject;
|
||||
private final SchemaType myInputType;
|
||||
|
||||
private Map<String, ?> myInputOptions = Collections.emptyMap();
|
||||
private Map<String, ?> myOutputOptions = Collections.emptyMap();
|
||||
|
||||
private JPanel myRoot;
|
||||
|
||||
private JRadioButton myOutputRng;
|
||||
private JRadioButton myOutputRnc;
|
||||
private JRadioButton myOutputXsd;
|
||||
private JRadioButton myOutputDtd;
|
||||
|
||||
private ComboBox myEncoding;
|
||||
|
||||
private JTextField myIndent;
|
||||
private JTextField myLineLength;
|
||||
|
||||
private TextFieldWithBrowseButton myOutputDestination;
|
||||
|
||||
public ConvertSchemaSettingsImpl(Project project, @NotNull SchemaType inputType, VirtualFile firstFile) {
|
||||
myProject = project;
|
||||
myInputType = inputType;
|
||||
|
||||
final FileType type;
|
||||
switch (inputType) {
|
||||
case RNG:
|
||||
myOutputRng.setVisible(false);
|
||||
myOutputXsd.setSelected(true);
|
||||
type = StdFileTypes.XML;
|
||||
break;
|
||||
case RNC:
|
||||
myOutputRnc.setVisible(false);
|
||||
myOutputRng.setSelected(true);
|
||||
type = RncFileType.getInstance();
|
||||
break;
|
||||
case XSD:
|
||||
myOutputXsd.setVisible(false);
|
||||
myOutputRng.setSelected(true);
|
||||
type = StdFileTypes.XML;
|
||||
break;
|
||||
case DTD:
|
||||
myOutputDtd.setVisible(false);
|
||||
myOutputRng.setSelected(true);
|
||||
type = StdFileTypes.DTD;
|
||||
break;
|
||||
case XML:
|
||||
myOutputRng.setSelected(true);
|
||||
type = StdFileTypes.XML;
|
||||
break;
|
||||
default:
|
||||
assert false;
|
||||
type = null;
|
||||
}
|
||||
|
||||
final Charset[] charsets = CharsetToolkit.getAvailableCharsets();
|
||||
final List<String> suggestions = new ArrayList<String>(charsets.length);
|
||||
for (Charset charset : charsets) {
|
||||
if (charset.canEncode()) {
|
||||
String name = charset.name();
|
||||
suggestions.add(name);
|
||||
}
|
||||
}
|
||||
|
||||
myEncoding.setModel(new DefaultComboBoxModel(suggestions.toArray()));
|
||||
final Charset charset = EncodingManager.getInstance().getDefaultCharset();
|
||||
if (charset == null) {
|
||||
myEncoding.setSelectedItem(System.getProperty("file.encoding", "UTF-8"));
|
||||
} else {
|
||||
myEncoding.setSelectedItem(charset.name());
|
||||
}
|
||||
|
||||
final CodeStyleSettings styleSettings = CodeStyleSettingsManager.getSettings(project);
|
||||
final int indent = styleSettings.getIndentSize(type);
|
||||
myIndent.setText(String.valueOf(indent));
|
||||
|
||||
myLineLength.setText(String.valueOf(styleSettings.RIGHT_MARGIN));
|
||||
final SchemaType outputType = getOutputType();
|
||||
myLineLength.setEnabled(outputType == SchemaType.DTD || outputType == SchemaType.RNC);
|
||||
|
||||
final FileChooserDescriptor descriptor = new FileChooserDescriptor(true, true, false, false, false, false);
|
||||
final Module module = ProjectRootManager.getInstance(project).getFileIndex().getModuleForFile(firstFile);
|
||||
descriptor.putUserData(LangDataKeys.MODULE_CONTEXT, module);
|
||||
|
||||
myOutputDestination.addBrowseFolderListener("Schema Conversion Destination",
|
||||
"Please select the destination the generated file(s) should be placed at", project, descriptor);
|
||||
|
||||
final JTextField tf = myOutputDestination.getTextField();
|
||||
tf.getDocument().addDocumentListener(new DocumentAdapter() {
|
||||
protected void textChanged(DocumentEvent e) {
|
||||
myPropertyChangeSupport.firePropertyChange(OUTPUT_PATH, null, getOutputDestination());
|
||||
}
|
||||
});
|
||||
tf.setText(firstFile.getParent().getPath().replace('/', File.separatorChar));
|
||||
|
||||
final ItemListener listener = new ItemListener() {
|
||||
public void itemStateChanged(ItemEvent e) {
|
||||
if (e.getStateChange() == ItemEvent.SELECTED) {
|
||||
final SchemaType type = getOutputType();
|
||||
myPropertyChangeSupport.firePropertyChange(OUTPUT_TYPE, null, type);
|
||||
myLineLength.setEnabled(type == SchemaType.DTD || type == SchemaType.RNC);
|
||||
}
|
||||
}
|
||||
};
|
||||
myOutputRng.addItemListener(listener);
|
||||
myOutputRnc.addItemListener(listener);
|
||||
myOutputXsd.addItemListener(listener);
|
||||
myOutputDtd.addItemListener(listener);
|
||||
|
||||
if (inputType == SchemaType.DTD) {
|
||||
myInputOptions = AdvancedDtdOptions.prepareNamespaceMap(project, firstFile);
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public SchemaType getOutputType() {
|
||||
if (myOutputRng.isSelected()) {
|
||||
return SchemaType.RNG;
|
||||
} else if (myOutputRnc.isSelected()) {
|
||||
return SchemaType.RNC;
|
||||
} else if (myOutputXsd.isSelected()) {
|
||||
return SchemaType.XSD;
|
||||
} else {
|
||||
assert myOutputDtd.isSelected();
|
||||
return SchemaType.DTD;
|
||||
}
|
||||
}
|
||||
|
||||
public String getOutputEncoding() {
|
||||
return (String)myEncoding.getSelectedItem();
|
||||
}
|
||||
|
||||
public int getIndent() {
|
||||
return parseInt(myIndent.getText().trim());
|
||||
}
|
||||
|
||||
private static int parseInt(String s) {
|
||||
try {
|
||||
return s.length() > 0 ? Integer.parseInt(s) : -1;
|
||||
} catch (NumberFormatException e) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
public int getLineLength() {
|
||||
return parseInt(myLineLength.getText());
|
||||
}
|
||||
|
||||
public String getOutputDestination() {
|
||||
return myOutputDestination.getText();
|
||||
}
|
||||
|
||||
public void addAdvancedSettings(List<String> inputParams, List<String> outputParams) {
|
||||
setParams(myInputOptions, inputParams);
|
||||
|
||||
if (getOutputType() == SchemaType.XSD) {
|
||||
setParams(myOutputOptions, outputParams);
|
||||
}
|
||||
}
|
||||
|
||||
private static void setParams(Map<String, ?> map, List<String> inputParams) {
|
||||
final Set<String> set = map.keySet();
|
||||
for (String s : set) {
|
||||
final Object value = map.get(s);
|
||||
if (value == Boolean.TRUE) {
|
||||
inputParams.add(s);
|
||||
} else if (value == Boolean.FALSE) {
|
||||
inputParams.add("no-" + s);
|
||||
} else if (value != null) {
|
||||
inputParams.add(s + "=" + value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public JComponent getRoot() {
|
||||
return myRoot;
|
||||
}
|
||||
|
||||
public JComponent getPreferredFocusedComponent() {
|
||||
return myOutputDestination;
|
||||
}
|
||||
|
||||
public void addPropertyChangeListener(String name, PropertyChangeListener listener) {
|
||||
myPropertyChangeSupport.addPropertyChangeListener(name, listener);
|
||||
}
|
||||
|
||||
public void showAdvancedSettings() {
|
||||
final AdvancedOptionsDialog dialog = new AdvancedOptionsDialog(myProject, myInputType, getOutputType());
|
||||
dialog.setOptions(myInputOptions, myOutputOptions);
|
||||
|
||||
dialog.show();
|
||||
if (dialog.isOK()) {
|
||||
myInputOptions = dialog.getInputOptions();
|
||||
myOutputOptions = dialog.getOutputOptions();
|
||||
}
|
||||
}
|
||||
|
||||
public boolean hasAdvancedSettings() {
|
||||
return getOutputType() == SchemaType.XSD || myInputType == SchemaType.DTD;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,210 @@
|
||||
/*
|
||||
* Copyright 2007 Sascha Weinreuter
|
||||
*
|
||||
* 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 org.intellij.plugins.relaxNG.convert;
|
||||
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.ui.Messages;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
|
||||
import com.thaiopensource.relaxng.edit.SchemaCollection;
|
||||
import com.thaiopensource.relaxng.input.InputFailedException;
|
||||
import com.thaiopensource.relaxng.input.InputFormat;
|
||||
import com.thaiopensource.relaxng.input.MultiInputFormat;
|
||||
import com.thaiopensource.relaxng.input.dtd.DtdInputFormat;
|
||||
import com.thaiopensource.relaxng.input.parse.compact.CompactParseInputFormat;
|
||||
import com.thaiopensource.relaxng.input.parse.sax.SAXParseInputFormat;
|
||||
import com.thaiopensource.relaxng.input.xml.XmlInputFormat;
|
||||
import com.thaiopensource.relaxng.output.LocalOutputDirectory;
|
||||
import com.thaiopensource.relaxng.output.OutputDirectory;
|
||||
import com.thaiopensource.relaxng.output.OutputFailedException;
|
||||
import com.thaiopensource.relaxng.output.OutputFormat;
|
||||
import com.thaiopensource.relaxng.output.dtd.DtdOutputFormat;
|
||||
import com.thaiopensource.relaxng.output.rnc.RncOutputFormat;
|
||||
import com.thaiopensource.relaxng.output.rng.RngOutputFormat;
|
||||
import com.thaiopensource.relaxng.output.xsd.XsdOutputFormat;
|
||||
import com.thaiopensource.relaxng.translate.util.InvalidParamsException;
|
||||
import com.thaiopensource.util.UriOrFile;
|
||||
import org.xml.sax.SAXException;
|
||||
import org.xml.sax.SAXParseException;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.net.MalformedURLException;
|
||||
import java.nio.charset.Charset;
|
||||
import java.util.ArrayList;
|
||||
|
||||
public class IdeaDriver {
|
||||
|
||||
private static final int DEFAULT_LINE_LENGTH = 72;
|
||||
private static final int DEFAULT_INDENT = 2;
|
||||
|
||||
private final ConvertSchemaSettings settings;
|
||||
private final Project myProject;
|
||||
|
||||
public IdeaDriver(ConvertSchemaSettings settings, Project project) {
|
||||
this.settings = settings;
|
||||
myProject = project;
|
||||
}
|
||||
|
||||
@SuppressWarnings({ "ThrowableInstanceNeverThrown" })
|
||||
public void convert(SchemaType inputType, IdeaErrorHandler errorHandler, VirtualFile... inputFiles) {
|
||||
if (inputFiles.length == 0) {
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
|
||||
try {
|
||||
final InputFormat inFormat = getInputFormat(inputType);
|
||||
if (inputFiles.length > 1) {
|
||||
if (!(inFormat instanceof MultiInputFormat)) {
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
}
|
||||
|
||||
final VirtualFile inputFile = inputFiles[0];
|
||||
final SchemaType type = settings.getOutputType();
|
||||
final String outputType = type.toString().toLowerCase();
|
||||
|
||||
final ArrayList<String> inputParams = new ArrayList<String>();
|
||||
|
||||
if (inputType != SchemaType.DTD) {
|
||||
final Charset charset = inputFile.getCharset();
|
||||
if (charset != null) {
|
||||
inputParams.add("encoding=" + charset.name());
|
||||
}
|
||||
}
|
||||
|
||||
final ArrayList<String> outputParams = new ArrayList<String>();
|
||||
settings.addAdvancedSettings(inputParams, outputParams);
|
||||
|
||||
// System.out.println("INPUT: " + inputParams);
|
||||
// System.out.println("OUTPUT: " + outputParams);
|
||||
|
||||
final SchemaCollection sc;
|
||||
final String input = inputFile.getPath();
|
||||
final String uri = UriOrFile.toUri(input);
|
||||
try {
|
||||
if (inFormat instanceof MultiInputFormat) {
|
||||
final MultiInputFormat format = (MultiInputFormat)inFormat;
|
||||
final String[] uris = new String[inputFiles.length];
|
||||
for (int i = 0; i < inputFiles.length; i++) {
|
||||
uris[i] = UriOrFile.toUri(inputFiles[i].getPath());
|
||||
}
|
||||
sc = format.load(uris, inputParams.toArray(new String[inputParams.size()]), outputType, errorHandler);
|
||||
} else {
|
||||
sc = inFormat.load(uri, inputParams.toArray(new String[inputParams.size()]), outputType, errorHandler);
|
||||
}
|
||||
} catch (IOException e) {
|
||||
errorHandler.fatalError(new SAXParseException(e.getMessage(), null, uri, -1, -1, e));
|
||||
return;
|
||||
}
|
||||
|
||||
final File destination = new File(settings.getOutputDestination());
|
||||
final File outputFile;
|
||||
if (destination.isDirectory()) {
|
||||
final String name = new File(input).getName();
|
||||
final int ext = name.lastIndexOf('.');
|
||||
outputFile = new File(destination, (ext > 0 ? name.substring(0, ext) : name) + "." + outputType);
|
||||
} else {
|
||||
outputFile = destination;
|
||||
}
|
||||
|
||||
try {
|
||||
final int indent = settings.getIndent();
|
||||
final int length = settings.getLineLength();
|
||||
final OutputDirectory od = new LocalOutputDirectory(sc.getMainUri(),
|
||||
outputFile,
|
||||
"." + outputType,
|
||||
settings.getOutputEncoding(),
|
||||
length > 0 ? length : DEFAULT_LINE_LENGTH,
|
||||
indent > 0 ? indent : DEFAULT_INDENT)
|
||||
{
|
||||
public Stream open(String sourceUri, String encoding) throws IOException {
|
||||
final String s = super.reference(null, sourceUri);
|
||||
final File file = new File(outputFile.getParentFile(), s);
|
||||
if (file.exists()) {
|
||||
final String msg = "The file '" + file.getAbsolutePath() + "' already exists. Overwrite it?";
|
||||
final int choice = Messages.showYesNoDialog(myProject, msg, "Output File Exists", Messages.getWarningIcon());
|
||||
if (choice == 0) {
|
||||
return super.open(sourceUri, encoding);
|
||||
} else if (choice == 1) {
|
||||
throw new CanceledException();
|
||||
}
|
||||
}
|
||||
return super.open(sourceUri, encoding);
|
||||
}
|
||||
};
|
||||
|
||||
final OutputFormat of = getOutputFormat(settings.getOutputType());
|
||||
|
||||
of.output(sc, od, outputParams.toArray(new String[outputParams.size()]), inputType.toString().toLowerCase(), errorHandler);
|
||||
} catch (IOException e) {
|
||||
errorHandler.fatalError(new SAXParseException(e.getMessage(), null, UriOrFile.fileToUri(outputFile), -1, -1, e));
|
||||
}
|
||||
} catch (CanceledException e) {
|
||||
// user abort
|
||||
} catch (SAXParseException e) {
|
||||
errorHandler.error(e);
|
||||
} catch (MalformedURLException e) {
|
||||
Logger.getInstance(getClass().getName()).error(e);
|
||||
} catch (InputFailedException e) {
|
||||
// handled by ErrorHandler
|
||||
} catch (InvalidParamsException e) {
|
||||
// handled by ErrorHandler
|
||||
} catch (OutputFailedException e) {
|
||||
// handled by ErrorHandler
|
||||
} catch (SAXException e) {
|
||||
// cannot happen or is already handled
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private OutputFormat getOutputFormat(SchemaType outputType) {
|
||||
switch (outputType) {
|
||||
case DTD:
|
||||
return new DtdOutputFormat();
|
||||
case RNC:
|
||||
return new RncOutputFormat();
|
||||
case RNG:
|
||||
return new RngOutputFormat();
|
||||
case XSD:
|
||||
return new XsdOutputFormat();
|
||||
default:
|
||||
assert false : "Unsupported output type: " + outputType;
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private InputFormat getInputFormat(SchemaType type) {
|
||||
switch (type) {
|
||||
case DTD:
|
||||
return new DtdInputFormat();
|
||||
case RNC:
|
||||
return new CompactParseInputFormat();
|
||||
case RNG:
|
||||
return new SAXParseInputFormat();
|
||||
case XML:
|
||||
return new XmlInputFormat();
|
||||
default:
|
||||
assert false : "Unsupported input type: " + type;
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private static class CanceledException extends RuntimeException {
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
/*
|
||||
* Copyright 2007 Sascha Weinreuter
|
||||
*
|
||||
* 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 org.intellij.plugins.relaxNG.convert;
|
||||
|
||||
import org.intellij.plugins.relaxNG.validation.MessageViewHelper;
|
||||
|
||||
import com.intellij.ide.errorTreeView.NewErrorTreeViewPanel;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.Key;
|
||||
|
||||
import com.thaiopensource.xml.sax.ErrorHandlerImpl;
|
||||
import org.xml.sax.SAXParseException;
|
||||
|
||||
/*
|
||||
* Created by IntelliJ IDEA.
|
||||
* User: sweinreuter
|
||||
* Date: 16.11.2007
|
||||
*/
|
||||
public class IdeaErrorHandler extends ErrorHandlerImpl {
|
||||
private static final String CONTENT_NAME = "Convert Schema";
|
||||
private static final Key<NewErrorTreeViewPanel> KEY = Key.create("CONVERSION_ERRORS");
|
||||
|
||||
private final MessageViewHelper myMessageViewHelper;
|
||||
|
||||
public IdeaErrorHandler(Project project) {
|
||||
myMessageViewHelper = new MessageViewHelper(project, CONTENT_NAME, KEY);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void warning(SAXParseException e) throws SAXParseException {
|
||||
myMessageViewHelper.processError(e, true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void error(SAXParseException e) {
|
||||
myMessageViewHelper.processError(e, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void fatalError(SAXParseException e) throws SAXParseException {
|
||||
myMessageViewHelper.processError(e, false);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
/*
|
||||
* Copyright 2007 Sascha Weinreuter
|
||||
*
|
||||
* 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 org.intellij.plugins.relaxNG.convert;
|
||||
|
||||
/**
|
||||
* Created by IntelliJ IDEA.
|
||||
* User: sweinreuter
|
||||
* Date: 17.11.2007
|
||||
*/
|
||||
public enum SchemaType {
|
||||
RNG, RNC, DTD,
|
||||
XSD, // output only
|
||||
XML // input only
|
||||
}
|
||||
@@ -0,0 +1,220 @@
|
||||
/*
|
||||
* Copyright 2007 Sascha Weinreuter
|
||||
*
|
||||
* 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 org.intellij.plugins.relaxNG.inspections;
|
||||
|
||||
import org.intellij.plugins.relaxNG.compact.psi.*;
|
||||
|
||||
import com.intellij.codeInspection.ProblemsHolder;
|
||||
import com.intellij.codeInspection.SuppressIntentionAction;
|
||||
import com.intellij.codeInspection.XmlSuppressableInspectionTool;
|
||||
import com.intellij.openapi.editor.Document;
|
||||
import com.intellij.openapi.editor.Editor;
|
||||
import com.intellij.openapi.fileTypes.StdFileTypes;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.TextRange;
|
||||
import com.intellij.openapi.vfs.ReadonlyStatusHandler;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.codeStyle.CodeStyleManager;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import com.intellij.util.ArrayUtil;
|
||||
import com.intellij.util.Function;
|
||||
import com.intellij.util.IncorrectOperationException;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import org.jetbrains.annotations.Nls;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
/**
|
||||
* Created by IntelliJ IDEA.
|
||||
* User: sweinreuter
|
||||
* Date: 25.11.2007
|
||||
*/
|
||||
public abstract class BaseInspection extends XmlSuppressableInspectionTool {
|
||||
@Nls
|
||||
@NotNull
|
||||
public final String getGroupDisplayName() {
|
||||
return getRngGroupDisplayName();
|
||||
}
|
||||
|
||||
public static String getRngGroupDisplayName() {
|
||||
return "RELAX NG";
|
||||
}
|
||||
|
||||
@SuppressWarnings({ "SSBasedInspection" })
|
||||
@Override
|
||||
public boolean isSuppressedFor(PsiElement element) {
|
||||
if (element.getContainingFile() instanceof RncFile) {
|
||||
final RncDefine define = PsiTreeUtil.getParentOfType(element, RncDefine.class, false);
|
||||
if (define != null) {
|
||||
if (isSuppressedAt(define)) return true;
|
||||
}
|
||||
|
||||
final RncGrammar grammar = PsiTreeUtil.getParentOfType(define, RncGrammar.class);
|
||||
if (grammar != null) {
|
||||
if (isSuppressedAt(grammar)) return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
} else {
|
||||
return super.isSuppressedFor(element);
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings({ "SSBasedInspection" })
|
||||
private boolean isSuppressedAt(RncElement location) {
|
||||
PsiElement prev = location.getPrevSibling();
|
||||
while (prev instanceof PsiWhiteSpace || prev instanceof PsiComment) {
|
||||
if (prev instanceof PsiComment) {
|
||||
@NonNls String text = prev.getText();
|
||||
if (text.matches("\n*#\\s*suppress\\s.+") && (text.contains(getID()) || "ALL".equals(text))) return true;
|
||||
}
|
||||
prev = prev.getPrevSibling();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public SuppressIntentionAction[] getSuppressActions(PsiElement element) {
|
||||
if (element.getContainingFile() instanceof RncFile) {
|
||||
return ArrayUtil.mergeArrays(new SuppressIntentionAction[]{
|
||||
new SuppressAction("Define") {
|
||||
protected PsiElement getTarget(PsiElement element) {
|
||||
return PsiTreeUtil.getParentOfType(element, RncDefine.class, false);
|
||||
}
|
||||
},
|
||||
new SuppressAction("Grammar") {
|
||||
protected PsiElement getTarget(PsiElement element) {
|
||||
final RncDefine define = PsiTreeUtil.getParentOfType(element, RncDefine.class, false);
|
||||
return define != null ? PsiTreeUtil.getParentOfType(define, RncGrammar.class, false) : null;
|
||||
}
|
||||
|
||||
@SuppressWarnings({ "SSBasedInspection" })
|
||||
public boolean isAvailable(@NotNull Project project, Editor editor, @Nullable PsiElement element) {
|
||||
return super.isAvailable(project, editor, element) && getTarget(element).getText().startsWith("grammar ");
|
||||
}
|
||||
}
|
||||
}, getXmlOnlySuppressions(element), SuppressIntentionAction.class);
|
||||
} else {
|
||||
return super.getSuppressActions(element);
|
||||
}
|
||||
}
|
||||
|
||||
private SuppressIntentionAction[] getXmlOnlySuppressions(PsiElement element) {
|
||||
return ContainerUtil.map(super.getSuppressActions(element), new Function<SuppressIntentionAction, SuppressIntentionAction>() {
|
||||
public SuppressIntentionAction fun(final SuppressIntentionAction action) {
|
||||
return new SuppressIntentionAction() {
|
||||
public void invoke(Project project, Editor editor, PsiElement element) throws IncorrectOperationException {
|
||||
action.invoke(project, editor, element);
|
||||
}
|
||||
|
||||
public boolean isAvailable(@NotNull Project project, Editor editor, @Nullable PsiElement element) {
|
||||
return element != null && element.getContainingFile().getFileType() == StdFileTypes.XML &&
|
||||
action.isAvailable(project, editor, element);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public String getText() {
|
||||
return action.getText();
|
||||
}
|
||||
|
||||
public boolean startInWriteAction() {
|
||||
return action.startInWriteAction();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public String getFamilyName() {
|
||||
return action.getFamilyName();
|
||||
}
|
||||
};
|
||||
}
|
||||
}, new SuppressIntentionAction[0]);
|
||||
}
|
||||
|
||||
private void suppress(PsiFile file, @NotNull PsiElement location) {
|
||||
suppress(file, location, "#suppress " + getID(), new Function<String, String>() {
|
||||
public String fun(final String text) {
|
||||
return text + ", " + getID();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@SuppressWarnings({ "SSBasedInspection" })
|
||||
private static void suppress(PsiFile file, @NotNull PsiElement location, String suppressComment, Function<String, String> replace) {
|
||||
final Project project = file.getProject();
|
||||
final VirtualFile vfile = file.getVirtualFile();
|
||||
if (vfile == null || ReadonlyStatusHandler.getInstance(project).ensureFilesWritable(vfile).hasReadonlyFiles()) {
|
||||
return;
|
||||
}
|
||||
|
||||
final Document doc = PsiDocumentManager.getInstance(project).getDocument(file);
|
||||
assert doc != null;
|
||||
|
||||
PsiElement leaf = location.getPrevSibling();
|
||||
|
||||
while (leaf instanceof PsiWhiteSpace) leaf = leaf.getPrevSibling();
|
||||
|
||||
while (leaf instanceof PsiComment || leaf instanceof PsiWhiteSpace) {
|
||||
@NonNls String text = leaf.getText();
|
||||
if (text.matches("\n*#\\s*suppress\\s.+")) {
|
||||
final TextRange textRange = leaf.getTextRange();
|
||||
doc.replaceString(textRange.getStartOffset(), textRange.getEndOffset(), replace.fun(text));
|
||||
return;
|
||||
}
|
||||
leaf = leaf.getPrevSibling();
|
||||
}
|
||||
|
||||
final int offset = location.getTextRange().getStartOffset();
|
||||
doc.insertString(offset, suppressComment + "\n");
|
||||
CodeStyleManager.getInstance(project).adjustLineIndent(doc, offset + suppressComment.length());
|
||||
// UndoManager.getInstance(file.getProject()).markDocumentForUndo(file);
|
||||
}
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public abstract RncElementVisitor buildVisitor(@NotNull ProblemsHolder holder, boolean isOnTheFly);
|
||||
|
||||
private abstract class SuppressAction extends SuppressIntentionAction {
|
||||
private final String myLocation;
|
||||
|
||||
public SuppressAction(String location) {
|
||||
myLocation = location;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public String getText() {
|
||||
return "Suppress for " + myLocation;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public String getFamilyName() {
|
||||
return getDisplayName();
|
||||
}
|
||||
|
||||
public void invoke(Project project, Editor editor, PsiElement element) throws IncorrectOperationException {
|
||||
suppress(element.getContainingFile(), getTarget(element));
|
||||
}
|
||||
|
||||
public boolean isAvailable(@NotNull Project project, Editor editor, @Nullable PsiElement element) {
|
||||
return getTarget(element) != null;
|
||||
}
|
||||
|
||||
protected abstract PsiElement getTarget(PsiElement element);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
/*
|
||||
* Copyright 2007 Sascha Weinreuter
|
||||
*
|
||||
* 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 org.intellij.plugins.relaxNG.inspections;
|
||||
|
||||
import org.intellij.plugins.relaxNG.xml.dom.RngDomElement;
|
||||
|
||||
import com.intellij.codeHighlighting.HighlightDisplayLevel;
|
||||
import com.intellij.util.xml.highlighting.BasicDomElementsInspection;
|
||||
import org.jetbrains.annotations.Nls;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
* Created by IntelliJ IDEA.
|
||||
* User: sweinreuter
|
||||
* Date: 03.10.2007
|
||||
*/
|
||||
public class RngDomInspection extends BasicDomElementsInspection<RngDomElement> {
|
||||
public RngDomInspection() {
|
||||
super(RngDomElement.class);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public HighlightDisplayLevel getDefaultLevel() {
|
||||
return HighlightDisplayLevel.ERROR;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEnabledByDefault() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Nls
|
||||
@NotNull
|
||||
public String getGroupDisplayName() {
|
||||
return BaseInspection.getRngGroupDisplayName();
|
||||
}
|
||||
|
||||
@Nls
|
||||
@NotNull
|
||||
public String getDisplayName() {
|
||||
return "Unresolved References";
|
||||
}
|
||||
|
||||
@NonNls
|
||||
@NotNull
|
||||
public String getShortName() {
|
||||
return "UnresolvedReference";
|
||||
}
|
||||
}
|
||||
+230
@@ -0,0 +1,230 @@
|
||||
/*
|
||||
* Copyright 2007 Sascha Weinreuter
|
||||
*
|
||||
* 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 org.intellij.plugins.relaxNG.inspections;
|
||||
|
||||
import org.intellij.plugins.relaxNG.ProjectLoader;
|
||||
import org.intellij.plugins.relaxNG.compact.psi.RncDefine;
|
||||
import org.intellij.plugins.relaxNG.compact.psi.RncElementVisitor;
|
||||
import org.intellij.plugins.relaxNG.compact.psi.RncGrammar;
|
||||
import org.intellij.plugins.relaxNG.compact.psi.impl.RncDefineImpl;
|
||||
import org.intellij.plugins.relaxNG.model.resolve.RelaxIncludeIndex;
|
||||
import org.intellij.plugins.relaxNG.xml.dom.RngGrammar;
|
||||
|
||||
import com.intellij.codeInspection.LocalQuickFix;
|
||||
import com.intellij.codeInspection.ProblemDescriptor;
|
||||
import com.intellij.codeInspection.ProblemHighlightType;
|
||||
import com.intellij.codeInspection.ProblemsHolder;
|
||||
import com.intellij.lang.ASTNode;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.fileTypes.StdFileTypes;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.PsiFile;
|
||||
import com.intellij.psi.PsiReference;
|
||||
import com.intellij.psi.XmlElementVisitor;
|
||||
import com.intellij.psi.search.LocalSearchScope;
|
||||
import com.intellij.psi.search.PsiElementProcessor;
|
||||
import com.intellij.psi.search.searches.ReferencesSearch;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import com.intellij.psi.xml.XmlAttribute;
|
||||
import com.intellij.psi.xml.XmlAttributeValue;
|
||||
import com.intellij.psi.xml.XmlFile;
|
||||
import com.intellij.psi.xml.XmlTag;
|
||||
import com.intellij.util.IncorrectOperationException;
|
||||
import com.intellij.util.Query;
|
||||
import com.intellij.util.xml.DomElement;
|
||||
import com.intellij.util.xml.DomManager;
|
||||
import org.jetbrains.annotations.Nls;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
* Created by IntelliJ IDEA.
|
||||
* User: sweinreuter
|
||||
* Date: 26.07.2007
|
||||
*/
|
||||
public class UnusedDefineInspection extends BaseInspection {
|
||||
public boolean isEnabledByDefault() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Nls
|
||||
@NotNull
|
||||
public String getDisplayName() {
|
||||
return "Unused Define";
|
||||
}
|
||||
|
||||
@NonNls
|
||||
@NotNull
|
||||
public String getShortName() {
|
||||
return "UnusedDefine";
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public RncElementVisitor buildVisitor(@NotNull ProblemsHolder holder, boolean isOnTheFly) {
|
||||
return new MyElementVisitor(holder);
|
||||
}
|
||||
|
||||
private static final class MyElementVisitor extends RncElementVisitor {
|
||||
private final ProblemsHolder myHolder;
|
||||
|
||||
private final XmlElementVisitor myXmlVisitor = new XmlElementVisitor() {
|
||||
@Override
|
||||
public void visitXmlTag(XmlTag tag) {
|
||||
MyElementVisitor.this.visitXmlTag(tag);
|
||||
}
|
||||
};
|
||||
|
||||
public MyElementVisitor(ProblemsHolder holder) {
|
||||
myHolder = holder;
|
||||
}
|
||||
|
||||
protected void superVisitElement(PsiElement element) {
|
||||
element.accept(myXmlVisitor);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitDefine(RncDefine pattern) {
|
||||
final RncGrammar grammar = PsiTreeUtil.getParentOfType(pattern, RncGrammar.class);
|
||||
final PsiFile file = pattern.getContainingFile();
|
||||
if (grammar != null) {
|
||||
if (processRncUsages(pattern, new LocalSearchScope(grammar))) return;
|
||||
} else {
|
||||
if (processRncUsages(pattern, new LocalSearchScope(file))) return;
|
||||
}
|
||||
|
||||
final PsiElementProcessor.CollectElements<XmlFile> collector = new PsiElementProcessor.CollectElements<XmlFile>();
|
||||
RelaxIncludeIndex.processBackwardDependencies((XmlFile)file, collector);
|
||||
|
||||
if (processRncUsages(pattern, new LocalSearchScope(collector.toArray()))) return;
|
||||
|
||||
final ASTNode astNode = ((RncDefineImpl)pattern).getNameNode();
|
||||
myHolder.registerProblem(astNode.getPsi(), "Unreferenced define", ProblemHighlightType.LIKE_UNUSED_SYMBOL, new MyFix<RncDefine>(pattern));
|
||||
}
|
||||
|
||||
private static boolean processRncUsages(PsiElement tag, LocalSearchScope scope) {
|
||||
final Query<PsiReference> query = ReferencesSearch.search(tag, scope);
|
||||
for (PsiReference reference : query) {
|
||||
final PsiElement e = reference.getElement();
|
||||
final RncDefine t = PsiTreeUtil.getParentOfType(e, RncDefine.class, false);
|
||||
if (t == null || !PsiTreeUtil.isAncestor(tag, t, true)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public void visitXmlTag(XmlTag tag) {
|
||||
final PsiFile file = tag.getContainingFile();
|
||||
if (file.getFileType() != StdFileTypes.XML) {
|
||||
return;
|
||||
}
|
||||
if (!tag.getLocalName().equals("define")) {
|
||||
return;
|
||||
}
|
||||
if (!tag.getNamespace().equals(ProjectLoader.RNG_NAMESPACE)) {
|
||||
return;
|
||||
}
|
||||
if (tag.getAttribute("combine") != null) {
|
||||
return; // ?
|
||||
}
|
||||
|
||||
final XmlAttribute attr = tag.getAttribute("name");
|
||||
if (attr == null) return;
|
||||
|
||||
final XmlAttributeValue value = attr.getValueElement();
|
||||
if (value == null) return;
|
||||
|
||||
final String s = value.getValue();
|
||||
if (s == null || s.length() == 0) {
|
||||
return;
|
||||
}
|
||||
final PsiElement parent = value.getParent();
|
||||
if (!(parent instanceof XmlAttribute)) {
|
||||
return;
|
||||
}
|
||||
if (!"name".equals(((XmlAttribute)parent).getName())) {
|
||||
return;
|
||||
}
|
||||
final PsiElement grandParent = parent.getParent();
|
||||
if (!(grandParent instanceof XmlTag)) {
|
||||
return;
|
||||
}
|
||||
|
||||
final DomElement element = DomManager.getDomManager(tag.getProject()).getDomElement(tag);
|
||||
if (element == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
final RngGrammar rngGrammar = element.getParentOfType(RngGrammar.class, true);
|
||||
if (rngGrammar != null) {
|
||||
if (processUsages(tag, value, new LocalSearchScope(rngGrammar.getXmlTag()))) return;
|
||||
} else {
|
||||
if (processUsages(tag, value, new LocalSearchScope(file))) return;
|
||||
}
|
||||
|
||||
final PsiElementProcessor.CollectElements<XmlFile> collector = new PsiElementProcessor.CollectElements<XmlFile>();
|
||||
RelaxIncludeIndex.processBackwardDependencies((XmlFile)file, collector);
|
||||
|
||||
if (processUsages(tag, value, new LocalSearchScope(collector.toArray()))) return;
|
||||
|
||||
myHolder.registerProblem(value, "Unreferenced define", ProblemHighlightType.LIKE_UNUSED_SYMBOL, new MyFix<XmlTag>(tag));
|
||||
}
|
||||
|
||||
private static boolean processUsages(PsiElement tag, XmlAttributeValue value, LocalSearchScope scope) {
|
||||
final Query<PsiReference> query = ReferencesSearch.search(tag, scope, true);
|
||||
for (PsiReference reference : query) {
|
||||
final PsiElement e = reference.getElement();
|
||||
if (e != value) {
|
||||
final XmlTag t = PsiTreeUtil.getParentOfType(e, XmlTag.class);
|
||||
if (t != null && !PsiTreeUtil.isAncestor(tag, t, true)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private static class MyFix<T extends PsiElement> implements LocalQuickFix {
|
||||
private final T myTag;
|
||||
|
||||
public MyFix(T tag) {
|
||||
myTag = tag;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public String getName() {
|
||||
return "Remove Define";
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public String getFamilyName() {
|
||||
return getName();
|
||||
}
|
||||
|
||||
public void applyFix(@NotNull Project project, @NotNull ProblemDescriptor descriptor) {
|
||||
try {
|
||||
if (myTag.isValid()) {
|
||||
myTag.delete();
|
||||
}
|
||||
} catch (IncorrectOperationException e) {
|
||||
Logger.getInstance(UnusedDefineInspection.class.getName()).error(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
/*
|
||||
* Copyright 2007 Sascha Weinreuter
|
||||
*
|
||||
* 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 org.intellij.plugins.relaxNG.model;
|
||||
|
||||
import com.intellij.psi.PsiElement;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
/**
|
||||
* Created by IntelliJ IDEA.
|
||||
* User: sweinreuter
|
||||
* Date: 17.09.2007
|
||||
*/
|
||||
public interface CommonElement<E extends PsiElement> {
|
||||
void accept(Visitor visitor);
|
||||
|
||||
void acceptChildren(Visitor visitor);
|
||||
|
||||
@Nullable
|
||||
E getPsiElement();
|
||||
|
||||
static abstract class Visitor {
|
||||
public void visitElement(CommonElement pattern) {
|
||||
}
|
||||
|
||||
public void visitPattern(Pattern pattern) {
|
||||
visitElement(pattern);
|
||||
}
|
||||
|
||||
public void visitGrammar(Grammar pattern) {
|
||||
visitElement(pattern);
|
||||
}
|
||||
|
||||
public void visitDefine(Define define) {
|
||||
visitElement(define);
|
||||
}
|
||||
|
||||
public void visitRef(Ref ref) {
|
||||
visitElement(ref);
|
||||
}
|
||||
|
||||
public void visitDiv(Div div) {
|
||||
visitElement(div);
|
||||
}
|
||||
|
||||
public void visitInclude(Include inc) {
|
||||
visitElement(inc);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
/*
|
||||
* Copyright 2007 Sascha Weinreuter
|
||||
*
|
||||
* 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 org.intellij.plugins.relaxNG.model;
|
||||
|
||||
import com.intellij.psi.PsiElement;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
/**
|
||||
* Created by IntelliJ IDEA.
|
||||
* User: sweinreuter
|
||||
* Date: 05.09.2007
|
||||
*/
|
||||
public interface Define<P extends Pattern, E extends PsiElement> extends Pattern<E> {
|
||||
String getName();
|
||||
|
||||
PsiElement getNameElement();
|
||||
|
||||
@Nullable
|
||||
P getPattern();
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
/*
|
||||
* Copyright 2007 Sascha Weinreuter
|
||||
*
|
||||
* 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 org.intellij.plugins.relaxNG.model;
|
||||
|
||||
import com.intellij.psi.PsiElement;
|
||||
|
||||
/**
|
||||
* Created by IntelliJ IDEA.
|
||||
* User: sweinreuter
|
||||
* Date: 17.09.2007
|
||||
*/
|
||||
public interface Div<E extends PsiElement> extends CommonElement<E> {
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
/*
|
||||
* Copyright 2007 Sascha Weinreuter
|
||||
*
|
||||
* 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 org.intellij.plugins.relaxNG.model;
|
||||
|
||||
import com.intellij.psi.PsiElement;
|
||||
|
||||
/*
|
||||
* Created by IntelliJ IDEA.
|
||||
* User: sweinreuter
|
||||
* Date: 24.08.2007
|
||||
*/
|
||||
public interface Grammar<P extends Pattern, E extends PsiElement> extends Pattern<E> {
|
||||
P getStart();
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user