diff --git a/compiler/cli/src/org/jetbrains/jet/cli/common/CLICompiler.java b/compiler/cli/src/org/jetbrains/jet/cli/common/CLICompiler.java index e77856c9f22..1cb04464717 100644 --- a/compiler/cli/src/org/jetbrains/jet/cli/common/CLICompiler.java +++ b/compiler/cli/src/org/jetbrains/jet/cli/common/CLICompiler.java @@ -93,6 +93,7 @@ public abstract class CLICompiler\n"); + out.append(">"); out.append(e(message)); diff --git a/compiler/cli/src/org/jetbrains/jet/cli/jvm/K2JVMCompiler.java b/compiler/cli/src/org/jetbrains/jet/cli/jvm/K2JVMCompiler.java index d9878514549..234191b7749 100644 --- a/compiler/cli/src/org/jetbrains/jet/cli/jvm/K2JVMCompiler.java +++ b/compiler/cli/src/org/jetbrains/jet/cli/jvm/K2JVMCompiler.java @@ -56,10 +56,8 @@ public class K2JVMCompiler extends CLICompiler() { + @Override + public Void invoke(MessageChecker checker) { + //nothing apart from header + return null; + } + }); + } + + + public void testSimpleWarning() { + doTest(new Function1() { + @Override + public Void invoke(MessageChecker checker) { + checker.expect(warning().text("Unnecessary non-null assertion (!!) on a non-null receiver of type jet.String") + .at("test.kt", 4, 4)); + return null; + } + }); + } + + public void testSimpleError() { + doTest(new Function1() { + @Override + public Void invoke(MessageChecker checker) { + checker.expect( + error().text("A 'return' expression required in a function with a block body ('{...}')").at("test.kt", 5, 1)); + return null; + } + }); + } + + private void doTest(@NotNull Function1 whatToExpect) { + String pathToTestDir = TEST_DATA_PATH + "/" + getTestName(true); + VirtualFile testDir = LocalFileSystem.getInstance().findFileByPath(pathToTestDir); + VirtualFile sampleFile = LocalFileSystem.getInstance().findFileByPath(pathToTestDir + "/src/test.kt"); + VirtualFile outDirectory = getOutDirectory(pathToTestDir, testDir); + VirtualFile root = LocalFileSystem.getInstance().findFileByPath(pathToTestDir + "/src/"); + MockCompileContext mockCompileContext = new MockCompileContext(myModule, outDirectory, root); + MockModuleChunk mockModuleChunk = new MockModuleChunk(myModule); + new JetCompiler() + .compile(mockCompileContext, mockModuleChunk, new VirtualFile[] {sampleFile}, new MockOutputSink()); + MessageChecker checker = new MessageChecker(mockCompileContext); + checkHeader(checker); + whatToExpect.invoke(checker); + checker.finish(); + } + + @NotNull + private VirtualFile getOutDirectory(@NotNull String pathToTestDir, @NotNull VirtualFile testDir) { + VirtualFile outDirectory = LocalFileSystem.getInstance().findFileByPath(pathToTestDir + "/out"); + if (outDirectory == null) { + try { + outDirectory = LocalFileSystem.getInstance().createChildDirectory(this, testDir, "out"); + } + catch (IOException e) { + fail(); + } + } + return outDirectory; + } + + private static void checkHeader(@NotNull MessageChecker checker) { + checker.expect(Message.info().textStartsWith("Using kotlinHome=")); + checker.expect(Message.info().textStartsWith("Invoking in-process compiler")); + checker.expect(Message.info().textStartsWith("Kotlin Compiler version")); + } +} diff --git a/idea/tests/org/jetbrains/jet/plugin/compilerMessages/Message.java b/idea/tests/org/jetbrains/jet/plugin/compilerMessages/Message.java new file mode 100644 index 00000000000..7e87696cac7 --- /dev/null +++ b/idea/tests/org/jetbrains/jet/plugin/compilerMessages/Message.java @@ -0,0 +1,101 @@ +/* + * Copyright 2010-2012 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.plugin.compilerMessages; + +import com.intellij.openapi.compiler.CompilerMessageCategory; +import junit.framework.Assert; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +/** + * @author Pavel Talanov + */ +@SuppressWarnings("ConstantConditions") +public final class Message { + + @NotNull + public static Message warning() { + return new Message(CompilerMessageCategory.WARNING); + } + + @NotNull + public static Message error() { + return new Message(CompilerMessageCategory.ERROR); + } + + @NotNull + public static Message info() { + return new Message(CompilerMessageCategory.INFORMATION); + } + + @NotNull + public CompilerMessageCategory category; + @Nullable + public String url = null; + @Nullable + public String message = null; + @Nullable + public String textStartsWith = null; + public int column = -1; + public int line = -1; + + public Message(CompilerMessageCategory category) { + this.category = category; + } + + public Message(CompilerMessageCategory category, String message, String url, int num, int num1) { + this(category); + text(message).at(url, num, num1); + } + + + public Message at(String url, int line, int column) { + this.url = url; + this.line = line; + this.column = column; + return this; + } + + public Message text(String message) { + this.message = message; + return this; + } + + public Message textStartsWith(String message) { + this.textStartsWith = message; + return this; + } + + public void check(@NotNull Message other) { + Assert.assertEquals(this.category, other.category); + checkMessages(other); + Assert.assertEquals(this.line, other.line); + Assert.assertEquals(this.column, other.column); + if (this.url != null) { + Assert.assertTrue(other.url.endsWith(this.url)); + } + } + + private void checkMessages(Message other) { + if (textStartsWith != null) { + Assert.assertTrue("Message should start with:\n" + textStartsWith + "\nBut it is:\n" + other.message, + other.message.startsWith(textStartsWith)); + return; + } + Assert.assertEquals(other.message, this.message); + } +} diff --git a/idea/tests/org/jetbrains/jet/plugin/compilerMessages/MessageChecker.java b/idea/tests/org/jetbrains/jet/plugin/compilerMessages/MessageChecker.java new file mode 100644 index 00000000000..03a9af7914f --- /dev/null +++ b/idea/tests/org/jetbrains/jet/plugin/compilerMessages/MessageChecker.java @@ -0,0 +1,48 @@ +/* + * Copyright 2010-2012 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.plugin.compilerMessages; + +import org.jetbrains.annotations.NotNull; +import org.junit.Assert; + +import java.util.Iterator; + +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +/** + * @author Pavel Talanov + */ +public final class MessageChecker { + + private final Iterator iterator; + + public MessageChecker(@NotNull MockCompileContext context) { + this.iterator = context.getReceivedMessages().iterator(); + } + + @NotNull + public MessageChecker expect(@NotNull Message message) { + assertTrue("More messages expected", iterator.hasNext()); + message.check(iterator.next()); + return this; + } + + public void finish() { + assertFalse("More message than expected", iterator.hasNext()); + } +} diff --git a/idea/tests/org/jetbrains/jet/plugin/compilerMessages/MockCompileContext.java b/idea/tests/org/jetbrains/jet/plugin/compilerMessages/MockCompileContext.java new file mode 100644 index 00000000000..cdadd26dde8 --- /dev/null +++ b/idea/tests/org/jetbrains/jet/plugin/compilerMessages/MockCompileContext.java @@ -0,0 +1,230 @@ +/* + * Copyright 2010-2012 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.plugin.compilerMessages; + +import com.google.common.collect.Lists; +import com.intellij.compiler.make.DependencyCache; +import com.intellij.mock.MockProgressIndicator; +import com.intellij.openapi.compiler.CompileScope; +import com.intellij.openapi.compiler.Compiler; +import com.intellij.openapi.compiler.CompilerMessage; +import com.intellij.openapi.compiler.CompilerMessageCategory; +import com.intellij.openapi.compiler.ex.CompileContextEx; +import com.intellij.openapi.module.Module; +import com.intellij.openapi.progress.ProgressIndicator; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.Key; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.pom.Navigatable; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +import java.util.Collection; +import java.util.List; +import java.util.Set; + +/** + * @author Pavel Talanov + */ +public class MockCompileContext implements CompileContextEx { + + @NotNull + private final List receivedMessages = Lists.newArrayList(); + @NotNull + private final Module module; + @NotNull + private final VirtualFile outputDirectory; + @NotNull + private final VirtualFile sourceRoot; + + public MockCompileContext(@NotNull Module module, @NotNull VirtualFile outputDir, @NotNull VirtualFile root) { + this.module = module; + outputDirectory = outputDir; + sourceRoot = root; + } + + @NotNull + public List getReceivedMessages() { + return receivedMessages; + } + + @Override + public DependencyCache getDependencyCache() { + throw new UnsupportedOperationException("org.jetbrains.jet.plugin.compilerMessages.MockCompileContext#getDependencyCache"); + } + + @Override + public VirtualFile getSourceFileByOutputFile(VirtualFile outputFile) { + throw new UnsupportedOperationException("org.jetbrains.jet.plugin.compilerMessages.MockCompileContext#getSourceFileByOutputFile"); + } + + @Override + public void addMessage(CompilerMessage message) { + throw new UnsupportedOperationException("org.jetbrains.jet.plugin.compilerMessages.MockCompileContext#addMessage"); + } + + @NotNull + @Override + public Set getTestOutputDirectories() { + throw new UnsupportedOperationException("org.jetbrains.jet.plugin.compilerMessages.MockCompileContext#getTestOutputDirectories"); + } + + @Override + public boolean isInTestSourceContent(@NotNull VirtualFile fileOrDir) { + return false; + } + + @Override + public boolean isInSourceContent(@NotNull VirtualFile fileOrDir) { + throw new UnsupportedOperationException("org.jetbrains.jet.plugin.compilerMessages.MockCompileContext#isInSourceContent"); + } + + @Override + public void addScope(CompileScope additionalScope) { + throw new UnsupportedOperationException("org.jetbrains.jet.plugin.compilerMessages.MockCompileContext#addScope"); + } + + @Override + public long getStartCompilationStamp() { + throw new UnsupportedOperationException("org.jetbrains.jet.plugin.compilerMessages.MockCompileContext#getStartCompilationStamp"); + } + + @Override + public void recalculateOutputDirs() { + throw new UnsupportedOperationException("org.jetbrains.jet.plugin.compilerMessages.MockCompileContext#recalculateOutputDirs"); + } + + @Override + public void markGenerated(Collection files) { + throw new UnsupportedOperationException("org.jetbrains.jet.plugin.compilerMessages.MockCompileContext#markGenerated"); + } + + @Override + public boolean isGenerated(VirtualFile file) { + throw new UnsupportedOperationException("org.jetbrains.jet.plugin.compilerMessages.MockCompileContext#isGenerated"); + } + + @Override + public void assignModule(@NotNull VirtualFile root, + @NotNull Module module, + boolean isTestSource, + @Nullable Compiler compiler) { + throw new UnsupportedOperationException("org.jetbrains.jet.plugin.compilerMessages.MockCompileContext#assignModule"); + } + + @Override + public void addMessage(CompilerMessageCategory category, String message, @Nullable String url, int lineNum, int columnNum) { + receivedMessages.add(new Message(category, message, url, lineNum, columnNum)); + } + + @Override + public void addMessage(CompilerMessageCategory category, + String message, + @Nullable String url, + int lineNum, + int columnNum, + Navigatable navigatable) { + throw new UnsupportedOperationException("org.jetbrains.jet.plugin.compilerMessages.MockCompileContext#addMessage"); + } + + @Override + public CompilerMessage[] getMessages(CompilerMessageCategory category) { + throw new UnsupportedOperationException("org.jetbrains.jet.plugin.compilerMessages.MockCompileContext#getMessages"); + } + + @Override + public int getMessageCount(CompilerMessageCategory category) { + throw new UnsupportedOperationException("org.jetbrains.jet.plugin.compilerMessages.MockCompileContext#getMessageCount"); + } + + @NotNull + @Override + public ProgressIndicator getProgressIndicator() { + return new MockProgressIndicator(); + } + + @Override + public CompileScope getCompileScope() { + throw new UnsupportedOperationException("org.jetbrains.jet.plugin.compilerMessages.MockCompileContext#getCompileScope"); + } + + @Override + public CompileScope getProjectCompileScope() { + throw new UnsupportedOperationException("org.jetbrains.jet.plugin.compilerMessages.MockCompileContext#getProjectCompileScope"); + } + + @Override + public void requestRebuildNextTime(String message) { + throw new UnsupportedOperationException("org.jetbrains.jet.plugin.compilerMessages.MockCompileContext#requestRebuildNextTime"); + } + + @Override + public Module getModuleByFile(VirtualFile file) { + return module; + } + + @Override + public VirtualFile[] getSourceRoots(Module module) { + return new VirtualFile[] {sourceRoot}; + } + + @Override + public VirtualFile[] getAllOutputDirectories() { + throw new UnsupportedOperationException("org.jetbrains.jet.plugin.compilerMessages.MockCompileContext#getAllOutputDirectories"); + } + + @Override + public VirtualFile getModuleOutputDirectory(Module module) { + return outputDirectory; + } + + @Override + public VirtualFile getModuleOutputDirectoryForTests(Module module) { + return outputDirectory; + } + + @Override + public boolean isMake() { + throw new UnsupportedOperationException("org.jetbrains.jet.plugin.compilerMessages.MockCompileContext#isMake"); + } + + @Override + public boolean isRebuild() { + throw new UnsupportedOperationException("org.jetbrains.jet.plugin.compilerMessages.MockCompileContext#isRebuild"); + } + + @Override + public Project getProject() { + throw new UnsupportedOperationException("org.jetbrains.jet.plugin.compilerMessages.MockCompileContext#getProject"); + } + + @Override + public boolean isAnnotationProcessorsEnabled() { + throw new UnsupportedOperationException( + "org.jetbrains.jet.plugin.compilerMessages.MockCompileContext#isAnnotationProcessorsEnabled"); + } + + @Override + public T getUserData(@NotNull Key key) { + throw new UnsupportedOperationException("org.jetbrains.jet.plugin.compilerMessages.MockCompileContext#getUserData"); + } + + @Override + public void putUserData(@NotNull Key key, @Nullable T value) { + throw new UnsupportedOperationException("org.jetbrains.jet.plugin.compilerMessages.MockCompileContext#putUserData"); + } +} \ No newline at end of file diff --git a/idea/tests/org/jetbrains/jet/plugin/compilerMessages/MockModuleChunk.java b/idea/tests/org/jetbrains/jet/plugin/compilerMessages/MockModuleChunk.java new file mode 100644 index 00000000000..cce70d8a6c0 --- /dev/null +++ b/idea/tests/org/jetbrains/jet/plugin/compilerMessages/MockModuleChunk.java @@ -0,0 +1,29 @@ +/* + * Copyright 2010-2012 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.plugin.compilerMessages; + +import com.intellij.openapi.module.Module; +import com.intellij.util.Chunk; + +/** + * @author Pavel Talanov + */ +public class MockModuleChunk extends Chunk { + public MockModuleChunk(Module module) { + super(module); + } +} diff --git a/idea/tests/org/jetbrains/jet/plugin/compilerMessages/MockOutputSink.java b/idea/tests/org/jetbrains/jet/plugin/compilerMessages/MockOutputSink.java new file mode 100644 index 00000000000..6dfb470b088 --- /dev/null +++ b/idea/tests/org/jetbrains/jet/plugin/compilerMessages/MockOutputSink.java @@ -0,0 +1,32 @@ +/* + * Copyright 2010-2012 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.plugin.compilerMessages; + +import com.intellij.openapi.compiler.TranslatingCompiler; +import com.intellij.openapi.vfs.VirtualFile; + +import java.util.Collection; + +/** + * @author Pavel Talanov + */ +public class MockOutputSink implements TranslatingCompiler.OutputSink { + @Override + public void add(String outputRoot, Collection items, VirtualFile[] filesToRecompile) { + // do nothing + } +}