Merge remote branch 'origin/master'

This commit is contained in:
Alex Tkachman
2012-01-25 13:30:06 +02:00
18 changed files with 178 additions and 77 deletions
@@ -43,7 +43,20 @@ public class KotlinCompiler {
target.println("Usage: KotlinCompiler [-output <outputDir>|-jar <jarFileName>] [-stdlib <path to runtime.jar>] [-src <filename or dirname>|-module <module file>] [-includeRuntime]"); target.println("Usage: KotlinCompiler [-output <outputDir>|-jar <jarFileName>] [-stdlib <path to runtime.jar>] [-src <filename or dirname>|-module <module file>] [-includeRuntime]");
} }
public static void main(String ... args) { public static void main(String... args) {
try {
int rc = exec(args);
if (rc != 0) {
System.err.println("exec() finished with " + rc + " return code");
System.exit(rc);
}
} catch (CompileEnvironmentException e) {
System.err.println(e.getMessage());
System.exit(1);
}
}
public static int exec(String... args) {
System.setProperty("java.awt.headless", "true"); System.setProperty("java.awt.headless", "true");
Arguments arguments = new Arguments(); Arguments arguments = new Arguments();
try { try {
@@ -51,18 +64,16 @@ public class KotlinCompiler {
} }
catch (IllegalArgumentException e) { catch (IllegalArgumentException e) {
usage(System.err); usage(System.err);
System.exit(1); return 1;
return;
} }
catch (Throwable t) { catch (Throwable t) {
t.printStackTrace(); t.printStackTrace();
System.exit(1); return 1;
return;
} }
if (arguments.help) { if (arguments.help) {
usage(System.out); usage(System.out);
System.exit(0); return 0;
} }
CompileEnvironment environment = new CompileEnvironment(); CompileEnvironment environment = new CompileEnvironment();
@@ -71,22 +82,16 @@ public class KotlinCompiler {
environment.setStdlib(arguments.stdlib); environment.setStdlib(arguments.stdlib);
} }
try { if (arguments.module != null) {
if (arguments.module != null) { environment.compileModuleScript(arguments.module, arguments.jar, arguments.includeRuntime);
environment.compileModuleScript(arguments.module, arguments.jar, arguments.includeRuntime); return 0;
return; }
} else {
else { if (!environment.compileBunchOfSources(arguments.src, arguments.jar, arguments.outputDir, arguments.includeRuntime)) {
if (!environment.compileBunchOfSources(arguments.src, arguments.jar, arguments.outputDir, arguments.includeRuntime)) { return 1;
System.exit(1); }
return;
}
}
} catch (CompileEnvironmentException e) {
System.err.println(e.getMessage());
System.exit(1);
return;
} }
}
return 0;
}
} }
@@ -22,6 +22,7 @@ import java.lang.reflect.Method;
import java.net.MalformedURLException; import java.net.MalformedURLException;
import java.net.URL; import java.net.URL;
import java.net.URLClassLoader; import java.net.URLClassLoader;
import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.jar.*; import java.util.jar.*;
@@ -124,6 +125,10 @@ public class CompileEnvironment {
throw new CompileEnvironmentException("Module script " + moduleFile + " compilation failed"); throw new CompileEnvironmentException("Module script " + moduleFile + " compilation failed");
} }
if (modules.isEmpty()) {
throw new CompileEnvironmentException("No modules where defined by " + moduleFile);
}
final String directory = new File(moduleFile).getParent(); final String directory = new File(moduleFile).getParent();
for (Module moduleBuilder : modules) { for (Module moduleBuilder : modules) {
ClassFileFactory moduleFactory = compileModule(moduleBuilder, directory); ClassFileFactory moduleFactory = compileModule(moduleBuilder, directory);
@@ -150,7 +155,7 @@ public class CompileEnvironment {
} }
private List<Module> runDefineModules(String moduleFile, ClassFileFactory factory) { private List<Module> runDefineModules(String moduleFile, ClassFileFactory factory) {
ClassLoader loader = myStdlib != null ? new GeneratedClassLoader(factory, new URLClassLoader(new URL[] {myStdlib})) : new GeneratedClassLoader(factory); ClassLoader loader = myStdlib != null ? new GeneratedClassLoader(factory, new URLClassLoader(new URL[] {myStdlib}, AllModules.class.getClassLoader())) : new GeneratedClassLoader(factory);
try { try {
Class namespaceClass = loader.loadClass(JvmAbi.PACKAGE_CLASS); Class namespaceClass = loader.loadClass(JvmAbi.PACKAGE_CLASS);
final Method method = namespaceClass.getDeclaredMethod("project"); final Method method = namespaceClass.getDeclaredMethod("project");
@@ -161,7 +166,9 @@ public class CompileEnvironment {
method.setAccessible(true); method.setAccessible(true);
method.invoke(null); method.invoke(null);
return AllModules.modules; ArrayList<Module> answer = new ArrayList<Module>(AllModules.modules);
AllModules.modules.clear();
return answer;
} catch (Exception e) { } catch (Exception e) {
throw new ModuleExecutionException(e); throw new ModuleExecutionException(e);
} }
@@ -169,12 +176,21 @@ public class CompileEnvironment {
public ClassFileFactory compileModule(Module moduleBuilder, String directory) { public ClassFileFactory compileModule(Module moduleBuilder, String directory) {
CompileSession moduleCompileSession = new CompileSession(myEnvironment); CompileSession moduleCompileSession = new CompileSession(myEnvironment);
if (moduleBuilder.getSourceFiles().isEmpty()) {
throw new CompileEnvironmentException("No source files where defined");
}
for (String sourceFile : moduleBuilder.getSourceFiles()) { for (String sourceFile : moduleBuilder.getSourceFiles()) {
File source = new File(sourceFile); File source = new File(sourceFile);
if (!source.isAbsolute()) { if (!source.isAbsolute()) {
source = new File(directory, sourceFile); source = new File(directory, sourceFile);
} }
if (!source.exists()) {
throw new CompileEnvironmentException("'" + source + "' does not exist");
}
moduleCompileSession.addSources(source.getPath()); moduleCompileSession.addSources(source.getPath());
} }
for (String classpathRoot : moduleBuilder.getClasspathRoots()) { for (String classpathRoot : moduleBuilder.getClasspathRoots()) {
@@ -20,6 +20,7 @@ public class JetExpressionParsing extends AbstractJetParsing {
private static final TokenSet WHEN_CONDITION_RECOVERY_SET = TokenSet.create(RBRACE, IN_KEYWORD, NOT_IN, IS_KEYWORD, NOT_IS, ELSE_KEYWORD); private static final TokenSet WHEN_CONDITION_RECOVERY_SET = TokenSet.create(RBRACE, IN_KEYWORD, NOT_IN, IS_KEYWORD, NOT_IS, ELSE_KEYWORD);
private static final TokenSet WHEN_CONDITION_RECOVERY_SET_WITH_ARROW = TokenSet.create(RBRACE, IN_KEYWORD, NOT_IN, IS_KEYWORD, NOT_IS, ELSE_KEYWORD, ARROW, DOT); private static final TokenSet WHEN_CONDITION_RECOVERY_SET_WITH_ARROW = TokenSet.create(RBRACE, IN_KEYWORD, NOT_IN, IS_KEYWORD, NOT_IS, ELSE_KEYWORD, ARROW, DOT);
private static final ImmutableMap<String, JetToken> KEYWORD_TEXTS = tokenSetToMap(KEYWORDS); private static final ImmutableMap<String, JetToken> KEYWORD_TEXTS = tokenSetToMap(KEYWORDS);
private static ImmutableMap<String, JetToken> tokenSetToMap(TokenSet tokens) { private static ImmutableMap<String, JetToken> tokenSetToMap(TokenSet tokens) {
@@ -1406,9 +1407,9 @@ public class JetExpressionParsing extends AbstractJetParsing {
parseControlStructureBody(); parseControlStructureBody();
} }
expect(WHILE_KEYWORD, "Expecting 'while' followed by a post-condition"); if (expect(WHILE_KEYWORD, "Expecting 'while' followed by a post-condition")) {
parseCondition();
parseCondition(); }
loop.done(DO_WHILE); loop.done(DO_WHILE);
} }
@@ -80,7 +80,7 @@ public class ForTestCompileStdlib {
private static void compileKotlinPartOfStdlib(File destdir) throws IOException { private static void compileKotlinPartOfStdlib(File destdir) throws IOException {
// lame // lame
KotlinCompiler.main("-output", destdir.getPath(), "-src", "./stdlib/ktSrc"); KotlinCompiler.exec("-output", destdir.getPath(), "-src", "./stdlib/ktSrc");
} }
private static List<File> javaFilesInDir(File dir) { private static List<File> javaFilesInDir(File dir) {
@@ -38,7 +38,7 @@ public class CompileEnvironmentTest extends TestCase {
try { try {
File stdlib = ForTestCompileStdlib.stdlibJarForTests(); File stdlib = ForTestCompileStdlib.stdlibJarForTests();
File resultJar = new File(tempDir, "result.jar"); File resultJar = new File(tempDir, "result.jar");
KotlinCompiler.main("-module", JetParsingTest.getTestDataDir() + "/compiler/smoke/Smoke.kts", KotlinCompiler.exec("-module", JetParsingTest.getTestDataDir() + "/compiler/smoke/Smoke.kts",
"-jar", resultJar.getAbsolutePath(), "-jar", resultJar.getAbsolutePath(),
"-stdlib", stdlib.getAbsolutePath()); "-stdlib", stdlib.getAbsolutePath());
FileInputStream fileInputStream = new FileInputStream(resultJar); FileInputStream fileInputStream = new FileInputStream(resultJar);
@@ -68,7 +68,7 @@ public class CompileEnvironmentTest extends TestCase {
File out = new File(tempDir, "out"); File out = new File(tempDir, "out");
File stdlib = new File(tempDir, "stdlib.jar"); File stdlib = new File(tempDir, "stdlib.jar");
FileUtil.copy(ForTestCompileStdlib.stdlibJarForTests(), stdlib); FileUtil.copy(ForTestCompileStdlib.stdlibJarForTests(), stdlib);
KotlinCompiler.main("-src", JetParsingTest.getTestDataDir() + "/compiler/smoke/Smoke.kt", KotlinCompiler.exec("-src", JetParsingTest.getTestDataDir() + "/compiler/smoke/Smoke.kt",
"-output", out.getAbsolutePath(), "-output", out.getAbsolutePath(),
"-stdlib", stdlib.getAbsolutePath()); "-stdlib", stdlib.getAbsolutePath());
@@ -2,9 +2,9 @@ package org.jetbrains.jet.plugin.formatter;
import com.intellij.formatting.*; import com.intellij.formatting.*;
import com.intellij.lang.ASTNode; import com.intellij.lang.ASTNode;
import com.intellij.openapi.util.TextRange;
import com.intellij.psi.TokenType; import com.intellij.psi.TokenType;
import com.intellij.psi.codeStyle.CodeStyleSettings; import com.intellij.psi.codeStyle.CodeStyleSettings;
import com.intellij.psi.formatter.common.AbstractBlock;
import com.intellij.psi.tree.IElementType; import com.intellij.psi.tree.IElementType;
import com.intellij.psi.tree.TokenSet; import com.intellij.psi.tree.TokenSet;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
@@ -16,15 +16,14 @@ import java.util.Collections;
import java.util.List; import java.util.List;
/** /**
* @see Block for good JavaDoc documentation
* @author yole * @author yole
*/ */
public class JetBlock implements ASTBlock { public class JetBlock extends AbstractBlock {
private ASTNode myNode;
private Alignment myAlignment;
private Indent myIndent; private Indent myIndent;
private Wrap myWrap;
private CodeStyleSettings mySettings; private CodeStyleSettings mySettings;
private final SpacingBuilder mySpacingBuilder; private final SpacingBuilder mySpacingBuilder;
private List<Block> mySubBlocks; private List<Block> mySubBlocks;
private static final TokenSet CODE_BLOCKS = TokenSet.create( private static final TokenSet CODE_BLOCKS = TokenSet.create(
@@ -36,45 +35,28 @@ public class JetBlock implements ASTBlock {
JetNodeTypes.THEN, JetNodeTypes.THEN,
JetNodeTypes.ELSE); JetNodeTypes.ELSE);
public JetBlock(ASTNode node, Alignment alignment, Indent indent, Wrap wrap, CodeStyleSettings settings, // private static final List<IndentWhitespaceRule>
SpacingBuilder spacingBuilder) {
myNode = node; public JetBlock(@NotNull ASTNode node,
myAlignment = alignment; Alignment alignment,
Indent indent,
Wrap wrap,
CodeStyleSettings settings,
SpacingBuilder spacingBuilder) {
super(node, wrap, alignment);
myIndent = indent; myIndent = indent;
myWrap = wrap;
mySettings = settings; mySettings = settings;
mySpacingBuilder = spacingBuilder; mySpacingBuilder = spacingBuilder;
} }
@Override
public ASTNode getNode() {
return myNode;
}
@NotNull
@Override
public TextRange getTextRange() {
return myNode.getTextRange();
}
@Override
public Wrap getWrap() {
return myWrap;
}
@Override @Override
public Indent getIndent() { public Indent getIndent() {
return myIndent; return myIndent;
} }
@Override @Override
public Alignment getAlignment() { protected List<Block> buildChildren() {
return myAlignment;
}
@NotNull
@Override
public List<Block> getSubBlocks() {
if (mySubBlocks == null) { if (mySubBlocks == null) {
mySubBlocks = buildSubBlocks(); mySubBlocks = buildSubBlocks();
} }
@@ -97,7 +79,8 @@ public class JetBlock implements ASTBlock {
return Collections.unmodifiableList(blocks); return Collections.unmodifiableList(blocks);
} }
private Block buildSubBlock(ASTNode child) { @NotNull
private Block buildSubBlock(@NotNull ASTNode child) {
Wrap wrap = null; Wrap wrap = null;
Indent childIndent = Indent.getNoneIndent(); Indent childIndent = Indent.getNoneIndent();
Alignment childAlignment = null; Alignment childAlignment = null;
@@ -128,7 +111,7 @@ public class JetBlock implements ASTBlock {
return new JetBlock(child, childAlignment, childIndent, wrap, mySettings, mySpacingBuilder); return new JetBlock(child, childAlignment, childIndent, wrap, mySettings, mySpacingBuilder);
} }
private static Indent indentIfNotBrace(ASTNode child) { private static Indent indentIfNotBrace(@NotNull ASTNode child) {
return child.getElementType() == JetTokens.RBRACE || child.getElementType() == JetTokens.LBRACE return child.getElementType() == JetTokens.RBRACE || child.getElementType() == JetTokens.LBRACE
? Indent.getNoneIndent() ? Indent.getNoneIndent()
: Indent.getNormalIndent(); : Indent.getNormalIndent();
@@ -151,16 +134,18 @@ public class JetBlock implements ASTBlock {
@NotNull @NotNull
@Override @Override
public ChildAttributes getChildAttributes(int newChildIndex) { public ChildAttributes getChildAttributes(int newChildIndex) {
Indent childIndent = Indent.getNoneIndent(); final IElementType type = getNode().getElementType();
if (CODE_BLOCKS.contains(myNode.getElementType()) || myNode.getElementType() == JetNodeTypes.WHEN) { if (CODE_BLOCKS.contains(type) ||
childIndent = Indent.getNormalIndent(); type == JetNodeTypes.WHEN ||
} type == JetNodeTypes.IF ||
return new ChildAttributes(childIndent, null); type == JetNodeTypes.FOR ||
} type == JetNodeTypes.WHILE ||
type == JetNodeTypes.DO_WHILE) {
@Override return new ChildAttributes(Indent.getNormalIndent(), null);
public boolean isIncomplete() { }
return false;
return new ChildAttributes(Indent.getNoneIndent(), null);
} }
@Override @Override
@@ -0,0 +1,4 @@
fun some() {
do
<caret>
}
@@ -0,0 +1,3 @@
fun some() {
do<caret>
}
@@ -0,0 +1,3 @@
fun some() {
for (var i in 1..10)
<caret>
@@ -0,0 +1,2 @@
fun some() {
for (var i in 1..10)<caret>
@@ -0,0 +1,4 @@
fun some() {
if (3 > 5)
<caret>
}
@@ -0,0 +1,3 @@
fun some() {
if (3 > 5)<caret>
}
@@ -0,0 +1,4 @@
fun some() {
var t = 12
while (t > 0)
<caret>
@@ -0,0 +1,3 @@
fun some() {
var t = 12
while (t > 0)<caret>
@@ -39,7 +39,7 @@ import java.util.Map;
// Based on from com.intellij.psi.formatter.java.AbstractJavaFormatterTest // Based on from com.intellij.psi.formatter.java.AbstractJavaFormatterTest
@SuppressWarnings("UnusedDeclaration") @SuppressWarnings("UnusedDeclaration")
public abstract class AbstractKotlinFormatterTest extends LightIdeaTestCase { public abstract class AbstractJetFormatterTest extends LightIdeaTestCase {
protected enum Action {REFORMAT, INDENT} protected enum Action {REFORMAT, INDENT}
@@ -96,6 +96,10 @@ public abstract class AbstractKotlinFormatterTest extends LightIdeaTestCase {
doTextTest(Action.REFORMAT, text, textAfter); doTextTest(Action.REFORMAT, text, textAfter);
} }
public void doIndentTextTest(@NonNls final String text, @NonNls String textAfter) throws IncorrectOperationException {
doTextTest(Action.INDENT, text, textAfter);
}
public void doTextTest(final Action action, final String text, String textAfter) throws IncorrectOperationException { public void doTextTest(final Action action, final String text, String textAfter) throws IncorrectOperationException {
final PsiFile file = createFile("A.kt", text); final PsiFile file = createFile("A.kt", text);
@@ -3,7 +3,7 @@ package org.jetbrains.jet.formatter;
/** /**
* Based on com.intellij.psi.formatter.java.JavaFormatterTest * Based on com.intellij.psi.formatter.java.JavaFormatterTest
*/ */
public class KotlinFormatterTest extends AbstractKotlinFormatterTest { public class JetFormatterTest extends AbstractJetFormatterTest {
public void testBlockFor() throws Exception { public void testBlockFor() throws Exception {
doTest(); doTest();
} }
@@ -0,0 +1,40 @@
package org.jetbrains.jet.formatter;
import com.intellij.testFramework.LightCodeInsightTestCase;
import org.jetbrains.jet.plugin.PluginTestCaseBase;
import java.io.File;
/**
* @author Nikolay Krasko
*/
public class JetTypingIndentationTest extends LightCodeInsightTestCase {
public void testWhile() {
doFileNewlineTest();
}
public void testFor() {
doFileNewlineTest();
}
public void testIf() {
doFileNewlineTest();
}
public void testDoInFun() {
doFileNewlineTest();
}
public void doFileNewlineTest() {
configureByFile(getTestName(false) + ".kt");
type('\n');
checkResultByFile(getTestName(false) + ".after.kt");
}
@Override
protected String getTestDataPath() {
final String testRelativeDir = "formatter/IndentationOnNewline";
return new File(PluginTestCaseBase.getTestDataPathBase(), testRelativeDir).getPath() +
File.separator;
}
}
+24
View File
@@ -0,0 +1,24 @@
package test.stdlib.issues
import java.util.List
import std.util.*
import stdhack.test.*
private fun listDifference<T>(first : List<T>, second : List<T>) : List<T> {
return first.filter{ !second.contains(it) }.toList()
}
class StdLibIssuesTest() : TestSupport() {
fun test_KT_1131() {
val data = arrayList("blah", "foo", "bar")
val filterValues = arrayList("bar", "something", "blah")
expect(arrayList("foo")) {
val answer = listDifference(data, filterValues)
println("Found answer ${answer}")
answer
}
}
}