From aca633cae0e06dd643a0781bd52266a4b6c5b233 Mon Sep 17 00:00:00 2001 From: Maxim Shafirov Date: Wed, 25 Jan 2012 14:49:41 +0400 Subject: [PATCH 1/8] Attempt to fix CompileEnvironmentTest --- .../cli/src/org/jetbrains/jet/compiler/CompileEnvironment.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/cli/src/org/jetbrains/jet/compiler/CompileEnvironment.java b/compiler/cli/src/org/jetbrains/jet/compiler/CompileEnvironment.java index 600c61ec281..8d44302eb30 100644 --- a/compiler/cli/src/org/jetbrains/jet/compiler/CompileEnvironment.java +++ b/compiler/cli/src/org/jetbrains/jet/compiler/CompileEnvironment.java @@ -154,7 +154,7 @@ public class CompileEnvironment { } private List 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 { Class namespaceClass = loader.loadClass(JvmAbi.PACKAGE_CLASS); final Method method = namespaceClass.getDeclaredMethod("project"); From 88a71b9ef211ef5ea148c25ee3b2c1f032e1aad0 Mon Sep 17 00:00:00 2001 From: Maxim Shafirov Date: Wed, 25 Jan 2012 15:02:58 +0400 Subject: [PATCH 2/8] Make sure we won't compile same modules in subsequent script runs in same VM instance --- .../src/org/jetbrains/jet/compiler/CompileEnvironment.java | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/compiler/cli/src/org/jetbrains/jet/compiler/CompileEnvironment.java b/compiler/cli/src/org/jetbrains/jet/compiler/CompileEnvironment.java index 8d44302eb30..92a05e64133 100644 --- a/compiler/cli/src/org/jetbrains/jet/compiler/CompileEnvironment.java +++ b/compiler/cli/src/org/jetbrains/jet/compiler/CompileEnvironment.java @@ -22,6 +22,7 @@ import java.lang.reflect.Method; import java.net.MalformedURLException; import java.net.URL; import java.net.URLClassLoader; +import java.util.ArrayList; import java.util.List; import java.util.jar.*; @@ -165,7 +166,9 @@ public class CompileEnvironment { method.setAccessible(true); method.invoke(null); - return AllModules.modules; + ArrayList answer = new ArrayList(AllModules.modules); + AllModules.modules.clear(); + return answer; } catch (Exception e) { throw new ModuleExecutionException(e); } From e5f4377ee44871b70dfa972d7f137c1b0419aeb4 Mon Sep 17 00:00:00 2001 From: Nikolay Krasko Date: Wed, 25 Jan 2012 14:58:28 +0400 Subject: [PATCH 3/8] - KT-1068 Formatter: no indent after for - KT-1098 After entering "if (lock == null)" and pressing enter indent is wrong - Move tests for formatter --- .../lang/parsing/JetExpressionParsing.java | 7 +- .../jet/plugin/formatter/JetBlock.java | 75 ++++++++----------- .../IndentationOnNewline/DoInFun.after.kt | 4 + .../formatter/IndentationOnNewline/DoInFun.kt | 3 + .../IndentationOnNewline/For.after.kt | 3 + .../formatter/IndentationOnNewline/For.kt | 2 + .../IndentationOnNewline/If.after.kt | 4 + .../formatter/IndentationOnNewline/If.kt | 3 + .../IndentationOnNewline/While.after.kt | 4 + .../formatter/IndentationOnNewline/While.kt | 3 + .../formatter/AbstractJetFormatterTest.java} | 6 +- .../jet/formatter/JetFormatterTest.java} | 2 +- .../formatter/JetTypingIndentationTest.java | 40 ++++++++++ 13 files changed, 106 insertions(+), 50 deletions(-) create mode 100644 idea/testData/formatter/IndentationOnNewline/DoInFun.after.kt create mode 100644 idea/testData/formatter/IndentationOnNewline/DoInFun.kt create mode 100644 idea/testData/formatter/IndentationOnNewline/For.after.kt create mode 100644 idea/testData/formatter/IndentationOnNewline/For.kt create mode 100644 idea/testData/formatter/IndentationOnNewline/If.after.kt create mode 100644 idea/testData/formatter/IndentationOnNewline/If.kt create mode 100644 idea/testData/formatter/IndentationOnNewline/While.after.kt create mode 100644 idea/testData/formatter/IndentationOnNewline/While.kt rename idea/tests/{org.jetbrains.jet.formatter/AbstractKotlinFormatterTest.java => org/jetbrains/jet/formatter/AbstractJetFormatterTest.java} (96%) rename idea/tests/{org.jetbrains.jet.formatter/KotlinFormatterTest.java => org/jetbrains/jet/formatter/JetFormatterTest.java} (88%) create mode 100644 idea/tests/org/jetbrains/jet/formatter/JetTypingIndentationTest.java diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/parsing/JetExpressionParsing.java b/compiler/frontend/src/org/jetbrains/jet/lang/parsing/JetExpressionParsing.java index 4e7db15ef0e..1e67a337309 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/parsing/JetExpressionParsing.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/parsing/JetExpressionParsing.java @@ -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_WITH_ARROW = TokenSet.create(RBRACE, IN_KEYWORD, NOT_IN, IS_KEYWORD, NOT_IS, ELSE_KEYWORD, ARROW, DOT); + private static final ImmutableMap KEYWORD_TEXTS = tokenSetToMap(KEYWORDS); private static ImmutableMap tokenSetToMap(TokenSet tokens) { @@ -1406,9 +1407,9 @@ public class JetExpressionParsing extends AbstractJetParsing { parseControlStructureBody(); } - expect(WHILE_KEYWORD, "Expecting 'while' followed by a post-condition"); - - parseCondition(); + if (expect(WHILE_KEYWORD, "Expecting 'while' followed by a post-condition")) { + parseCondition(); + } loop.done(DO_WHILE); } diff --git a/idea/src/org/jetbrains/jet/plugin/formatter/JetBlock.java b/idea/src/org/jetbrains/jet/plugin/formatter/JetBlock.java index 2fd443a39c9..9bfa22ee50d 100644 --- a/idea/src/org/jetbrains/jet/plugin/formatter/JetBlock.java +++ b/idea/src/org/jetbrains/jet/plugin/formatter/JetBlock.java @@ -2,9 +2,9 @@ package org.jetbrains.jet.plugin.formatter; import com.intellij.formatting.*; import com.intellij.lang.ASTNode; -import com.intellij.openapi.util.TextRange; import com.intellij.psi.TokenType; import com.intellij.psi.codeStyle.CodeStyleSettings; +import com.intellij.psi.formatter.common.AbstractBlock; import com.intellij.psi.tree.IElementType; import com.intellij.psi.tree.TokenSet; import org.jetbrains.annotations.NotNull; @@ -16,15 +16,14 @@ import java.util.Collections; import java.util.List; /** + * @see Block for good JavaDoc documentation * @author yole */ -public class JetBlock implements ASTBlock { - private ASTNode myNode; - private Alignment myAlignment; +public class JetBlock extends AbstractBlock { private Indent myIndent; - private Wrap myWrap; private CodeStyleSettings mySettings; private final SpacingBuilder mySpacingBuilder; + private List mySubBlocks; private static final TokenSet CODE_BLOCKS = TokenSet.create( @@ -35,52 +34,35 @@ public class JetBlock implements ASTBlock { private static final TokenSet STATEMENT_PARTS = TokenSet.create( JetNodeTypes.THEN, JetNodeTypes.ELSE); + + // private static final List - public JetBlock(ASTNode node, Alignment alignment, Indent indent, Wrap wrap, CodeStyleSettings settings, - SpacingBuilder spacingBuilder) { - myNode = node; - myAlignment = alignment; + public JetBlock(@NotNull ASTNode node, + Alignment alignment, + Indent indent, + Wrap wrap, + CodeStyleSettings settings, + SpacingBuilder spacingBuilder) { + + super(node, wrap, alignment); myIndent = indent; - myWrap = wrap; mySettings = settings; mySpacingBuilder = spacingBuilder; } - @Override - public ASTNode getNode() { - return myNode; - } - - @NotNull - @Override - public TextRange getTextRange() { - return myNode.getTextRange(); - } - - @Override - public Wrap getWrap() { - return myWrap; - } - @Override public Indent getIndent() { return myIndent; } @Override - public Alignment getAlignment() { - return myAlignment; - } - - @NotNull - @Override - public List getSubBlocks() { + protected List buildChildren() { if (mySubBlocks == null) { mySubBlocks = buildSubBlocks(); } return new ArrayList(mySubBlocks); } - + private List buildSubBlocks() { List blocks = new ArrayList(); for (ASTNode child = myNode.getFirstChildNode(); child != null; child = child.getTreeNext()) { @@ -97,7 +79,8 @@ public class JetBlock implements ASTBlock { return Collections.unmodifiableList(blocks); } - private Block buildSubBlock(ASTNode child) { + @NotNull + private Block buildSubBlock(@NotNull ASTNode child) { Wrap wrap = null; Indent childIndent = Indent.getNoneIndent(); Alignment childAlignment = null; @@ -128,7 +111,7 @@ public class JetBlock implements ASTBlock { 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 ? Indent.getNoneIndent() : Indent.getNormalIndent(); @@ -151,16 +134,18 @@ public class JetBlock implements ASTBlock { @NotNull @Override public ChildAttributes getChildAttributes(int newChildIndex) { - Indent childIndent = Indent.getNoneIndent(); - if (CODE_BLOCKS.contains(myNode.getElementType()) || myNode.getElementType() == JetNodeTypes.WHEN) { - childIndent = Indent.getNormalIndent(); - } - return new ChildAttributes(childIndent, null); - } + final IElementType type = getNode().getElementType(); + if (CODE_BLOCKS.contains(type) || + type == JetNodeTypes.WHEN || + type == JetNodeTypes.IF || + type == JetNodeTypes.FOR || + type == JetNodeTypes.WHILE || + type == JetNodeTypes.DO_WHILE) { - @Override - public boolean isIncomplete() { - return false; + return new ChildAttributes(Indent.getNormalIndent(), null); + } + + return new ChildAttributes(Indent.getNoneIndent(), null); } @Override diff --git a/idea/testData/formatter/IndentationOnNewline/DoInFun.after.kt b/idea/testData/formatter/IndentationOnNewline/DoInFun.after.kt new file mode 100644 index 00000000000..e168ec583e2 --- /dev/null +++ b/idea/testData/formatter/IndentationOnNewline/DoInFun.after.kt @@ -0,0 +1,4 @@ +fun some() { + do + +} \ No newline at end of file diff --git a/idea/testData/formatter/IndentationOnNewline/DoInFun.kt b/idea/testData/formatter/IndentationOnNewline/DoInFun.kt new file mode 100644 index 00000000000..4c17791e4e2 --- /dev/null +++ b/idea/testData/formatter/IndentationOnNewline/DoInFun.kt @@ -0,0 +1,3 @@ +fun some() { + do +} \ No newline at end of file diff --git a/idea/testData/formatter/IndentationOnNewline/For.after.kt b/idea/testData/formatter/IndentationOnNewline/For.after.kt new file mode 100644 index 00000000000..0fc22bb9341 --- /dev/null +++ b/idea/testData/formatter/IndentationOnNewline/For.after.kt @@ -0,0 +1,3 @@ +fun some() { + for (var i in 1..10) + \ No newline at end of file diff --git a/idea/testData/formatter/IndentationOnNewline/For.kt b/idea/testData/formatter/IndentationOnNewline/For.kt new file mode 100644 index 00000000000..e0306a79eb4 --- /dev/null +++ b/idea/testData/formatter/IndentationOnNewline/For.kt @@ -0,0 +1,2 @@ +fun some() { + for (var i in 1..10) \ No newline at end of file diff --git a/idea/testData/formatter/IndentationOnNewline/If.after.kt b/idea/testData/formatter/IndentationOnNewline/If.after.kt new file mode 100644 index 00000000000..ac818828a71 --- /dev/null +++ b/idea/testData/formatter/IndentationOnNewline/If.after.kt @@ -0,0 +1,4 @@ +fun some() { + if (3 > 5) + +} \ No newline at end of file diff --git a/idea/testData/formatter/IndentationOnNewline/If.kt b/idea/testData/formatter/IndentationOnNewline/If.kt new file mode 100644 index 00000000000..8f5f367e3b4 --- /dev/null +++ b/idea/testData/formatter/IndentationOnNewline/If.kt @@ -0,0 +1,3 @@ +fun some() { + if (3 > 5) +} \ No newline at end of file diff --git a/idea/testData/formatter/IndentationOnNewline/While.after.kt b/idea/testData/formatter/IndentationOnNewline/While.after.kt new file mode 100644 index 00000000000..568a7d9a336 --- /dev/null +++ b/idea/testData/formatter/IndentationOnNewline/While.after.kt @@ -0,0 +1,4 @@ +fun some() { + var t = 12 + while (t > 0) + \ No newline at end of file diff --git a/idea/testData/formatter/IndentationOnNewline/While.kt b/idea/testData/formatter/IndentationOnNewline/While.kt new file mode 100644 index 00000000000..93cb6c3c351 --- /dev/null +++ b/idea/testData/formatter/IndentationOnNewline/While.kt @@ -0,0 +1,3 @@ +fun some() { + var t = 12 + while (t > 0) \ No newline at end of file diff --git a/idea/tests/org.jetbrains.jet.formatter/AbstractKotlinFormatterTest.java b/idea/tests/org/jetbrains/jet/formatter/AbstractJetFormatterTest.java similarity index 96% rename from idea/tests/org.jetbrains.jet.formatter/AbstractKotlinFormatterTest.java rename to idea/tests/org/jetbrains/jet/formatter/AbstractJetFormatterTest.java index e4d1709d83c..0bc2dd41f47 100644 --- a/idea/tests/org.jetbrains.jet.formatter/AbstractKotlinFormatterTest.java +++ b/idea/tests/org/jetbrains/jet/formatter/AbstractJetFormatterTest.java @@ -39,7 +39,7 @@ import java.util.Map; // Based on from com.intellij.psi.formatter.java.AbstractJavaFormatterTest @SuppressWarnings("UnusedDeclaration") -public abstract class AbstractKotlinFormatterTest extends LightIdeaTestCase { +public abstract class AbstractJetFormatterTest extends LightIdeaTestCase { protected enum Action {REFORMAT, INDENT} @@ -96,6 +96,10 @@ public abstract class AbstractKotlinFormatterTest extends LightIdeaTestCase { 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 { final PsiFile file = createFile("A.kt", text); diff --git a/idea/tests/org.jetbrains.jet.formatter/KotlinFormatterTest.java b/idea/tests/org/jetbrains/jet/formatter/JetFormatterTest.java similarity index 88% rename from idea/tests/org.jetbrains.jet.formatter/KotlinFormatterTest.java rename to idea/tests/org/jetbrains/jet/formatter/JetFormatterTest.java index 0230cda7c12..5f6ca551d5d 100644 --- a/idea/tests/org.jetbrains.jet.formatter/KotlinFormatterTest.java +++ b/idea/tests/org/jetbrains/jet/formatter/JetFormatterTest.java @@ -3,7 +3,7 @@ package org.jetbrains.jet.formatter; /** * Based on com.intellij.psi.formatter.java.JavaFormatterTest */ -public class KotlinFormatterTest extends AbstractKotlinFormatterTest { +public class JetFormatterTest extends AbstractJetFormatterTest { public void testBlockFor() throws Exception { doTest(); } diff --git a/idea/tests/org/jetbrains/jet/formatter/JetTypingIndentationTest.java b/idea/tests/org/jetbrains/jet/formatter/JetTypingIndentationTest.java new file mode 100644 index 00000000000..524c6d60f0a --- /dev/null +++ b/idea/tests/org/jetbrains/jet/formatter/JetTypingIndentationTest.java @@ -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; + } +} From 4633e1c7f4191df08e81fa40e38a2ec82c0cd7e9 Mon Sep 17 00:00:00 2001 From: Alex Tkachman Date: Wed, 25 Jan 2012 13:29:16 +0200 Subject: [PATCH 4/8] KT-1136 proper generation of accessors --- .../jet/codegen/ClassBodyCodegen.java | 6 +- .../jetbrains/jet/codegen/ClassCodegen.java | 5 +- .../jetbrains/jet/codegen/CodegenContext.java | 9 + .../jet/codegen/GenerationState.java | 2 +- .../codegen/ImplementationBodyCodegen.java | 173 +++++++++--------- .../testData/codegen/regressions/kt1136.kt | 35 ++++ .../jetbrains/jet/codegen/ObjectGenTest.java | 4 + 7 files changed, 144 insertions(+), 90 deletions(-) create mode 100644 compiler/testData/codegen/regressions/kt1136.kt diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/ClassBodyCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/ClassBodyCodegen.java index 6d353c1bf46..94f066ccb20 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/ClassBodyCodegen.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/ClassBodyCodegen.java @@ -40,19 +40,19 @@ public abstract class ClassBodyCodegen { this.v = v; } - public final void generate(@Nullable HashMap accessors) { + public final void generate() { generateDeclaration(); generateClassBody(); - generateSyntheticParts(accessors); + generateSyntheticParts(); generateStaticInitializer(); } protected abstract void generateDeclaration(); - protected void generateSyntheticParts(HashMap accessors) { + protected void generateSyntheticParts() { } private void generateClassBody() { diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/ClassCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/ClassCodegen.java index 50996384f19..5ecc867aa69 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/ClassCodegen.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/ClassCodegen.java @@ -51,11 +51,12 @@ public class ClassCodegen { private void generateImplementation(CodegenContext context, JetClassOrObject aClass, OwnerKind kind, HashMap accessors, ClassBuilder classBuilder) { ClassDescriptor descriptor = state.getBindingContext().get(BindingContext.CLASS, aClass); CodegenContext classContext = context.intoClass(descriptor, kind, state.getTypeMapper()); - new ImplementationBodyCodegen(aClass, classContext, classBuilder, state).generate(accessors); + classContext.copyAccessors(accessors); + new ImplementationBodyCodegen(aClass, classContext, classBuilder, state).generate(); if(aClass instanceof JetClass && ((JetClass)aClass).isTrait()) { ClassBuilder traitBuilder = state.forTraitImplementation(descriptor); - new TraitImplBodyCodegen(aClass, context.intoClass(descriptor, OwnerKind.TRAIT_IMPL, state.getTypeMapper()), traitBuilder, state).generate(null); + new TraitImplBodyCodegen(aClass, context.intoClass(descriptor, OwnerKind.TRAIT_IMPL, state.getTypeMapper()), traitBuilder, state).generate(); traitBuilder.done(); } } diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/CodegenContext.java b/compiler/backend/src/org/jetbrains/jet/codegen/CodegenContext.java index f83089cf5e9..a7c1b270ff2 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/CodegenContext.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/CodegenContext.java @@ -264,6 +264,15 @@ public abstract class CodegenContext { public abstract boolean isStatic(); + public void copyAccessors(HashMap accessors) { + if(accessors != null) { + if(this.accessors == null) { + this.accessors = new HashMap(); + } + this.accessors.putAll(accessors); + } + } + public abstract static class ReceiverContext extends CodegenContext { final CallableDescriptor receiverDescriptor; diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/GenerationState.java b/compiler/backend/src/org/jetbrains/jet/codegen/GenerationState.java index 99539cb3875..7b97fd41f2d 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/GenerationState.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/GenerationState.java @@ -145,7 +145,7 @@ public class GenerationState { closure.name = nameAndVisitor.getFirst(); final CodegenContext objectContext = closure.context.intoAnonymousClass(closure, getBindingContext().get(BindingContext.CLASS, objectDeclaration), OwnerKind.IMPLEMENTATION, typeMapper); - new ImplementationBodyCodegen(objectDeclaration, objectContext, nameAndVisitor.getSecond(), this).generate(null); + new ImplementationBodyCodegen(objectDeclaration, objectContext, nameAndVisitor.getSecond(), this).generate(); ConstructorDescriptor constructorDescriptor = closure.state.getBindingContext().get(BindingContext.CONSTRUCTOR, objectDeclaration); CallableMethod callableMethod = closure.state.getTypeMapper().mapToCallableMethod(constructorDescriptor, OwnerKind.IMPLEMENTATION); diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/ImplementationBodyCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/ImplementationBodyCodegen.java index 52c23bd170e..3ed944f727f 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/ImplementationBodyCodegen.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/ImplementationBodyCodegen.java @@ -206,10 +206,9 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { } @Override - protected void generateSyntheticParts(HashMap accessors) { + protected void generateSyntheticParts() { generateFieldForObjectInstance(); generateFieldForClassObject(); - generateAccessors(accessors); try { generatePrimaryConstructor(); @@ -222,98 +221,104 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { } generateGetTypeInfo(); + + generateAccessors(); } - private void generateAccessors(HashMap accessors) { - if(accessors != null) { - for (Map.Entry entry : accessors.entrySet()) { - if(entry.getValue() instanceof FunctionDescriptor) { - FunctionDescriptor bridge = (FunctionDescriptor) entry.getValue(); - FunctionDescriptor original = (FunctionDescriptor) entry.getKey(); + private void generateAccessors() { + if(context.accessors != null) { + for (Map.Entry entry : context.accessors.entrySet()) { + genAccessor(entry); + } + } + } - Method method = typeMapper.mapSignature(bridge.getName(), bridge).getAsmMethod(); - Method originalMethod = typeMapper.mapSignature(original.getName(), original).getAsmMethod(); - Type[] argTypes = method.getArgumentTypes(); + private void genAccessor(Map.Entry entry) { + if(entry.getValue() instanceof FunctionDescriptor) { + FunctionDescriptor bridge = (FunctionDescriptor) entry.getValue(); + FunctionDescriptor original = (FunctionDescriptor) entry.getKey(); - MethodVisitor mv = v.newMethod(null, Opcodes.ACC_PUBLIC|Opcodes.ACC_BRIDGE|Opcodes.ACC_FINAL, bridge.getName(), method.getDescriptor(), null, null); - if (v.generateCode()) { - mv.visitCode(); + Method method = typeMapper.mapSignature(bridge.getName(), bridge).getAsmMethod(); + Method originalMethod = typeMapper.mapSignature(original.getName(), original).getAsmMethod(); + Type[] argTypes = method.getArgumentTypes(); - InstructionAdapter iv = new InstructionAdapter(mv); + MethodVisitor mv = v.newMethod(null, Opcodes.ACC_PUBLIC|Opcodes.ACC_BRIDGE|Opcodes.ACC_FINAL, bridge.getName(), method.getDescriptor(), null, null); + if (v.generateCode()) { + mv.visitCode(); - iv.load(0, JetTypeMapper.TYPE_OBJECT); - for (int i = 0, reg = 1; i < argTypes.length; i++) { - Type argType = argTypes[i]; - iv.load(reg, argType); - //noinspection AssignmentToForLoopParameter - reg += argType.getSize(); - } + InstructionAdapter iv = new InstructionAdapter(mv); + + iv.load(0, JetTypeMapper.TYPE_OBJECT); + for (int i = 0, reg = 1; i < argTypes.length; i++) { + Type argType = argTypes[i]; + iv.load(reg, argType); + //noinspection AssignmentToForLoopParameter + reg += argType.getSize(); + } + iv.invokespecial(typeMapper.getOwner(original, OwnerKind.IMPLEMENTATION), originalMethod.getName(), originalMethod.getDescriptor()); + + iv.areturn(method.getReturnType()); + FunctionCodegen.endVisit(iv, "accessor", null); + } + } + else if(entry.getValue() instanceof PropertyDescriptor) { + PropertyDescriptor bridge = (PropertyDescriptor) entry.getValue(); + PropertyDescriptor original = (PropertyDescriptor) entry.getKey(); + + { + Method method = typeMapper.mapGetterSignature(bridge, OwnerKind.IMPLEMENTATION).getJvmMethodSignature().getAsmMethod(); + JvmPropertyAccessorSignature originalSignature = typeMapper.mapGetterSignature(original, OwnerKind.IMPLEMENTATION); + Method originalMethod = originalSignature.getJvmMethodSignature().getAsmMethod(); + MethodVisitor mv = v.newMethod(null, Opcodes.ACC_PUBLIC | Opcodes.ACC_BRIDGE | Opcodes.ACC_FINAL, method.getName(), method.getDescriptor(), null, null); + PropertyCodegen.generateJetPropertyAnnotation(mv, originalSignature.getPropertyTypeKotlinSignature(), originalSignature.getJvmMethodSignature().getKotlinTypeParameter()); + if (v.generateCode()) { + mv.visitCode(); + + InstructionAdapter iv = new InstructionAdapter(mv); + + iv.load(0, JetTypeMapper.TYPE_OBJECT); + if(original.getVisibility() == Visibility.PRIVATE) + iv.getfield(typeMapper.getOwner(original, OwnerKind.IMPLEMENTATION), original.getName(), originalMethod.getReturnType().getDescriptor()); + else iv.invokespecial(typeMapper.getOwner(original, OwnerKind.IMPLEMENTATION), originalMethod.getName(), originalMethod.getDescriptor()); - iv.areturn(method.getReturnType()); - FunctionCodegen.endVisit(iv, "accessor", null); - } - } - else if(entry.getValue() instanceof PropertyDescriptor) { - PropertyDescriptor bridge = (PropertyDescriptor) entry.getValue(); - PropertyDescriptor original = (PropertyDescriptor) entry.getKey(); - - { - Method method = typeMapper.mapGetterSignature(bridge, OwnerKind.IMPLEMENTATION).getJvmMethodSignature().getAsmMethod(); - JvmPropertyAccessorSignature originalSignature = typeMapper.mapGetterSignature(original, OwnerKind.IMPLEMENTATION); - Method originalMethod = originalSignature.getJvmMethodSignature().getAsmMethod(); - MethodVisitor mv = v.newMethod(null, Opcodes.ACC_PUBLIC | Opcodes.ACC_BRIDGE | Opcodes.ACC_FINAL, method.getName(), method.getDescriptor(), null, null); - PropertyCodegen.generateJetPropertyAnnotation(mv, originalSignature.getPropertyTypeKotlinSignature(), originalSignature.getJvmMethodSignature().getKotlinTypeParameter()); - if (v.generateCode()) { - mv.visitCode(); - - InstructionAdapter iv = new InstructionAdapter(mv); - - iv.load(0, JetTypeMapper.TYPE_OBJECT); - if(original.getVisibility() == Visibility.PRIVATE) - iv.getfield(typeMapper.getOwner(original, OwnerKind.IMPLEMENTATION), original.getName(), originalMethod.getReturnType().getDescriptor()); - else - iv.invokespecial(typeMapper.getOwner(original, OwnerKind.IMPLEMENTATION), originalMethod.getName(), originalMethod.getDescriptor()); - - iv.areturn(method.getReturnType()); - FunctionCodegen.endVisit(iv, "accessor", null); - } - } - - { - - Method method = typeMapper.mapSetterSignature(bridge, OwnerKind.IMPLEMENTATION).getJvmMethodSignature().getAsmMethod(); - JvmPropertyAccessorSignature originalSignature2 = typeMapper.mapSetterSignature(original, OwnerKind.IMPLEMENTATION); - Method originalMethod = originalSignature2.getJvmMethodSignature().getAsmMethod(); - MethodVisitor mv = v.newMethod(null, Opcodes.ACC_PUBLIC | Opcodes.ACC_BRIDGE | Opcodes.ACC_FINAL, method.getName(), method.getDescriptor(), null, null); - PropertyCodegen.generateJetPropertyAnnotation(mv, originalSignature2.getPropertyTypeKotlinSignature(), originalSignature2.getJvmMethodSignature().getKotlinTypeParameter()); - if (v.generateCode()) { - mv.visitCode(); - - InstructionAdapter iv = new InstructionAdapter(mv); - - iv.load(0, JetTypeMapper.TYPE_OBJECT); - Type[] argTypes = method.getArgumentTypes(); - for (int i = 0, reg = 1; i < argTypes.length; i++) { - Type argType = argTypes[i]; - iv.load(reg, argType); - //noinspection AssignmentToForLoopParameter - reg += argType.getSize(); - } - if(original.getVisibility() == Visibility.PRIVATE) - iv.putfield(typeMapper.getOwner(original, OwnerKind.IMPLEMENTATION), original.getName(), originalMethod.getArgumentTypes()[0].getDescriptor()); - else - iv.invokespecial(typeMapper.getOwner(original, OwnerKind.IMPLEMENTATION), originalMethod.getName(), originalMethod.getDescriptor()); - - iv.areturn(method.getReturnType()); - FunctionCodegen.endVisit(iv, "accessor", null); - } - } - } - else { - throw new UnsupportedOperationException(); + iv.areturn(method.getReturnType()); + FunctionCodegen.endVisit(iv, "accessor", null); } } + + if(bridge.isVar()) + { + Method method = typeMapper.mapSetterSignature(bridge, OwnerKind.IMPLEMENTATION).getJvmMethodSignature().getAsmMethod(); + JvmPropertyAccessorSignature originalSignature2 = typeMapper.mapSetterSignature(original, OwnerKind.IMPLEMENTATION); + Method originalMethod = originalSignature2.getJvmMethodSignature().getAsmMethod(); + MethodVisitor mv = v.newMethod(null, Opcodes.ACC_PUBLIC | Opcodes.ACC_BRIDGE | Opcodes.ACC_FINAL, method.getName(), method.getDescriptor(), null, null); + PropertyCodegen.generateJetPropertyAnnotation(mv, originalSignature2.getPropertyTypeKotlinSignature(), originalSignature2.getJvmMethodSignature().getKotlinTypeParameter()); + if (v.generateCode()) { + mv.visitCode(); + + InstructionAdapter iv = new InstructionAdapter(mv); + + iv.load(0, JetTypeMapper.TYPE_OBJECT); + Type[] argTypes = method.getArgumentTypes(); + for (int i = 0, reg = 1; i < argTypes.length; i++) { + Type argType = argTypes[i]; + iv.load(reg, argType); + //noinspection AssignmentToForLoopParameter + reg += argType.getSize(); + } + if(original.getVisibility() == Visibility.PRIVATE) + iv.putfield(typeMapper.getOwner(original, OwnerKind.IMPLEMENTATION), original.getName(), originalMethod.getArgumentTypes()[0].getDescriptor()); + else + iv.invokespecial(typeMapper.getOwner(original, OwnerKind.IMPLEMENTATION), originalMethod.getName(), originalMethod.getDescriptor()); + + iv.areturn(method.getReturnType()); + FunctionCodegen.endVisit(iv, "accessor", null); + } + } + } + else { + throw new UnsupportedOperationException(); } } diff --git a/compiler/testData/codegen/regressions/kt1136.kt b/compiler/testData/codegen/regressions/kt1136.kt new file mode 100644 index 00000000000..4abaa6ab1c7 --- /dev/null +++ b/compiler/testData/codegen/regressions/kt1136.kt @@ -0,0 +1,35 @@ +import java.util.ArrayList + +public class SomeClass() { + class Inner { + val copy = list + } + + private val list = ArrayList() + var status : Throwable? = null + private val workerThread = object : Thread() { + public override fun run() { + try { + list.add("123") + list.add("33") + Inner().copy.add("444") + } + catch(t: Throwable) { + status = t + } + } + } + + { + workerThread.start() + workerThread.join() + } +} + +public fun box():String { + var obj = SomeClass() + return if(obj.status == null) "OK" else { + obj.status?.printStackTrace() + "failed" + } +} \ No newline at end of file diff --git a/compiler/tests/org/jetbrains/jet/codegen/ObjectGenTest.java b/compiler/tests/org/jetbrains/jet/codegen/ObjectGenTest.java index a698aab25e2..9db2d483ca3 100644 --- a/compiler/tests/org/jetbrains/jet/codegen/ObjectGenTest.java +++ b/compiler/tests/org/jetbrains/jet/codegen/ObjectGenTest.java @@ -30,4 +30,8 @@ public class ObjectGenTest extends CodegenTestCase { public void testKt640() throws Exception { blackBoxFile("regressions/kt640.jet"); } + + public void testKt1136() throws Exception { + blackBoxFile("regressions/kt1136.kt"); + } } From 1154d3dd9845c5d1c5446a132966f3b488758b57 Mon Sep 17 00:00:00 2001 From: Alex Tkachman Date: Wed, 25 Jan 2012 13:32:06 +0200 Subject: [PATCH 5/8] improved test for KT-1136 --- compiler/testData/codegen/regressions/kt1136.kt | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/compiler/testData/codegen/regressions/kt1136.kt b/compiler/testData/codegen/regressions/kt1136.kt index 4abaa6ab1c7..e3214c521fa 100644 --- a/compiler/testData/codegen/regressions/kt1136.kt +++ b/compiler/testData/codegen/regressions/kt1136.kt @@ -1,5 +1,20 @@ import java.util.ArrayList +public object SomeObject { + private val workerThread = object : Thread() { + override fun run() { + foo() + } + } + + { + workerThread.start() + } + + private fun foo() : Unit { + } +} + public class SomeClass() { class Inner { val copy = list From 4f630ca390d1fb14b73339a2482eb5ad60208e8a Mon Sep 17 00:00:00 2001 From: Andrey Breslav Date: Wed, 25 Jan 2012 15:33:29 +0400 Subject: [PATCH 6/8] Supported creating JetFiles with custom names --- .../src/org/jetbrains/jet/lang/psi/JetPsiFactory.java | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetPsiFactory.java b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetPsiFactory.java index d542ea6a699..43159fc432c 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetPsiFactory.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetPsiFactory.java @@ -46,7 +46,12 @@ public class JetPsiFactory { @NotNull public static JetFile createFile(Project project, String text) { - return (JetFile) PsiFileFactory.getInstance(project).createFileFromText("dummy.jet", JetFileType.INSTANCE, text, LocalTimeCounter.currentTime(), true); + return createFile(project, "dummy.jet", text); + } + + @NotNull + public static JetFile createFile(Project project, String fileName, String text) { + return (JetFile) PsiFileFactory.getInstance(project).createFileFromText(fileName, JetFileType.INSTANCE, text, LocalTimeCounter.currentTime(), true); } public static JetProperty createProperty(Project project, String name, String type, boolean isVar) { From 9d8abdac0c8fc60d1f546043500e809ff1742d35 Mon Sep 17 00:00:00 2001 From: Andrey Breslav Date: Wed, 25 Jan 2012 15:34:17 +0400 Subject: [PATCH 7/8] Introduce variable for clarity --- .../org/jetbrains/jet/plugin/annotations/JetPsiChecker.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/idea/src/org/jetbrains/jet/plugin/annotations/JetPsiChecker.java b/idea/src/org/jetbrains/jet/plugin/annotations/JetPsiChecker.java index 450fc302ee1..06fd0e7c2ce 100644 --- a/idea/src/org/jetbrains/jet/plugin/annotations/JetPsiChecker.java +++ b/idea/src/org/jetbrains/jet/plugin/annotations/JetPsiChecker.java @@ -173,9 +173,10 @@ public class JetPsiChecker implements Annotator { return; } - // General annotation + // Generic annotation + Annotation errorAnnotation = holder.createErrorAnnotation(diagnostic.getFactory().getTextRange(diagnostic), getMessage(diagnostic)); registerQuickFix( - holder.createErrorAnnotation(diagnostic.getFactory().getTextRange(diagnostic), getMessage(diagnostic)), + errorAnnotation, diagnostic); } else if (diagnostic.getSeverity() == Severity.WARNING) { From 20920f0a0bc49d3c1dd4aa29e945e9a78dd9af93 Mon Sep 17 00:00:00 2001 From: Maxim Shafirov Date: Wed, 25 Jan 2012 15:51:00 +0400 Subject: [PATCH 8/8] Temp directories, which reside under project root replaced with java.io.tmpdir based ones. --- .../tests/org/jetbrains/jet/JetTestUtils.java | 31 +++++-------------- .../jet/codegen/ForTestCompileStdlib.java | 5 ++- .../jet/compiler/CompileEnvironmentTest.java | 3 +- .../jet/compiler/TestCaseWithTmpdir.java | 1 - 4 files changed, 11 insertions(+), 29 deletions(-) diff --git a/compiler/tests/org/jetbrains/jet/JetTestUtils.java b/compiler/tests/org/jetbrains/jet/JetTestUtils.java index 8ec4ac13b07..de3f1a108f7 100644 --- a/compiler/tests/org/jetbrains/jet/JetTestUtils.java +++ b/compiler/tests/org/jetbrains/jet/JetTestUtils.java @@ -165,31 +165,16 @@ public class JetTestUtils { } } - public static void rmrf(File file) { - if (file != null) { - FileUtil.delete(file); - } + public static File tmpDirForTest(TestCase test) throws IOException { + File answer = FileUtil.createTempDirectory(test.getClass().getSimpleName(), test.getName()); + deleteOnShutdown(answer); + return answer; } - public static File tmpRoot() { - return new File("tmp"); - } - - public static File tmpDirForTest(TestCase test) { - return new File(tmpRoot(), test.getClass().getSimpleName() + "/" + test.getName()); - } - - public static File tmpDirForTest(Class clazz) { - return tmpDirForTest(clazz.getSimpleName()); - } - - public static File tmpDirForTest(String name) { - return new File(tmpRoot(), name); - } - - public static void recreateDirectory(File file) throws IOException { - rmrf(file); - mkdirs(file); + public static File tmpDir(String name) throws IOException { + File answer = FileUtil.createTempDirectory(name, ""); + deleteOnShutdown(answer); + return answer; } public static void deleteOnShutdown(File file) { diff --git a/compiler/tests/org/jetbrains/jet/codegen/ForTestCompileStdlib.java b/compiler/tests/org/jetbrains/jet/codegen/ForTestCompileStdlib.java index 5d2503916d6..2a80b80bdc1 100644 --- a/compiler/tests/org/jetbrains/jet/codegen/ForTestCompileStdlib.java +++ b/compiler/tests/org/jetbrains/jet/codegen/ForTestCompileStdlib.java @@ -30,8 +30,7 @@ public class ForTestCompileStdlib { private static File stdlibJarFile; private static File doCompile() throws Exception { - File tmpDir = FileUtil.createTempDirectory("stdlibjar", ""); - JetTestUtils.deleteOnShutdown(tmpDir); + File tmpDir = JetTestUtils.tmpDir("stdlibjar"); File jarFile = new File(tmpDir, "stdlib.jar"); @@ -119,7 +118,7 @@ public class ForTestCompileStdlib { public static File stdlibJarForTests() { synchronized (ForTestCompileStdlib.class) { - if (stdlibJarFile == null) { + if (stdlibJarFile == null || !stdlibJarFile.exists()) { try { stdlibJarFile = doCompile(); } catch (Exception e) { diff --git a/compiler/tests/org/jetbrains/jet/compiler/CompileEnvironmentTest.java b/compiler/tests/org/jetbrains/jet/compiler/CompileEnvironmentTest.java index b1054ea97a3..0187f2f8278 100644 --- a/compiler/tests/org/jetbrains/jet/compiler/CompileEnvironmentTest.java +++ b/compiler/tests/org/jetbrains/jet/compiler/CompileEnvironmentTest.java @@ -66,8 +66,7 @@ public class CompileEnvironmentTest extends TestCase { File tempDir = FileUtil.createTempDirectory("compilerTest", "compilerTest"); try { File out = new File(tempDir, "out"); - File stdlib = new File(tempDir, "stdlib.jar"); - FileUtil.copy(ForTestCompileStdlib.stdlibJarForTests(), stdlib); + File stdlib = ForTestCompileStdlib.stdlibJarForTests(); KotlinCompiler.exec("-src", JetParsingTest.getTestDataDir() + "/compiler/smoke/Smoke.kt", "-output", out.getAbsolutePath(), "-stdlib", stdlib.getAbsolutePath()); diff --git a/compiler/tests/org/jetbrains/jet/compiler/TestCaseWithTmpdir.java b/compiler/tests/org/jetbrains/jet/compiler/TestCaseWithTmpdir.java index fc503564e16..79636b4fc12 100644 --- a/compiler/tests/org/jetbrains/jet/compiler/TestCaseWithTmpdir.java +++ b/compiler/tests/org/jetbrains/jet/compiler/TestCaseWithTmpdir.java @@ -16,7 +16,6 @@ public abstract class TestCaseWithTmpdir extends UsefulTestCase { protected void setUp() throws Exception { super.setUp(); tmpdir = JetTestUtils.tmpDirForTest(this); - JetTestUtils.recreateDirectory(tmpdir); } }