Merge remote-tracking branch 'origin/master'
This commit is contained in:
@@ -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|";
|
||||
}
|
||||
}
|
||||
|
||||
+5
@@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
+7
-2
@@ -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);
|
||||
|
||||
+3
-1
@@ -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;
|
||||
|
||||
+5
@@ -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() + "}";
|
||||
}
|
||||
}
|
||||
|
||||
+5
@@ -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() + "}";
|
||||
}
|
||||
}
|
||||
|
||||
+5
@@ -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 + "}";
|
||||
}
|
||||
}
|
||||
|
||||
+5
@@ -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<!>
|
||||
}
|
||||
|
||||
+1
-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"
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
@@ -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 + "]");
|
||||
}
|
||||
}
|
||||
@@ -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 + "]");
|
||||
}
|
||||
@@ -5,7 +5,7 @@ bq. See [Pattern matching]
|
||||
*/
|
||||
|
||||
when
|
||||
: "when" "(" (modifiers "val" SimpleName "=")? expression ")" "{"
|
||||
: "when" ("(" (modifiers "val" SimpleName "=")? expression ")")? "{"
|
||||
whenEntry*
|
||||
"}"
|
||||
;
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user