Module descriptions in XML
This commit is contained in:
+114
@@ -0,0 +1,114 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2013 JetBrains s.r.o.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.jetbrains.jet.cli.common.modules;
|
||||||
|
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.xml.sax.*;
|
||||||
|
import org.xml.sax.helpers.DefaultHandler;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
public abstract class DelegatedSaxHandler extends DefaultHandler {
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
protected abstract DefaultHandler getDelegate();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public InputSource resolveEntity(String publicId, String systemId) throws IOException, SAXException {
|
||||||
|
return getDelegate().resolveEntity(publicId, systemId);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void notationDecl(String name, String publicId, String systemId) throws SAXException {
|
||||||
|
getDelegate().notationDecl(name, publicId, systemId);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void unparsedEntityDecl(String name, String publicId, String systemId, String notationName) throws SAXException {
|
||||||
|
getDelegate().unparsedEntityDecl(name, publicId, systemId, notationName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setDocumentLocator(Locator locator) {
|
||||||
|
getDelegate().setDocumentLocator(locator);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void startDocument() throws SAXException {
|
||||||
|
getDelegate().startDocument();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void endDocument() throws SAXException {
|
||||||
|
getDelegate().endDocument();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void startPrefixMapping(String prefix, String uri) throws SAXException {
|
||||||
|
getDelegate().startPrefixMapping(prefix, uri);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void endPrefixMapping(String prefix) throws SAXException {
|
||||||
|
getDelegate().endPrefixMapping(prefix);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
|
||||||
|
getDelegate().startElement(uri, localName, qName, attributes);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void endElement(String uri, String localName, String qName) throws SAXException {
|
||||||
|
getDelegate().endElement(uri, localName, qName);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void characters(char[] ch, int start, int length) throws SAXException {
|
||||||
|
getDelegate().characters(ch, start, length);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void ignorableWhitespace(char[] ch, int start, int length) throws SAXException {
|
||||||
|
getDelegate().ignorableWhitespace(ch, start, length);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void processingInstruction(String target, String data) throws SAXException {
|
||||||
|
getDelegate().processingInstruction(target, data);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void skippedEntity(String name) throws SAXException {
|
||||||
|
getDelegate().skippedEntity(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void warning(SAXParseException e) throws SAXException {
|
||||||
|
getDelegate().warning(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void error(SAXParseException e) throws SAXException {
|
||||||
|
getDelegate().error(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void fatalError(SAXParseException e) throws SAXException {
|
||||||
|
getDelegate().fatalError(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
+93
@@ -0,0 +1,93 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2013 JetBrains s.r.o.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.jetbrains.jet.cli.common.modules;
|
||||||
|
|
||||||
|
import com.intellij.util.SmartList;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This interface duplicates {@link jet.modules.Module}, because cli-common should not depend on kotlin-runtime.jar
|
||||||
|
*/
|
||||||
|
public interface ModuleDescription {
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
String getModuleName();
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
List<String> getSourceFiles();
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
List<String> getClasspathRoots();
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
List<String> getAnnotationsRoots();
|
||||||
|
|
||||||
|
class Impl implements ModuleDescription {
|
||||||
|
|
||||||
|
private String name;
|
||||||
|
private final List<String> sources = new SmartList<String>();
|
||||||
|
private final List<String> classpath = new SmartList<String>();
|
||||||
|
private final List<String> annotations = new SmartList<String>();
|
||||||
|
|
||||||
|
public void setName(String name) {
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addSourcePath(String path) {
|
||||||
|
sources.add(path);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addClassPath(String path) {
|
||||||
|
classpath.add(path);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addAnnotationPath(String path) {
|
||||||
|
annotations.add(path);
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
@Override
|
||||||
|
public String getModuleName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
@Override
|
||||||
|
public List<String> getSourceFiles() {
|
||||||
|
return sources;
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
@Override
|
||||||
|
public List<String> getClasspathRoots() {
|
||||||
|
return classpath;
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
@Override
|
||||||
|
public List<String> getAnnotationsRoots() {
|
||||||
|
return annotations;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return name + "\n\tsources=" + sources + "\n\tclasspath=" + classpath + "\n\tannotations=" + annotations;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+178
@@ -0,0 +1,178 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2013 JetBrains s.r.o.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.jetbrains.jet.cli.common.modules;
|
||||||
|
|
||||||
|
import com.intellij.openapi.util.io.StreamUtil;
|
||||||
|
import com.intellij.util.SmartList;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.jet.cli.common.messages.*;
|
||||||
|
import org.xml.sax.Attributes;
|
||||||
|
import org.xml.sax.SAXException;
|
||||||
|
import org.xml.sax.helpers.DefaultHandler;
|
||||||
|
|
||||||
|
import javax.xml.parsers.ParserConfigurationException;
|
||||||
|
import javax.xml.parsers.SAXParser;
|
||||||
|
import javax.xml.parsers.SAXParserFactory;
|
||||||
|
import java.io.*;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import static org.jetbrains.jet.cli.common.messages.CompilerMessageLocation.*;
|
||||||
|
import static org.jetbrains.jet.cli.common.messages.CompilerMessageSeverity.*;
|
||||||
|
|
||||||
|
public class ModuleXmlParser {
|
||||||
|
|
||||||
|
public static final String MODULES = "modules";
|
||||||
|
public static final String MODULE = "module";
|
||||||
|
public static final String NAME = "name";
|
||||||
|
public static final String SOURCES = "sources";
|
||||||
|
public static final String PATH = "path";
|
||||||
|
public static final String CLASSPATH = "classpath";
|
||||||
|
public static final String EXTERNAL_ANNOTATIONS = "externalAnnotations";
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
public static List<ModuleDescription> parse(@NotNull String xmlFile, @NotNull MessageCollector messageCollector) {
|
||||||
|
FileInputStream stream = null;
|
||||||
|
try {
|
||||||
|
stream = new FileInputStream(xmlFile);
|
||||||
|
//noinspection IOResourceOpenedButNotSafelyClosed
|
||||||
|
return new ModuleXmlParser(messageCollector).parse(new BufferedInputStream(stream));
|
||||||
|
}
|
||||||
|
catch (FileNotFoundException e) {
|
||||||
|
MessageCollectorUtil.reportException(messageCollector, e);
|
||||||
|
return Collections.emptyList();
|
||||||
|
}
|
||||||
|
finally {
|
||||||
|
StreamUtil.closeStream(stream);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private final MessageCollector messageCollector;
|
||||||
|
private final List<ModuleDescription> result = new SmartList<ModuleDescription>();
|
||||||
|
private DefaultHandler currentState;
|
||||||
|
|
||||||
|
private ModuleXmlParser(@NotNull MessageCollector messageCollector) {
|
||||||
|
this.messageCollector = messageCollector;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setCurrentState(@NotNull DefaultHandler currentState) {
|
||||||
|
this.currentState = currentState;
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<ModuleDescription> parse(@NotNull InputStream xml) {
|
||||||
|
try {
|
||||||
|
setCurrentState(initial);
|
||||||
|
SAXParser saxParser = SAXParserFactory.newInstance().newSAXParser();
|
||||||
|
saxParser.parse(xml, new DelegatedSaxHandler() {
|
||||||
|
@NotNull
|
||||||
|
@Override
|
||||||
|
protected DefaultHandler getDelegate() {
|
||||||
|
return currentState;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
catch (ParserConfigurationException e) {
|
||||||
|
MessageCollectorUtil.reportException(messageCollector, e);
|
||||||
|
}
|
||||||
|
catch (SAXException e) {
|
||||||
|
messageCollector.report(ERROR, MessageRenderer.PLAIN.renderException(e), NO_LOCATION);
|
||||||
|
}
|
||||||
|
catch (IOException e) {
|
||||||
|
MessageCollectorUtil.reportException(messageCollector, e);
|
||||||
|
}
|
||||||
|
return Collections.emptyList();
|
||||||
|
}
|
||||||
|
|
||||||
|
private final DefaultHandler initial = new DefaultHandler() {
|
||||||
|
@Override
|
||||||
|
public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
|
||||||
|
if (!MODULES.equalsIgnoreCase(qName)) {
|
||||||
|
throw createError(qName);
|
||||||
|
}
|
||||||
|
|
||||||
|
setCurrentState(insideModules);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
private final DefaultHandler insideModules = new DefaultHandler() {
|
||||||
|
@Override
|
||||||
|
public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
|
||||||
|
if (!MODULE.equalsIgnoreCase(qName)) {
|
||||||
|
throw createError(qName);
|
||||||
|
}
|
||||||
|
|
||||||
|
setCurrentState(new InsideModule(getAttribute(attributes, NAME, qName)));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void endElement(String uri, String localName, String qName) throws SAXException {
|
||||||
|
if (MODULE.equalsIgnoreCase(qName) || MODULES.equalsIgnoreCase(qName)) {
|
||||||
|
setCurrentState(insideModules);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
private class InsideModule extends DefaultHandler {
|
||||||
|
|
||||||
|
private final ModuleDescription.Impl moduleDescription;
|
||||||
|
private InsideModule(String name) {
|
||||||
|
this.moduleDescription = new ModuleDescription.Impl();
|
||||||
|
this.moduleDescription.setName(name);
|
||||||
|
result.add(moduleDescription);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
|
||||||
|
if (SOURCES.equalsIgnoreCase(qName)) {
|
||||||
|
String path = getAttribute(attributes, PATH, qName);
|
||||||
|
moduleDescription.addSourcePath(path);
|
||||||
|
}
|
||||||
|
else if (CLASSPATH.equalsIgnoreCase(qName)) {
|
||||||
|
String path = getAttribute(attributes, PATH, qName);
|
||||||
|
moduleDescription.addClassPath(path);
|
||||||
|
}
|
||||||
|
else if (EXTERNAL_ANNOTATIONS.equalsIgnoreCase(qName)) {
|
||||||
|
String path = getAttribute(attributes, PATH, qName);
|
||||||
|
moduleDescription.addAnnotationPath(path);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
throw createError(qName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void endElement(String uri, String localName, String qName) throws SAXException {
|
||||||
|
if (MODULE.equalsIgnoreCase(qName)) {
|
||||||
|
setCurrentState(insideModules);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
private static String getAttribute(Attributes attributes, String qName, String tag) throws SAXException {
|
||||||
|
String name = attributes.getValue(qName);
|
||||||
|
if (name == null) {
|
||||||
|
throw new SAXException("No '" + qName + "' attribute for " + tag);
|
||||||
|
}
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static SAXException createError(String qName) throws SAXException {
|
||||||
|
return new SAXException("Unexpected tag: " + qName);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
name
|
||||||
|
sources=[foo]
|
||||||
|
classpath=[bar]
|
||||||
|
annotations=[baz]
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
<modules>
|
||||||
|
<module name="name">
|
||||||
|
<sources path="foo"/>
|
||||||
|
<classpath path="bar"/>
|
||||||
|
<externalAnnotations path="baz"/>
|
||||||
|
</module>
|
||||||
|
</modules>
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
name
|
||||||
|
sources=[foo, foo1, foo2]
|
||||||
|
classpath=[bar1, bar2]
|
||||||
|
annotations=[baz, baz1, baz2]
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
<modules>
|
||||||
|
<module name="name">
|
||||||
|
<sources path="foo"/>
|
||||||
|
<sources path="foo1"/>
|
||||||
|
<sources path="foo2"/>
|
||||||
|
<!--
|
||||||
|
<classpath path="bar"/>
|
||||||
|
-->
|
||||||
|
<classpath path="bar1"/>
|
||||||
|
<!-- sdfgadfg -->
|
||||||
|
<classpath path="bar2"/>
|
||||||
|
<externalAnnotations path="baz"/>
|
||||||
|
<externalAnnotations path="baz1"/>
|
||||||
|
<externalAnnotations path="baz2"/>
|
||||||
|
</module>
|
||||||
|
</modules>
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
<modules/>
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
name
|
||||||
|
sources=[]
|
||||||
|
classpath=[]
|
||||||
|
annotations=[]
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
<modules>
|
||||||
|
<module name="name"/>
|
||||||
|
</modules>
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
name
|
||||||
|
sources=[foo, foo1, foo2]
|
||||||
|
classpath=[bar, bar1, bar2]
|
||||||
|
annotations=[baz, baz1, baz2]
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
<modules>
|
||||||
|
<module name="name">
|
||||||
|
<sources path="foo"/>
|
||||||
|
<sources path="foo1"/>
|
||||||
|
<sources path="foo2"/>
|
||||||
|
<classpath path="bar"/>
|
||||||
|
<classpath path="bar1"/>
|
||||||
|
<classpath path="bar2"/>
|
||||||
|
<externalAnnotations path="baz"/>
|
||||||
|
<externalAnnotations path="baz1"/>
|
||||||
|
<externalAnnotations path="baz2"/>
|
||||||
|
</module>
|
||||||
|
</modules>
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
name
|
||||||
|
sources=[foo]
|
||||||
|
classpath=[]
|
||||||
|
annotations=[]
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
<modules>
|
||||||
|
<module name="name">
|
||||||
|
<sources path="foo"/>
|
||||||
|
</module>
|
||||||
|
</modules>
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
name
|
||||||
|
sources=[foo, foo1, foo2]
|
||||||
|
classpath=[bar, bar1, bar2]
|
||||||
|
annotations=[baz, baz1, baz2]
|
||||||
|
name2
|
||||||
|
sources=[2foo, 2foo1, 2foo2]
|
||||||
|
classpath=[2bar, 2bar1, 2bar2]
|
||||||
|
annotations=[2baz, 2baz1, 2baz2]
|
||||||
@@ -0,0 +1,24 @@
|
|||||||
|
<modules>
|
||||||
|
<module name="name">
|
||||||
|
<sources path="foo"/>
|
||||||
|
<sources path="foo1"/>
|
||||||
|
<sources path="foo2"/>
|
||||||
|
<classpath path="bar"/>
|
||||||
|
<classpath path="bar1"/>
|
||||||
|
<classpath path="bar2"/>
|
||||||
|
<externalAnnotations path="baz"/>
|
||||||
|
<externalAnnotations path="baz1"/>
|
||||||
|
<externalAnnotations path="baz2"/>
|
||||||
|
</module>
|
||||||
|
<module name="name2">
|
||||||
|
<sources path="2foo"/>
|
||||||
|
<sources path="2foo1"/>
|
||||||
|
<sources path="2foo2"/>
|
||||||
|
<classpath path="2bar"/>
|
||||||
|
<classpath path="2bar1"/>
|
||||||
|
<classpath path="2bar2"/>
|
||||||
|
<externalAnnotations path="2baz"/>
|
||||||
|
<externalAnnotations path="2baz1"/>
|
||||||
|
<externalAnnotations path="2baz2"/>
|
||||||
|
</module>
|
||||||
|
</modules>
|
||||||
@@ -0,0 +1,63 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2013 JetBrains s.r.o.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.jetbrains.jet.modules.xml;
|
||||||
|
|
||||||
|
import com.intellij.openapi.util.io.FileUtil;
|
||||||
|
import junit.framework.TestCase;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.jet.cli.common.messages.CompilerMessageLocation;
|
||||||
|
import org.jetbrains.jet.cli.common.messages.CompilerMessageSeverity;
|
||||||
|
import org.jetbrains.jet.cli.common.messages.MessageCollector;
|
||||||
|
import org.jetbrains.jet.cli.common.messages.MessageRenderer;
|
||||||
|
import org.jetbrains.jet.cli.common.modules.ModuleDescription;
|
||||||
|
import org.jetbrains.jet.cli.common.modules.ModuleXmlParser;
|
||||||
|
import org.jetbrains.jet.utils.Printer;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public abstract class AbstractModuleXmlParserTest extends TestCase {
|
||||||
|
|
||||||
|
protected void doTest(String xmlPath) throws IOException {
|
||||||
|
File txtFile = new File(FileUtil.getNameWithoutExtension(xmlPath) + ".txt");
|
||||||
|
|
||||||
|
List<ModuleDescription> result = ModuleXmlParser.parse(xmlPath, new MessageCollector() {
|
||||||
|
@Override
|
||||||
|
public void report(
|
||||||
|
@NotNull CompilerMessageSeverity severity, @NotNull String message, @NotNull CompilerMessageLocation location
|
||||||
|
) {
|
||||||
|
throw new AssertionError(MessageRenderer.PLAIN.render(severity, message, location));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
StringBuilder sb = new StringBuilder();
|
||||||
|
Printer p = new Printer(sb);
|
||||||
|
for (ModuleDescription description : result) {
|
||||||
|
p.println(description);
|
||||||
|
}
|
||||||
|
|
||||||
|
String actual = sb.toString();
|
||||||
|
|
||||||
|
if (!txtFile.exists()) {
|
||||||
|
FileUtil.writeToFile(txtFile, actual);
|
||||||
|
fail("Expected data file does not exist. A new file created: " + txtFile);
|
||||||
|
}
|
||||||
|
|
||||||
|
assertEquals(FileUtil.loadFile(txtFile), actual);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,68 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2013 JetBrains s.r.o.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.jetbrains.jet.modules.xml;
|
||||||
|
|
||||||
|
import org.jetbrains.jet.JetTestUtils;
|
||||||
|
import org.jetbrains.jet.test.TestMetadata;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
|
/** This class is generated by {@link org.jetbrains.jet.generators.tests.GenerateTests}. DO NOT MODIFY MANUALLY */
|
||||||
|
@SuppressWarnings("all")
|
||||||
|
@TestMetadata("compiler/testData/modules.xml")
|
||||||
|
public class ModuleXmlParserTestGenerated extends AbstractModuleXmlParserTest {
|
||||||
|
public void testAllFilesPresentInModules_xml() throws Exception {
|
||||||
|
JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.GenerateTests", new File("compiler/testData/modules.xml"), Pattern.compile("^(.+)\\.xml$"), true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("allOnce.xml")
|
||||||
|
public void testAllOnce() throws Exception {
|
||||||
|
doTest("compiler/testData/modules.xml/allOnce.xml");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("comments.xml")
|
||||||
|
public void testComments() throws Exception {
|
||||||
|
doTest("compiler/testData/modules.xml/comments.xml");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("empty.xml")
|
||||||
|
public void testEmpty() throws Exception {
|
||||||
|
doTest("compiler/testData/modules.xml/empty.xml");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("emptyModule.xml")
|
||||||
|
public void testEmptyModule() throws Exception {
|
||||||
|
doTest("compiler/testData/modules.xml/emptyModule.xml");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("manyTimes.xml")
|
||||||
|
public void testManyTimes() throws Exception {
|
||||||
|
doTest("compiler/testData/modules.xml/manyTimes.xml");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("onlySources.xml")
|
||||||
|
public void testOnlySources() throws Exception {
|
||||||
|
doTest("compiler/testData/modules.xml/onlySources.xml");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("twoModules.xml")
|
||||||
|
public void testTwoModules() throws Exception {
|
||||||
|
doTest("compiler/testData/modules.xml/twoModules.xml");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -35,6 +35,7 @@ import org.jetbrains.jet.jvm.compiler.*;
|
|||||||
import org.jetbrains.jet.lang.resolve.lazy.AbstractLazyResolveDescriptorRendererTest;
|
import org.jetbrains.jet.lang.resolve.lazy.AbstractLazyResolveDescriptorRendererTest;
|
||||||
import org.jetbrains.jet.lang.resolve.lazy.AbstractLazyResolveNamespaceComparingTest;
|
import org.jetbrains.jet.lang.resolve.lazy.AbstractLazyResolveNamespaceComparingTest;
|
||||||
import org.jetbrains.jet.lang.resolve.lazy.AbstractLazyResolveTest;
|
import org.jetbrains.jet.lang.resolve.lazy.AbstractLazyResolveTest;
|
||||||
|
import org.jetbrains.jet.modules.xml.AbstractModuleXmlParserTest;
|
||||||
import org.jetbrains.jet.plugin.codeInsight.codeTransformations.AbstractCodeTransformationTest;
|
import org.jetbrains.jet.plugin.codeInsight.codeTransformations.AbstractCodeTransformationTest;
|
||||||
import org.jetbrains.jet.plugin.codeInsight.surroundWith.AbstractSurroundWithTest;
|
import org.jetbrains.jet.plugin.codeInsight.surroundWith.AbstractSurroundWithTest;
|
||||||
import org.jetbrains.jet.plugin.folding.AbstractKotlinFoldingTest;
|
import org.jetbrains.jet.plugin.folding.AbstractKotlinFoldingTest;
|
||||||
@@ -203,6 +204,13 @@ public class GenerateTests {
|
|||||||
testModel("compiler/testData/lazyResolve/namespaceComparator", "doTestCheckingPrimaryConstructors")
|
testModel("compiler/testData/lazyResolve/namespaceComparator", "doTestCheckingPrimaryConstructors")
|
||||||
);
|
);
|
||||||
|
|
||||||
|
generateTest(
|
||||||
|
"compiler/tests/",
|
||||||
|
"ModuleXmlParserTestGenerated",
|
||||||
|
AbstractModuleXmlParserTest.class,
|
||||||
|
testModel("compiler/testData/modules.xml", true, "xml", "doTest")
|
||||||
|
);
|
||||||
|
|
||||||
generateTest(
|
generateTest(
|
||||||
"idea/tests/",
|
"idea/tests/",
|
||||||
"JetPsiCheckerTestGenerated",
|
"JetPsiCheckerTestGenerated",
|
||||||
|
|||||||
+2
-2
@@ -32,11 +32,11 @@ public interface KotlinModuleDescriptionGenerator {
|
|||||||
Set<File> directoriesToFilterOut
|
Set<File> directoriesToFilterOut
|
||||||
);
|
);
|
||||||
|
|
||||||
public interface DependencyProvider {
|
interface DependencyProvider {
|
||||||
void processClassPath(@NotNull DependencyProcessor processor);
|
void processClassPath(@NotNull DependencyProcessor processor);
|
||||||
}
|
}
|
||||||
|
|
||||||
public interface DependencyProcessor {
|
interface DependencyProcessor {
|
||||||
void processClassPathSection(@NotNull String sectionDescription, @NotNull Collection<File> files);
|
void processClassPathSection(@NotNull String sectionDescription, @NotNull Collection<File> files);
|
||||||
void processAnnotationRoots(@NotNull List<File> files);
|
void processAnnotationRoots(@NotNull List<File> files);
|
||||||
}
|
}
|
||||||
|
|||||||
+116
@@ -0,0 +1,116 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2013 JetBrains s.r.o.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.jetbrains.jet.compiler.runner;
|
||||||
|
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.jet.utils.Printer;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
import static com.intellij.openapi.util.io.FileUtil.toSystemIndependentName;
|
||||||
|
import static com.intellij.openapi.util.text.StringUtil.escapeXml;
|
||||||
|
import static org.jetbrains.jet.cli.common.modules.ModuleXmlParser.*;
|
||||||
|
|
||||||
|
public class KotlinModuleXmlGenerator implements KotlinModuleDescriptionGenerator {
|
||||||
|
|
||||||
|
public static final KotlinModuleXmlGenerator INSTANCE = new KotlinModuleXmlGenerator();
|
||||||
|
|
||||||
|
private KotlinModuleXmlGenerator() {}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CharSequence generateModuleScript(
|
||||||
|
String moduleName,
|
||||||
|
DependencyProvider dependencyProvider,
|
||||||
|
List<File> sourceFiles,
|
||||||
|
boolean tests,
|
||||||
|
final Set<File> directoriesToFilterOut
|
||||||
|
) {
|
||||||
|
StringBuilder xml = new StringBuilder();
|
||||||
|
final Printer p = new Printer(xml);
|
||||||
|
|
||||||
|
openTag(p, MODULES);
|
||||||
|
|
||||||
|
if (tests) {
|
||||||
|
p.println("<!-- Module script for tests -->");
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
p.println("<!-- Module script for production -->");
|
||||||
|
}
|
||||||
|
|
||||||
|
p.println("<", MODULE, " ", NAME, "=\"", escapeXml(moduleName), "\">");
|
||||||
|
p.pushIndent();
|
||||||
|
|
||||||
|
for (File sourceFile : sourceFiles) {
|
||||||
|
p.println("<", SOURCES, " ", PATH, "=\"", getEscapedPath(sourceFile), "\"/>");
|
||||||
|
}
|
||||||
|
|
||||||
|
dependencyProvider.processClassPath(new DependencyProcessor() {
|
||||||
|
@Override
|
||||||
|
public void processClassPathSection(@NotNull String sectionDescription, @NotNull Collection<File> files) {
|
||||||
|
p.println("<!-- ", sectionDescription, " -->");
|
||||||
|
for (File file : files) {
|
||||||
|
boolean isOutput = directoriesToFilterOut.contains(file);
|
||||||
|
if (isOutput) {
|
||||||
|
// For IDEA's make (incremental compilation) purposes, output directories of the current module and its dependencies
|
||||||
|
// appear on the class path, so we are at risk of seeing the results of the previous build, i.e. if some class was
|
||||||
|
// removed in the sources, it may still be there in binaries. Thus, we delete these entries from the classpath.
|
||||||
|
p.println("<!-- Output directory, commented out -->");
|
||||||
|
p.println("<!-- ");
|
||||||
|
p.pushIndent();
|
||||||
|
}
|
||||||
|
|
||||||
|
p.println("<", CLASSPATH, " ", PATH, "=\"", getEscapedPath(file), "\"/>");
|
||||||
|
|
||||||
|
if (isOutput) {
|
||||||
|
p.popIndent();
|
||||||
|
p.println("-->");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void processAnnotationRoots(@NotNull List<File> files) {
|
||||||
|
p.println("<!-- External annotations -->");
|
||||||
|
for (File file : files) {
|
||||||
|
p.println("<", EXTERNAL_ANNOTATIONS, " ", PATH, "= \"", getEscapedPath(file), "\"/>");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
closeTag(p, MODULE);
|
||||||
|
|
||||||
|
closeTag(p, MODULES);
|
||||||
|
return xml;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void openTag(Printer p, String tag) {
|
||||||
|
p.println("<" + tag + ">");
|
||||||
|
p.pushIndent();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void closeTag(Printer p, String tag) {
|
||||||
|
p.popIndent();
|
||||||
|
p.println("</" + tag + ">");
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String getEscapedPath(File sourceFile) {
|
||||||
|
return escapeXml(toSystemIndependentName(sourceFile.getPath()));
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
<modules>
|
||||||
|
<!-- Module script for production -->
|
||||||
|
<module name="name">
|
||||||
|
<sources path="s1"/>
|
||||||
|
<sources path="s2"/>
|
||||||
|
<!-- External annotations -->
|
||||||
|
<externalAnnotations path= "a1/f1"/>
|
||||||
|
<externalAnnotations path= "a2"/>
|
||||||
|
<!-- s1 -->
|
||||||
|
<classpath path="cp1"/>
|
||||||
|
<classpath path="cp2"/>
|
||||||
|
</module>
|
||||||
|
</modules>
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
<modules>
|
||||||
|
<!-- Module script for production -->
|
||||||
|
<module name="name">
|
||||||
|
<sources path="s1"/>
|
||||||
|
<sources path="s2"/>
|
||||||
|
<!-- External annotations -->
|
||||||
|
<externalAnnotations path= "a1/f1"/>
|
||||||
|
<externalAnnotations path= "a2"/>
|
||||||
|
<!-- s1 -->
|
||||||
|
<!-- Output directory, commented out -->
|
||||||
|
<!--
|
||||||
|
<classpath path="cp1"/>
|
||||||
|
-->
|
||||||
|
<classpath path="cp2"/>
|
||||||
|
</module>
|
||||||
|
</modules>
|
||||||
@@ -0,0 +1,65 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2013 JetBrains s.r.o.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.jetbrains.jet.modules.xml;
|
||||||
|
|
||||||
|
import com.intellij.openapi.util.io.FileUtil;
|
||||||
|
import junit.framework.TestCase;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.jet.compiler.runner.KotlinModuleDescriptionGenerator;
|
||||||
|
import org.jetbrains.jet.compiler.runner.KotlinModuleXmlGenerator;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.Collections;
|
||||||
|
|
||||||
|
public class KotlinModuleXmlGeneratorTest extends TestCase {
|
||||||
|
public void testBasic() throws Exception {
|
||||||
|
String actual = KotlinModuleXmlGenerator.INSTANCE.generateModuleScript(
|
||||||
|
"name",
|
||||||
|
new KotlinModuleDescriptionGenerator.DependencyProvider() {
|
||||||
|
@Override
|
||||||
|
public void processClassPath(@NotNull KotlinModuleDescriptionGenerator.DependencyProcessor processor) {
|
||||||
|
processor.processAnnotationRoots(Arrays.asList(new File("a1/f1"), new File("a2")));
|
||||||
|
processor.processClassPathSection("s1", Arrays.asList(new File("cp1"), new File("cp2")));
|
||||||
|
}
|
||||||
|
},
|
||||||
|
Arrays.asList(new File("s1"), new File("s2")),
|
||||||
|
false,
|
||||||
|
Collections.<File>emptySet()
|
||||||
|
).toString();
|
||||||
|
String expected = FileUtil.loadFile(new File("idea/testData/modules.xml/basic.xml"));
|
||||||
|
assertEquals(expected, actual);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testFiltered() throws Exception {
|
||||||
|
String actual = KotlinModuleXmlGenerator.INSTANCE.generateModuleScript(
|
||||||
|
"name",
|
||||||
|
new KotlinModuleDescriptionGenerator.DependencyProvider() {
|
||||||
|
@Override
|
||||||
|
public void processClassPath(@NotNull KotlinModuleDescriptionGenerator.DependencyProcessor processor) {
|
||||||
|
processor.processAnnotationRoots(Arrays.asList(new File("a1/f1"), new File("a2")));
|
||||||
|
processor.processClassPathSection("s1", Arrays.asList(new File("cp1"), new File("cp2")));
|
||||||
|
}
|
||||||
|
},
|
||||||
|
Arrays.asList(new File("s1"), new File("s2")),
|
||||||
|
false,
|
||||||
|
Collections.singleton(new File("cp1"))
|
||||||
|
).toString();
|
||||||
|
String expected = FileUtil.loadFile(new File("idea/testData/modules.xml/filtered.xml"));
|
||||||
|
assertEquals(expected, actual);
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user