Merge remote-tracking branch 'origin/master'

This commit is contained in:
svtk
2011-11-29 19:04:30 +04:00
41 changed files with 1000 additions and 55 deletions
@@ -155,6 +155,19 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
return genQualified(receiver, expression.getBaseExpression());
}
private static boolean isEmptyExpression(JetElement expr) {
if(expr == null)
return true;
if(expr instanceof JetBlockExpression) {
JetBlockExpression blockExpression = (JetBlockExpression) expr;
List<JetElement> statements = blockExpression.getStatements();
if(statements.size() == 0 || statements.size() == 1 && isEmptyExpression(statements.get(0))) {
return true;
}
}
return false;
}
@Override
public StackValue visitIfExpression(JetIfExpression expression, StackValue receiver) {
Type asmType = expressionType(expression);
@@ -167,27 +180,36 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
throw new CompilationException();
}
if (thenExpression == null) {
if (isEmptyExpression(thenExpression)) {
if (isEmptyExpression(elseExpression)) {
condition.put(asmType, v);
return StackValue.onStack(asmType);
}
return generateSingleBranchIf(condition, elseExpression, false);
}
if (elseExpression == null) {
return generateSingleBranchIf(condition, thenExpression, true);
else {
if (isEmptyExpression(elseExpression)) {
return generateSingleBranchIf(condition, thenExpression, true);
}
}
Label elseLabel = new Label();
condition.condJump(elseLabel, true, v); // == 0, i.e. false
Label end = continueLabel == null ? new Label() : continueLabel;
gen(thenExpression, asmType);
Label endLabel = new Label();
v.goTo(endLabel);
v.goTo(end);
v.mark(elseLabel);
gen(elseExpression, asmType);
v.mark(endLabel);
if(end != continueLabel)
v.mark(end);
else
v.goTo(end);
return StackValue.onStack(asmType);
}
@@ -198,16 +220,21 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
myContinueTargets.push(condition);
v.mark(condition);
Label end = new Label();
Label end = continueLabel != null ? continueLabel : new Label();
myBreakTargets.push(end);
Label savedContinueLabel = continueLabel;
continueLabel = condition;
final StackValue conditionValue = gen(expression.getCondition());
conditionValue.condJump(end, true, v);
gen(expression.getBody(), Type.VOID_TYPE);
v.goTo(condition);
v.mark(end);
continueLabel = savedContinueLabel;
if(end != continueLabel)
v.mark(end);
myBreakTargets.pop();
myContinueTargets.pop();
@@ -519,13 +546,14 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
}
private StackValue generateSingleBranchIf(StackValue condition, JetExpression expression, boolean inverse) {
Label endLabel = new Label();
Label end = continueLabel != null ? continueLabel : new Label();
condition.condJump(endLabel, inverse, v);
condition.condJump(end, inverse, v);
gen(expression, Type.VOID_TYPE);
v.mark(endLabel);
if(continueLabel != end)
v.mark(end);
return StackValue.none();
}
@@ -655,6 +683,8 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
return StackValue.onStack(Type.getObjectType(closure.getClassname()));
}
private Label continueLabel;
private StackValue generateBlock(List<JetElement> statements) {
Label blockStart = new Label();
v.mark(blockStart);
@@ -671,9 +701,12 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
}
StackValue answer = StackValue.none();
Label savedContinueLabel = continueLabel;
continueLabel = null;
for (int i = 0, statementsSize = statements.size(); i < statementsSize; i++) {
JetElement statement = statements.get(i);
if (i == statements.size() - 1 /*&& statement instanceof JetExpression && !bindingContext.get(BindingContext.STATEMENT, statement)*/) {
continueLabel = savedContinueLabel;
answer = gen(statement);
}
else {
@@ -1905,8 +1938,16 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
DeclarationDescriptor cls = op.getContainingDeclaration();
if (isNumberPrimitive(cls) && (op.getName().equals("inc") || op.getName().equals("dec"))) {
receiver.put(receiver.type, v);
gen(expression.getBaseExpression(), asmType); // old value
generateIncrement(op, asmType, expression.getBaseExpression(), receiver); // increment in-place
JetExpression operand = expression.getBaseExpression();
if (operand instanceof JetReferenceExpression) {
final int index = indexOfLocal((JetReferenceExpression) operand);
if (index >= 0 && JetTypeMapper.isIntPrimitive(asmType)) {
int increment = op.getName().equals("inc") ? 1 : -1;
return StackValue.postIncrement(index, increment);
}
}
gen(operand, asmType); // old value
generateIncrement(op, asmType, operand, receiver); // increment in-place
return StackValue.onStack(asmType); // old value
}
}
@@ -256,6 +256,14 @@ public abstract class StackValue {
return new ThisOuter(codegen, descriptor);
}
public static StackValue postIncrement(int index, int increment) {
return new PostIncrement(index, increment);
}
public static StackValue preIncrement(int index, int increment) {
return new PreIncrement(index, increment);
}
private static class None extends StackValue {
public static None INSTANCE = new None();
private None() {
@@ -963,4 +971,44 @@ public abstract class StackValue {
codegen.generateThisOrOuter(descriptor);
}
}
private static class PostIncrement extends StackValue {
private int index;
private int increment;
public PostIncrement(int index, int increment) {
super(Type.INT_TYPE);
this.index = index;
this.increment = increment;
}
@Override
public void put(Type type, InstructionAdapter v) {
if(!type.equals(Type.VOID_TYPE)) {
v.load(index, Type.INT_TYPE);
coerce(type, v);
}
v.iinc(index, increment);
}
}
private static class PreIncrement extends StackValue {
private int index;
private int increment;
public PreIncrement(int index, int increment) {
super(Type.INT_TYPE);
this.index = index;
this.increment = increment;
}
@Override
public void put(Type type, InstructionAdapter v) {
v.iinc(index, increment);
if(!type.equals(Type.VOID_TYPE)) {
v.load(index, Type.INT_TYPE);
coerce(type, v);
}
}
}
}
@@ -31,8 +31,7 @@ public class Increment implements IntrinsicMethod {
if (operand instanceof JetReferenceExpression) {
final int index = codegen.indexOfLocal((JetReferenceExpression) operand);
if (index >= 0 && JetTypeMapper.isIntPrimitive(expectedType)) {
v.iinc(index, myDelta);
return StackValue.local(index, expectedType);
return StackValue.preIncrement(index, myDelta);
}
}
StackValue value = codegen.genQualified(receiver, operand);
@@ -2,8 +2,13 @@ package org.jetbrains.jet.checkers;
import com.google.common.collect.*;
import com.intellij.openapi.util.TextRange;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFile;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.lang.diagnostics.Diagnostic;
import org.jetbrains.jet.lang.diagnostics.DiagnosticFactory;
import org.jetbrains.jet.lang.diagnostics.Severity;
import org.jetbrains.jet.lang.resolve.AnalyzingUtils;
import org.jetbrains.jet.lang.resolve.BindingContext;
import java.util.*;
@@ -32,6 +37,15 @@ public class CheckerTestUtil {
private static final Pattern RANGE_START_OR_END_PATTERN = Pattern.compile("(<!\\w+(,\\s*\\w+)*!>)|(<!>)");
private static final Pattern INDIVIDUAL_DIAGNOSTIC_PATTERN = Pattern.compile("\\w+");
public static List<Diagnostic> getDiagnosticsIncludingSyntaxErrors(BindingContext bindingContext, PsiElement root) {
ArrayList<Diagnostic> diagnostics = new ArrayList<Diagnostic>();
diagnostics.addAll(bindingContext.getDiagnostics());
for (TextRange textRange : AnalyzingUtils.getSyntaxErrorRanges(root)) {
diagnostics.add(new SyntaxErrorDiagnostic(textRange));
}
return diagnostics;
}
public interface DiagnosticDiffCallbacks {
void missingDiagnostic(String type, int expectedStart, int expectedEnd);
void unexpectedDiagnostic(String type, int actualStart, int actualEnd);
@@ -144,7 +158,7 @@ public class CheckerTestUtil {
Matcher diagnosticTypeMatcher = INDIVIDUAL_DIAGNOSTIC_PATTERN.matcher(matchedText);
DiagnosedRange range = new DiagnosedRange(effectiveOffset);
while (diagnosticTypeMatcher.find()) {
range.addDiagnostic(diagnosticTypeMatcher.group());
range.addDiagnostic(diagnosticTypeMatcher.group());
}
opened.push(range);
result.add(range);
@@ -158,9 +172,17 @@ public class CheckerTestUtil {
return matcher.replaceAll("");
}
public static StringBuffer addDiagnosticMarkersToText(PsiFile psiFile, BindingContext bindingContext) {
Collection<Diagnostic> diagnostics = bindingContext.getDiagnostics();
public static StringBuffer addDiagnosticMarkersToText(PsiFile psiFile, BindingContext bindingContext, List<TextRange> syntaxErrors) {
Collection<Diagnostic> diagnostics = new ArrayList<Diagnostic>();
diagnostics.addAll(bindingContext.getDiagnostics());
for (TextRange syntaxError : syntaxErrors) {
diagnostics.add(new SyntaxErrorDiagnostic(syntaxError));
}
return addDiagnosticMarkersToText(psiFile, diagnostics);
}
public static StringBuffer addDiagnosticMarkersToText(PsiFile psiFile, Collection<Diagnostic> diagnostics) {
StringBuffer result = new StringBuffer();
String text = psiFile.getText();
if (!diagnostics.isEmpty()) {
@@ -193,6 +215,14 @@ public class CheckerTestUtil {
}
result.append(c);
}
if (currentDescriptor != null) {
assert currentDescriptor.start == text.length();
assert currentDescriptor.end == text.length();
openDiagnosticsString(result, currentDescriptor);
opened.push(currentDescriptor);
}
while (!opened.isEmpty() && text.length() == opened.peek().end) {
closeDiagnosticString(result);
opened.pop();
@@ -223,6 +253,55 @@ public class CheckerTestUtil {
result.append("<!>");
}
private static class SyntaxErrorDiagnosticFactory implements DiagnosticFactory {
private static final SyntaxErrorDiagnosticFactory instance = new SyntaxErrorDiagnosticFactory();
@NotNull
@Override
public TextRange getTextRange(@NotNull Diagnostic diagnostic) {
return ((SyntaxErrorDiagnostic) diagnostic).textRange;
}
@NotNull
@Override
public PsiFile getPsiFile(@NotNull Diagnostic diagnostic) {
throw new IllegalStateException();
}
@NotNull
@Override
public String getName() {
return "SYNTAX";
}
}
public static class SyntaxErrorDiagnostic implements Diagnostic {
private final TextRange textRange;
public SyntaxErrorDiagnostic(TextRange textRange) {
this.textRange = textRange;
}
@NotNull
@Override
public DiagnosticFactory getFactory() {
return SyntaxErrorDiagnosticFactory.instance;
}
@NotNull
@Override
public String getMessage() {
throw new IllegalStateException();
}
@NotNull
@Override
public Severity getSeverity() {
throw new IllegalStateException();
}
}
private static List<DiagnosticDescriptor> getSortedDiagnosticDescriptors(Collection<Diagnostic> diagnostics) {
List<Diagnostic> list = Lists.newArrayList(diagnostics);
Collections.sort(list, DIAGNOSTIC_COMPARATOR);
@@ -282,6 +361,10 @@ public class CheckerTestUtil {
public List<Diagnostic> getDiagnostics() {
return diagnostics;
}
public TextRange getTextRange() {
return new TextRange(start, end);
}
}
public static class DiagnosedRange {
@@ -670,7 +670,7 @@ public class JetExpressionParsing extends AbstractJetParsing {
/*
* when
* : "when" "(" (modifiers "val" SimpleName "=")? element ")" "{"
* : "when" ("(" (modifiers "val" SimpleName "=")? element ")")? "{"
* whenEntry*
* "}"
* ;
@@ -682,22 +682,26 @@ public class JetExpressionParsing extends AbstractJetParsing {
advance(); // WHEN_KEYWORD
// Parse condition
myBuilder.disableNewlines();
expect(LPAR, "Expecting '('");
if (at(LPAR)) {
advanceAt(LPAR);
int valPos = matchTokenStreamPredicate(new FirstBefore(new At(VAL_KEYWORD), new AtSet(RPAR, LBRACE, RBRACE, SEMICOLON, EQ)));
if (valPos >= 0) {
PsiBuilder.Marker property = mark();
myJetParsing.parseModifierList(MODIFIER_LIST, true);
myJetParsing.parseProperty(true);
property.done(PROPERTY);
} else {
parseExpression();
int valPos = matchTokenStreamPredicate(new FirstBefore(new At(VAL_KEYWORD), new AtSet(RPAR, LBRACE, RBRACE, SEMICOLON, EQ)));
if (valPos >= 0) {
PsiBuilder.Marker property = mark();
myJetParsing.parseModifierList(MODIFIER_LIST, true);
myJetParsing.parseProperty(true);
property.done(PROPERTY);
} else {
parseExpression();
}
expect(RPAR, "Expecting ')'");
}
expect(RPAR, "Expecting ')'");
myBuilder.restoreNewlinesState();
// Parse when block
myBuilder.enableNewlines();
expect(LBRACE, "Expecting '{'");
@@ -20,7 +20,7 @@ public class JetWhenExpression extends JetExpression {
return findChildrenByType(JetNodeTypes.WHEN_ENTRY);
}
@Nullable @IfNotParsed
@Nullable
public JetExpression getSubjectExpression() {
return findChildByClass(JetExpression.class);
}
@@ -4,6 +4,7 @@ import com.google.common.base.Predicate;
import com.google.common.base.Predicates;
import com.google.common.collect.Maps;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.TextRange;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiElementVisitor;
import com.intellij.psi.PsiErrorElement;
@@ -45,6 +46,22 @@ public class AnalyzingUtils {
}
});
}
public static List<TextRange> getSyntaxErrorRanges(@NotNull PsiElement root) {
final ArrayList<TextRange> r = new ArrayList<TextRange>();
root.acceptChildren(new PsiElementVisitor() {
@Override
public void visitElement(PsiElement element) {
element.acceptChildren(this);
}
@Override
public void visitErrorElement(PsiErrorElement element) {
r.add(element.getTextRange());
}
});
return r;
}
public static void throwExceptionOnErrors(BindingContext bindingContext) {
for (Diagnostic diagnostic : bindingContext.getDiagnostics()) {
@@ -32,4 +32,9 @@ public class AutoCastReceiver extends AbstractReceiverDescriptor {
public <R, D> R accept(@NotNull ReceiverDescriptorVisitor<R, D> visitor, D data) {
return original.accept(visitor, data);
}
@Override
public String toString() {
return "(" + original + " as " + getType() + ")";
}
}
@@ -19,4 +19,9 @@ public class DefaultValueArgument implements ResolvedValueArgument {
public List<JetExpression> getArgumentExpressions() {
return Collections.emptyList(); //throw new UnsupportedOperationException("Look into the default value of the parameter");
}
@Override
public String toString() {
return "|DEFAULT|";
}
}
@@ -29,4 +29,9 @@ public class ExpressionValueArgument implements ResolvedValueArgument {
if (expression == null) return Collections.emptyList();
return Collections.singletonList(expression);
}
@Override
public String toString() {
return expression.getText();
}
}
@@ -4,6 +4,7 @@ import com.google.common.collect.Lists;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.lang.psi.JetExpression;
import java.util.Iterator;
import java.util.List;
/**
@@ -17,4 +18,17 @@ public class VarargValueArgument implements ResolvedValueArgument {
public List<JetExpression> getArgumentExpressions() {
return values;
}
@Override
public String toString() {
StringBuilder builder = new StringBuilder("vararg:{");
for (Iterator<JetExpression> iterator = values.iterator(); iterator.hasNext(); ) {
JetExpression expression = iterator.next();
builder.append(expression.getText());
if (iterator.hasNext()) {
builder.append(", ");
}
}
return builder.append("}").toString();
}
}
@@ -11,6 +11,7 @@ import java.util.List;
*/
public interface AutoCastService {
AutoCastService NO_AUTO_CASTS = new AutoCastService() {
@NotNull
@Override
public DataFlowInfo getDataFlowInfo() {
return DataFlowInfo.EMPTY;
@@ -21,13 +22,17 @@ public interface AutoCastService {
return !receiver.getType().isNullable();
}
@NotNull
@Override
public List<ReceiverDescriptor> getVariantsForReceiver(ReceiverDescriptor receiverDescriptor) {
public List<ReceiverDescriptor> getVariantsForReceiver(@NotNull ReceiverDescriptor receiverDescriptor) {
return Collections.singletonList(receiverDescriptor);
}
};
List<ReceiverDescriptor> getVariantsForReceiver(ReceiverDescriptor receiverDescriptor);
@NotNull
List<ReceiverDescriptor> getVariantsForReceiver(@NotNull ReceiverDescriptor receiverDescriptor);
@NotNull
DataFlowInfo getDataFlowInfo();
boolean isNotNull(@NotNull ReceiverDescriptor receiver);
@@ -18,11 +18,13 @@ public class AutoCastServiceImpl implements AutoCastService {
this.bindingContext = bindingContext;
}
@NotNull
@Override
public List<ReceiverDescriptor> getVariantsForReceiver(ReceiverDescriptor receiverDescriptor) {
public List<ReceiverDescriptor> getVariantsForReceiver(@NotNull ReceiverDescriptor receiverDescriptor) {
return AutoCastUtils.getAutoCastVariants(bindingContext, dataFlowInfo, receiverDescriptor);
}
@NotNull
@Override
public DataFlowInfo getDataFlowInfo() {
return dataFlowInfo;
@@ -37,4 +37,9 @@ public class ClassReceiver implements ThisReceiverDescriptor {
public <R, D> R accept(@NotNull ReceiverDescriptorVisitor<R, D> visitor, D data) {
return visitor.visitClassReceiver(this, data);
}
@Override
public String toString() {
return "Class{" + getType() + "}";
}
}
@@ -25,4 +25,9 @@ public class ExpressionReceiver extends AbstractReceiverDescriptor implements Re
public <R, D> R accept(@NotNull ReceiverDescriptorVisitor<R, D> visitor, D data) {
return visitor.visitExpressionReceiver(this, data);
}
@Override
public String toString() {
return getType() + " {" + expression + ": " + expression.getText() + "}";
}
}
@@ -27,4 +27,9 @@ public class ExtensionReceiver extends AbstractReceiverDescriptor implements Thi
public <R, D> R accept(@NotNull ReceiverDescriptorVisitor<R, D> visitor, D data) {
return visitor.visitExtensionReceiver(this, data);
}
@Override
public String toString() {
return getType() + "Ext{" + descriptor + "}";
}
}
@@ -18,4 +18,9 @@ public class TransientReceiver extends AbstractReceiverDescriptor {
public <R, D> R accept(@NotNull ReceiverDescriptorVisitor<R, D> visitor, D data) {
return visitor.visitTransientReceiver(this, data);
}
@Override
public String toString() {
return "{Transient} : " + getType();
}
}
@@ -28,7 +28,7 @@ class WithPC1(a : Int) {
}
class Foo() : <!SUPERTYPE_NOT_INITIALIZED, FINAL_SUPERTYPE!>WithPC0<!>, <!MANY_CLASSES_IN_SUPERTYPE_LIST!>this<!>() {
class Foo() : <!SUPERTYPE_NOT_INITIALIZED, FINAL_SUPERTYPE!>WithPC0<!>, <!MANY_CLASSES_IN_SUPERTYPE_LIST, SYNTAX!>this<!>() {
}
@@ -47,4 +47,4 @@ class <!PRIMARY_CONSTRUCTOR_MISSING_STATEFUL_PROPERTY!>NoCPI<!> {
var ab = <!PROPERTY_INITIALIZER_NO_BACKING_FIELD!>1<!>
get() = 1
set(v) {}
}
}
@@ -1,4 +1,4 @@
namespace return
namespace <!SYNTAX!>return<!>
class A {
fun outer() {
@@ -14,4 +14,4 @@ class A {
<!RETURN_NOT_ALLOWED!>return<!UNRESOLVED_REFERENCE!>@inner<!><!>
return@outer
}
}
}
@@ -32,7 +32,7 @@ class A<E>() : C(), T {
super<<!NOT_A_SUPERTYPE!>E<!>>.bar()
super<<!NOT_A_SUPERTYPE!>E<!>>@A.bar()
super<<!NOT_A_SUPERTYPE!>Int<!>>.foo()
super<>.foo()
super<<!SYNTAX!><!>>.foo()
super<<!NOT_A_SUPERTYPE!>fun() : Unit<!>>.foo()
super<<!NOT_A_SUPERTYPE!>()<!>>.foo()
super<T><!UNRESOLVED_REFERENCE!>@B<!>.foo()
@@ -86,4 +86,4 @@ class A1 {
fun test() {
<!SUPER_IS_NOT_AN_EXPRESSION!>super<!>.equals(null)
}
}
}
@@ -0,0 +1,5 @@
// dummy test of syntax error highlighing in tests
fun get() {
1 + 2 <!SYNTAX!>2 3 4<!>
}
@@ -0,0 +1 @@
fun f() {<!SYNTAX!><!>
@@ -4,5 +4,5 @@ import java.util.List;
fun ff(l: Any) = when(l) {
is <!CANNOT_CHECK_FOR_ERASED!>List<String><!> => 1
else 2
else <!SYNTAX!>2<!>
}
@@ -3,5 +3,4 @@
fun block(f : fun() : Unit) = f()
fun bar() = block{ <!UNRESOLVED_REFERENCE!>foo<!>() // <-- missing closing curly bracket
fun foo() = block{ <!TYPECHECKER_HAS_RUN_INTO_RECURSIVE_PROBLEM!>bar()<!> }
fun foo() = block{ <!TYPECHECKER_HAS_RUN_INTO_RECURSIVE_PROBLEM!>bar()<!> }<!SYNTAX!><!>
@@ -0,0 +1,42 @@
fun IntArray.swap(i:Int, j:Int) {
val temp = this[i]
this[i] = this[j]
this[j] = temp
}
fun IntArray.quicksort() = quicksort(0, size-1)
fun IntArray.quicksort(L: Int, R:Int) {
val m = this[(L + R) / 2]
var i = L
var j = R
while (i <= j) {
while (this[i] < m)
i++
while (this[j] > m)
j--
if (i <= j) {
swap(i++, j--)
}
else {
}
}
if (L < j)
quicksort(L, j)
if (R > i)
quicksort(i, R)
}
fun box() : String {
val a = IntArray(10)
for(i in 0..4) {
a[2*i] = 2*i
a[2*i+1] = -2*i-1
}
a.quicksort()
for(i in 0..9) {
System.out?.print(a[i])
System.out?.print(' ')
}
return "OK"
}
@@ -1,3 +1,5 @@
fun box(i: Int?) {
fun box() : String {
val i : Int? = 0
val j = i?.plus(3) //verify error
return "OK"
}
+11
View File
@@ -70,3 +70,14 @@ fun foo() {
is a.a @ (val b, b) => c
}
}
fun whenWithoutCondition(i : Int) {
val j = 12
when {
3 => -1
i == 3 => -1
j < i, j == i => -1
i is Int => 1
else => 2
}
}
+137
View File
@@ -1205,4 +1205,141 @@ JetFile: When.jet
PsiWhiteSpace('\n ')
PsiElement(RBRACE)('}')
PsiWhiteSpace('\n')
PsiElement(RBRACE)('}')
PsiWhiteSpace('\n\n')
FUN
PsiElement(fun)('fun')
PsiWhiteSpace(' ')
PsiElement(IDENTIFIER)('whenWithoutCondition')
VALUE_PARAMETER_LIST
PsiElement(LPAR)('(')
VALUE_PARAMETER
PsiElement(IDENTIFIER)('i')
PsiWhiteSpace(' ')
PsiElement(COLON)(':')
PsiWhiteSpace(' ')
TYPE_REFERENCE
USER_TYPE
REFERENCE_EXPRESSION
PsiElement(IDENTIFIER)('Int')
PsiElement(RPAR)(')')
PsiWhiteSpace(' ')
BLOCK
PsiElement(LBRACE)('{')
PsiWhiteSpace('\n ')
PROPERTY
PsiElement(val)('val')
PsiWhiteSpace(' ')
PsiElement(IDENTIFIER)('j')
PsiWhiteSpace(' ')
PsiElement(EQ)('=')
PsiWhiteSpace(' ')
INTEGER_CONSTANT
PsiElement(INTEGER_LITERAL)('12')
PsiWhiteSpace('\n ')
WHEN
PsiElement(when)('when')
PsiWhiteSpace(' ')
PsiElement(LBRACE)('{')
PsiWhiteSpace('\n ')
WHEN_ENTRY
WHEN_CONDITION_IS_PATTERN
EXPRESSION_PATTERN
INTEGER_CONSTANT
PsiElement(INTEGER_LITERAL)('3')
PsiWhiteSpace(' ')
PsiElement(DOUBLE_ARROW)('=>')
PsiWhiteSpace(' ')
PREFIX_EXPRESSION
OPERATION_REFERENCE
PsiElement(MINUS)('-')
INTEGER_CONSTANT
PsiElement(INTEGER_LITERAL)('1')
PsiWhiteSpace('\n ')
WHEN_ENTRY
WHEN_CONDITION_IS_PATTERN
EXPRESSION_PATTERN
BINARY_EXPRESSION
REFERENCE_EXPRESSION
PsiElement(IDENTIFIER)('i')
PsiWhiteSpace(' ')
OPERATION_REFERENCE
PsiElement(EQEQ)('==')
PsiWhiteSpace(' ')
INTEGER_CONSTANT
PsiElement(INTEGER_LITERAL)('3')
PsiWhiteSpace(' ')
PsiElement(DOUBLE_ARROW)('=>')
PsiWhiteSpace(' ')
PREFIX_EXPRESSION
OPERATION_REFERENCE
PsiElement(MINUS)('-')
INTEGER_CONSTANT
PsiElement(INTEGER_LITERAL)('1')
PsiWhiteSpace('\n ')
WHEN_ENTRY
WHEN_CONDITION_IS_PATTERN
EXPRESSION_PATTERN
BINARY_EXPRESSION
REFERENCE_EXPRESSION
PsiElement(IDENTIFIER)('j')
PsiWhiteSpace(' ')
OPERATION_REFERENCE
PsiElement(LT)('<')
PsiWhiteSpace(' ')
REFERENCE_EXPRESSION
PsiElement(IDENTIFIER)('i')
PsiElement(COMMA)(',')
PsiWhiteSpace(' ')
WHEN_CONDITION_IS_PATTERN
EXPRESSION_PATTERN
BINARY_EXPRESSION
REFERENCE_EXPRESSION
PsiElement(IDENTIFIER)('j')
PsiWhiteSpace(' ')
OPERATION_REFERENCE
PsiElement(EQEQ)('==')
PsiWhiteSpace(' ')
REFERENCE_EXPRESSION
PsiElement(IDENTIFIER)('i')
PsiWhiteSpace(' ')
PsiElement(DOUBLE_ARROW)('=>')
PsiWhiteSpace(' ')
PREFIX_EXPRESSION
OPERATION_REFERENCE
PsiElement(MINUS)('-')
INTEGER_CONSTANT
PsiElement(INTEGER_LITERAL)('1')
PsiWhiteSpace('\n ')
WHEN_ENTRY
WHEN_CONDITION_IS_PATTERN
EXPRESSION_PATTERN
BINARY_WITH_PATTERN
REFERENCE_EXPRESSION
PsiElement(IDENTIFIER)('i')
PsiWhiteSpace(' ')
OPERATION_REFERENCE
PsiElement(is)('is')
PsiWhiteSpace(' ')
TYPE_PATTERN
TYPE_REFERENCE
USER_TYPE
REFERENCE_EXPRESSION
PsiElement(IDENTIFIER)('Int')
PsiWhiteSpace(' ')
PsiElement(DOUBLE_ARROW)('=>')
PsiWhiteSpace(' ')
INTEGER_CONSTANT
PsiElement(INTEGER_LITERAL)('1')
PsiWhiteSpace('\n ')
WHEN_ENTRY
PsiElement(else)('else')
PsiWhiteSpace(' ')
PsiElement(DOUBLE_ARROW)('=>')
PsiWhiteSpace(' ')
INTEGER_CONSTANT
PsiElement(INTEGER_LITERAL)('2')
PsiWhiteSpace('\n ')
PsiElement(RBRACE)('}')
PsiWhiteSpace('\n')
PsiElement(RBRACE)('}')
@@ -1,6 +1,7 @@
package org.jetbrains.jet.checkers;
import com.google.common.collect.Lists;
import com.intellij.openapi.util.TextRange;
import com.intellij.psi.PsiFile;
import org.jetbrains.jet.JetLiteFixture;
import org.jetbrains.jet.lang.diagnostics.Diagnostic;
@@ -82,12 +83,12 @@ public class CheckerTestUtilTest extends JetLiteFixture {
public void test(PsiFile psiFile) {
BindingContext bindingContext = AnalyzerFacade.analyzeFileWithCache(AnalyzingUtils.getInstance(ImportingStrategy.NONE), (JetFile) psiFile, AnalyzerFacade.SINGLE_DECLARATION_PROVIDER);
String expectedText = CheckerTestUtil.addDiagnosticMarkersToText(psiFile, bindingContext).toString();
String expectedText = CheckerTestUtil.addDiagnosticMarkersToText(psiFile, CheckerTestUtil.getDiagnosticsIncludingSyntaxErrors(bindingContext, psiFile)).toString();
List<CheckerTestUtil.DiagnosedRange> diagnosedRanges = Lists.newArrayList();
CheckerTestUtil.parseDiagnosedRanges(expectedText, diagnosedRanges);
List<Diagnostic> diagnostics = Lists.newArrayList(bindingContext.getDiagnostics());
List<Diagnostic> diagnostics = CheckerTestUtil.getDiagnosticsIncludingSyntaxErrors(bindingContext, psiFile);
Collections.sort(diagnostics, CheckerTestUtil.DIAGNOSTIC_COMPARATOR);
makeTestData(diagnostics, diagnosedRanges);
@@ -47,7 +47,7 @@ public class QuickJetPsiCheckerTest extends JetLiteFixture {
BindingContext bindingContext = AnalyzerFacade.analyzeFileWithCache(AnalyzingUtils.getInstance(importingStrategy), jetFile, AnalyzerFacade.SINGLE_DECLARATION_PROVIDER);
CheckerTestUtil.diagnosticsDiff(diagnosedRanges, bindingContext.getDiagnostics(), new CheckerTestUtil.DiagnosticDiffCallbacks() {
CheckerTestUtil.diagnosticsDiff(diagnosedRanges, CheckerTestUtil.getDiagnosticsIncludingSyntaxErrors(bindingContext, jetFile), new CheckerTestUtil.DiagnosticDiffCallbacks() {
@Override
public void missingDiagnostic(String type, int expectedStart, int expectedEnd) {
String message = "Missing " + type + DiagnosticUtils.atLocation(myFile, new TextRange(expectedStart, expectedEnd));
@@ -61,14 +61,14 @@ public class QuickJetPsiCheckerTest extends JetLiteFixture {
}
});
String actualText = CheckerTestUtil.addDiagnosticMarkersToText(jetFile, bindingContext).toString();
String actualText = CheckerTestUtil.addDiagnosticMarkersToText(jetFile, bindingContext, AnalyzingUtils.getSyntaxErrorRanges(jetFile)).toString();
assertEquals(expectedText, actualText);
// convert(new File(myFullDataPath + "/../../checker/"), new File(myFullDataPath));
}
// private void convert(File src, File dest) throws IOException {
// private void convert(File src, File dest) throws IOException {
// File[] files = src.listFiles();
// for (File file : files) {
// try {
@@ -220,4 +220,9 @@ public class ControlStructuresTest extends CodegenTestCase {
createEnvironmentWithFullJdk();
blackBoxFile("regressions/kt434.jet");
}
public void testQuicksort() throws Exception {
blackBoxFile("controlStructures/quicksort.jet");
// System.out.println(generateToText());
}
}
@@ -266,7 +266,7 @@ public class PrimitiveTypesTest extends CodegenTestCase {
}
public void testKt239 () throws Exception {
blackBoxFile("regressions/kt242.jet");
blackBoxFile("regressions/kt239.jet");
}
public void testKt243 () throws Exception {
+74
View File
@@ -0,0 +1,74 @@
public class BinaryTrees {
private final static int minDepth = 4;
public static void main(String[] args){
final long millis = System.currentTimeMillis();
int n = 20;
if (args.length > 0) n = Integer.parseInt(args[0]);
int maxDepth = (minDepth + 2 > n) ? minDepth + 2 : n;
int stretchDepth = maxDepth + 1;
int check = (TreeNode.bottomUpTree(0,stretchDepth)).itemCheck();
System.out.println("stretch tree of depth "+stretchDepth+"\t check: " + check);
TreeNode longLivedTree = TreeNode.bottomUpTree(0,maxDepth);
for (int depth=minDepth; depth<=maxDepth; depth+=2){
int iterations = 1 << (maxDepth - depth + minDepth);
check = 0;
for (int i=1; i<=iterations; i++){
check += (TreeNode.bottomUpTree(i,depth)).itemCheck();
check += (TreeNode.bottomUpTree(-i,depth)).itemCheck();
}
System.out.println((iterations*2) + "\t trees of depth " + depth + "\t check: " + check);
}
System.out.println("long lived tree of depth " + maxDepth + "\t check: "+ longLivedTree.itemCheck());
long total = System.currentTimeMillis() - millis;
System.out.println("[Binary Trees-" + System.getProperty("project.name")+ " Benchmark Result: " + total + "]");
}
private static class TreeNode
{
private TreeNode left, right;
private int item;
TreeNode(int item){
this.item = item;
}
private static TreeNode bottomUpTree(int item, int depth){
if (depth>0){
return new TreeNode(
bottomUpTree(2*item-1, depth-1)
, bottomUpTree(2*item, depth-1)
, item
);
}
else {
return new TreeNode(item);
}
}
TreeNode(TreeNode left, TreeNode right, int item){
this.left = left;
this.right = right;
this.item = item;
}
private int itemCheck(){
// if necessary deallocate here
if (left==null)
return item;
else {
return item + left.itemCheck() - right.itemCheck();
}
}
}
}
+52
View File
@@ -0,0 +1,52 @@
val minDepth = 4
fun main(args: Array<String>) {
val millis = System.currentTimeMillis()
val n = if (args.size > 0) Integer.parseInt(args[0]) else 20;
val maxDepth = if (minDepth + 2 > n) minDepth + 2 else n
val stretchDepth = maxDepth + 1
var check = bottomUpTree(0,stretchDepth).itemCheck()
System.out?.println("stretch tree of depth "+stretchDepth+"\t check: " + check);
val longLivedTree = bottomUpTree(0,maxDepth);
var depth = minDepth
while(depth<=maxDepth){
val iterations = 1 shl (maxDepth - depth + minDepth)
check = 0
for (i in 1..iterations){
check += bottomUpTree(i,depth).itemCheck()
check += bottomUpTree(-i,depth).itemCheck()
}
System.out?.println("${iterations*2}\t trees of depth $depth\t check: $check")
depth+=2
}
System.out?.println("long lived tree of depth " + maxDepth + "\t check: "+ longLivedTree.itemCheck());
val total = System.currentTimeMillis() - millis
System.out?.println("[Binary Trees-" + System.getProperty("project.name") + " Benchmark Result: " + total + "]");
}
fun bottomUpTree(item: Int, depth: Int) : TreeNode =
if (depth>0){
TreeNode(item, bottomUpTree(2*item-1, depth-1), bottomUpTree(2*item, depth-1))
}
else {
TreeNode(item, null, null)
}
class TreeNode(val item: Int, val left: TreeNode?, val right: TreeNode?) {
fun itemCheck() : Int {
var res = item
if(left != null)
res += left.itemCheck()
if(right != null)
res -= right.itemCheck()
return res
}
}
+48
View File
@@ -0,0 +1,48 @@
public class Quicksort {
public static void swap(int[] a, int i, int j) {
int temp = a[i];
a[i] = a[j];
a[j] = temp;
}
public static void quicksort(int[] a, int L, int R) {
int m = a[(L + R) / 2];
int i = L;
int j = R;
while (i <= j) {
while (a[i] < m)
i++;
while (a[j] > m)
j--;
if (i <= j) {
swap(a, i++, j--);
}
}
if (L < j)
quicksort(a, L, j);
if (R > i)
quicksort(a, i, R);
}
public static void quicksort(int[] a) {
quicksort(a, 0, a.length - 1);
}
public static void main(String[] args) {
long start = System.currentTimeMillis();
// Sample data
int[] a = new int[100000000];
for (int i = 0; i < a.length; i++) {
a[i] = i * 3 / 2 + 1;
if (i % 3 == 0)
a[i] = -a[i];
}
quicksort(a);
long total = System.currentTimeMillis() - start;
System.out.println("[Quicksort-" + System.getProperty("project.name")+ " Benchmark Result: " + total + "]");
}
}
+47
View File
@@ -0,0 +1,47 @@
namespace quicksort
fun IntArray.swap(i:Int, j:Int) {
val temp = this[i]
this[i] = this[j]
this[j] = temp
}
fun IntArray.quicksort() = quicksort(0, size-1)
fun IntArray.quicksort(L: Int, R:Int) {
val m = this[(L + R) / 2]
var i = L
var j = R
while (i <= j) {
while (this[i] < m)
i++
while (this[j] > m)
j--
if (i <= j) {
swap(i++, j--)
}
}
if (L < j)
quicksort(L, j)
if (R > i)
quicksort(i, R)
}
fun main(array: Array<String>) {
val start = System.currentTimeMillis()
val a = IntArray(100000000)
var i = 0
val len = a.size
while (i < len) {
a[i] = i * 3 / 2 + 1
if (i % 3 == 0)
a[i] = -a[i]
i++
}
a.quicksort()
val total = System.currentTimeMillis() - start
System.out?.println("[Quicksort-" + System.getProperty("project.name")+ " Benchmark Result: " + total + "]");
}
+1 -1
View File
@@ -5,7 +5,7 @@ bq. See [Pattern matching]
*/
when
: "when" "(" (modifiers "val" SimpleName "=")? expression ")" "{"
: "when" ("(" (modifiers "val" SimpleName "=")? expression ")")? "{"
whenEntry*
"}"
;
+3
View File
@@ -61,5 +61,8 @@
<toolWindow id="CodeWindow"
factoryClass="org.jetbrains.jet.plugin.internal.codewindow.BytecodeToolwindow$Factory"
anchor="right"/>
<toolWindow id="ResolveWindow"
factoryClass="org.jetbrains.jet.plugin.internal.resolvewindow.ResolveToolwindow$Factory"
anchor="right"/>
</extensions>
</idea-plugin>
@@ -6,11 +6,12 @@ import com.intellij.openapi.actionSystem.LangDataKeys;
import com.intellij.openapi.actionSystem.PlatformDataKeys;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.util.TextRange;
import com.intellij.psi.PsiFile;
import org.jetbrains.jet.checkers.CheckerTestUtil;
import org.jetbrains.jet.lang.psi.JetFile;
import org.jetbrains.jet.lang.resolve.AnalyzingUtils;
import org.jetbrains.jet.lang.resolve.BindingContext;
import org.jetbrains.jet.lang.resolve.java.AnalyzerFacade;
import org.jetbrains.jet.plugin.compiler.WholeProjectAnalyzerFacade;
import java.awt.*;
@@ -18,6 +19,7 @@ import java.awt.datatransfer.Clipboard;
import java.awt.datatransfer.ClipboardOwner;
import java.awt.datatransfer.StringSelection;
import java.awt.datatransfer.Transferable;
import java.util.List;
/**
* @author abreslav
@@ -30,8 +32,9 @@ public class CopyAsDiagnosticTestAction extends AnAction {
assert editor != null && psiFile != null;
BindingContext bindingContext = WholeProjectAnalyzerFacade.analyzeProjectWithCacheOnAFile((JetFile) psiFile);
List<TextRange> syntaxError = AnalyzingUtils.getSyntaxErrorRanges(psiFile);
String result = CheckerTestUtil.addDiagnosticMarkersToText(psiFile, bindingContext).toString();
String result = CheckerTestUtil.addDiagnosticMarkersToText(psiFile, bindingContext, syntaxError).toString();
Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard();
clipboard.setContents(new StringSelection(result), new ClipboardOwner() {
@@ -208,7 +208,7 @@ public class BytecodeToolwindow extends JPanel {
}
}
private static class Location {
public static class Location {
final Editor editor;
final long modificationStamp;
final int startOffset;
@@ -225,6 +225,22 @@ public class BytecodeToolwindow extends JPanel {
return new Location(editor);
}
public Editor getEditor() {
return editor;
}
public long getModificationStamp() {
return modificationStamp;
}
public int getStartOffset() {
return startOffset;
}
public int getEndOffset() {
return endOffset;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
@@ -0,0 +1,251 @@
/*
* @author max
*/
package org.jetbrains.jet.plugin.internal.resolvewindow;
import com.intellij.openapi.application.Result;
import com.intellij.openapi.command.WriteCommandAction;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.editor.EditorFactory;
import com.intellij.openapi.editor.ex.EditorEx;
import com.intellij.openapi.fileEditor.FileEditorManager;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Comparing;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.openapi.wm.ToolWindow;
import com.intellij.openapi.wm.ToolWindowFactory;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFile;
import com.intellij.psi.PsiManager;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.psi.util.PsiUtilCore;
import com.intellij.ui.content.ContentFactory;
import com.intellij.util.Alarm;
import org.jetbrains.jet.lang.descriptors.*;
import org.jetbrains.jet.lang.psi.JetElement;
import org.jetbrains.jet.lang.psi.JetExpression;
import org.jetbrains.jet.lang.psi.JetFile;
import org.jetbrains.jet.lang.psi.JetReferenceExpression;
import org.jetbrains.jet.lang.resolve.BindingContext;
import org.jetbrains.jet.lang.resolve.calls.ResolvedCall;
import org.jetbrains.jet.lang.resolve.calls.ResolvedValueArgument;
import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor;
import org.jetbrains.jet.lang.types.JetType;
import org.jetbrains.jet.plugin.JetFileType;
import org.jetbrains.jet.plugin.compiler.WholeProjectAnalyzerFacade;
import org.jetbrains.jet.plugin.internal.codewindow.BytecodeToolwindow;
import javax.swing.*;
import java.awt.*;
import java.util.Map;
import static org.jetbrains.jet.lang.resolve.BindingContext.EXPRESSION_TYPE;
import static org.jetbrains.jet.lang.resolve.BindingContext.REFERENCE_TARGET;
import static org.jetbrains.jet.lang.resolve.BindingContext.RESOLVED_CALL;
/*
* @author abreslav
*/
public class ResolveToolwindow extends JPanel {
public static class Factory implements ToolWindowFactory {
@Override
public void createToolWindowContent(Project project, ToolWindow toolWindow) {
toolWindow.getContentManager().addContent(ContentFactory.SERVICE.getInstance().createContent(new ResolveToolwindow(project), "", false));
}
}
private static final int UPDATE_DELAY = 500;
private final Editor myEditor;
private final Alarm myUpdateAlarm;
private BytecodeToolwindow.Location myCurrentLocation;
private final Project myProject;
public ResolveToolwindow(Project project) {
super(new BorderLayout());
myProject = project;
myEditor = EditorFactory.getInstance().createEditor(EditorFactory.getInstance().createDocument(""), project, JetFileType.INSTANCE, true);
add(myEditor.getComponent());
myUpdateAlarm = new Alarm(Alarm.ThreadToUse.SWING_THREAD);
myUpdateAlarm.addRequest(new Runnable() {
@Override
public void run() {
myUpdateAlarm.addRequest(this, UPDATE_DELAY);
BytecodeToolwindow.Location location = BytecodeToolwindow.Location.fromEditor(FileEditorManager.getInstance(myProject).getSelectedTextEditor());
if (!Comparing.equal(location, myCurrentLocation)) {
render(location, myCurrentLocation);
myCurrentLocation = location;
}
}
}, UPDATE_DELAY);
}
private void render(BytecodeToolwindow.Location location, BytecodeToolwindow.Location oldLocation) {
Editor editor = location.getEditor();
if (editor == null) {
setText("No editor");
}
else {
VirtualFile vFile = ((EditorEx) editor).getVirtualFile();
if (vFile == null) {
setText("");
return;
}
PsiFile psiFile = PsiManager.getInstance(myProject).findFile(vFile);
if (!(psiFile instanceof JetFile)) {
setText("");
return;
}
int startOffset = location.getStartOffset();
int endOffset = location.getEndOffset();
if (oldLocation == null || !Comparing.equal(oldLocation.getEditor(), location.getEditor())
|| oldLocation.getStartOffset() != startOffset
|| oldLocation.getEndOffset() != endOffset) {
BindingContext bindingContext = WholeProjectAnalyzerFacade.analyzeProjectWithCacheOnAFile((JetFile) psiFile);
PsiElement elementAtOffset;
if (startOffset == endOffset) {
elementAtOffset = PsiUtilCore.getElementAtOffset(psiFile, startOffset);
}
else {
PsiElement start = PsiUtilCore.getElementAtOffset(psiFile, startOffset);
PsiElement end = PsiUtilCore.getElementAtOffset(psiFile, endOffset - 1);
elementAtOffset = PsiTreeUtil.findCommonParent(start, end);
}
PsiElement currentElement = elementAtOffset;
boolean callFound = false;
while (currentElement != null && !(currentElement instanceof PsiFile)) {
if (currentElement instanceof JetElement) {
JetElement atOffset = (JetElement) currentElement;
ResolvedCall<? extends CallableDescriptor> resolvedCall = bindingContext.get(RESOLVED_CALL, (JetElement) atOffset);
if (resolvedCall != null) {
setText(renderCall(resolvedCall) + "\n===\n" + currentElement + ": " + currentElement.getText());
callFound = true;
break;
}
}
currentElement = currentElement.getParent();
}
if (!callFound) {
JetExpression parentExpression = (elementAtOffset instanceof JetExpression) ? (JetExpression) elementAtOffset
: PsiTreeUtil.getParentOfType(elementAtOffset, JetExpression.class);
if (parentExpression != null) {
JetType type = bindingContext.get(EXPRESSION_TYPE, parentExpression);
String text = parentExpression + "|" + parentExpression.getText() + "| : " + type;
if (parentExpression instanceof JetReferenceExpression) {
JetReferenceExpression referenceExpression = (JetReferenceExpression) parentExpression;
DeclarationDescriptor target = bindingContext.get(REFERENCE_TARGET, referenceExpression);
text += "\nReference target: \n" + target;
}
setText(text);
}
}
}
}
}
private String renderCall(ResolvedCall<? extends CallableDescriptor> resolvedCall) {
StringBuilder builder = new StringBuilder();
CallableDescriptor resultingDescriptor = resolvedCall.getResultingDescriptor();
ReceiverDescriptor receiverArgument = resolvedCall.getReceiverArgument();
ReceiverDescriptor thisObject = resolvedCall.getThisObject();
Map<TypeParameterDescriptor, JetType> typeArguments = resolvedCall.getTypeArguments();
Map<ValueParameterDescriptor, ResolvedValueArgument> valueArguments = resolvedCall.getValueArguments();
renderReceiver(receiverArgument, thisObject, builder);
builder.append(resultingDescriptor.getName());
renderTypeArguments(typeArguments, builder);
if (resultingDescriptor instanceof FunctionDescriptor) {
renderValueArguments(valueArguments, builder);
}
builder.append(" : ").append(resultingDescriptor.getReturnType());
builder.append("\n");
builder.append("\n");
CallableDescriptor candidateDescriptor = resolvedCall.getCandidateDescriptor();
builder.append("Candidate: \n").append(candidateDescriptor).append("\n");
if (resultingDescriptor != candidateDescriptor) {
builder.append("Result: \n").append(resultingDescriptor).append("\n");
}
builder.append("Receiver: \n").append(receiverArgument).append("\n");
builder.append("This object: \n").append(thisObject).append("\n");
builder.append("Type args: \n").append(typeArguments).append("\n");
builder.append("Value args: \n").append(valueArguments).append("\n");
return builder.toString();
}
private void renderValueArguments(Map<ValueParameterDescriptor, ResolvedValueArgument> valueArguments, StringBuilder builder) {
ResolvedValueArgument[] args = new ResolvedValueArgument[valueArguments.size()];
for (Map.Entry<ValueParameterDescriptor, ResolvedValueArgument> entry : valueArguments.entrySet()) {
ValueParameterDescriptor key = entry.getKey();
ResolvedValueArgument value = entry.getValue();
args[key.getIndex()] = value;
}
builder.append("(");
for (int i = 0, argsLength = args.length; i < argsLength; i++) {
ResolvedValueArgument arg = args[i];
builder.append(arg);
if (i != argsLength - 1) {
builder.append(", ");
}
}
builder.append(")");
}
private void renderTypeArguments(Map<TypeParameterDescriptor, JetType> typeArguments, StringBuilder builder) {
JetType[] args = new JetType[typeArguments.size()];
for (Map.Entry<TypeParameterDescriptor, JetType> entry : typeArguments.entrySet()) {
TypeParameterDescriptor key = entry.getKey();
JetType value = entry.getValue();
args[key.getIndex()] = value;
}
builder.append("<");
for (int i = 0, argsLength = args.length; i < argsLength; i++) {
JetType type = args[i];
builder.append(type);
if (i != argsLength - 1) {
builder.append(", ");
}
}
builder.append(">");
}
private void renderReceiver(ReceiverDescriptor receiverArgument, ReceiverDescriptor thisObject, StringBuilder builder) {
if (receiverArgument.exists()) {
builder.append("/").append(receiverArgument);
}
if (thisObject.exists()) {
builder.append("/this=").append(thisObject);
}
if (thisObject.exists() || receiverArgument.exists()) {
builder.append("/.");
}
}
private void setText(final String text) {
new WriteCommandAction(myProject) {
@Override
protected void run(Result result) throws Throwable {
myEditor.getDocument().setText(text);
}
}.execute();
}
}