Merge remote branch 'origin/master'
Conflicts: compiler/cli/src/org/jetbrains/jet/cli/KotlinCompiler.java
This commit is contained in:
@@ -277,14 +277,17 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
|
|||||||
|
|
||||||
v.mark(begin);
|
v.mark(begin);
|
||||||
v.load(iteratorVar, asmIterType);
|
v.load(iteratorVar, asmIterType);
|
||||||
FunctionDescriptor hND;
|
|
||||||
if(hasNextDescriptor instanceof FunctionDescriptor) {
|
if(hasNextDescriptor instanceof FunctionDescriptor) {
|
||||||
hND = (FunctionDescriptor) hasNextDescriptor;
|
FunctionDescriptor hND = (FunctionDescriptor) hasNextDescriptor;
|
||||||
|
invokeFunctionNoParams(hND, Type.BOOLEAN_TYPE, v);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
hND = ((PropertyDescriptor) hasNextDescriptor).getGetter();
|
// hND = ((PropertyDescriptor) hasNextDescriptor).getGetter();
|
||||||
|
// if(hND != null)
|
||||||
|
// invokeFunctionNoParams(hND, Type.BOOLEAN_TYPE, v);
|
||||||
|
// else
|
||||||
|
intermediateValueForProperty((PropertyDescriptor) hasNextDescriptor, false, false).put(Type.BOOLEAN_TYPE, v);
|
||||||
}
|
}
|
||||||
invokeFunctionNoParams(hND, Type.BOOLEAN_TYPE, v);
|
|
||||||
v.ifeq(end);
|
v.ifeq(end);
|
||||||
|
|
||||||
myMap.enter(parameterDescriptor, asmParamType.getSize());
|
myMap.enter(parameterDescriptor, asmParamType.getSize());
|
||||||
@@ -598,8 +601,10 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (DeclarationDescriptor descriptor : closureCodegen.closure.keySet()) {
|
for (DeclarationDescriptor descriptor : closureCodegen.closure.keySet()) {
|
||||||
final Type sharedVarType = getSharedVarType(descriptor);
|
Type sharedVarType = getSharedVarType(descriptor);
|
||||||
consArgTypes.add(sharedVarType != null ? sharedVarType : state.getTypeMapper().mapType(((VariableDescriptor) descriptor).getOutType()));
|
if(sharedVarType == null)
|
||||||
|
sharedVarType = state.getTypeMapper().mapType(((VariableDescriptor) descriptor).getOutType());
|
||||||
|
consArgTypes.add(sharedVarType);
|
||||||
final EnclosedValueDescriptor valueDescriptor = closureCodegen.closure.get(descriptor);
|
final EnclosedValueDescriptor valueDescriptor = closureCodegen.closure.get(descriptor);
|
||||||
valueDescriptor.getOuterValue().put(sharedVarType, v);
|
valueDescriptor.getOuterValue().put(sharedVarType, v);
|
||||||
}
|
}
|
||||||
@@ -1462,7 +1467,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
|
|||||||
return StackValue.onStack(Type.BOOLEAN_TYPE);
|
return StackValue.onStack(Type.BOOLEAN_TYPE);
|
||||||
}
|
}
|
||||||
|
|
||||||
private StackValue generateEqualsForExpressionsOnStack(IElementType opToken, Type leftType, Type rightType, boolean leftNullable, boolean rightNullable) {
|
public StackValue generateEqualsForExpressionsOnStack(IElementType opToken, Type leftType, Type rightType, boolean leftNullable, boolean rightNullable) {
|
||||||
if (isNumberPrimitive(leftType) && leftType == rightType) {
|
if (isNumberPrimitive(leftType) && leftType == rightType) {
|
||||||
return compareExpressionsOnStack(opToken, leftType);
|
return compareExpressionsOnStack(opToken, leftType);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -342,7 +342,10 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
|
|||||||
Map<DeclarationDescriptor, EnclosedValueDescriptor> closure = context.closure.closure;
|
Map<DeclarationDescriptor, EnclosedValueDescriptor> closure = context.closure.closure;
|
||||||
int k = 0;
|
int k = 0;
|
||||||
for (DeclarationDescriptor varDescr : closure.keySet()) {
|
for (DeclarationDescriptor varDescr : closure.keySet()) {
|
||||||
final Type sharedVarType = context.closure.exprContext.getSharedVarType(varDescr);
|
Type sharedVarType = context.closure.exprContext.getSharedVarType(varDescr);
|
||||||
|
if(sharedVarType == null) {
|
||||||
|
sharedVarType = state.getTypeMapper().mapType(((VariableDescriptor) varDescr).getOutType());
|
||||||
|
}
|
||||||
iv.load(0, JetTypeMapper.TYPE_OBJECT);
|
iv.load(0, JetTypeMapper.TYPE_OBJECT);
|
||||||
iv.load(firstClosureIndex + k, StackValue.refType(sharedVarType));
|
iv.load(firstClosureIndex + k, StackValue.refType(sharedVarType));
|
||||||
iv.putfield(state.getTypeMapper().jvmName(descriptor, OwnerKind.IMPLEMENTATION), "$" + (k+1), sharedVarType.getDescriptor());
|
iv.putfield(state.getTypeMapper().jvmName(descriptor, OwnerKind.IMPLEMENTATION), "$" + (k+1), sharedVarType.getDescriptor());
|
||||||
|
|||||||
@@ -39,6 +39,7 @@ public class JetTypeMapper {
|
|||||||
public static final Type JL_BOOLEAN_TYPE = Type.getObjectType("java/lang/Boolean");
|
public static final Type JL_BOOLEAN_TYPE = Type.getObjectType("java/lang/Boolean");
|
||||||
public static final Type JL_NUMBER_TYPE = Type.getObjectType("java/lang/Number");
|
public static final Type JL_NUMBER_TYPE = Type.getObjectType("java/lang/Number");
|
||||||
public static final Type JL_STRING_BUILDER = Type.getObjectType("java/lang/StringBuilder");
|
public static final Type JL_STRING_BUILDER = Type.getObjectType("java/lang/StringBuilder");
|
||||||
|
public static final Type JL_STRING_TYPE = Type.getObjectType("java/lang/String");
|
||||||
|
|
||||||
public static final Type ARRAY_INT_TYPE = Type.getType(int[].class);
|
public static final Type ARRAY_INT_TYPE = Type.getType(int[].class);
|
||||||
public static final Type ARRAY_LONG_TYPE = Type.getType(long[].class);
|
public static final Type ARRAY_LONG_TYPE = Type.getType(long[].class);
|
||||||
@@ -59,15 +60,15 @@ public class JetTypeMapper {
|
|||||||
public static final Type TYPE_FUNCTION1 = Type.getObjectType("jet/Function1");
|
public static final Type TYPE_FUNCTION1 = Type.getObjectType("jet/Function1");
|
||||||
public static final Type TYPE_ITERATOR = Type.getObjectType("jet/Iterator");
|
public static final Type TYPE_ITERATOR = Type.getObjectType("jet/Iterator");
|
||||||
public static final Type TYPE_INT_RANGE = Type.getObjectType("jet/IntRange");
|
public static final Type TYPE_INT_RANGE = Type.getObjectType("jet/IntRange");
|
||||||
public static final Type TYPE_SHARED_VAR = Type.getObjectType("jet/refs/SharedVar$Object");
|
public static final Type TYPE_SHARED_VAR = Type.getObjectType("jet/runtime/SharedVar$Object");
|
||||||
public static final Type TYPE_SHARED_INT = Type.getObjectType("jet/refs/SharedVar$Int");
|
public static final Type TYPE_SHARED_INT = Type.getObjectType("jet/runtime/SharedVar$Int");
|
||||||
public static final Type TYPE_SHARED_DOUBLE = Type.getObjectType("jet/refs/SharedVar$Double");
|
public static final Type TYPE_SHARED_DOUBLE = Type.getObjectType("jet/runtime/SharedVar$Double");
|
||||||
public static final Type TYPE_SHARED_FLOAT = Type.getObjectType("jet/refs/SharedVar$Float");
|
public static final Type TYPE_SHARED_FLOAT = Type.getObjectType("jet/runtime/SharedVar$Float");
|
||||||
public static final Type TYPE_SHARED_BYTE = Type.getObjectType("jet/refs/SharedVar$Byte");
|
public static final Type TYPE_SHARED_BYTE = Type.getObjectType("jet/runtime/SharedVar$Byte");
|
||||||
public static final Type TYPE_SHARED_SHORT = Type.getObjectType("jet/refs/SharedVar$Short");
|
public static final Type TYPE_SHARED_SHORT = Type.getObjectType("jet/runtime/SharedVar$Short");
|
||||||
public static final Type TYPE_SHARED_CHAR = Type.getObjectType("jet/refs/SharedVar$Char");
|
public static final Type TYPE_SHARED_CHAR = Type.getObjectType("jet/runtime/SharedVar$Char");
|
||||||
public static final Type TYPE_SHARED_LONG = Type.getObjectType("jet/refs/SharedVar$Long");
|
public static final Type TYPE_SHARED_LONG = Type.getObjectType("jet/runtime/SharedVar$Long");
|
||||||
public static final Type TYPE_SHARED_BOOLEAN = Type.getObjectType("jet/refs/SharedVar$Boolean");
|
public static final Type TYPE_SHARED_BOOLEAN = Type.getObjectType("jet/runtime/SharedVar$Boolean");
|
||||||
|
|
||||||
public JetTypeMapper(JetStandardLibrary standardLibrary, BindingContext bindingContext) {
|
public JetTypeMapper(JetStandardLibrary standardLibrary, BindingContext bindingContext) {
|
||||||
this.standardLibrary = standardLibrary;
|
this.standardLibrary = standardLibrary;
|
||||||
@@ -460,7 +461,10 @@ public class JetTypeMapper {
|
|||||||
parameterTypes.add(type);
|
parameterTypes.add(type);
|
||||||
}
|
}
|
||||||
for (ValueParameterDescriptor parameter : parameters) {
|
for (ValueParameterDescriptor parameter : parameters) {
|
||||||
final Type type = mapType(parameter.getOutType());
|
Type type = mapType(parameter.getOutType());
|
||||||
|
if(parameter.isVararg()) {
|
||||||
|
type = Type.getType("[" + type.getDescriptor());
|
||||||
|
}
|
||||||
valueParameterTypes.add(type);
|
valueParameterTypes.add(type);
|
||||||
parameterTypes.add(type);
|
parameterTypes.add(type);
|
||||||
}
|
}
|
||||||
@@ -558,7 +562,13 @@ public class JetTypeMapper {
|
|||||||
parameterTypes.add(mapType(receiver.getType()));
|
parameterTypes.add(mapType(receiver.getType()));
|
||||||
}
|
}
|
||||||
for (ValueParameterDescriptor parameter : parameters) {
|
for (ValueParameterDescriptor parameter : parameters) {
|
||||||
parameterTypes.add(mapType(parameter.getOutType()));
|
if(parameter.isVararg()) {
|
||||||
|
Type type = mapType(parameter.getOutType());
|
||||||
|
type = Type.getType("[" + type.getDescriptor());
|
||||||
|
parameterTypes.add(type);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
parameterTypes.add(mapType(parameter.getOutType()));
|
||||||
}
|
}
|
||||||
Type returnType = mapReturnType(f.getReturnType());
|
Type returnType = mapReturnType(f.getReturnType());
|
||||||
return new Method(name, returnType, parameterTypes.toArray(new Type[parameterTypes.size()]));
|
return new Method(name, returnType, parameterTypes.toArray(new Type[parameterTypes.size()]));
|
||||||
|
|||||||
@@ -31,31 +31,31 @@ public class ArrayIterator implements IntrinsicMethod {
|
|||||||
JetStandardLibrary standardLibrary = codegen.getState().getStandardLibrary();
|
JetStandardLibrary standardLibrary = codegen.getState().getStandardLibrary();
|
||||||
if(containingDeclaration.equals(standardLibrary.getArray())) {
|
if(containingDeclaration.equals(standardLibrary.getArray())) {
|
||||||
codegen.generateTypeInfo(funDescriptor.getReturnType().getArguments().get(0).getType());
|
codegen.generateTypeInfo(funDescriptor.getReturnType().getArguments().get(0).getType());
|
||||||
v.invokestatic("jet/arrays/ArrayIterator", "iterator", "([Ljava/lang/Object;Ljet/typeinfo/TypeInfo;)Ljet/Iterator;");
|
v.invokestatic("jet/runtime/ArrayIterator", "iterator", "([Ljava/lang/Object;Ljet/typeinfo/TypeInfo;)Ljet/Iterator;");
|
||||||
}
|
}
|
||||||
else if(containingDeclaration.equals(standardLibrary.getByteArrayClass())) {
|
else if(containingDeclaration.equals(standardLibrary.getByteArrayClass())) {
|
||||||
v.invokestatic("jet/arrays/ArrayIterator", "iterator", "([B)Ljet/Iterator;");
|
v.invokestatic("jet/runtime/ArrayIterator", "iterator", "([B)Ljet/Iterator;");
|
||||||
}
|
}
|
||||||
else if(containingDeclaration.equals(standardLibrary.getShortArrayClass())) {
|
else if(containingDeclaration.equals(standardLibrary.getShortArrayClass())) {
|
||||||
v.invokestatic("jet/arrays/ArrayIterator", "iterator", "([S)Ljet/Iterator;");
|
v.invokestatic("jet/runtime/ArrayIterator", "iterator", "([S)Ljet/Iterator;");
|
||||||
}
|
}
|
||||||
else if(containingDeclaration.equals(standardLibrary.getIntArrayClass())) {
|
else if(containingDeclaration.equals(standardLibrary.getIntArrayClass())) {
|
||||||
v.invokestatic("jet/arrays/ArrayIterator", "iterator", "([I)Ljet/Iterator;");
|
v.invokestatic("jet/runtime/ArrayIterator", "iterator", "([I)Ljet/Iterator;");
|
||||||
}
|
}
|
||||||
else if(containingDeclaration.equals(standardLibrary.getLongArrayClass())) {
|
else if(containingDeclaration.equals(standardLibrary.getLongArrayClass())) {
|
||||||
v.invokestatic("jet/arrays/ArrayIterator", "iterator", "([J)Ljet/Iterator;");
|
v.invokestatic("jet/runtime/ArrayIterator", "iterator", "([J)Ljet/Iterator;");
|
||||||
}
|
}
|
||||||
else if(containingDeclaration.equals(standardLibrary.getFloatArrayClass())) {
|
else if(containingDeclaration.equals(standardLibrary.getFloatArrayClass())) {
|
||||||
v.invokestatic("jet/arrays/ArrayIterator", "iterator", "([F)Ljet/Iterator;");
|
v.invokestatic("jet/runtime/ArrayIterator", "iterator", "([F)Ljet/Iterator;");
|
||||||
}
|
}
|
||||||
else if(containingDeclaration.equals(standardLibrary.getDoubleArrayClass())) {
|
else if(containingDeclaration.equals(standardLibrary.getDoubleArrayClass())) {
|
||||||
v.invokestatic("jet/arrays/ArrayIterator", "iterator", "([D)Ljet/Iterator;");
|
v.invokestatic("jet/runtime/ArrayIterator", "iterator", "([D)Ljet/Iterator;");
|
||||||
}
|
}
|
||||||
else if(containingDeclaration.equals(standardLibrary.getCharArrayClass())) {
|
else if(containingDeclaration.equals(standardLibrary.getCharArrayClass())) {
|
||||||
v.invokestatic("jet/arrays/ArrayIterator", "iterator", "([C)Ljet/Iterator;");
|
v.invokestatic("jet/runtime/ArrayIterator", "iterator", "([C)Ljet/Iterator;");
|
||||||
}
|
}
|
||||||
else if(containingDeclaration.equals(standardLibrary.getBooleanArrayClass())) {
|
else if(containingDeclaration.equals(standardLibrary.getBooleanArrayClass())) {
|
||||||
v.invokestatic("jet/arrays/ArrayIterator", "iterator", "([Z)Ljet/Iterator;");
|
v.invokestatic("jet/runtime/ArrayIterator", "iterator", "([Z)Ljet/Iterator;");
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
throw new UnsupportedOperationException(containingDeclaration.toString());
|
throw new UnsupportedOperationException(containingDeclaration.toString());
|
||||||
|
|||||||
@@ -0,0 +1,43 @@
|
|||||||
|
package org.jetbrains.jet.codegen.intrinsics;
|
||||||
|
|
||||||
|
import com.intellij.psi.PsiElement;
|
||||||
|
import com.intellij.psi.tree.IElementType;
|
||||||
|
import org.jetbrains.jet.codegen.ExpressionCodegen;
|
||||||
|
import org.jetbrains.jet.codegen.JetTypeMapper;
|
||||||
|
import org.jetbrains.jet.codegen.StackValue;
|
||||||
|
import org.jetbrains.jet.lang.psi.JetCallExpression;
|
||||||
|
import org.jetbrains.jet.lang.psi.JetExpression;
|
||||||
|
import org.jetbrains.jet.lang.resolve.BindingContext;
|
||||||
|
import org.jetbrains.jet.lang.types.JetType;
|
||||||
|
import org.jetbrains.jet.lexer.JetTokens;
|
||||||
|
import org.objectweb.asm.Type;
|
||||||
|
import org.objectweb.asm.commons.InstructionAdapter;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author alex.tkachman
|
||||||
|
*/
|
||||||
|
public class Equals implements IntrinsicMethod {
|
||||||
|
@Override
|
||||||
|
public StackValue generate(ExpressionCodegen codegen, InstructionAdapter v, Type expectedType, PsiElement element, List<JetExpression> arguments, StackValue receiver) {
|
||||||
|
receiver.put(JetTypeMapper.TYPE_OBJECT, v);
|
||||||
|
|
||||||
|
boolean leftNullable = true;
|
||||||
|
if(element instanceof JetCallExpression) {
|
||||||
|
JetCallExpression jetCallExpression = (JetCallExpression) element;
|
||||||
|
JetExpression calleeExpression = jetCallExpression.getCalleeExpression();
|
||||||
|
if(calleeExpression != null) {
|
||||||
|
JetType leftType = codegen.getBindingContext().get(BindingContext.EXPRESSION_TYPE, calleeExpression);
|
||||||
|
if(leftType != null)
|
||||||
|
leftNullable = leftType.isNullable();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
JetExpression rightExpr = arguments.get(0);
|
||||||
|
JetType rightType = codegen.getBindingContext().get(BindingContext.EXPRESSION_TYPE, rightExpr);
|
||||||
|
codegen.gen(rightExpr).put(JetTypeMapper.TYPE_OBJECT, v);
|
||||||
|
|
||||||
|
return codegen.generateEqualsForExpressionsOnStack(JetTokens.EQEQ, JetTypeMapper.TYPE_OBJECT, JetTypeMapper.TYPE_OBJECT, leftNullable, rightType.isNullable());
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -73,6 +73,11 @@ public class IntrinsicMethods {
|
|||||||
|
|
||||||
declareIntrinsicFunction("String", "plus", 1, new Concat());
|
declareIntrinsicFunction("String", "plus", 1, new Concat());
|
||||||
|
|
||||||
|
declareOverload(myStdLib.getLibraryScope().getFunctions("toString"), 0, new ToString());
|
||||||
|
declareOverload(myStdLib.getLibraryScope().getFunctions("equals"), 1, new Equals());
|
||||||
|
|
||||||
|
// declareIntrinsicFunction("Any", "equals", 1, new Equals());
|
||||||
|
//
|
||||||
declareIntrinsicStringMethods();
|
declareIntrinsicStringMethods();
|
||||||
declareIntrinsicProperty("String", "length", new StringLength());
|
declareIntrinsicProperty("String", "length", new StringLength());
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,24 @@
|
|||||||
|
package org.jetbrains.jet.codegen.intrinsics;
|
||||||
|
|
||||||
|
import com.intellij.psi.PsiElement;
|
||||||
|
import org.jetbrains.jet.codegen.ExpressionCodegen;
|
||||||
|
import org.jetbrains.jet.codegen.JetTypeMapper;
|
||||||
|
import org.jetbrains.jet.codegen.StackValue;
|
||||||
|
import org.jetbrains.jet.lang.psi.JetExpression;
|
||||||
|
import org.jetbrains.jet.lang.types.JetStandardClasses;
|
||||||
|
import org.objectweb.asm.Type;
|
||||||
|
import org.objectweb.asm.commons.InstructionAdapter;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author alex.tkachman
|
||||||
|
*/
|
||||||
|
public class ToString implements IntrinsicMethod {
|
||||||
|
@Override
|
||||||
|
public StackValue generate(ExpressionCodegen codegen, InstructionAdapter v, Type expectedType, PsiElement element, List<JetExpression> arguments, StackValue receiver) {
|
||||||
|
receiver.put(JetTypeMapper.TYPE_OBJECT, v);
|
||||||
|
v.invokestatic("java/lang/String", "valueOf", "(Ljava/lang/Object;)Ljava/lang/String;");
|
||||||
|
return StackValue.onStack(JetTypeMapper.JL_STRING_TYPE);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,37 +1,58 @@
|
|||||||
package org.jetbrains.jet.cli;
|
package org.jetbrains.jet.cli;
|
||||||
|
|
||||||
import com.google.common.collect.Lists;
|
import com.google.common.collect.*;
|
||||||
|
import com.intellij.core.JavaCoreEnvironment;
|
||||||
import com.intellij.openapi.Disposable;
|
import com.intellij.openapi.Disposable;
|
||||||
import com.intellij.openapi.project.Project;
|
import com.intellij.openapi.project.Project;
|
||||||
import com.intellij.openapi.util.io.FileUtil;
|
import com.intellij.openapi.util.io.FileUtil;
|
||||||
import com.intellij.openapi.vfs.VirtualFile;
|
import com.intellij.openapi.vfs.VirtualFile;
|
||||||
import com.intellij.psi.PsiFile;
|
import com.intellij.psi.PsiFile;
|
||||||
import com.intellij.psi.PsiManager;
|
import com.intellij.psi.PsiManager;
|
||||||
import org.jetbrains.jet.JetCoreEnvironment;
|
import com.sampullara.cli.Args;
|
||||||
|
import com.sampullara.cli.Argument;
|
||||||
import org.jetbrains.jet.codegen.ClassFileFactory;
|
import org.jetbrains.jet.codegen.ClassFileFactory;
|
||||||
import org.jetbrains.jet.codegen.GenerationState;
|
import org.jetbrains.jet.codegen.GenerationState;
|
||||||
import org.jetbrains.jet.lang.cfg.pseudocode.JetControlFlowDataTraceFactory;
|
import org.jetbrains.jet.lang.cfg.pseudocode.JetControlFlowDataTraceFactory;
|
||||||
import org.jetbrains.jet.lang.diagnostics.Diagnostic;
|
import org.jetbrains.jet.lang.diagnostics.Diagnostic;
|
||||||
|
import org.jetbrains.jet.lang.diagnostics.DiagnosticUtils;
|
||||||
|
import org.jetbrains.jet.lang.diagnostics.DiagnosticWithTextRange;
|
||||||
|
import org.jetbrains.jet.lang.diagnostics.Severity;
|
||||||
|
import org.jetbrains.jet.lang.parsing.JetParserDefinition;
|
||||||
import org.jetbrains.jet.lang.psi.JetFile;
|
import org.jetbrains.jet.lang.psi.JetFile;
|
||||||
import org.jetbrains.jet.lang.psi.JetNamespace;
|
import org.jetbrains.jet.lang.psi.JetNamespace;
|
||||||
import org.jetbrains.jet.lang.resolve.AnalyzingUtils;
|
import org.jetbrains.jet.lang.resolve.AnalyzingUtils;
|
||||||
import org.jetbrains.jet.lang.resolve.BindingContext;
|
import org.jetbrains.jet.lang.resolve.BindingContext;
|
||||||
import org.jetbrains.jet.lang.resolve.java.JavaDefaultImports;
|
import org.jetbrains.jet.lang.resolve.java.JavaDefaultImports;
|
||||||
|
import org.jetbrains.jet.plugin.JetFileType;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
import java.net.URLClassLoader;
|
import java.net.URLClassLoader;
|
||||||
|
import java.util.Collection;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author yole
|
* @author yole
|
||||||
|
* @author alex.tkachman
|
||||||
*/
|
*/
|
||||||
public class KotlinCompiler {
|
public class KotlinCompiler {
|
||||||
|
public static class Arguments {
|
||||||
|
@Argument(value = "output", description = "output directory")
|
||||||
|
public String outputDir;
|
||||||
|
@Argument(value = "src", description = "source file or directory", required = true)
|
||||||
|
public String src;
|
||||||
|
}
|
||||||
|
|
||||||
public static void main(String[] args) {
|
public static void main(String[] args) {
|
||||||
System.setProperty("java.awt.headless", "true");
|
System.setProperty("java.awt.headless", "true");
|
||||||
if (args.length < 1) {
|
Arguments arguments = new Arguments();
|
||||||
System.out.println("Usage: KotlinCompiler <filename>");
|
try {
|
||||||
|
Args.parse(arguments, args);
|
||||||
|
}
|
||||||
|
catch (Throwable t) {
|
||||||
|
System.out.println("Usage: KotlinCompiler -output <outputDir> -src <filename or dirname>");
|
||||||
|
t.printStackTrace();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -40,8 +61,121 @@ public class KotlinCompiler {
|
|||||||
public void dispose() {
|
public void dispose() {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
JetCoreEnvironment environment = new JetCoreEnvironment(root);
|
JavaCoreEnvironment environment = new JavaCoreEnvironment(root);
|
||||||
|
|
||||||
|
File rtJar = initJdk();
|
||||||
|
if (rtJar == null) return;
|
||||||
|
|
||||||
|
environment.addToClasspath(rtJar);
|
||||||
|
|
||||||
|
environment.registerFileType(JetFileType.INSTANCE, "kt");
|
||||||
|
environment.registerParserDefinition(new JetParserDefinition());
|
||||||
|
|
||||||
|
VirtualFile vFile = environment.getLocalFileSystem().findFileByPath(arguments.src);
|
||||||
|
if (vFile == null) {
|
||||||
|
System.out.print("File/directory not found: " + arguments.src);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Project project = environment.getProject();
|
||||||
|
GenerationState generationState = new GenerationState(project, false);
|
||||||
|
List<JetNamespace> namespaces = Lists.newArrayList();
|
||||||
|
if(vFile.isDirectory()) {
|
||||||
|
File dir = new File(vFile.getPath());
|
||||||
|
addFiles(environment, project, namespaces, dir);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
PsiFile psiFile = PsiManager.getInstance(project).findFile(vFile);
|
||||||
|
if (psiFile instanceof JetFile) {
|
||||||
|
namespaces.add(((JetFile) psiFile).getRootNamespace());
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
System.out.print("Not a Kotlin file: " + vFile.getPath());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
BindingContext bindingContext = AnalyzingUtils.getInstance(JavaDefaultImports.JAVA_DEFAULT_IMPORTS).analyzeNamespaces(project, namespaces, JetControlFlowDataTraceFactory.EMPTY);
|
||||||
|
|
||||||
|
ErrorCollector errorCollector = new ErrorCollector(bindingContext);
|
||||||
|
errorCollector.report();
|
||||||
|
|
||||||
|
if (!errorCollector.hasErrors) {
|
||||||
|
generationState.compileCorrectNamespaces(bindingContext, namespaces);
|
||||||
|
|
||||||
|
final ClassFileFactory factory = generationState.getFactory();
|
||||||
|
if(arguments.outputDir == null) {
|
||||||
|
System.out.println("Output directory is not specified - no files will be saved to the disk");
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
List<String> files = factory.files();
|
||||||
|
for (String file : files) {
|
||||||
|
File target = new File(arguments.outputDir, file);
|
||||||
|
try {
|
||||||
|
FileUtil.writeToFile(target, factory.asBytes(file));
|
||||||
|
System.out.println("Generated classfile: " + target);
|
||||||
|
} catch (IOException e) {
|
||||||
|
System.out.println(e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class ErrorCollector {
|
||||||
|
Multimap<PsiFile,DiagnosticWithTextRange> maps = LinkedHashMultimap.<PsiFile, DiagnosticWithTextRange>create();
|
||||||
|
|
||||||
|
boolean hasErrors;
|
||||||
|
|
||||||
|
public ErrorCollector(BindingContext bindingContext) {
|
||||||
|
for (Diagnostic diagnostic : bindingContext.getDiagnostics()) {
|
||||||
|
report(diagnostic);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void report(Diagnostic diagnostic) {
|
||||||
|
hasErrors |= diagnostic.getSeverity() == Severity.ERROR;
|
||||||
|
if(diagnostic instanceof DiagnosticWithTextRange) {
|
||||||
|
DiagnosticWithTextRange diagnosticWithTextRange = (DiagnosticWithTextRange) diagnostic;
|
||||||
|
maps.put(diagnosticWithTextRange.getPsiFile(), diagnosticWithTextRange);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
System.out.println(diagnostic.getSeverity().toString() + ": " + diagnostic.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void report() {
|
||||||
|
if(!maps.isEmpty()) {
|
||||||
|
for (PsiFile psiFile : maps.keySet()) {
|
||||||
|
System.out.println(psiFile.getVirtualFile().getPath());
|
||||||
|
Collection<DiagnosticWithTextRange> diagnosticWithTextRanges = maps.get(psiFile);
|
||||||
|
for (DiagnosticWithTextRange diagnosticWithTextRange : diagnosticWithTextRanges) {
|
||||||
|
String position = DiagnosticUtils.formatPosition(diagnosticWithTextRange);
|
||||||
|
System.out.println("\t" + diagnosticWithTextRange.getSeverity().toString() + ": " + position + " " + diagnosticWithTextRange.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void addFiles(JavaCoreEnvironment environment, Project project, List<JetNamespace> namespaces, File dir) {
|
||||||
|
for(File file : dir.listFiles()) {
|
||||||
|
if(!file.isDirectory()) {
|
||||||
|
VirtualFile virtualFile = environment.getLocalFileSystem().findFileByPath(file.getAbsolutePath());
|
||||||
|
PsiFile psiFile = PsiManager.getInstance(project).findFile(virtualFile);
|
||||||
|
if (psiFile instanceof JetFile) {
|
||||||
|
namespaces.add(((JetFile) psiFile).getRootNamespace());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
addFiles(environment, project, namespaces, file);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static File initJdk() {
|
||||||
String javaHome = System.getenv("JAVA_HOME");
|
String javaHome = System.getenv("JAVA_HOME");
|
||||||
File rtJar = null;
|
File rtJar = null;
|
||||||
if (javaHome == null) {
|
if (javaHome == null) {
|
||||||
@@ -64,7 +198,7 @@ public class KotlinCompiler {
|
|||||||
|
|
||||||
if(rtJar == null) {
|
if(rtJar == null) {
|
||||||
System.out.println("JAVA_HOME environment variable needs to be defined");
|
System.out.println("JAVA_HOME environment variable needs to be defined");
|
||||||
return;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@@ -73,67 +207,9 @@ public class KotlinCompiler {
|
|||||||
|
|
||||||
if (rtJar == null || !rtJar.exists()) {
|
if (rtJar == null || !rtJar.exists()) {
|
||||||
System.out.print("No rt.jar found under JAVA_HOME=" + javaHome);
|
System.out.print("No rt.jar found under JAVA_HOME=" + javaHome);
|
||||||
return;
|
return null;
|
||||||
}
|
}
|
||||||
|
return rtJar;
|
||||||
environment.addToClasspath(rtJar);
|
|
||||||
|
|
||||||
VirtualFile vFile = environment.getLocalFileSystem().findFileByPath(args [0]);
|
|
||||||
if (vFile == null) {
|
|
||||||
System.out.print("File not found: " + args[0]);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
Project project = environment.getProject();
|
|
||||||
GenerationState generationState = new GenerationState(project, false);
|
|
||||||
List<JetNamespace> namespaces = Lists.newArrayList();
|
|
||||||
PsiFile psiFile = PsiManager.getInstance(project).findFile(vFile);
|
|
||||||
if (psiFile instanceof JetFile) {
|
|
||||||
namespaces.add(((JetFile) psiFile).getRootNamespace());
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
System.out.print("Not a Kotlin file: " + vFile.getPath());
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
BindingContext bindingContext = AnalyzingUtils.getInstance(JavaDefaultImports.JAVA_DEFAULT_IMPORTS).analyzeNamespaces(project, namespaces, JetControlFlowDataTraceFactory.EMPTY);
|
|
||||||
|
|
||||||
boolean errors = false;
|
|
||||||
for (Diagnostic diagnostic : bindingContext.getDiagnostics()) {
|
|
||||||
switch (diagnostic.getSeverity()) {
|
|
||||||
case ERROR:
|
|
||||||
errors = true;
|
|
||||||
report(diagnostic);
|
|
||||||
break;
|
|
||||||
case INFO:
|
|
||||||
report(diagnostic);
|
|
||||||
break;
|
|
||||||
case WARNING:
|
|
||||||
report(diagnostic);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!errors) {
|
|
||||||
generationState.compileCorrectNamespaces(bindingContext, namespaces);
|
|
||||||
|
|
||||||
final ClassFileFactory factory = generationState.getFactory();
|
|
||||||
List<String> files = factory.files();
|
|
||||||
for (String file : files) {
|
|
||||||
File target = new File(vFile.getParent().getPath(), file);
|
|
||||||
try {
|
|
||||||
FileUtil.writeToFile(target, factory.asBytes(file));
|
|
||||||
System.out.println("Generated classfile: " + target);
|
|
||||||
} catch (IOException e) {
|
|
||||||
System.out.println(e.getMessage());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void report(Diagnostic diagnostic) {
|
|
||||||
System.out.println(diagnostic.getMessage());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static File findRtJar(String javaHome) {
|
private static File findRtJar(String javaHome) {
|
||||||
|
|||||||
@@ -20,4 +20,7 @@ public class JavaDefaultImports {
|
|||||||
rootScope.importScope(new JavaPackageScope("java.lang", null, javaSemanticServices));
|
rootScope.importScope(new JavaPackageScope("java.lang", null, javaSemanticServices));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
private JavaDefaultImports() {
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -41,8 +41,8 @@ fun Any?.equals(other : Any?) : Boolean// = this === other
|
|||||||
fun Any?.toString() : String// = this === other
|
fun Any?.toString() : String// = this === other
|
||||||
|
|
||||||
trait Iterator<out T> {
|
trait Iterator<out T> {
|
||||||
fun next() : T
|
fun next() : T
|
||||||
fun hasNext() : Boolean
|
val hasNext : Boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
trait Iterable<out T> {
|
trait Iterable<out T> {
|
||||||
|
|||||||
@@ -118,18 +118,26 @@ public class JetFlowInformationProvider {
|
|||||||
Pseudocode pseudocode = pseudocodeMap.get(subroutine);
|
Pseudocode pseudocode = pseudocodeMap.get(subroutine);
|
||||||
assert pseudocode != null;
|
assert pseudocode != null;
|
||||||
|
|
||||||
SubroutineEnterInstruction enterInstruction = pseudocode.getEnterInstruction();
|
for (Instruction deadInstruction : pseudocode.getDeadInstructions()) {
|
||||||
Set<Instruction> visited = new HashSet<Instruction>();
|
if (deadInstruction instanceof JetElementInstruction &&
|
||||||
collectReachable(enterInstruction, visited, null);
|
|
||||||
|
|
||||||
for (Instruction instruction : pseudocode.getInstructions()) {
|
|
||||||
if (!visited.contains(instruction) &&
|
|
||||||
instruction instanceof JetElementInstruction &&
|
|
||||||
// TODO : do {return} while (1 > a)
|
// TODO : do {return} while (1 > a)
|
||||||
!(instruction instanceof ReadUnitValueInstruction)) {
|
!(deadInstruction instanceof ReadUnitValueInstruction)) {
|
||||||
unreachableElements.add(((JetElementInstruction) instruction).getElement());
|
unreachableElements.add(((JetElementInstruction) deadInstruction).getElement());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SubroutineEnterInstruction enterInstruction = pseudocode.getEnterInstruction();
|
||||||
|
// Set<Instruction> visited = new HashSet<Instruction>();
|
||||||
|
// collectReachable(enterInstruction, visited, null);
|
||||||
|
//
|
||||||
|
// for (Instruction instruction : pseudocode.getInstructions()) {
|
||||||
|
// if (!visited.contains(instruction) &&
|
||||||
|
// instruction instanceof JetElementInstruction &&
|
||||||
|
// // TODO : do {return} while (1 > a)
|
||||||
|
// !(instruction instanceof ReadUnitValueInstruction)) {
|
||||||
|
// unreachableElements.add(((JetElementInstruction) instruction).getElement());
|
||||||
|
// }
|
||||||
|
// }
|
||||||
}
|
}
|
||||||
// public void collectDominatedExpressions(@NotNull JetExpression dominator, @NotNull Collection<JetElement> dominated) {
|
// public void collectDominatedExpressions(@NotNull JetExpression dominator, @NotNull Collection<JetElement> dominated) {
|
||||||
// Instruction dominatorInstruction = representativeInstructions.get(dominator);
|
// Instruction dominatorInstruction = representativeInstructions.get(dominator);
|
||||||
@@ -175,17 +183,17 @@ public class JetFlowInformationProvider {
|
|||||||
// }
|
// }
|
||||||
// }
|
// }
|
||||||
|
|
||||||
private boolean collectReachable(Instruction current, Set<Instruction> visited, @Nullable Instruction lookFor) {
|
// private boolean collectReachable(Instruction current, Set<Instruction> visited, @Nullable Instruction lookFor) {
|
||||||
if (!visited.add(current)) return false;
|
// if (!visited.add(current)) return false;
|
||||||
if (current == lookFor) return true;
|
// if (current == lookFor) return true;
|
||||||
|
//
|
||||||
for (Instruction nextInstruction : current.getNextInstructions()) {
|
// for (Instruction nextInstruction : current.getNextInstructions()) {
|
||||||
if (collectReachable(nextInstruction, visited, lookFor)) {
|
// if (collectReachable(nextInstruction, visited, lookFor)) {
|
||||||
return true;
|
// return true;
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
return false;
|
// return false;
|
||||||
}
|
// }
|
||||||
|
|
||||||
// private void processPreviousInstructions(Instruction previousFor, final Set<Instruction> visited, final Collection<JetExpression> returnedExpressions, final Collection<JetElement> elementsReturningUnit) {
|
// private void processPreviousInstructions(Instruction previousFor, final Set<Instruction> visited, final Collection<JetExpression> returnedExpressions, final Collection<JetElement> elementsReturningUnit) {
|
||||||
// if (!visited.add(previousFor)) return;
|
// if (!visited.add(previousFor)) return;
|
||||||
@@ -248,20 +256,29 @@ public class JetFlowInformationProvider {
|
|||||||
// }
|
// }
|
||||||
// }
|
// }
|
||||||
|
|
||||||
private <D> Map<Instruction, D> traverseInstructionGraphUntilFactsStabilization(Pseudocode pseudocode, InstructionsMergeHandler<D> instructionsMergeHandler, D initialDataValue, boolean straightDirection) {
|
private <D> Map<Instruction, D> traverseInstructionGraphUntilFactsStabilization(
|
||||||
|
Pseudocode pseudocode,
|
||||||
|
InstructionsMergeHandler<D> instructionsMergeHandler,
|
||||||
|
D initialDataValue,
|
||||||
|
D initialDataValueForEnterInstruction,
|
||||||
|
boolean straightDirection) {
|
||||||
Map<Instruction, D> dataMap = Maps.newHashMap();
|
Map<Instruction, D> dataMap = Maps.newHashMap();
|
||||||
initializeDataMap(dataMap, pseudocode, initialDataValue);
|
initializeDataMap(dataMap, pseudocode, initialDataValue);
|
||||||
|
dataMap.put(pseudocode.getEnterInstruction(), initialDataValueForEnterInstruction);
|
||||||
|
|
||||||
boolean[] changed = new boolean[1];
|
boolean[] changed = new boolean[1];
|
||||||
changed[0] = true;
|
changed[0] = true;
|
||||||
while (changed[0]) {
|
while (changed[0]) {
|
||||||
changed[0] = false;
|
changed[0] = false;
|
||||||
traverseSubGraph(pseudocode, instructionsMergeHandler, Collections.<Instruction>emptyList(), straightDirection, dataMap, changed);
|
traverseSubGraph(pseudocode, instructionsMergeHandler, Collections.<Instruction>emptyList(), straightDirection, dataMap, changed, false);
|
||||||
}
|
}
|
||||||
return dataMap;
|
return dataMap;
|
||||||
}
|
}
|
||||||
|
|
||||||
private <D> void initializeDataMap(Map<Instruction, D> dataMap, Pseudocode pseudocode, D initialDataValue) {
|
private <D> void initializeDataMap(
|
||||||
|
Map<Instruction, D> dataMap,
|
||||||
|
Pseudocode pseudocode,
|
||||||
|
D initialDataValue) {
|
||||||
List<Instruction> instructions = pseudocode.getInstructions();
|
List<Instruction> instructions = pseudocode.getInstructions();
|
||||||
for (Instruction instruction : instructions) {
|
for (Instruction instruction : instructions) {
|
||||||
dataMap.put(instruction, initialDataValue);
|
dataMap.put(instruction, initialDataValue);
|
||||||
@@ -271,10 +288,19 @@ public class JetFlowInformationProvider {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private <D> void traverseSubGraph(Pseudocode pseudocode, InstructionsMergeHandler<D> instructionsMergeHandler, Collection<Instruction> previousSubGraphInstructions, boolean straightDirection, Map<Instruction, D> dataMap, boolean[] changed) {
|
private <D> void traverseSubGraph(
|
||||||
|
Pseudocode pseudocode,
|
||||||
|
InstructionsMergeHandler<D> instructionsMergeHandler,
|
||||||
|
Collection<Instruction> previousSubGraphInstructions,
|
||||||
|
boolean straightDirection,
|
||||||
|
Map<Instruction, D> dataMap,
|
||||||
|
boolean[] changed,
|
||||||
|
boolean isLocal) {
|
||||||
List<Instruction> instructions = pseudocode.getInstructions();
|
List<Instruction> instructions = pseudocode.getInstructions();
|
||||||
SubroutineEnterInstruction enterInstruction = pseudocode.getEnterInstruction();
|
SubroutineEnterInstruction enterInstruction = pseudocode.getEnterInstruction();
|
||||||
for (Instruction instruction : instructions) {
|
for (Instruction instruction : instructions) {
|
||||||
|
if (!isLocal && instruction instanceof SubroutineEnterInstruction) continue;
|
||||||
|
|
||||||
Collection<Instruction> allPreviousInstructions;
|
Collection<Instruction> allPreviousInstructions;
|
||||||
Collection<Instruction> previousInstructions = straightDirection
|
Collection<Instruction> previousInstructions = straightDirection
|
||||||
? instruction.getPreviousInstructions()
|
? instruction.getPreviousInstructions()
|
||||||
@@ -290,7 +316,7 @@ public class JetFlowInformationProvider {
|
|||||||
|
|
||||||
if (instruction instanceof LocalDeclarationInstruction) {
|
if (instruction instanceof LocalDeclarationInstruction) {
|
||||||
Pseudocode subroutinePseudocode = ((LocalDeclarationInstruction) instruction).getBody();
|
Pseudocode subroutinePseudocode = ((LocalDeclarationInstruction) instruction).getBody();
|
||||||
traverseSubGraph(subroutinePseudocode, instructionsMergeHandler, previousInstructions, straightDirection, dataMap, changed);
|
traverseSubGraph(subroutinePseudocode, instructionsMergeHandler, previousInstructions, straightDirection, dataMap, changed, true);
|
||||||
}
|
}
|
||||||
D previousDataValue = dataMap.get(instruction);
|
D previousDataValue = dataMap.get(instruction);
|
||||||
|
|
||||||
@@ -299,7 +325,7 @@ public class JetFlowInformationProvider {
|
|||||||
for (Instruction previousInstruction : allPreviousInstructions) {
|
for (Instruction previousInstruction : allPreviousInstructions) {
|
||||||
incomingEdgesData.add(dataMap.get(previousInstruction));
|
incomingEdgesData.add(dataMap.get(previousInstruction));
|
||||||
}
|
}
|
||||||
D mergedData = instructionsMergeHandler.merge(instruction, previousDataValue, incomingEdgesData);
|
D mergedData = instructionsMergeHandler.merge(instruction, incomingEdgesData);
|
||||||
if (!mergedData.equals(previousDataValue)) {
|
if (!mergedData.equals(previousDataValue)) {
|
||||||
changed[0] = true;
|
changed[0] = true;
|
||||||
dataMap.put(instruction, mergedData);
|
dataMap.put(instruction, mergedData);
|
||||||
@@ -312,80 +338,203 @@ public class JetFlowInformationProvider {
|
|||||||
assert pseudocode != null;
|
assert pseudocode != null;
|
||||||
|
|
||||||
Collection<Instruction> instructions = pseudocode.getInstructions();
|
Collection<Instruction> instructions = pseudocode.getInstructions();
|
||||||
InstructionsMergeHandler<Set<LocalVariableDescriptor>> instructionsMergeHandler = new InstructionsMergeHandler<Set<LocalVariableDescriptor>>() {
|
InstructionsMergeHandler<Map<LocalVariableDescriptor, InitializationPoints>> instructionsMergeHandler = new InstructionsMergeHandler<Map<LocalVariableDescriptor, InitializationPoints>>() {
|
||||||
@Override
|
@Override
|
||||||
public Set<LocalVariableDescriptor> merge(Instruction instruction, Set<LocalVariableDescriptor> previousDataValue, Collection<Set<LocalVariableDescriptor>> incomingEdgesData) {
|
public Map<LocalVariableDescriptor, InitializationPoints> merge(
|
||||||
Set<LocalVariableDescriptor> initializedVariables = Sets.newHashSet();
|
Instruction instruction,
|
||||||
initializedVariables.addAll(previousDataValue);
|
Collection<Map<LocalVariableDescriptor, InitializationPoints>> incomingEdgesData) {
|
||||||
for (Set<LocalVariableDescriptor> edgeDataValue : incomingEdgesData) {
|
|
||||||
initializedVariables.addAll(edgeDataValue);
|
Set<LocalVariableDescriptor> variablesInScope = Sets.newHashSet();
|
||||||
|
for (Map<LocalVariableDescriptor, InitializationPoints> edgePointsMap : incomingEdgesData) {
|
||||||
|
variablesInScope.addAll(edgePointsMap.keySet());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (instruction instanceof WriteValueInstruction) {
|
Map<LocalVariableDescriptor, InitializationPoints> pointsMap = Maps.newHashMap();
|
||||||
DeclarationDescriptor descriptor = null;
|
for (LocalVariableDescriptor variable : variablesInScope) {
|
||||||
JetElement lValue = ((WriteValueInstruction) instruction).getlValue();
|
Set<InitializationPoints> edgesDataForVariable = Sets.newHashSet();
|
||||||
if (lValue instanceof JetProperty) {
|
for (Map<LocalVariableDescriptor, InitializationPoints> edgePointsMap : incomingEdgesData) {
|
||||||
descriptor = trace.get(BindingContext.DECLARATION_TO_DESCRIPTOR, lValue);
|
InitializationPoints points = edgePointsMap.get(variable);
|
||||||
}
|
if (points != null) {
|
||||||
else if (lValue instanceof JetSimpleNameExpression) {
|
edgesDataForVariable.add(points);
|
||||||
descriptor = trace.get(BindingContext.REFERENCE_TARGET, (JetSimpleNameExpression) lValue);
|
}
|
||||||
}
|
|
||||||
else if (lValue instanceof JetParameter) {
|
|
||||||
descriptor = trace.get(BindingContext.DECLARATION_TO_DESCRIPTOR, lValue);
|
|
||||||
}
|
|
||||||
if (descriptor instanceof LocalVariableDescriptor) {
|
|
||||||
initializedVariables.add((LocalVariableDescriptor) descriptor);
|
|
||||||
}
|
}
|
||||||
|
pointsMap.put(variable, new InitializationPoints(edgesDataForVariable));
|
||||||
}
|
}
|
||||||
return initializedVariables;
|
|
||||||
|
if (instruction instanceof WriteValueInstruction) {
|
||||||
|
LocalVariableDescriptor variableDescriptor = extractVariableDescriptorIfAny(instruction);
|
||||||
|
// DeclarationDescriptor descriptor = null;
|
||||||
|
// JetElement lValue = ((WriteValueInstruction) instruction).getlValue();
|
||||||
|
// if (lValue instanceof JetProperty || lValue instanceof JetParameter) {
|
||||||
|
// descriptor = trace.get(BindingContext.DECLARATION_TO_DESCRIPTOR, lValue);
|
||||||
|
// }
|
||||||
|
// else if (lValue instanceof JetSimpleNameExpression) {
|
||||||
|
// descriptor = trace.get(BindingContext.REFERENCE_TARGET, (JetSimpleNameExpression) lValue);
|
||||||
|
// }
|
||||||
|
// if (descriptor instanceof LocalVariableDescriptor) {
|
||||||
|
// LocalVariableDescriptor variableDescriptor = (LocalVariableDescriptor) descriptor;
|
||||||
|
InitializationPoints initializationAtThisPoint = new InitializationPoints(((WriteValueInstruction) instruction).getElement());
|
||||||
|
pointsMap.put(variableDescriptor, initializationAtThisPoint);
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
|
||||||
|
return pointsMap;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
Map<Instruction, Set<LocalVariableDescriptor>> dataMap = traverseInstructionGraphUntilFactsStabilization(pseudocode, instructionsMergeHandler, Collections.<LocalVariableDescriptor>emptySet(), true);
|
|
||||||
InstructionDataAnalyzer instructionDataAnalyzer = new InstructionDataAnalyzer<Set<LocalVariableDescriptor>>() {
|
Set<LocalVariableDescriptor> localVariables = collectAllLocalVariables(pseudocode);
|
||||||
|
Map<LocalVariableDescriptor, InitializationPoints> initialMapForStartInstruction = Maps.newHashMap();
|
||||||
|
InitializationPoints initialPoints = new InitializationPoints();
|
||||||
|
for (LocalVariableDescriptor variable : localVariables) {
|
||||||
|
initialMapForStartInstruction.put(variable, initialPoints);
|
||||||
|
}
|
||||||
|
Map<Instruction, Map<LocalVariableDescriptor, InitializationPoints>> dataMap =
|
||||||
|
traverseInstructionGraphUntilFactsStabilization(pseudocode, instructionsMergeHandler, Collections.<LocalVariableDescriptor, InitializationPoints>emptyMap(), initialMapForStartInstruction, true);
|
||||||
|
|
||||||
|
InstructionDataAnalyzer<Map<LocalVariableDescriptor, InitializationPoints>> instructionDataAnalyzer = new InstructionDataAnalyzer<Map<LocalVariableDescriptor, InitializationPoints>>() {
|
||||||
@Override
|
@Override
|
||||||
public void analyze(Instruction instruction, Map<Instruction, Set<LocalVariableDescriptor>> dataMap) {
|
public void analyze(Instruction instruction, Map<Instruction, Map<LocalVariableDescriptor, InitializationPoints>> dataMap) {
|
||||||
Set<LocalVariableDescriptor> initializedVariables = dataMap.get(instruction);
|
Map<LocalVariableDescriptor, InitializationPoints> variablesData = dataMap.get(instruction);
|
||||||
if (instruction instanceof ReadValueInstruction) {
|
if (instruction instanceof ReadValueInstruction) {
|
||||||
|
LocalVariableDescriptor variableDescriptor = extractVariableDescriptorIfAny(instruction);
|
||||||
JetElement element = ((ReadValueInstruction) instruction).getElement();
|
JetElement element = ((ReadValueInstruction) instruction).getElement();
|
||||||
if (element instanceof JetSimpleNameExpression) {
|
if (element instanceof JetSimpleNameExpression && variableDescriptor != null) {
|
||||||
DeclarationDescriptor descriptor = trace.get(BindingContext.REFERENCE_TARGET, (JetSimpleNameExpression) element);
|
// DeclarationDescriptor descriptor = trace.get(BindingContext.REFERENCE_TARGET, (JetSimpleNameExpression) element);
|
||||||
if (descriptor instanceof LocalVariableDescriptor) {
|
// if (descriptor instanceof LocalVariableDescriptor) {
|
||||||
if (!initializedVariables.contains(descriptor)) {
|
InitializationPoints initializationPoints = variablesData.get(variableDescriptor);
|
||||||
trace.report(Errors.UNINITIALIZED_VARIABLE.on((JetSimpleNameExpression) element, descriptor));
|
assert initializationPoints != null;
|
||||||
}
|
if (initializationPoints.canBeUninitialized) {
|
||||||
|
trace.report(Errors.UNINITIALIZED_VARIABLE.on((JetSimpleNameExpression) element, variableDescriptor));
|
||||||
}
|
}
|
||||||
|
// }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (instruction instanceof WriteValueInstruction) {
|
else if (instruction instanceof WriteValueInstruction) {
|
||||||
JetElement element = ((WriteValueInstruction) instruction).getElement();
|
JetElement element = ((WriteValueInstruction) instruction).getlValue();
|
||||||
if (element instanceof JetSimpleNameExpression) {
|
LocalVariableDescriptor variableDescriptor = extractVariableDescriptorIfAny(instruction);
|
||||||
DeclarationDescriptor descriptor = trace.get(BindingContext.REFERENCE_TARGET, (JetSimpleNameExpression) element);
|
if (element instanceof JetSimpleNameExpression && variableDescriptor != null) {
|
||||||
if (descriptor instanceof LocalVariableDescriptor) {
|
// DeclarationDescriptor descriptor = trace.get(BindingContext.REFERENCE_TARGET, (JetSimpleNameExpression) element);
|
||||||
if (initializedVariables.contains(descriptor) && ((LocalVariableDescriptor) descriptor).isVar()) {
|
// if (descriptor instanceof LocalVariableDescriptor) {
|
||||||
trace.report(Errors.VAL_REASSIGNMENT.on((JetSimpleNameExpression) element, descriptor));
|
InitializationPoints initializationPoints = variablesData.get(variableDescriptor);
|
||||||
}
|
assert initializationPoints != null;
|
||||||
|
if (initializationPoints.hasPossibleInitializers() && !variableDescriptor.isVar()) {
|
||||||
|
trace.report(Errors.VAL_REASSIGNMENT.on((JetSimpleNameExpression) element, variableDescriptor));
|
||||||
}
|
}
|
||||||
|
// }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
traverseInstructionGraphAndReportErrors(instructions, dataMap, instructionDataAnalyzer);
|
traverseAndAnalyzeInstructionGraph(instructions, dataMap, instructionDataAnalyzer);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void traverseInstructionGraphAndReportErrors(Collection<Instruction> instructions, Map<Instruction, Set<LocalVariableDescriptor>> dataMap, InstructionDataAnalyzer<Set<LocalVariableDescriptor>> instructionDataAnalyzer) {
|
@Nullable
|
||||||
|
private LocalVariableDescriptor extractVariableDescriptorIfAny(Instruction instruction) {
|
||||||
|
LocalVariableDescriptor variableDescriptor = null;
|
||||||
|
if (instruction instanceof ReadValueInstruction) {
|
||||||
|
JetElement element = ((ReadValueInstruction) instruction).getElement();
|
||||||
|
if (element instanceof JetSimpleNameExpression) {
|
||||||
|
DeclarationDescriptor descriptor = trace.get(BindingContext.REFERENCE_TARGET, (JetSimpleNameExpression) element);
|
||||||
|
if (descriptor instanceof LocalVariableDescriptor) {
|
||||||
|
variableDescriptor = (LocalVariableDescriptor) descriptor;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (instruction instanceof WriteValueInstruction) {
|
||||||
|
DeclarationDescriptor descriptor = null;
|
||||||
|
JetElement lValue = ((WriteValueInstruction) instruction).getlValue();
|
||||||
|
if (lValue instanceof JetProperty || lValue instanceof JetParameter) {
|
||||||
|
descriptor = trace.get(BindingContext.DECLARATION_TO_DESCRIPTOR, lValue);
|
||||||
|
}
|
||||||
|
else if (lValue instanceof JetSimpleNameExpression) {
|
||||||
|
descriptor = trace.get(BindingContext.REFERENCE_TARGET, (JetSimpleNameExpression) lValue);
|
||||||
|
}
|
||||||
|
if (descriptor instanceof LocalVariableDescriptor) {
|
||||||
|
variableDescriptor = (LocalVariableDescriptor) descriptor;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return variableDescriptor;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Set<LocalVariableDescriptor> collectAllLocalVariables(Pseudocode pseudocode) {
|
||||||
|
final Set<LocalVariableDescriptor> localVariables = Sets.newHashSet();
|
||||||
|
InstructionDataAnalyzer<Void> analyzer = new InstructionDataAnalyzer<Void>() {
|
||||||
|
@Override
|
||||||
|
public void analyze(Instruction instruction, Map<Instruction, Void> dataMap) {
|
||||||
|
LocalVariableDescriptor variableDescriptor = extractVariableDescriptorIfAny(instruction);
|
||||||
|
if (variableDescriptor != null) {
|
||||||
|
localVariables.add(variableDescriptor);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
traverseAndAnalyzeInstructionGraph(pseudocode.getInstructions(), Collections.<Instruction, Void>emptyMap(), analyzer);
|
||||||
|
return localVariables;
|
||||||
|
}
|
||||||
|
|
||||||
|
private <D> void traverseAndAnalyzeInstructionGraph(Collection<Instruction> instructions, Map<Instruction, D> dataMap, InstructionDataAnalyzer<D> instructionDataAnalyzer) {
|
||||||
for (Instruction instruction : instructions) {
|
for (Instruction instruction : instructions) {
|
||||||
if (instruction instanceof LocalDeclarationInstruction) {
|
if (instruction instanceof LocalDeclarationInstruction) {
|
||||||
traverseInstructionGraphAndReportErrors(((LocalDeclarationInstruction) instruction).getBody().getInstructions(), dataMap, instructionDataAnalyzer);
|
traverseAndAnalyzeInstructionGraph(((LocalDeclarationInstruction) instruction).getBody().getInstructions(), dataMap, instructionDataAnalyzer);
|
||||||
}
|
}
|
||||||
instructionDataAnalyzer.analyze(instruction, dataMap);
|
instructionDataAnalyzer.analyze(instruction, dataMap);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
interface InstructionsMergeHandler<D> {
|
interface InstructionsMergeHandler<D> {
|
||||||
D merge(Instruction instruction, D previousDataValue, Collection<D> incomingEdgesData);
|
D merge(Instruction instruction, Collection<D> incomingEdgesData);
|
||||||
}
|
}
|
||||||
|
|
||||||
interface InstructionDataAnalyzer<D> {
|
interface InstructionDataAnalyzer<D> {
|
||||||
void analyze(Instruction instruction, Map<Instruction, D> dataMap);
|
void analyze(Instruction instruction, Map<Instruction, D> dataMap);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
private static class InitializationPoints {
|
||||||
|
private Set<JetElement> possiblePoints = Sets.newHashSet();
|
||||||
|
private boolean canBeUninitialized;
|
||||||
|
|
||||||
|
public InitializationPoints() {
|
||||||
|
canBeUninitialized = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public InitializationPoints(JetElement element) {
|
||||||
|
canBeUninitialized = false;
|
||||||
|
possiblePoints.add(element);
|
||||||
|
}
|
||||||
|
|
||||||
|
public InitializationPoints(Set<InitializationPoints> edgesData) {
|
||||||
|
canBeUninitialized = false;
|
||||||
|
for (InitializationPoints edgeData : edgesData) {
|
||||||
|
if (edgeData.canBeUninitialized) {
|
||||||
|
canBeUninitialized = true;
|
||||||
|
}
|
||||||
|
possiblePoints.addAll(edgeData.possiblePoints);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean hasPossibleInitializers() {
|
||||||
|
return !possiblePoints.isEmpty();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object o) {
|
||||||
|
if (this == o) return true;
|
||||||
|
if (!(o instanceof InitializationPoints)) return false;
|
||||||
|
|
||||||
|
InitializationPoints that = (InitializationPoints) o;
|
||||||
|
|
||||||
|
if (canBeUninitialized != that.canBeUninitialized) return false;
|
||||||
|
if (possiblePoints != null ? !possiblePoints.equals(that.possiblePoints) : that.possiblePoints != null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
int result = possiblePoints != null ? possiblePoints.hashCode() : 0;
|
||||||
|
result = 31 * result + (canBeUninitialized ? 1 : 0);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -12,6 +12,7 @@ import java.util.LinkedHashSet;
|
|||||||
public abstract class InstructionImpl implements Instruction {
|
public abstract class InstructionImpl implements Instruction {
|
||||||
private Pseudocode owner;
|
private Pseudocode owner;
|
||||||
private final Collection<Instruction> previousInstructions = new LinkedHashSet<Instruction>();
|
private final Collection<Instruction> previousInstructions = new LinkedHashSet<Instruction>();
|
||||||
|
protected boolean isDead = false;
|
||||||
|
|
||||||
protected InstructionImpl() {
|
protected InstructionImpl() {
|
||||||
}
|
}
|
||||||
@@ -42,4 +43,11 @@ public abstract class InstructionImpl implements Instruction {
|
|||||||
return target;
|
return target;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void die() {
|
||||||
|
isDead = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isDead() {
|
||||||
|
return isDead;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
package org.jetbrains.jet.lang.cfg.pseudocode;
|
package org.jetbrains.jet.lang.cfg.pseudocode;
|
||||||
|
|
||||||
|
import com.google.common.collect.Lists;
|
||||||
|
import com.google.common.collect.Sets;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
import org.jetbrains.jet.lang.cfg.Label;
|
import org.jetbrains.jet.lang.cfg.Label;
|
||||||
@@ -77,6 +79,17 @@ public class Pseudocode {
|
|||||||
public List<Instruction> getInstructions() {
|
public List<Instruction> getInstructions() {
|
||||||
return instructions;
|
return instructions;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
public List<Instruction> getDeadInstructions() {
|
||||||
|
List<Instruction> deadInstructions = Lists.newArrayList();
|
||||||
|
for (Instruction instruction : instructions) {
|
||||||
|
if (((InstructionImpl)instruction).isDead()) {
|
||||||
|
deadInstructions.add(instruction);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return deadInstructions;
|
||||||
|
}
|
||||||
|
|
||||||
@Deprecated //for tests only
|
@Deprecated //for tests only
|
||||||
public List<PseudocodeLabel> getLabels() {
|
public List<PseudocodeLabel> getLabels() {
|
||||||
@@ -166,6 +179,26 @@ public class Pseudocode {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
removeDeadInstructions();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void removeDeadInstructions() {
|
||||||
|
boolean hasRemovedInstruction = true;
|
||||||
|
Collection<Instruction> processedInstructions = Sets.newHashSet();
|
||||||
|
while (hasRemovedInstruction) {
|
||||||
|
hasRemovedInstruction = false;
|
||||||
|
for (Instruction instruction : instructions) {
|
||||||
|
if (!(instruction instanceof SubroutineEnterInstruction || instruction instanceof SubroutineExitInstruction) &&
|
||||||
|
instruction.getPreviousInstructions().isEmpty() && !processedInstructions.contains(instruction)) {
|
||||||
|
hasRemovedInstruction = true;
|
||||||
|
for (Instruction nextInstruction : instruction.getNextInstructions()) {
|
||||||
|
nextInstruction.getPreviousInstructions().remove(instruction);
|
||||||
|
}
|
||||||
|
((InstructionImpl)instruction).die();
|
||||||
|
processedInstructions.add(instruction);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
|
|||||||
@@ -63,4 +63,22 @@ public class DiagnosticUtils {
|
|||||||
return "' at offset " + offset + " (line unknown)" + pathSuffix;
|
return "' at offset " + offset + " (line unknown)" + pathSuffix;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static String formatPosition(DiagnosticWithTextRange diagnosticWithTextRange) {
|
||||||
|
PsiFile file = diagnosticWithTextRange.getPsiFile();
|
||||||
|
Document document = file.getViewProvider().getDocument();
|
||||||
|
String position;
|
||||||
|
int offset = diagnosticWithTextRange.getTextRange().getStartOffset();
|
||||||
|
if (document != null) {
|
||||||
|
int lineNumber = document.getLineNumber(offset);
|
||||||
|
int lineStartOffset = document.getLineStartOffset(lineNumber);
|
||||||
|
int column = offset - lineStartOffset;
|
||||||
|
|
||||||
|
position = "(" + (lineNumber + 1) + "," + column + ")";
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
position = "(offset: " + offset + " line unknown)";
|
||||||
|
}
|
||||||
|
return position;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -142,7 +142,7 @@ public interface Errors {
|
|||||||
};
|
};
|
||||||
PsiElementOnlyDiagnosticFactory3<JetModifierListOwner, CallableMemberDescriptor, CallableMemberDescriptor, DeclarationDescriptor> VIRTUAL_MEMBER_HIDDEN = PsiElementOnlyDiagnosticFactory3.create(ERROR, "''{0}'' hides ''{1}'' in class {2} and needs 'override' modifier", DescriptorRenderer.TEXT);
|
PsiElementOnlyDiagnosticFactory3<JetModifierListOwner, CallableMemberDescriptor, CallableMemberDescriptor, DeclarationDescriptor> VIRTUAL_MEMBER_HIDDEN = PsiElementOnlyDiagnosticFactory3.create(ERROR, "''{0}'' hides ''{1}'' in class {2} and needs 'override' modifier", DescriptorRenderer.TEXT);
|
||||||
|
|
||||||
PsiElementOnlyDiagnosticFactory1<JetSimpleNameExpression, DeclarationDescriptor> UNINITIALIZED_VARIABLE = PsiElementOnlyDiagnosticFactory1.create(ERROR, "Variable ''{0}'' must be uninitialized", NAME);
|
PsiElementOnlyDiagnosticFactory1<JetSimpleNameExpression, DeclarationDescriptor> UNINITIALIZED_VARIABLE = PsiElementOnlyDiagnosticFactory1.create(ERROR, "Variable ''{0}'' must be initialized", NAME);
|
||||||
PsiElementOnlyDiagnosticFactory1<JetSimpleNameExpression, DeclarationDescriptor> VAL_REASSIGNMENT = PsiElementOnlyDiagnosticFactory1.create(ERROR, "Val can not be reassigned", NAME);
|
PsiElementOnlyDiagnosticFactory1<JetSimpleNameExpression, DeclarationDescriptor> VAL_REASSIGNMENT = PsiElementOnlyDiagnosticFactory1.create(ERROR, "Val can not be reassigned", NAME);
|
||||||
|
|
||||||
SimpleDiagnosticFactory UNREACHABLE_CODE = SimpleDiagnosticFactory.create(ERROR, "Unreachable code");
|
SimpleDiagnosticFactory UNREACHABLE_CODE = SimpleDiagnosticFactory.create(ERROR, "Unreachable code");
|
||||||
|
|||||||
@@ -1429,7 +1429,7 @@ public class JetParsing extends AbstractJetParsing {
|
|||||||
|
|
||||||
/*
|
/*
|
||||||
* functionType
|
* functionType
|
||||||
* : "fun" (type ".")? functionTypeContents
|
* : "fun" (type ".")? "(" (parameter | modifiers type){","} ")" (":" type)? // Unit by default
|
||||||
* ;
|
* ;
|
||||||
*/
|
*/
|
||||||
private void parseFunctionType() {
|
private void parseFunctionType() {
|
||||||
@@ -1446,22 +1446,15 @@ public class JetParsing extends AbstractJetParsing {
|
|||||||
advance(); // DOT
|
advance(); // DOT
|
||||||
}
|
}
|
||||||
|
|
||||||
parseFunctionTypeContents();
|
|
||||||
|
|
||||||
functionType.done(FUNCTION_TYPE);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* functionTypeContents
|
|
||||||
* : "(" (parameter | type){","} ")" ":" type
|
|
||||||
* ;
|
|
||||||
*/
|
|
||||||
private void parseFunctionTypeContents() {
|
|
||||||
parseValueParameterList(true, TokenSet.EMPTY);
|
parseValueParameterList(true, TokenSet.EMPTY);
|
||||||
|
|
||||||
expect(COLON, "Expecting ':' followed by a return type", TYPE_REF_FIRST);
|
if (at(COLON)) {
|
||||||
|
advance(); // COLON // expect(COLON, "Expecting ':' followed by a return type", TYPE_REF_FIRST);
|
||||||
|
|
||||||
parseTypeRef();
|
parseTypeRef();
|
||||||
|
}
|
||||||
|
|
||||||
|
functionType.done(FUNCTION_TYPE);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|||||||
@@ -70,6 +70,11 @@ public class DelegatingBindingTrace implements BindingTrace {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void clear() {
|
||||||
|
map.clear();
|
||||||
|
diagnostics.clear();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void report(@NotNull Diagnostic diagnostic) {
|
public void report(@NotNull Diagnostic diagnostic) {
|
||||||
diagnostics.add(diagnostic);
|
diagnostics.add(diagnostic);
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ public class TemporaryBindingTrace extends DelegatingBindingTrace {
|
|||||||
|
|
||||||
private final BindingTrace trace;
|
private final BindingTrace trace;
|
||||||
|
|
||||||
|
|
||||||
private TemporaryBindingTrace(BindingTrace trace) {
|
private TemporaryBindingTrace(BindingTrace trace) {
|
||||||
super(trace.getBindingContext());
|
super(trace.getBindingContext());
|
||||||
this.trace = trace;
|
this.trace = trace;
|
||||||
@@ -18,5 +19,6 @@ public class TemporaryBindingTrace extends DelegatingBindingTrace {
|
|||||||
|
|
||||||
public void commit() {
|
public void commit() {
|
||||||
addAllMyDataTo(trace);
|
addAllMyDataTo(trace);
|
||||||
|
clear();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -105,12 +105,9 @@ public class TypeResolver {
|
|||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (actualArgumentCount != expectedArgumentCount) {
|
if (actualArgumentCount != expectedArgumentCount) {
|
||||||
// String errorMessage = (expectedArgumentCount == 0 ? "No" : expectedArgumentCount) + " type arguments expected";
|
|
||||||
if (actualArgumentCount == 0) {
|
if (actualArgumentCount == 0) {
|
||||||
// trace.getErrorHandler().genericError(type.getNode(), errorMessage);
|
|
||||||
trace.report(WRONG_NUMBER_OF_TYPE_ARGUMENTS.on(type, expectedArgumentCount));
|
trace.report(WRONG_NUMBER_OF_TYPE_ARGUMENTS.on(type, expectedArgumentCount));
|
||||||
} else {
|
} else {
|
||||||
// trace.getErrorHandler().genericError(type.getTypeArgumentList().getNode(), errorMessage);
|
|
||||||
trace.report(WRONG_NUMBER_OF_TYPE_ARGUMENTS.on(type.getTypeArgumentList(), expectedArgumentCount));
|
trace.report(WRONG_NUMBER_OF_TYPE_ARGUMENTS.on(type.getTypeArgumentList(), expectedArgumentCount));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@@ -160,10 +157,14 @@ public class TypeResolver {
|
|||||||
}
|
}
|
||||||
|
|
||||||
JetTypeReference returnTypeRef = type.getReturnTypeRef();
|
JetTypeReference returnTypeRef = type.getReturnTypeRef();
|
||||||
|
JetType returnType;
|
||||||
if (returnTypeRef != null) {
|
if (returnTypeRef != null) {
|
||||||
JetType returnType = resolveType(scope, returnTypeRef);
|
returnType = resolveType(scope, returnTypeRef);
|
||||||
result[0] = JetStandardClasses.getFunctionType(annotations, receiverType, parameterTypes, returnType);
|
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
returnType = JetStandardClasses.getUnitType();
|
||||||
|
}
|
||||||
|
result[0] = JetStandardClasses.getFunctionType(annotations, receiverType, parameterTypes, returnType);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -206,8 +206,6 @@ public class CallResolver {
|
|||||||
@NotNull JetType expectedType,
|
@NotNull JetType expectedType,
|
||||||
@NotNull final List<ResolutionTask<D>> prioritizedTasks, // high to low priority
|
@NotNull final List<ResolutionTask<D>> prioritizedTasks, // high to low priority
|
||||||
@NotNull final JetReferenceExpression reference) {
|
@NotNull final JetReferenceExpression reference) {
|
||||||
TemporaryBindingTrace traceForFirstNonemptyCandidateSet = null;
|
|
||||||
OverloadResolutionResults<D> resultsForFirstNonemptyCandidateSet = null;
|
|
||||||
TracingStrategy tracing = new TracingStrategy() {
|
TracingStrategy tracing = new TracingStrategy() {
|
||||||
@Override
|
@Override
|
||||||
public <D extends CallableDescriptor> void bindReference(@NotNull BindingTrace trace, @NotNull ResolvedCallImpl<D> resolvedCall) {
|
public <D extends CallableDescriptor> void bindReference(@NotNull BindingTrace trace, @NotNull ResolvedCallImpl<D> resolvedCall) {
|
||||||
@@ -272,12 +270,12 @@ public class CallResolver {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public <D extends CallableDescriptor> void ambiguity(@NotNull BindingTrace trace, @NotNull Set<ResolvedCallImpl<D>> descriptors) {
|
public <D extends CallableDescriptor> void ambiguity(@NotNull BindingTrace trace, @NotNull Collection<ResolvedCallImpl<D>> descriptors) {
|
||||||
trace.report(OVERLOAD_RESOLUTION_AMBIGUITY.on(call.getCallNode(), descriptors));
|
trace.report(OVERLOAD_RESOLUTION_AMBIGUITY.on(call.getCallNode(), descriptors));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public <D extends CallableDescriptor> void noneApplicable(@NotNull BindingTrace trace, @NotNull Set<ResolvedCallImpl<D>> descriptors) {
|
public <D extends CallableDescriptor> void noneApplicable(@NotNull BindingTrace trace, @NotNull Collection<ResolvedCallImpl<D>> descriptors) {
|
||||||
trace.report(NONE_APPLICABLE.on(reference, descriptors));
|
trace.report(NONE_APPLICABLE.on(reference, descriptors));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -323,6 +321,9 @@ public class CallResolver {
|
|||||||
trace.report(UNNECESSARY_SAFE_CALL.on((JetElement) callOperationNode.getTreeParent().getPsi(), callOperationNode, type));
|
trace.report(UNNECESSARY_SAFE_CALL.on((JetElement) callOperationNode.getTreeParent().getPsi(), callOperationNode, type));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
TemporaryBindingTrace traceForFirstNonemptyCandidateSet = null;
|
||||||
|
OverloadResolutionResults<D> resultsForFirstNonemptyCandidateSet = null;
|
||||||
for (ResolutionTask<D> task : prioritizedTasks) {
|
for (ResolutionTask<D> task : prioritizedTasks) {
|
||||||
TemporaryBindingTrace temporaryTrace = TemporaryBindingTrace.create(trace);
|
TemporaryBindingTrace temporaryTrace = TemporaryBindingTrace.create(trace);
|
||||||
OverloadResolutionResults<D> results = performResolution(temporaryTrace, scope, expectedType, task, tracing);
|
OverloadResolutionResults<D> results = performResolution(temporaryTrace, scope, expectedType, task, tracing);
|
||||||
@@ -479,6 +480,14 @@ public class CallResolver {
|
|||||||
|
|
||||||
task.performAdvancedChecks(candidate, temporaryTrace, tracing);
|
task.performAdvancedChecks(candidate, temporaryTrace, tracing);
|
||||||
|
|
||||||
|
// 'super' cannot be passed as an argument, for receiver arguments expression typer does not track this
|
||||||
|
// See TaskPrioritizer for more
|
||||||
|
JetSuperExpression superExpression = TaskPrioritizer.getReceiverSuper(candidateCall.getReceiverArgument());
|
||||||
|
if (superExpression != null) {
|
||||||
|
temporaryTrace.report(SUPER_IS_NOT_AN_EXPRESSION.on(superExpression, superExpression.getText()));
|
||||||
|
candidateCall.setStatus(OTHER_ERROR);
|
||||||
|
}
|
||||||
|
|
||||||
recordAutoCastIfNecessary(candidateCall.getReceiverArgument(), candidateCall.getTrace());
|
recordAutoCastIfNecessary(candidateCall.getReceiverArgument(), candidateCall.getTrace());
|
||||||
recordAutoCastIfNecessary(candidateCall.getThisObject(), candidateCall.getTrace());
|
recordAutoCastIfNecessary(candidateCall.getThisObject(), candidateCall.getTrace());
|
||||||
}
|
}
|
||||||
@@ -540,21 +549,6 @@ public class CallResolver {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// private <D extends CallableDescriptor> Function<ValueParameterDescriptor, ValueParameterDescriptor> createMapFunction(D substitutedFunctionDescriptor) {
|
|
||||||
// assert substitutedFunctionDescriptor != null;
|
|
||||||
// final Map<ValueParameterDescriptor, ValueParameterDescriptor> parameterMap = Maps.newHashMap();
|
|
||||||
// for (ValueParameterDescriptor valueParameterDescriptor : substitutedFunctionDescriptor.getValueParameters()) {
|
|
||||||
// parameterMap.put(valueParameterDescriptor.getOriginal(), valueParameterDescriptor);
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// return new Function<ValueParameterDescriptor, ValueParameterDescriptor>() {
|
|
||||||
// @Override
|
|
||||||
// public ValueParameterDescriptor apply(ValueParameterDescriptor input) {
|
|
||||||
// return parameterMap.get(input.getOriginal());
|
|
||||||
// }
|
|
||||||
// };
|
|
||||||
// }
|
|
||||||
|
|
||||||
private <D extends CallableDescriptor> void replaceValueParametersWithSubstitutedOnes(ResolvedCallImpl<D> candidateCall, @NotNull D substitutedDescriptor) {
|
private <D extends CallableDescriptor> void replaceValueParametersWithSubstitutedOnes(ResolvedCallImpl<D> candidateCall, @NotNull D substitutedDescriptor) {
|
||||||
Map<ValueParameterDescriptor, ValueParameterDescriptor> parameterMap = Maps.newHashMap();
|
Map<ValueParameterDescriptor, ValueParameterDescriptor> parameterMap = Maps.newHashMap();
|
||||||
for (ValueParameterDescriptor valueParameterDescriptor : substitutedDescriptor.getValueParameters()) {
|
for (ValueParameterDescriptor valueParameterDescriptor : substitutedDescriptor.getValueParameters()) {
|
||||||
@@ -656,30 +650,47 @@ public class CallResolver {
|
|||||||
Set<ResolvedCallImpl<D>> successfulCandidates,
|
Set<ResolvedCallImpl<D>> successfulCandidates,
|
||||||
Set<ResolvedCallImpl<D>> failedCandidates) {
|
Set<ResolvedCallImpl<D>> failedCandidates) {
|
||||||
// TODO : maybe it's better to filter overrides out first, and only then look for the maximally specific
|
// TODO : maybe it's better to filter overrides out first, and only then look for the maximally specific
|
||||||
|
|
||||||
if (successfulCandidates.size() > 0) {
|
if (successfulCandidates.size() > 0) {
|
||||||
return chooseAndReportMaximallySpecific(trace, tracing, successfulCandidates);
|
OverloadResolutionResults<D> results = chooseAndReportMaximallySpecific(successfulCandidates);
|
||||||
|
if (results.isAmbiguity()) {
|
||||||
|
// This check is needed for the following case:
|
||||||
|
// x.foo(unresolved) -- if there are multiple foo's, we'd report an ambiguity, and it does not make sense here
|
||||||
|
if (allClean(results.getResults())) {
|
||||||
|
tracing.ambiguity(trace, results.getResults());
|
||||||
|
}
|
||||||
|
tracing.recordAmbiguity(trace, results.getResults());
|
||||||
|
}
|
||||||
|
return results;
|
||||||
}
|
}
|
||||||
else if (!failedCandidates.isEmpty()) {
|
else if (!failedCandidates.isEmpty()) {
|
||||||
if (failedCandidates.size() != 1) {
|
if (failedCandidates.size() != 1) {
|
||||||
Set<ResolvedCallImpl<D>> weakErrors = Sets.newLinkedHashSet();
|
// This is needed when there are several overloads some of which are OK but for nullability of the receiver,
|
||||||
for (ResolvedCallImpl<D> candidate : failedCandidates) {
|
// and some are not OK at all. In this case we'd like to say "unsafe call" rather than "none applicable"
|
||||||
if (candidate.getStatus().isWeakError()) {
|
// Used to be: weak errors. Generalized for future extensions
|
||||||
weakErrors.add(candidate);
|
for (EnumSet<ResolutionStatus> severityLevel : SEVERITY_LEVELS) {
|
||||||
}
|
Set<ResolvedCallImpl<D>> thisLevel = Sets.newLinkedHashSet();
|
||||||
}
|
for (ResolvedCallImpl<D> candidate : failedCandidates) {
|
||||||
if (!weakErrors.isEmpty()) {
|
if (severityLevel.contains(candidate.getStatus())) {
|
||||||
OverloadResolutionResults<D> results = chooseAndReportMaximallySpecific(trace, tracing, weakErrors);
|
thisLevel.add(candidate);
|
||||||
if (results.isSuccess()) {
|
}
|
||||||
return OverloadResolutionResults.singleFailedCandidate(results.getResult());
|
|
||||||
}
|
}
|
||||||
|
if (!thisLevel.isEmpty()) {
|
||||||
|
OverloadResolutionResults<D> results = chooseAndReportMaximallySpecific(thisLevel);
|
||||||
|
if (results.isSuccess()) {
|
||||||
|
results.getResult().getTrace().commit();
|
||||||
|
return OverloadResolutionResults.singleFailedCandidate(results.getResult());
|
||||||
|
}
|
||||||
|
|
||||||
return OverloadResolutionResults.manyFailedCandidates(results.getResults());
|
tracing.noneApplicable(trace, results.getResults());
|
||||||
|
tracing.recordAmbiguity(trace, results.getResults());
|
||||||
|
return OverloadResolutionResults.manyFailedCandidates(results.getResults());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
assert false : "Should not be reachable, cause every status must belong to some level";
|
||||||
|
|
||||||
Set<ResolvedCallImpl<D>> noOverrides = OverridingUtil.filterOverrides(failedCandidates, MAP_TO_CANDIDATE);
|
Set<ResolvedCallImpl<D>> noOverrides = OverridingUtil.filterOverrides(failedCandidates, MAP_TO_CANDIDATE);
|
||||||
if (noOverrides.size() != 1) {
|
if (noOverrides.size() != 1) {
|
||||||
// tracing.reportOverallResolutionError(trace, "None of the following functions can be called with the arguments supplied: "
|
|
||||||
// + makeErrorMessageForMultipleDescriptors(noOverrides));
|
|
||||||
tracing.noneApplicable(trace, noOverrides);
|
tracing.noneApplicable(trace, noOverrides);
|
||||||
tracing.recordAmbiguity(trace, noOverrides);
|
tracing.recordAmbiguity(trace, noOverrides);
|
||||||
return OverloadResolutionResults.manyFailedCandidates(noOverrides);
|
return OverloadResolutionResults.manyFailedCandidates(noOverrides);
|
||||||
@@ -696,15 +707,20 @@ public class CallResolver {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private <D extends CallableDescriptor> OverloadResolutionResults<D> chooseAndReportMaximallySpecific(BindingTrace trace, TracingStrategy tracing, Set<ResolvedCallImpl<D>> candidates) {
|
private <D extends CallableDescriptor> boolean allClean(Collection<ResolvedCallImpl<D>> results) {
|
||||||
|
for (ResolvedCallImpl<D> result : results) {
|
||||||
|
if (result.isDirty()) return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private <D extends CallableDescriptor> OverloadResolutionResults<D> chooseAndReportMaximallySpecific(Set<ResolvedCallImpl<D>> candidates) {
|
||||||
if (candidates.size() != 1) {
|
if (candidates.size() != 1) {
|
||||||
Set<ResolvedCallImpl<D>> cleanCandidates = Sets.newLinkedHashSet(candidates);
|
Set<ResolvedCallImpl<D>> cleanCandidates = Sets.newLinkedHashSet(candidates);
|
||||||
boolean allClean = true;
|
|
||||||
for (Iterator<ResolvedCallImpl<D>> iterator = cleanCandidates.iterator(); iterator.hasNext(); ) {
|
for (Iterator<ResolvedCallImpl<D>> iterator = cleanCandidates.iterator(); iterator.hasNext(); ) {
|
||||||
ResolvedCallImpl<D> candidate = iterator.next();
|
ResolvedCallImpl<D> candidate = iterator.next();
|
||||||
if (candidate.isDirty()) {
|
if (candidate.isDirty()) {
|
||||||
iterator.remove();
|
iterator.remove();
|
||||||
allClean = false;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -722,13 +738,6 @@ public class CallResolver {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Set<ResolvedCallImpl<D>> noOverrides = OverridingUtil.filterOverrides(candidates, MAP_TO_RESULT);
|
Set<ResolvedCallImpl<D>> noOverrides = OverridingUtil.filterOverrides(candidates, MAP_TO_RESULT);
|
||||||
if (allClean) {
|
|
||||||
// tracing.reportOverallResolutionError(trace, "Overload resolution ambiguity: "
|
|
||||||
// + makeErrorMessageForMultipleDescriptors(noOverrides));
|
|
||||||
tracing.ambiguity(trace, noOverrides);
|
|
||||||
}
|
|
||||||
|
|
||||||
tracing.recordAmbiguity(trace, noOverrides);
|
|
||||||
|
|
||||||
return OverloadResolutionResults.ambiguity(noOverrides);
|
return OverloadResolutionResults.ambiguity(noOverrides);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
package org.jetbrains.jet.lang.resolve.calls;
|
package org.jetbrains.jet.lang.resolve.calls;
|
||||||
|
|
||||||
|
import java.util.EnumSet;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author abreslav
|
* @author abreslav
|
||||||
*/
|
*/
|
||||||
@@ -9,7 +11,14 @@ public enum ResolutionStatus {
|
|||||||
OTHER_ERROR,
|
OTHER_ERROR,
|
||||||
SUCCESS(true);
|
SUCCESS(true);
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
public static final EnumSet<ResolutionStatus>[] SEVERITY_LEVELS = new EnumSet[] {
|
||||||
|
EnumSet.of(UNSAFE_CALL_ERROR), // weakest
|
||||||
|
EnumSet.of(OTHER_ERROR), // most severe
|
||||||
|
};
|
||||||
|
|
||||||
private final boolean success;
|
private final boolean success;
|
||||||
|
private int severityIndex = -1;
|
||||||
|
|
||||||
private ResolutionStatus(boolean success) {
|
private ResolutionStatus(boolean success) {
|
||||||
this.success = success;
|
this.success = success;
|
||||||
@@ -25,11 +34,21 @@ public enum ResolutionStatus {
|
|||||||
|
|
||||||
public ResolutionStatus combine(ResolutionStatus other) {
|
public ResolutionStatus combine(ResolutionStatus other) {
|
||||||
if (this.isSuccess()) return other;
|
if (this.isSuccess()) return other;
|
||||||
if (this.isWeakError() && !other.isSuccess()) return other;
|
if (!other.isSuccess() && this.getSeverityIndex() < other.getSeverityIndex()) return other;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private int getSeverityIndex() {
|
||||||
|
if (severityIndex == -1) {
|
||||||
|
for (int i = 0; i < SEVERITY_LEVELS.length; i++) {
|
||||||
|
if (SEVERITY_LEVELS[i].contains(this)) {
|
||||||
|
severityIndex = i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
assert severityIndex >= 0;
|
||||||
|
|
||||||
public boolean isWeakError() {
|
return severityIndex;
|
||||||
return this == UNSAFE_CALL_ERROR;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,16 +2,20 @@ package org.jetbrains.jet.lang.resolve.calls;
|
|||||||
|
|
||||||
import com.google.common.collect.Lists;
|
import com.google.common.collect.Lists;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
import org.jetbrains.jet.lang.descriptors.CallableDescriptor;
|
import org.jetbrains.jet.lang.descriptors.CallableDescriptor;
|
||||||
import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor;
|
import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor;
|
||||||
import org.jetbrains.jet.lang.descriptors.FunctionDescriptor;
|
import org.jetbrains.jet.lang.descriptors.FunctionDescriptor;
|
||||||
import org.jetbrains.jet.lang.descriptors.ValueParameterDescriptor;
|
import org.jetbrains.jet.lang.descriptors.ValueParameterDescriptor;
|
||||||
import org.jetbrains.jet.lang.psi.Call;
|
import org.jetbrains.jet.lang.psi.Call;
|
||||||
|
import org.jetbrains.jet.lang.psi.JetExpression;
|
||||||
|
import org.jetbrains.jet.lang.psi.JetSuperExpression;
|
||||||
import org.jetbrains.jet.lang.resolve.BindingContext;
|
import org.jetbrains.jet.lang.resolve.BindingContext;
|
||||||
import org.jetbrains.jet.lang.resolve.calls.autocasts.AutoCastService;
|
import org.jetbrains.jet.lang.resolve.calls.autocasts.AutoCastService;
|
||||||
import org.jetbrains.jet.lang.resolve.calls.autocasts.AutoCastServiceImpl;
|
import org.jetbrains.jet.lang.resolve.calls.autocasts.AutoCastServiceImpl;
|
||||||
import org.jetbrains.jet.lang.resolve.calls.autocasts.DataFlowInfo;
|
import org.jetbrains.jet.lang.resolve.calls.autocasts.DataFlowInfo;
|
||||||
import org.jetbrains.jet.lang.resolve.scopes.JetScope;
|
import org.jetbrains.jet.lang.resolve.scopes.JetScope;
|
||||||
|
import org.jetbrains.jet.lang.resolve.scopes.receivers.ExpressionReceiver;
|
||||||
import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor;
|
import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor;
|
||||||
import org.jetbrains.jet.lang.types.JetType;
|
import org.jetbrains.jet.lang.types.JetType;
|
||||||
import org.jetbrains.jet.lang.types.JetTypeChecker;
|
import org.jetbrains.jet.lang.types.JetTypeChecker;
|
||||||
@@ -72,6 +76,18 @@ import static org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
/*package*/ static JetSuperExpression getReceiverSuper(@NotNull ReceiverDescriptor receiver) {
|
||||||
|
if (receiver instanceof ExpressionReceiver) {
|
||||||
|
ExpressionReceiver expressionReceiver = (ExpressionReceiver) receiver;
|
||||||
|
JetExpression expression = expressionReceiver.getExpression();
|
||||||
|
if (expression instanceof JetSuperExpression) {
|
||||||
|
return (JetSuperExpression) expression;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
public List<ResolutionTask<D>> computePrioritizedTasks(@NotNull JetScope scope, @NotNull Call call, @NotNull String name, @NotNull BindingContext bindingContext, @NotNull DataFlowInfo dataFlowInfo) {
|
public List<ResolutionTask<D>> computePrioritizedTasks(@NotNull JetScope scope, @NotNull Call call, @NotNull String name, @NotNull BindingContext bindingContext, @NotNull DataFlowInfo dataFlowInfo) {
|
||||||
List<ResolutionTask<D>> result = Lists.newArrayList();
|
List<ResolutionTask<D>> result = Lists.newArrayList();
|
||||||
|
|
||||||
@@ -108,8 +124,17 @@ import static org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor
|
|||||||
convertWithReceivers(membersForThisVariant, Collections.singletonList(variant), Collections.singletonList(NO_RECEIVER), members);
|
convertWithReceivers(membersForThisVariant, Collections.singletonList(variant), Collections.singletonList(NO_RECEIVER), members);
|
||||||
}
|
}
|
||||||
|
|
||||||
addTask(result, call, locals, dataFlowInfo);
|
if (getReceiverSuper(receiver) != null) {
|
||||||
addTask(result, call, members, dataFlowInfo);
|
// If the call is of the form super.foo(), it can actually be only a member
|
||||||
|
// But if there's no appropriate member, we would like to report that super cannot be a receiver for an extension
|
||||||
|
// Thus, put members first
|
||||||
|
addTask(result, call, members, dataFlowInfo);
|
||||||
|
addTask(result, call, locals, dataFlowInfo);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
addTask(result, call, locals, dataFlowInfo);
|
||||||
|
addTask(result, call, members, dataFlowInfo);
|
||||||
|
}
|
||||||
|
|
||||||
for (ReceiverDescriptor implicitReceiver : implicitReceivers) {
|
for (ReceiverDescriptor implicitReceiver : implicitReceivers) {
|
||||||
Collection<D> memberExtensions = getExtensionsByName(implicitReceiver.getType().getMemberScope(), name);
|
Collection<D> memberExtensions = getExtensionsByName(implicitReceiver.getType().getMemberScope(), name);
|
||||||
|
|||||||
@@ -8,7 +8,6 @@ import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor;
|
|||||||
import org.jetbrains.jet.lang.types.JetType;
|
import org.jetbrains.jet.lang.types.JetType;
|
||||||
|
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author abreslav
|
* @author abreslav
|
||||||
@@ -40,10 +39,10 @@ import java.util.Set;
|
|||||||
public void wrongNumberOfTypeArguments(@NotNull BindingTrace trace, int expectedTypeArgumentCount) {}
|
public void wrongNumberOfTypeArguments(@NotNull BindingTrace trace, int expectedTypeArgumentCount) {}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public <D extends CallableDescriptor> void ambiguity(@NotNull BindingTrace trace, @NotNull Set<ResolvedCallImpl<D>> descriptors) {}
|
public <D extends CallableDescriptor> void ambiguity(@NotNull BindingTrace trace, @NotNull Collection<ResolvedCallImpl<D>> descriptors) {}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public <D extends CallableDescriptor> void noneApplicable(@NotNull BindingTrace trace, @NotNull Set<ResolvedCallImpl<D>> descriptors) {}
|
public <D extends CallableDescriptor> void noneApplicable(@NotNull BindingTrace trace, @NotNull Collection<ResolvedCallImpl<D>> descriptors) {}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void instantiationOfAbstractClass(@NotNull BindingTrace trace) {}
|
public void instantiationOfAbstractClass(@NotNull BindingTrace trace) {}
|
||||||
@@ -74,9 +73,9 @@ import java.util.Set;
|
|||||||
|
|
||||||
void wrongNumberOfTypeArguments(@NotNull BindingTrace trace, int expectedTypeArgumentCount);
|
void wrongNumberOfTypeArguments(@NotNull BindingTrace trace, int expectedTypeArgumentCount);
|
||||||
|
|
||||||
<D extends CallableDescriptor> void ambiguity(@NotNull BindingTrace trace, @NotNull Set<ResolvedCallImpl<D>> descriptors);
|
<D extends CallableDescriptor> void ambiguity(@NotNull BindingTrace trace, @NotNull Collection<ResolvedCallImpl<D>> descriptors);
|
||||||
|
|
||||||
<D extends CallableDescriptor> void noneApplicable(@NotNull BindingTrace trace, @NotNull Set<ResolvedCallImpl<D>> descriptors);
|
<D extends CallableDescriptor> void noneApplicable(@NotNull BindingTrace trace, @NotNull Collection<ResolvedCallImpl<D>> descriptors);
|
||||||
|
|
||||||
void instantiationOfAbstractClass(@NotNull BindingTrace trace);
|
void instantiationOfAbstractClass(@NotNull BindingTrace trace);
|
||||||
|
|
||||||
|
|||||||
@@ -8,4 +8,6 @@ public interface MutableSlicedMap extends SlicedMap {
|
|||||||
<K, V> void put(WritableSlice<K, V> slice, K key, V value);
|
<K, V> void put(WritableSlice<K, V> slice, K key, V value);
|
||||||
|
|
||||||
<K, V> V remove(RemovableSlice<K, V> slice, K key);
|
<K, V> V remove(RemovableSlice<K, V> slice, K key);
|
||||||
|
|
||||||
|
void clear();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -47,6 +47,11 @@ public class SlicedMapImpl implements MutableSlicedMap {
|
|||||||
slice.afterPut(this, key, value);
|
slice.afterPut(this, key, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void clear() {
|
||||||
|
map.clear();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public <K, V> V get(ReadOnlySlice<K, V> slice, K key) {
|
public <K, V> V get(ReadOnlySlice<K, V> slice, K key) {
|
||||||
SlicedMapKey<K, V> slicedMapKey = slice.makeKey(key);
|
SlicedMapKey<K, V> slicedMapKey = slice.makeKey(key);
|
||||||
|
|||||||
@@ -41,12 +41,12 @@ l0:
|
|||||||
jf(l3) NEXT:[read (Unit), r(2)] PREV:[r(2 > 3)]
|
jf(l3) NEXT:[read (Unit), r(2)] PREV:[r(2 > 3)]
|
||||||
r(2) NEXT:[ret l1] PREV:[jf(l3)]
|
r(2) NEXT:[ret l1] PREV:[jf(l3)]
|
||||||
ret l1 NEXT:[<END>] PREV:[r(2)]
|
ret l1 NEXT:[<END>] PREV:[r(2)]
|
||||||
jmp(l4) NEXT:[r(2)] PREV:[]
|
* jmp(l4) NEXT:[r(2)] PREV:[]
|
||||||
l3:
|
l3:
|
||||||
read (Unit) NEXT:[r(2)] PREV:[jf(l3)]
|
read (Unit) NEXT:[r(2)] PREV:[jf(l3)]
|
||||||
l2:
|
l2:
|
||||||
l4:
|
l4:
|
||||||
r(2) NEXT:[<END>] PREV:[jmp?(l2), jmp(l4), read (Unit)]
|
r(2) NEXT:[<END>] PREV:[jmp?(l2), read (Unit)]
|
||||||
l1:
|
l1:
|
||||||
<END> NEXT:[] PREV:[ret l1, r(2)]
|
<END> NEXT:[] PREV:[ret l1, r(2)]
|
||||||
error:
|
error:
|
||||||
@@ -67,12 +67,12 @@ l3:
|
|||||||
r(2 > 3) NEXT:[jf(l5)] PREV:[r(>)]
|
r(2 > 3) NEXT:[jf(l5)] PREV:[r(>)]
|
||||||
jf(l5) NEXT:[read (Unit), ret l4] PREV:[r(2 > 3)]
|
jf(l5) NEXT:[read (Unit), ret l4] PREV:[r(2 > 3)]
|
||||||
ret l4 NEXT:[<END>] PREV:[jf(l5)]
|
ret l4 NEXT:[<END>] PREV:[jf(l5)]
|
||||||
jmp(l6) NEXT:[<END>] PREV:[]
|
* jmp(l6) NEXT:[<END>] PREV:[]
|
||||||
l5:
|
l5:
|
||||||
read (Unit) NEXT:[<END>] PREV:[jf(l5)]
|
read (Unit) NEXT:[<END>] PREV:[jf(l5)]
|
||||||
l4:
|
l4:
|
||||||
l6:
|
l6:
|
||||||
<END> NEXT:[] PREV:[ret l4, jmp(l6), read (Unit)]
|
<END> NEXT:[] PREV:[ret l4, read (Unit)]
|
||||||
error:
|
error:
|
||||||
<ERROR> NEXT:[] PREV:[]
|
<ERROR> NEXT:[] PREV:[]
|
||||||
=====================
|
=====================
|
||||||
@@ -113,12 +113,12 @@ l3:
|
|||||||
r(2 > 3) NEXT:[jf(l5)] PREV:[r(>)]
|
r(2 > 3) NEXT:[jf(l5)] PREV:[r(>)]
|
||||||
jf(l5) NEXT:[read (Unit), ret l4] PREV:[r(2 > 3)]
|
jf(l5) NEXT:[read (Unit), ret l4] PREV:[r(2 > 3)]
|
||||||
ret l4 NEXT:[<END>] PREV:[jf(l5)]
|
ret l4 NEXT:[<END>] PREV:[jf(l5)]
|
||||||
jmp(l6) NEXT:[<END>] PREV:[]
|
* jmp(l6) NEXT:[<END>] PREV:[]
|
||||||
l5:
|
l5:
|
||||||
read (Unit) NEXT:[<END>] PREV:[jf(l5)]
|
read (Unit) NEXT:[<END>] PREV:[jf(l5)]
|
||||||
l4:
|
l4:
|
||||||
l6:
|
l6:
|
||||||
<END> NEXT:[] PREV:[ret l4, jmp(l6), read (Unit)]
|
<END> NEXT:[] PREV:[ret l4, read (Unit)]
|
||||||
error:
|
error:
|
||||||
<ERROR> NEXT:[] PREV:[]
|
<ERROR> NEXT:[] PREV:[]
|
||||||
=====================
|
=====================
|
||||||
@@ -145,12 +145,12 @@ l2:
|
|||||||
jf(l5) NEXT:[read (Unit), r(2)] PREV:[r(2 > 3)]
|
jf(l5) NEXT:[read (Unit), r(2)] PREV:[r(2 > 3)]
|
||||||
r(2) NEXT:[ret l3] PREV:[jf(l5)]
|
r(2) NEXT:[ret l3] PREV:[jf(l5)]
|
||||||
ret l3 NEXT:[<END>] PREV:[r(2)]
|
ret l3 NEXT:[<END>] PREV:[r(2)]
|
||||||
jmp(l6) NEXT:[r(2)] PREV:[]
|
* jmp(l6) NEXT:[r(2)] PREV:[]
|
||||||
l5:
|
l5:
|
||||||
read (Unit) NEXT:[r(2)] PREV:[jf(l5)]
|
read (Unit) NEXT:[r(2)] PREV:[jf(l5)]
|
||||||
l4:
|
l4:
|
||||||
l6:
|
l6:
|
||||||
r(2) NEXT:[<END>] PREV:[jmp?(l4), jmp(l6), read (Unit)]
|
r(2) NEXT:[<END>] PREV:[jmp?(l4), read (Unit)]
|
||||||
l3:
|
l3:
|
||||||
<END> NEXT:[] PREV:[ret l3, r(2)]
|
<END> NEXT:[] PREV:[ret l3, r(2)]
|
||||||
error:
|
error:
|
||||||
@@ -197,12 +197,12 @@ l2:
|
|||||||
jf(l5) NEXT:[read (Unit), r(2)] PREV:[r(2 > 3)]
|
jf(l5) NEXT:[read (Unit), r(2)] PREV:[r(2 > 3)]
|
||||||
r(2) NEXT:[ret l3] PREV:[jf(l5)]
|
r(2) NEXT:[ret l3] PREV:[jf(l5)]
|
||||||
ret l3 NEXT:[<END>] PREV:[r(2)]
|
ret l3 NEXT:[<END>] PREV:[r(2)]
|
||||||
jmp(l6) NEXT:[r(2)] PREV:[]
|
* jmp(l6) NEXT:[r(2)] PREV:[]
|
||||||
l5:
|
l5:
|
||||||
read (Unit) NEXT:[r(2)] PREV:[jf(l5)]
|
read (Unit) NEXT:[r(2)] PREV:[jf(l5)]
|
||||||
l4:
|
l4:
|
||||||
l6:
|
l6:
|
||||||
r(2) NEXT:[<END>] PREV:[jmp?(l4), jmp(l6), read (Unit)]
|
r(2) NEXT:[<END>] PREV:[jmp?(l4), read (Unit)]
|
||||||
l3:
|
l3:
|
||||||
<END> NEXT:[] PREV:[ret l3, r(2)]
|
<END> NEXT:[] PREV:[ret l3, r(2)]
|
||||||
error:
|
error:
|
||||||
@@ -238,12 +238,12 @@ l4:
|
|||||||
jf(l7) NEXT:[read (Unit), r(2)] PREV:[r(2 > 3)]
|
jf(l7) NEXT:[read (Unit), r(2)] PREV:[r(2 > 3)]
|
||||||
r(2) NEXT:[jmp(l3)] PREV:[jf(l7)]
|
r(2) NEXT:[jmp(l3)] PREV:[jf(l7)]
|
||||||
jmp(l3) NEXT:[read (Unit)] PREV:[r(2)]
|
jmp(l3) NEXT:[read (Unit)] PREV:[r(2)]
|
||||||
jmp(l8) NEXT:[r(2)] PREV:[]
|
* jmp(l8) NEXT:[r(2)] PREV:[]
|
||||||
l7:
|
l7:
|
||||||
read (Unit) NEXT:[r(2)] PREV:[jf(l7)]
|
read (Unit) NEXT:[r(2)] PREV:[jf(l7)]
|
||||||
l6:
|
l6:
|
||||||
l8:
|
l8:
|
||||||
r(2) NEXT:[jmp(l2)] PREV:[jmp?(l6), jmp(l8), read (Unit)]
|
r(2) NEXT:[jmp(l2)] PREV:[jmp?(l6), read (Unit)]
|
||||||
jmp(l2) NEXT:[r(true)] PREV:[r(2)]
|
jmp(l2) NEXT:[r(true)] PREV:[r(2)]
|
||||||
l3:
|
l3:
|
||||||
read (Unit) NEXT:[<END>] PREV:[jf(l3), jmp(l3)]
|
read (Unit) NEXT:[<END>] PREV:[jf(l3), jmp(l3)]
|
||||||
@@ -282,11 +282,11 @@ l5:
|
|||||||
r(2 > 3) NEXT:[jf(l7)] PREV:[r(>)]
|
r(2 > 3) NEXT:[jf(l7)] PREV:[r(>)]
|
||||||
jf(l7) NEXT:[read (Unit), jmp(l4)] PREV:[r(2 > 3)]
|
jf(l7) NEXT:[read (Unit), jmp(l4)] PREV:[r(2 > 3)]
|
||||||
jmp(l4) NEXT:[read (Unit)] PREV:[jf(l7)]
|
jmp(l4) NEXT:[read (Unit)] PREV:[jf(l7)]
|
||||||
jmp(l8) NEXT:[jmp(l3)] PREV:[]
|
* jmp(l8) NEXT:[jmp(l3)] PREV:[]
|
||||||
l7:
|
l7:
|
||||||
read (Unit) NEXT:[jmp(l3)] PREV:[jf(l7)]
|
read (Unit) NEXT:[jmp(l3)] PREV:[jf(l7)]
|
||||||
l8:
|
l8:
|
||||||
jmp(l3) NEXT:[r(true)] PREV:[jmp(l8), read (Unit)]
|
jmp(l3) NEXT:[r(true)] PREV:[read (Unit)]
|
||||||
l4:
|
l4:
|
||||||
read (Unit) NEXT:[r(5)] PREV:[jf(l4), jmp(l4)]
|
read (Unit) NEXT:[r(5)] PREV:[jf(l4), jmp(l4)]
|
||||||
r(5) NEXT:[r(2)] PREV:[read (Unit)]
|
r(5) NEXT:[r(2)] PREV:[read (Unit)]
|
||||||
@@ -326,11 +326,11 @@ l5:
|
|||||||
r(2 > 3) NEXT:[jf(l7)] PREV:[r(>)]
|
r(2 > 3) NEXT:[jf(l7)] PREV:[r(>)]
|
||||||
jf(l7) NEXT:[read (Unit), jmp(l4)] PREV:[r(2 > 3)]
|
jf(l7) NEXT:[read (Unit), jmp(l4)] PREV:[r(2 > 3)]
|
||||||
jmp(l4) NEXT:[read (Unit)] PREV:[jf(l7)]
|
jmp(l4) NEXT:[read (Unit)] PREV:[jf(l7)]
|
||||||
jmp(l8) NEXT:[jmp(l3)] PREV:[]
|
* jmp(l8) NEXT:[jmp(l3)] PREV:[]
|
||||||
l7:
|
l7:
|
||||||
read (Unit) NEXT:[jmp(l3)] PREV:[jf(l7)]
|
read (Unit) NEXT:[jmp(l3)] PREV:[jf(l7)]
|
||||||
l8:
|
l8:
|
||||||
jmp(l3) NEXT:[r(true)] PREV:[jmp(l8), read (Unit)]
|
jmp(l3) NEXT:[r(true)] PREV:[read (Unit)]
|
||||||
l4:
|
l4:
|
||||||
read (Unit) NEXT:[r(2)] PREV:[jf(l4), jmp(l4)]
|
read (Unit) NEXT:[r(2)] PREV:[jf(l4), jmp(l4)]
|
||||||
l2:
|
l2:
|
||||||
@@ -374,12 +374,12 @@ l5:
|
|||||||
jf(l7) NEXT:[read (Unit), r(2)] PREV:[r(2 > 3)]
|
jf(l7) NEXT:[read (Unit), r(2)] PREV:[r(2 > 3)]
|
||||||
r(2) NEXT:[jmp(l4)] PREV:[jf(l7)]
|
r(2) NEXT:[jmp(l4)] PREV:[jf(l7)]
|
||||||
jmp(l4) NEXT:[jmp?(l6)] PREV:[r(2)]
|
jmp(l4) NEXT:[jmp?(l6)] PREV:[r(2)]
|
||||||
jmp(l8) NEXT:[r(2)] PREV:[]
|
* jmp(l8) NEXT:[r(2)] PREV:[]
|
||||||
l7:
|
l7:
|
||||||
read (Unit) NEXT:[r(2)] PREV:[jf(l7)]
|
read (Unit) NEXT:[r(2)] PREV:[jf(l7)]
|
||||||
l6:
|
l6:
|
||||||
l8:
|
l8:
|
||||||
r(2) NEXT:[jmp?(l4)] PREV:[jmp?(l6), jmp(l8), read (Unit)]
|
r(2) NEXT:[jmp?(l4)] PREV:[jmp?(l6), read (Unit)]
|
||||||
jmp?(l4) NEXT:[jmp?(l6), read (Unit)] PREV:[r(2)]
|
jmp?(l4) NEXT:[jmp?(l6), read (Unit)] PREV:[r(2)]
|
||||||
l2:
|
l2:
|
||||||
read (Unit) NEXT:[<END>] PREV:[jmp?(l2), jmp?(l4)]
|
read (Unit) NEXT:[<END>] PREV:[jmp?(l2), jmp?(l4)]
|
||||||
@@ -422,11 +422,11 @@ l6:
|
|||||||
r(2 > 3) NEXT:[jf(l7)] PREV:[r(>)]
|
r(2 > 3) NEXT:[jf(l7)] PREV:[r(>)]
|
||||||
jf(l7) NEXT:[read (Unit), jmp(l5)] PREV:[r(2 > 3)]
|
jf(l7) NEXT:[read (Unit), jmp(l5)] PREV:[r(2 > 3)]
|
||||||
jmp(l5) NEXT:[r(1)] PREV:[jf(l7)]
|
jmp(l5) NEXT:[r(1)] PREV:[jf(l7)]
|
||||||
jmp(l8) NEXT:[jmp?(l5)] PREV:[]
|
* jmp(l8) NEXT:[jmp?(l5)] PREV:[]
|
||||||
l7:
|
l7:
|
||||||
read (Unit) NEXT:[jmp?(l5)] PREV:[jf(l7)]
|
read (Unit) NEXT:[jmp?(l5)] PREV:[jf(l7)]
|
||||||
l8:
|
l8:
|
||||||
jmp?(l5) NEXT:[r(1), read (Unit)] PREV:[jmp(l8), read (Unit)]
|
jmp?(l5) NEXT:[r(1), read (Unit)] PREV:[read (Unit)]
|
||||||
l3:
|
l3:
|
||||||
read (Unit) NEXT:[r(5)] PREV:[jmp?(l3), jmp?(l5)]
|
read (Unit) NEXT:[r(5)] PREV:[jmp?(l3), jmp?(l5)]
|
||||||
r(5) NEXT:[r(2)] PREV:[read (Unit)]
|
r(5) NEXT:[r(2)] PREV:[read (Unit)]
|
||||||
@@ -470,11 +470,11 @@ l6:
|
|||||||
r(2 > 3) NEXT:[jf(l7)] PREV:[r(>)]
|
r(2 > 3) NEXT:[jf(l7)] PREV:[r(>)]
|
||||||
jf(l7) NEXT:[read (Unit), jmp(l5)] PREV:[r(2 > 3)]
|
jf(l7) NEXT:[read (Unit), jmp(l5)] PREV:[r(2 > 3)]
|
||||||
jmp(l5) NEXT:[r(1)] PREV:[jf(l7)]
|
jmp(l5) NEXT:[r(1)] PREV:[jf(l7)]
|
||||||
jmp(l8) NEXT:[jmp?(l5)] PREV:[]
|
* jmp(l8) NEXT:[jmp?(l5)] PREV:[]
|
||||||
l7:
|
l7:
|
||||||
read (Unit) NEXT:[jmp?(l5)] PREV:[jf(l7)]
|
read (Unit) NEXT:[jmp?(l5)] PREV:[jf(l7)]
|
||||||
l8:
|
l8:
|
||||||
jmp?(l5) NEXT:[r(1), read (Unit)] PREV:[jmp(l8), read (Unit)]
|
jmp?(l5) NEXT:[r(1), read (Unit)] PREV:[read (Unit)]
|
||||||
l3:
|
l3:
|
||||||
read (Unit) NEXT:[r(2)] PREV:[jmp?(l3), jmp?(l5)]
|
read (Unit) NEXT:[r(2)] PREV:[jmp?(l3), jmp?(l5)]
|
||||||
l2:
|
l2:
|
||||||
@@ -500,12 +500,12 @@ l0:
|
|||||||
r(1) NEXT:[r(2)] PREV:[jmp?(l2)]
|
r(1) NEXT:[r(2)] PREV:[jmp?(l2)]
|
||||||
r(2) NEXT:[ret(*) l1] PREV:[r(1)]
|
r(2) NEXT:[ret(*) l1] PREV:[r(1)]
|
||||||
ret(*) l1 NEXT:[<END>] PREV:[r(2)]
|
ret(*) l1 NEXT:[<END>] PREV:[r(2)]
|
||||||
ret(*) l1 NEXT:[<END>] PREV:[]
|
* ret(*) l1 NEXT:[<END>] PREV:[]
|
||||||
l2:
|
l2:
|
||||||
r(2) NEXT:[ret(*) l1] PREV:[jmp?(l2)]
|
r(2) NEXT:[ret(*) l1] PREV:[jmp?(l2)]
|
||||||
ret(*) l1 NEXT:[<END>] PREV:[r(2)]
|
ret(*) l1 NEXT:[<END>] PREV:[r(2)]
|
||||||
l1:
|
l1:
|
||||||
<END> NEXT:[] PREV:[ret(*) l1, ret(*) l1, ret(*) l1]
|
<END> NEXT:[] PREV:[ret(*) l1, ret(*) l1]
|
||||||
error:
|
error:
|
||||||
<ERROR> NEXT:[] PREV:[]
|
<ERROR> NEXT:[] PREV:[]
|
||||||
=====================
|
=====================
|
||||||
|
|||||||
@@ -0,0 +1,40 @@
|
|||||||
|
== t1 ==
|
||||||
|
fun t1() {
|
||||||
|
for (i in 1..2) {
|
||||||
|
doSmth(i)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
---------------------
|
||||||
|
l0:
|
||||||
|
<START> NEXT:[r(1)] PREV:[]
|
||||||
|
r(1) NEXT:[r(2)] PREV:[<START>]
|
||||||
|
r(2) NEXT:[r(..)] PREV:[r(1)]
|
||||||
|
r(..) NEXT:[r(1..2)] PREV:[r(2)]
|
||||||
|
r(1..2) NEXT:[w(i)] PREV:[r(..)]
|
||||||
|
w(i) NEXT:[jmp?(l2)] PREV:[r(1..2)]
|
||||||
|
l3:
|
||||||
|
jmp?(l2) NEXT:[read (Unit), r(i)] PREV:[w(i)]
|
||||||
|
l4:
|
||||||
|
l5:
|
||||||
|
r(i) NEXT:[r(doSmth)] PREV:[jmp?(l2), jmp?(l4)]
|
||||||
|
r(doSmth) NEXT:[r(doSmth(i))] PREV:[r(i)]
|
||||||
|
r(doSmth(i)) NEXT:[jmp?(l4)] PREV:[r(doSmth)]
|
||||||
|
jmp?(l4) NEXT:[r(i), read (Unit)] PREV:[r(doSmth(i))]
|
||||||
|
l2:
|
||||||
|
read (Unit) NEXT:[<END>] PREV:[jmp?(l2), jmp?(l4)]
|
||||||
|
l1:
|
||||||
|
<END> NEXT:[] PREV:[read (Unit)]
|
||||||
|
error:
|
||||||
|
<ERROR> NEXT:[] PREV:[]
|
||||||
|
=====================
|
||||||
|
== doSmth ==
|
||||||
|
fun doSmth(i: Int) {}
|
||||||
|
---------------------
|
||||||
|
l0:
|
||||||
|
<START> NEXT:[read (Unit)] PREV:[]
|
||||||
|
read (Unit) NEXT:[<END>] PREV:[<START>]
|
||||||
|
l1:
|
||||||
|
<END> NEXT:[] PREV:[read (Unit)]
|
||||||
|
error:
|
||||||
|
<ERROR> NEXT:[] PREV:[]
|
||||||
|
=====================
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
fun t1() {
|
||||||
|
for (i in 1..2) {
|
||||||
|
doSmth(i)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun doSmth(i: Int) {}
|
||||||
@@ -0,0 +1,98 @@
|
|||||||
|
== t1 ==
|
||||||
|
fun t1(b: Boolean) {
|
||||||
|
var u: String
|
||||||
|
if (b) {
|
||||||
|
u = "s"
|
||||||
|
}
|
||||||
|
doSmth(u)
|
||||||
|
|
||||||
|
var r: String
|
||||||
|
if (b) {
|
||||||
|
r = "s"
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
r = "t"
|
||||||
|
}
|
||||||
|
doSmth(r)
|
||||||
|
}
|
||||||
|
---------------------
|
||||||
|
l0:
|
||||||
|
<START> NEXT:[r(b)] PREV:[]
|
||||||
|
r(b) NEXT:[jf(l2)] PREV:[<START>]
|
||||||
|
jf(l2) NEXT:[read (Unit), r("s")] PREV:[r(b)]
|
||||||
|
r("s") NEXT:[w(u)] PREV:[jf(l2)]
|
||||||
|
w(u) NEXT:[jmp(l3)] PREV:[r("s")]
|
||||||
|
jmp(l3) NEXT:[r(u)] PREV:[w(u)]
|
||||||
|
l2:
|
||||||
|
read (Unit) NEXT:[r(u)] PREV:[jf(l2)]
|
||||||
|
l3:
|
||||||
|
r(u) NEXT:[r(doSmth)] PREV:[jmp(l3), read (Unit)]
|
||||||
|
r(doSmth) NEXT:[r(doSmth(u))] PREV:[r(u)]
|
||||||
|
r(doSmth(u)) NEXT:[r(b)] PREV:[r(doSmth)]
|
||||||
|
r(b) NEXT:[jf(l4)] PREV:[r(doSmth(u))]
|
||||||
|
jf(l4) NEXT:[r("t"), r("s")] PREV:[r(b)]
|
||||||
|
r("s") NEXT:[w(r)] PREV:[jf(l4)]
|
||||||
|
w(r) NEXT:[jmp(l5)] PREV:[r("s")]
|
||||||
|
jmp(l5) NEXT:[r(r)] PREV:[w(r)]
|
||||||
|
l4:
|
||||||
|
r("t") NEXT:[w(r)] PREV:[jf(l4)]
|
||||||
|
w(r) NEXT:[r(r)] PREV:[r("t")]
|
||||||
|
l5:
|
||||||
|
r(r) NEXT:[r(doSmth)] PREV:[jmp(l5), w(r)]
|
||||||
|
r(doSmth) NEXT:[r(doSmth(r))] PREV:[r(r)]
|
||||||
|
r(doSmth(r)) NEXT:[<END>] PREV:[r(doSmth)]
|
||||||
|
l1:
|
||||||
|
<END> NEXT:[] PREV:[r(doSmth(r))]
|
||||||
|
error:
|
||||||
|
<ERROR> NEXT:[] PREV:[]
|
||||||
|
=====================
|
||||||
|
== t2 ==
|
||||||
|
fun t2(b: Boolean) {
|
||||||
|
val i = 3
|
||||||
|
if (b) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
doSmth(i)
|
||||||
|
if (i is Int) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
---------------------
|
||||||
|
l0:
|
||||||
|
<START> NEXT:[r(3)] PREV:[]
|
||||||
|
r(3) NEXT:[w(i)] PREV:[<START>]
|
||||||
|
w(i) NEXT:[r(b)] PREV:[r(3)]
|
||||||
|
r(b) NEXT:[jf(l2)] PREV:[w(i)]
|
||||||
|
jf(l2) NEXT:[read (Unit), ret l1] PREV:[r(b)]
|
||||||
|
ret l1 NEXT:[<END>] PREV:[jf(l2)]
|
||||||
|
* jmp(l3) NEXT:[r(i)] PREV:[]
|
||||||
|
l2:
|
||||||
|
read (Unit) NEXT:[r(i)] PREV:[jf(l2)]
|
||||||
|
l3:
|
||||||
|
r(i) NEXT:[r(doSmth)] PREV:[read (Unit)]
|
||||||
|
r(doSmth) NEXT:[r(doSmth(i))] PREV:[r(i)]
|
||||||
|
r(doSmth(i)) NEXT:[r(i)] PREV:[r(doSmth)]
|
||||||
|
r(i) NEXT:[r(i is Int)] PREV:[r(doSmth(i))]
|
||||||
|
r(i is Int) NEXT:[jf(l4)] PREV:[r(i)]
|
||||||
|
jf(l4) NEXT:[read (Unit), ret l1] PREV:[r(i is Int)]
|
||||||
|
ret l1 NEXT:[<END>] PREV:[jf(l4)]
|
||||||
|
* jmp(l5) NEXT:[<END>] PREV:[]
|
||||||
|
l4:
|
||||||
|
read (Unit) NEXT:[<END>] PREV:[jf(l4)]
|
||||||
|
l1:
|
||||||
|
l5:
|
||||||
|
<END> NEXT:[] PREV:[ret l1, ret l1, read (Unit)]
|
||||||
|
error:
|
||||||
|
<ERROR> NEXT:[] PREV:[]
|
||||||
|
=====================
|
||||||
|
== doSmth ==
|
||||||
|
fun doSmth(s: String) {}
|
||||||
|
---------------------
|
||||||
|
l0:
|
||||||
|
<START> NEXT:[read (Unit)] PREV:[]
|
||||||
|
read (Unit) NEXT:[<END>] PREV:[<START>]
|
||||||
|
l1:
|
||||||
|
<END> NEXT:[] PREV:[read (Unit)]
|
||||||
|
error:
|
||||||
|
<ERROR> NEXT:[] PREV:[]
|
||||||
|
=====================
|
||||||
@@ -0,0 +1,31 @@
|
|||||||
|
fun t1(b: Boolean) {
|
||||||
|
var u: String
|
||||||
|
if (b) {
|
||||||
|
u = "s"
|
||||||
|
}
|
||||||
|
doSmth(u)
|
||||||
|
|
||||||
|
var r: String
|
||||||
|
if (b) {
|
||||||
|
r = "s"
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
r = "t"
|
||||||
|
}
|
||||||
|
doSmth(r)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun t2(b: Boolean) {
|
||||||
|
val i = 3
|
||||||
|
if (b) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
doSmth(i)
|
||||||
|
if (i is Int) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun doSmth(s: String) {}
|
||||||
|
|
||||||
|
|
||||||
@@ -34,17 +34,17 @@ l0:
|
|||||||
<START> NEXT:[ret l1] PREV:[]
|
<START> NEXT:[ret l1] PREV:[]
|
||||||
l2:
|
l2:
|
||||||
l4:
|
l4:
|
||||||
ret l1 NEXT:[<END>] PREV:[<START>, jt(l2)]
|
ret l1 NEXT:[<END>] PREV:[<START>]
|
||||||
l5:
|
l5:
|
||||||
r(1) NEXT:[r(0)] PREV:[]
|
* r(1) NEXT:[r(0)] PREV:[]
|
||||||
r(0) NEXT:[r(>)] PREV:[r(1)]
|
* r(0) NEXT:[r(>)] PREV:[]
|
||||||
r(>) NEXT:[r(1 > 0)] PREV:[r(0)]
|
* r(>) NEXT:[r(1 > 0)] PREV:[]
|
||||||
r(1 > 0) NEXT:[jt(l2)] PREV:[r(>)]
|
* r(1 > 0) NEXT:[jt(l2)] PREV:[]
|
||||||
jt(l2) NEXT:[read (Unit), ret l1] PREV:[r(1 > 0)]
|
* jt(l2) NEXT:[read (Unit), ret l1] PREV:[]
|
||||||
l3:
|
l3:
|
||||||
read (Unit) NEXT:[<END>] PREV:[jt(l2)]
|
* read (Unit) NEXT:[<END>] PREV:[]
|
||||||
l1:
|
l1:
|
||||||
<END> NEXT:[] PREV:[ret l1, read (Unit)]
|
<END> NEXT:[] PREV:[ret l1]
|
||||||
error:
|
error:
|
||||||
<ERROR> NEXT:[] PREV:[]
|
<ERROR> NEXT:[] PREV:[]
|
||||||
=====================
|
=====================
|
||||||
|
|||||||
@@ -22,8 +22,9 @@ fun testUnresolved() {
|
|||||||
|
|
||||||
//TODO
|
//TODO
|
||||||
for (j in <error>collection</error>) {
|
for (j in <error>collection</error>) {
|
||||||
val i: Int = j
|
var i: Int = j
|
||||||
j += 1
|
i += 1
|
||||||
|
foo1(j)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
fun test() {
|
fun test() {
|
||||||
val a : Any? = null
|
var a : Any? = null
|
||||||
if (a is Any) else a = null;
|
if (a is Any) else a = null;
|
||||||
while (a is Any) a = null
|
while (a is Any) a = null
|
||||||
while (true) a = null
|
while (true) a = null
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ abstract enum class ProtocolState {
|
|||||||
|
|
||||||
|
|
||||||
fun box(): String {
|
fun box(): String {
|
||||||
val x: ProtocolState = ProtocolState.WAITING
|
var x: ProtocolState = ProtocolState.WAITING
|
||||||
x = x.signal()
|
x = x.signal()
|
||||||
if (x != ProtocolState.TALKING) return "fail 1"
|
if (x != ProtocolState.TALKING) return "fail 1"
|
||||||
x = x.signal()
|
x = x.signal()
|
||||||
|
|||||||
@@ -0,0 +1,99 @@
|
|||||||
|
namespace uninitialized_vals {
|
||||||
|
|
||||||
|
fun t1(b : Boolean) {
|
||||||
|
val v : Int
|
||||||
|
if (<!UNINITIALIZED_VARIABLE!>v<!> == 0) {}
|
||||||
|
|
||||||
|
var u: String
|
||||||
|
if (b) {
|
||||||
|
u = "s"
|
||||||
|
}
|
||||||
|
doSmth(<!UNINITIALIZED_VARIABLE!>u<!>)
|
||||||
|
|
||||||
|
var r: String
|
||||||
|
if (b) {
|
||||||
|
r = "s"
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
r = "tg"
|
||||||
|
}
|
||||||
|
doSmth(r)
|
||||||
|
|
||||||
|
var t: String
|
||||||
|
if (b)
|
||||||
|
doSmth(<!UNINITIALIZED_VARIABLE!>t<!>)
|
||||||
|
else
|
||||||
|
t = "ss"
|
||||||
|
doSmth(<!UNINITIALIZED_VARIABLE!>t<!>)
|
||||||
|
|
||||||
|
val i = 3
|
||||||
|
doSmth(i)
|
||||||
|
if (b) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
doSmth(i)
|
||||||
|
if (i is Int) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun t2() {
|
||||||
|
val s = "ss"
|
||||||
|
|
||||||
|
for (i in 0..2) {
|
||||||
|
doSmth(s)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun doSmth(s: String) {}
|
||||||
|
fun doSmth(i: Int) {}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace reassigned_vals {
|
||||||
|
|
||||||
|
fun t1() {
|
||||||
|
val a : Int = 1
|
||||||
|
<!VAL_REASSIGNMENT!>a<!> = 2
|
||||||
|
|
||||||
|
var b : Int = 1
|
||||||
|
b = 3
|
||||||
|
}
|
||||||
|
|
||||||
|
abstract enum class ProtocolState {
|
||||||
|
WAITING {
|
||||||
|
override fun signal() = ProtocolState.TALKING
|
||||||
|
}
|
||||||
|
|
||||||
|
TALKING {
|
||||||
|
override fun signal() = ProtocolState.WAITING
|
||||||
|
}
|
||||||
|
|
||||||
|
abstract fun signal() : ProtocolState
|
||||||
|
}
|
||||||
|
|
||||||
|
fun t2() {
|
||||||
|
val x: ProtocolState = ProtocolState.WAITING
|
||||||
|
<!VAL_REASSIGNMENT!>x<!> = x.signal()
|
||||||
|
<!VAL_REASSIGNMENT!>x<!> = x.signal()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun t3() {
|
||||||
|
val x = 1
|
||||||
|
<!VAL_REASSIGNMENT!>x<!> += 2
|
||||||
|
val y = 3
|
||||||
|
<!VAL_REASSIGNMENT!>y<!> *= 4
|
||||||
|
var z = 5
|
||||||
|
z -= y
|
||||||
|
}
|
||||||
|
|
||||||
|
fun t4() {
|
||||||
|
for (i in 0..2) {
|
||||||
|
<!VAL_REASSIGNMENT!>i<!> += 1
|
||||||
|
fun t5() {
|
||||||
|
<!VAL_REASSIGNMENT!>i<!> += 3
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -176,23 +176,23 @@ fun testFunctionLiterals() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
val endsWithAssignment = { () : Int =>
|
val endsWithAssignment = { () : Int =>
|
||||||
val x = 1
|
var x = 1
|
||||||
<!EXPECTED_TYPE_MISMATCH!>x = 333<!>
|
<!EXPECTED_TYPE_MISMATCH!>x = 333<!>
|
||||||
}
|
}
|
||||||
|
|
||||||
val endsWithReAssignment = { () : Int =>
|
val endsWithReAssignment = { () : Int =>
|
||||||
val x = 1
|
var x = 1
|
||||||
<!EXPECTED_TYPE_MISMATCH!>x += 333<!>
|
<!EXPECTED_TYPE_MISMATCH!>x += 333<!>
|
||||||
}
|
}
|
||||||
|
|
||||||
val endsWithFunDeclaration : fun() : String = {
|
val endsWithFunDeclaration : fun() : String = {
|
||||||
val x = 1
|
var x = 1
|
||||||
x = 333
|
x = 333
|
||||||
<!EXPECTED_TYPE_MISMATCH!>fun meow() : Unit {}<!>
|
<!EXPECTED_TYPE_MISMATCH!>fun meow() : Unit {}<!>
|
||||||
}
|
}
|
||||||
|
|
||||||
val endsWithObjectDeclaration : fun() : Int = {
|
val endsWithObjectDeclaration : fun() : Int = {
|
||||||
val x = 1
|
var x = 1
|
||||||
x = 333
|
x = 333
|
||||||
<!EXPECTED_TYPE_MISMATCH!>object A {}<!>
|
<!EXPECTED_TYPE_MISMATCH!>object A {}<!>
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,8 +22,9 @@ fun testUnresolved() {
|
|||||||
|
|
||||||
//TODO
|
//TODO
|
||||||
for (j in <!UNRESOLVED_REFERENCE!>collection<!>) {
|
for (j in <!UNRESOLVED_REFERENCE!>collection<!>) {
|
||||||
val i: Int = j
|
var i: Int = j
|
||||||
j += 1
|
i += 1
|
||||||
|
foo1(j)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -1,5 +1,5 @@
|
|||||||
fun test() {
|
fun test() {
|
||||||
val a : Any? = null
|
var a : Any? = null
|
||||||
if (a is Any) else a = null;
|
if (a is Any) else a = null;
|
||||||
while (a is Any) a = null
|
while (a is Any) a = null
|
||||||
while (true) a = null
|
while (true) a = null
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ abstract enum class ProtocolState {
|
|||||||
|
|
||||||
|
|
||||||
fun box(): String {
|
fun box(): String {
|
||||||
val x: ProtocolState = ProtocolState.WAITING
|
var x: ProtocolState = ProtocolState.WAITING
|
||||||
x = x.signal()
|
x = x.signal()
|
||||||
if (x != ProtocolState.TALKING) return "fail 1"
|
if (x != ProtocolState.TALKING) return "fail 1"
|
||||||
x = x.signal()
|
x = x.signal()
|
||||||
|
|||||||
@@ -0,0 +1,21 @@
|
|||||||
|
trait T {
|
||||||
|
fun foo() {}
|
||||||
|
fun buzz() {}
|
||||||
|
fun buzz1(i : Int) {}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun T.bar() {}
|
||||||
|
|
||||||
|
fun T.buzz() {}
|
||||||
|
fun T.buzz1() {}
|
||||||
|
|
||||||
|
class C : T {
|
||||||
|
fun test() {
|
||||||
|
fun T.buzz() {}
|
||||||
|
fun T.buzz1() {}
|
||||||
|
super.foo() // OK
|
||||||
|
<!SUPER_IS_NOT_AN_EXPRESSION!>super<!>.bar() // Error
|
||||||
|
super.buzz() // OK, resolved to a member
|
||||||
|
super.<!NO_VALUE_FOR_PARAMETER!>buzz1<!>() // Resolved to a member, but error: no parameter passed where required
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,5 +1,17 @@
|
|||||||
namespace example;
|
namespace example;
|
||||||
|
|
||||||
|
fun any(a : Any) {}
|
||||||
|
|
||||||
|
fun notAnExpression() {
|
||||||
|
any(<!SUPER_IS_NOT_AN_EXPRESSION!>super<!>) // not an expression
|
||||||
|
if (<!SUPER_IS_NOT_AN_EXPRESSION!>super<!>) {} else {} // not an expression
|
||||||
|
val x = <!SUPER_IS_NOT_AN_EXPRESSION!>super<!> // not an expression
|
||||||
|
when (1) {
|
||||||
|
<!SUPER_IS_NOT_AN_EXPRESSION!>super<!> => 1 // not an expression
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
trait T {
|
trait T {
|
||||||
fun foo() {}
|
fun foo() {}
|
||||||
}
|
}
|
||||||
@@ -72,6 +84,6 @@ class ERROR<E>() : <!UNRESOLVED_REFERENCE!>UR<!> {
|
|||||||
// No supertype at all
|
// No supertype at all
|
||||||
class A1 {
|
class A1 {
|
||||||
fun test() {
|
fun test() {
|
||||||
super.equals(null)
|
<!SUPER_IS_NOT_AN_EXPRESSION!>super<!>.equals(null)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
fun foo(f : fun()) {
|
||||||
|
val x : Unit = f()
|
||||||
|
}
|
||||||
+13
@@ -0,0 +1,13 @@
|
|||||||
|
trait Iterator<out T> {
|
||||||
|
fun next() : T
|
||||||
|
val hasNext : Boolean
|
||||||
|
|
||||||
|
fun <R> map(transform: fun(element: T) : R) : Iterator<R> =
|
||||||
|
object : Iterator<R> {
|
||||||
|
override fun next() : R = transform(<!NO_THIS!>this@map<!>.next())
|
||||||
|
|
||||||
|
override val hasNext : Boolean
|
||||||
|
// There's no 'this' associated with the map() function, only this of the Iterator class
|
||||||
|
get() = <!NO_THIS!>this@map<!>.hasNext
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -17,7 +17,7 @@ class ArrayWrapper<T>() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun box(): String {
|
fun box(): String {
|
||||||
val v1 = ArrayWrapper<String>()
|
var v1 = ArrayWrapper<String>()
|
||||||
val v2 = ArrayWrapper<String>()
|
val v2 = ArrayWrapper<String>()
|
||||||
v1.add("foo")
|
v1.add("foo")
|
||||||
v2.add("bar")
|
v2.add("bar")
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ class ArrayWrapper<T>() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun box(): String {
|
fun box(): String {
|
||||||
val v1 = ArrayWrapper<String>()
|
var v1 = ArrayWrapper<String>()
|
||||||
val v2 = ArrayWrapper<String>()
|
val v2 = ArrayWrapper<String>()
|
||||||
v1.add("foo")
|
v1.add("foo")
|
||||||
val v3 = v1
|
val v3 = v1
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ class ArrayWrapper<T>() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun box(): String {
|
fun box(): String {
|
||||||
val v1 = ArrayWrapper<String>()
|
var v1 = ArrayWrapper<String>()
|
||||||
val v2 = ArrayWrapper<String>()
|
val v2 = ArrayWrapper<String>()
|
||||||
v1.add("foo")
|
v1.add("foo")
|
||||||
val v3 = v1
|
val v3 = v1
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ fun box() : String {
|
|||||||
a[1] = "b"
|
a[1] = "b"
|
||||||
a[2] = "c"
|
a[2] = "c"
|
||||||
|
|
||||||
val result = 0
|
var result = 0
|
||||||
for(i in a.indices) {
|
for(i in a.indices) {
|
||||||
result += i
|
result += i
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -88,7 +88,8 @@ class MyCollection2(): Iterable<Int> {
|
|||||||
var k : Int = 5
|
var k : Int = 5
|
||||||
|
|
||||||
override fun next() : Int = k--
|
override fun next() : Int = k--
|
||||||
override fun hasNext() = k > 0
|
override val hasNext : Boolean
|
||||||
|
get() = k > 0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -99,7 +100,8 @@ class MyCollection3() {
|
|||||||
var k : Int = 5
|
var k : Int = 5
|
||||||
|
|
||||||
fun next() : Int? = k--
|
fun next() : Int? = k--
|
||||||
fun hasNext() = k > 0
|
val hasNext : Boolean
|
||||||
|
get() = k > 0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -107,11 +107,15 @@ public class JetControlFlowTest extends JetTestCaseBase {
|
|||||||
//check edges directions
|
//check edges directions
|
||||||
Collection<Instruction> instructions = pseudocode.getInstructions();
|
Collection<Instruction> instructions = pseudocode.getInstructions();
|
||||||
for (Instruction instruction : instructions) {
|
for (Instruction instruction : instructions) {
|
||||||
for (Instruction nextInstruction : instruction.getNextInstructions()) {
|
if (!((InstructionImpl) instruction).isDead()) {
|
||||||
assertTrue("instruction: " + instruction + " next: " + nextInstruction, nextInstruction.getPreviousInstructions().contains(instruction));
|
for (Instruction nextInstruction : instruction.getNextInstructions()) {
|
||||||
}
|
assertTrue("instruction '" + instruction + "' has '" + nextInstruction + "' among next instructions list, but not vice versa",
|
||||||
for (Instruction prevInstruction : instruction.getPreviousInstructions()) {
|
nextInstruction.getPreviousInstructions().contains(instruction));
|
||||||
assertTrue("instruction: " + instruction + " prev: " + prevInstruction, prevInstruction.getNextInstructions().contains(instruction));
|
}
|
||||||
|
for (Instruction prevInstruction : instruction.getPreviousInstructions()) {
|
||||||
|
assertTrue("instruction '" + instruction + "' has '" + prevInstruction + "' among previous instructions list, but not vice versa",
|
||||||
|
prevInstruction.getNextInstructions().contains(instruction));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -150,13 +154,14 @@ public class JetControlFlowTest extends JetTestCaseBase {
|
|||||||
|
|
||||||
private static String formatInstruction(Instruction instruction, int maxLength) {
|
private static String formatInstruction(Instruction instruction, int maxLength) {
|
||||||
String[] parts = instruction.toString().split("\n");
|
String[] parts = instruction.toString().split("\n");
|
||||||
|
String prefix = ((InstructionImpl)instruction).isDead() ? "* " : " ";
|
||||||
if (parts.length == 1) {
|
if (parts.length == 1) {
|
||||||
return " " + String.format("%1$-" + maxLength + "s", instruction);
|
return prefix + String.format("%1$-" + maxLength + "s", instruction);
|
||||||
}
|
}
|
||||||
StringBuilder sb = new StringBuilder();
|
StringBuilder sb = new StringBuilder();
|
||||||
for (int i = 0, partsLength = parts.length; i < partsLength; i++) {
|
for (int i = 0, partsLength = parts.length; i < partsLength; i++) {
|
||||||
String part = parts[i];
|
String part = parts[i];
|
||||||
sb.append(" ").append(String.format("%1$-" + maxLength + "s", part));
|
sb.append(prefix).append(String.format("%1$-" + maxLength + "s", part));
|
||||||
if (i < partsLength - 1) sb.append("\n");
|
if (i < partsLength - 1) sb.append("\n");
|
||||||
}
|
}
|
||||||
return sb.toString();
|
return sb.toString();
|
||||||
@@ -210,7 +215,9 @@ public class JetControlFlowTest extends JetTestCaseBase {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
maxLength = instuctionText.length();
|
if (instuctionText.length() > maxLength) {
|
||||||
|
maxLength = instuctionText.length();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
String instructionListText = formatInstructionList(instruction.getNextInstructions());
|
String instructionListText = formatInstructionList(instruction.getNextInstructions());
|
||||||
|
|||||||
@@ -56,42 +56,42 @@ public class ArrayGenTest extends CodegenTestCase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void testIterator () throws Exception {
|
public void testIterator () throws Exception {
|
||||||
loadText("fun box() { val x = Array<Int>(5, { it } ).iterator(); while(x.hasNext()) { java.lang.System.out?.println(x.next()) } }");
|
loadText("fun box() { val x = Array<Int>(5, { it } ).iterator(); while(x.hasNext) { java.lang.System.out?.println(x.next()) } }");
|
||||||
System.out.println(generateToText());
|
System.out.println(generateToText());
|
||||||
Method foo = generateFunction();
|
Method foo = generateFunction();
|
||||||
foo.invoke(null);
|
foo.invoke(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testPrimitiveIterator () throws Exception {
|
public void testPrimitiveIterator () throws Exception {
|
||||||
loadText("fun box() { val x = ByteArray(5).iterator(); while(x.hasNext()) { java.lang.System.out?.println(x.next()) } }");
|
loadText("fun box() { val x = ByteArray(5).iterator(); while(x.hasNext) { java.lang.System.out?.println(x.next()) } }");
|
||||||
System.out.println(generateToText());
|
System.out.println(generateToText());
|
||||||
Method foo = generateFunction();
|
Method foo = generateFunction();
|
||||||
foo.invoke(null);
|
foo.invoke(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testLongIterator () throws Exception {
|
public void testLongIterator () throws Exception {
|
||||||
loadText("fun box() { val x = LongArray(5).iterator(); while(x.hasNext()) { java.lang.System.out?.println(x.next()) } }");
|
loadText("fun box() { val x = LongArray(5).iterator(); while(x.hasNext) { java.lang.System.out?.println(x.next()) } }");
|
||||||
System.out.println(generateToText());
|
System.out.println(generateToText());
|
||||||
Method foo = generateFunction();
|
Method foo = generateFunction();
|
||||||
foo.invoke(null);
|
foo.invoke(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testCharIterator () throws Exception {
|
public void testCharIterator () throws Exception {
|
||||||
loadText("fun box() { val x = CharArray(5).iterator(); while(x.hasNext()) { java.lang.System.out?.println(x.next()) } }");
|
loadText("fun box() { val x = CharArray(5).iterator(); while(x.hasNext) { java.lang.System.out?.println(x.next()) } }");
|
||||||
System.out.println(generateToText());
|
System.out.println(generateToText());
|
||||||
Method foo = generateFunction();
|
Method foo = generateFunction();
|
||||||
foo.invoke(null);
|
foo.invoke(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testArrayIndices () throws Exception {
|
public void testArrayIndices () throws Exception {
|
||||||
loadText("fun box() { val x = Array<Int>(5, {it}).indices.iterator(); while(x.hasNext()) { java.lang.System.out?.println(x.next()) } }");
|
loadText("fun box() { val x = Array<Int>(5, {it}).indices.iterator(); while(x.hasNext) { java.lang.System.out?.println(x.next()) } }");
|
||||||
System.out.println(generateToText());
|
System.out.println(generateToText());
|
||||||
Method foo = generateFunction();
|
Method foo = generateFunction();
|
||||||
foo.invoke(null);
|
foo.invoke(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testCharIndices () throws Exception {
|
public void testCharIndices () throws Exception {
|
||||||
loadText("fun box() { val x = CharArray(5).indices.iterator(); while(x.hasNext()) { java.lang.System.out?.println(x.next()) } }");
|
loadText("fun box() { val x = CharArray(5).indices.iterator(); while(x.hasNext) { java.lang.System.out?.println(x.next()) } }");
|
||||||
System.out.println(generateToText());
|
System.out.println(generateToText());
|
||||||
Method foo = generateFunction();
|
Method foo = generateFunction();
|
||||||
foo.invoke(null);
|
foo.invoke(null);
|
||||||
|
|||||||
@@ -1,5 +1,8 @@
|
|||||||
package org.jetbrains.jet.codegen;
|
package org.jetbrains.jet.codegen;
|
||||||
|
|
||||||
|
import java.lang.reflect.InvocationTargetException;
|
||||||
|
import java.lang.reflect.Method;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author alex.tkachman
|
* @author alex.tkachman
|
||||||
*/
|
*/
|
||||||
@@ -13,4 +16,29 @@ public class FunctionGenTest extends CodegenTestCase {
|
|||||||
blackBoxFile("functions/nothisnoclosure.jet");
|
blackBoxFile("functions/nothisnoclosure.jet");
|
||||||
System.out.println(generateToText());
|
System.out.println(generateToText());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void testAnyToString () throws InvocationTargetException, IllegalAccessException {
|
||||||
|
loadText("fun foo(x: Any) = x.toString()");
|
||||||
|
System.out.println(generateToText());
|
||||||
|
Method foo = generateFunction();
|
||||||
|
assertEquals("something", foo.invoke(null, "something"));
|
||||||
|
assertEquals("null", foo.invoke(null, new Object[]{null}));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testAnyEqualsNullable () throws InvocationTargetException, IllegalAccessException {
|
||||||
|
loadText("fun foo(x: Any?) = x.equals(\"lala\")");
|
||||||
|
System.out.println(generateToText());
|
||||||
|
Method foo = generateFunction();
|
||||||
|
assertTrue((Boolean) foo.invoke(null, "lala"));
|
||||||
|
assertFalse((Boolean) foo.invoke(null, "mama"));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testAnyEquals () throws InvocationTargetException, IllegalAccessException {
|
||||||
|
loadText("fun foo(x: Any) = x.equals(\"lala\")");
|
||||||
|
System.out.println(generateToText());
|
||||||
|
Method foo = generateFunction();
|
||||||
|
assertTrue((Boolean) foo.invoke(null, "lala"));
|
||||||
|
assertFalse((Boolean) foo.invoke(null, "mama"));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -268,7 +268,7 @@ public class NamespaceGenTest extends CodegenTestCase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void testStringPlusEq() throws Exception {
|
public void testStringPlusEq() throws Exception {
|
||||||
loadText("fun foo(s: String) : String { val result = s; result += s; return result; } ");
|
loadText("fun foo(s: String) : String { var result = s; result += s; return result; } ");
|
||||||
System.out.println(generateToText());
|
System.out.println(generateToText());
|
||||||
final Method main = generateFunction();
|
final Method main = generateFunction();
|
||||||
assertEquals("JarJar", main.invoke(null, "Jar"));
|
assertEquals("JarJar", main.invoke(null, "Jar"));
|
||||||
|
|||||||
@@ -0,0 +1,29 @@
|
|||||||
|
package org.jetbrains.jet.codegen;
|
||||||
|
|
||||||
|
import java.lang.reflect.InvocationTargetException;
|
||||||
|
import java.lang.reflect.Method;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author alex.tkachman
|
||||||
|
*/
|
||||||
|
public class VarArgTest extends CodegenTestCase {
|
||||||
|
public void testStringArray () throws InvocationTargetException, IllegalAccessException {
|
||||||
|
/*
|
||||||
|
loadText("fun test(vararg ts: String) = ts");
|
||||||
|
System.out.println(generateToText());
|
||||||
|
final Method main = generateFunction();
|
||||||
|
Object[] args = {"mama", "papa"};
|
||||||
|
assertTrue(args == main.invoke(null, args));
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testIntArray () throws InvocationTargetException, IllegalAccessException {
|
||||||
|
/*
|
||||||
|
loadText("fun test(vararg ts: Int) = ts");
|
||||||
|
System.out.println(generateToText());
|
||||||
|
final Method main = generateFunction();
|
||||||
|
int[] args = {3, 4};
|
||||||
|
assertTrue(args == main.invoke(null, args));
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,15 +1,15 @@
|
|||||||
open class IEquality {
|
trait IEquality {
|
||||||
fun equals(other : Any) : Boolean
|
fun equals(other : Any) : Boolean
|
||||||
= (this as java.lang.Object).equals(other as java.lang.Object)
|
= (this as java.lang.Object).equals(other as java.lang.Object)
|
||||||
}
|
}
|
||||||
|
|
||||||
open class IHashable : IEquality {
|
trait IHashable : IEquality {
|
||||||
val hashCode : Integer
|
val hashCode : Integer
|
||||||
get() = (this as java.lang.Object).hashCode()
|
get() = (this as java.lang.Object).hashCode()
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
open class IMap<K, V> {
|
trait IMap<K : IHashable, V> {
|
||||||
fun get(key : K) : V
|
fun get(key : K) : V
|
||||||
fun set(key : K, value : V) : V
|
fun set(key : K, value : V) : V
|
||||||
fun remove(key : K) : V
|
fun remove(key : K) : V
|
||||||
@@ -21,7 +21,7 @@ class HashableWrapper wraps (val obj : Any) : IHashable
|
|||||||
|
|
||||||
[inline] fun Any.hashable() : HashableWrapper = new HashableWrapper(this)
|
[inline] fun Any.hashable() : HashableWrapper = new HashableWrapper(this)
|
||||||
|
|
||||||
open class IHashingStrategy<K> {
|
trait IHashingStrategy<K : IHashable> {
|
||||||
fun equals(a : K, b : K) : Boolean
|
fun equals(a : K, b : K) : Boolean
|
||||||
fun hashCode(a : K) : Integer
|
fun hashCode(a : K) : Integer
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,3 +0,0 @@
|
|||||||
open class IIterable<out T> {
|
|
||||||
fun iterator() : IIterator<T>
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
namespace jet.collections.iterable
|
||||||
|
|
||||||
|
import jet.collections.iterator.IIterator
|
||||||
|
|
||||||
|
trait IIterable<out T> {
|
||||||
|
fun iterator() : IIterator<T>
|
||||||
|
|
||||||
|
inline fun foreach(operation: fun(element: T) : Unit) = iterator() foreach operation
|
||||||
|
}
|
||||||
@@ -1,25 +0,0 @@
|
|||||||
open class IIterator<out T> {
|
|
||||||
fun next() : T
|
|
||||||
val hasNext : Boolean
|
|
||||||
|
|
||||||
fun toArray(buffer : MutableArray<in T>) : Int { // T is still an in-parameter
|
|
||||||
return fillBuffer(buffer, 0, buffer.size)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun toArray(buffer : MutableArray<in T>, from : Int, length : Int) : Int { // T is still an in-parameter
|
|
||||||
if (from < 0 || from > buffer.lastIndex || length < 0 || length > buffer.size - from) {
|
|
||||||
throw IndexOutOfBoundsException();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (len == 0) return 0
|
|
||||||
|
|
||||||
var count = 0;
|
|
||||||
for (i in from .. from + length - 1) {
|
|
||||||
if (!hasNext)
|
|
||||||
return count
|
|
||||||
buffer[i] = next()
|
|
||||||
count++
|
|
||||||
}
|
|
||||||
return count
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,4 +0,0 @@
|
|||||||
open class IList<out T> : IIterable<T>, ISized {
|
|
||||||
[operator] fun get(index : Int) : T
|
|
||||||
val isEmpty : Boolean
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
trait IList<out T> : IIterable<T>, ISized {
|
||||||
|
fun get(index : Int) : T
|
||||||
|
}
|
||||||
@@ -1,3 +0,0 @@
|
|||||||
open class ISet<T> : IIterable<T>, ISized {
|
|
||||||
fun contains(item : T) : Boolean
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
namespace jet.collections.set
|
||||||
|
|
||||||
|
import jet.collections.sized.ISized
|
||||||
|
import jet.collections.iterable.IIterable
|
||||||
|
|
||||||
|
trait ISet<T> : IIterable<T>, ISized {
|
||||||
|
fun contains(item : T) : Boolean
|
||||||
|
}
|
||||||
@@ -1,3 +0,0 @@
|
|||||||
open class ISized {
|
|
||||||
val size : Int
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
namespace jet.collections.sized
|
||||||
|
|
||||||
|
trait ISized {
|
||||||
|
val size : Int
|
||||||
|
|
||||||
|
val isEmpty : Boolean
|
||||||
|
get() = size == 0
|
||||||
|
|
||||||
|
val isNonEmpty : Boolean
|
||||||
|
get() = size != 0
|
||||||
|
}
|
||||||
@@ -0,0 +1,170 @@
|
|||||||
|
namespace jet.collections
|
||||||
|
|
||||||
|
import java.util.NoSuchElementException
|
||||||
|
|
||||||
|
trait Iterator<out T> {
|
||||||
|
fun next() : T
|
||||||
|
val hasNext : Boolean
|
||||||
|
|
||||||
|
fun <R> map(transform: fun(element: T) : R) : Iterator<R> =
|
||||||
|
object : Iterator<R> {
|
||||||
|
override fun next() : R = transform(this@map.next())
|
||||||
|
|
||||||
|
override val hasNext : Boolean
|
||||||
|
get() = this@map.hasNext
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
trait ISized {
|
||||||
|
val size : Int
|
||||||
|
}
|
||||||
|
|
||||||
|
val ISized.isEmpty : Boolean
|
||||||
|
get() = size == 0
|
||||||
|
|
||||||
|
val ISized.isNonEmpty : Boolean
|
||||||
|
get() = size != 0
|
||||||
|
|
||||||
|
trait ISet<T> : Iterable<T>, ISized {
|
||||||
|
fun contains(item : T) : Boolean
|
||||||
|
}
|
||||||
|
|
||||||
|
trait IList<out T> : Iterable<T>, ISized {
|
||||||
|
fun get(index : Int) : T
|
||||||
|
|
||||||
|
fun iterator() : Iterator<T> =
|
||||||
|
object Iterator<T> {
|
||||||
|
var index = 0
|
||||||
|
|
||||||
|
override fun next() : T = get(index++)
|
||||||
|
|
||||||
|
override val hasNext : Boolean
|
||||||
|
get() = index < size
|
||||||
|
}
|
||||||
|
|
||||||
|
fun toArray() : Array<T> = Array<T>(size) { index => get(index) }
|
||||||
|
}
|
||||||
|
|
||||||
|
fun <T> Array<T>.asList() : IList<T> = object IList<T> {
|
||||||
|
override val size
|
||||||
|
get() = this@Array.size
|
||||||
|
|
||||||
|
override fun get(index: Int) = this@asList[index]
|
||||||
|
}
|
||||||
|
|
||||||
|
fun <T> Iterator<T>.foreach(operation: fun(element: T) : Unit) : Unit = while(hasNext) operation(next())
|
||||||
|
|
||||||
|
fun <T> Iterator<T>.foreach(operation: fun(index: Int, element: T) : Unit) : Unit {
|
||||||
|
var k = 0
|
||||||
|
while(hasNext)
|
||||||
|
operation(k++, next())
|
||||||
|
}
|
||||||
|
|
||||||
|
fun <T> Iterable<T>.foreach(operation: fun(element: T) : Unit) : Unit = iterator() foreach operation
|
||||||
|
|
||||||
|
fun <T> Iterable<T>.foreach(operation: fun(index: Int, element: T) : Unit) : Unit = iterator() foreach operation
|
||||||
|
|
||||||
|
fun <T,R> Iterable<T>.foldLeft(init: R, operation: fun(accumulated: R, element: T) : R) : R =
|
||||||
|
iterator () foreach operation
|
||||||
|
|
||||||
|
fun <T,R> Iterable<T>.foldLeft(init: R, operation: fun(accumulated: R, index: Int, element: T) : R) : R =
|
||||||
|
iterator () foreach operation
|
||||||
|
|
||||||
|
fun <T,R> Iterator<T>.foldLeft(init: R, operation: fun(accumulated: R, element: T) : R) : R {
|
||||||
|
while(hasNext)
|
||||||
|
init = operation(init, next())
|
||||||
|
return init
|
||||||
|
}
|
||||||
|
|
||||||
|
fun <T,R> Iterator<T>.foldLeft(init: R, operation: fun(accumulated: R, index: Int, element: T) : R) : R {
|
||||||
|
var k = 0
|
||||||
|
while(hasNext)
|
||||||
|
init = operation(init, k++, next())
|
||||||
|
return init
|
||||||
|
}
|
||||||
|
|
||||||
|
fun <T,R> Iterator<T>.map(transform: fun(element: T) : R) : Iterator<R> =
|
||||||
|
object : Iterator<R> {
|
||||||
|
override fun next() : R = transform(this@map.next())
|
||||||
|
|
||||||
|
override val hasNext : Boolean
|
||||||
|
get() = this@map.hasNext
|
||||||
|
}
|
||||||
|
|
||||||
|
fun <T,R> Iterator<T>.map(transform: fun(index: Int, element: T) : R) : Iterator<R> {
|
||||||
|
return object : Iterator<R> {
|
||||||
|
var index = 0
|
||||||
|
|
||||||
|
override fun next() : R = transform(index++, this@map.next())
|
||||||
|
|
||||||
|
override val hasNext : Boolean
|
||||||
|
get() = this@map.hasNext
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun <T> Iterator<T>.plus(other: Iterator<T>) : Iterator<T> =
|
||||||
|
object : Iterator<T> {
|
||||||
|
override fun next() : T = if(this@plus.hasNext) this@plus.next() else other.next()
|
||||||
|
|
||||||
|
override val hasNext : Boolean
|
||||||
|
get() = this@plus.hasNext || other.hasNext
|
||||||
|
}
|
||||||
|
|
||||||
|
fun <T> Iterator<T>.filter(condition: fun(element: T) : Boolean) : Iterator<T> {
|
||||||
|
return object : Iterator<T> {
|
||||||
|
private var _next : T = null
|
||||||
|
private var _lookedAhead : Boolean = false
|
||||||
|
private var _hasNext : Boolean = false
|
||||||
|
|
||||||
|
private fun lookAhead() : Boolean {
|
||||||
|
if(!_lookedAhead) {
|
||||||
|
_lookedAhead = true
|
||||||
|
while(this@filter.hasNext) {
|
||||||
|
_next = this@filter.next()
|
||||||
|
if(condition(_next)) {
|
||||||
|
_hasNext = true
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return _hasNext
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun next() : T {
|
||||||
|
lookAhead()
|
||||||
|
_lookedAhead = false
|
||||||
|
if(_hasNext) {
|
||||||
|
val res = _next
|
||||||
|
_next = null
|
||||||
|
_hasNext = false
|
||||||
|
return res
|
||||||
|
}
|
||||||
|
throw NoSuchElementException()
|
||||||
|
}
|
||||||
|
|
||||||
|
override val hasNext : Boolean
|
||||||
|
get() = lookAhead()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
fun toArray(buffer : MutableArray<in T>) : Int { // T is still an in-parameter
|
||||||
|
return fillBuffer(buffer, 0, buffer.size)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun toArray(buffer : MutableArray<in T>, from : Int, length : Int) : Int { // T is still an in-parameter
|
||||||
|
if (from < 0 || from > buffer.lastIndex || length < 0 || length > buffer.size - from) {
|
||||||
|
throw IndexOutOfBoundsException();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (len == 0) return 0
|
||||||
|
|
||||||
|
var count = 0;
|
||||||
|
for (i in from .. from + length - 1) {
|
||||||
|
if (!hasNext)
|
||||||
|
return count
|
||||||
|
buffer[i] = next()
|
||||||
|
count++
|
||||||
|
}
|
||||||
|
return count
|
||||||
|
}
|
||||||
|
*/
|
||||||
@@ -47,11 +47,7 @@ optionalProjection
|
|||||||
;
|
;
|
||||||
|
|
||||||
functionType
|
functionType
|
||||||
: "fun" (type ".")? functionTypeContents
|
: "fun" (type ".")? "(" (parameter | modifiers /*lazy out ref*/ type){","} ")" (":" type)? // Unit by default
|
||||||
;
|
|
||||||
|
|
||||||
functionTypeContents
|
|
||||||
: "(" (parameter | modifiers /*lazy out ref*/ type){","} ")" ":" type
|
|
||||||
;
|
;
|
||||||
|
|
||||||
tupleType
|
tupleType
|
||||||
|
|||||||
@@ -1,19 +1,19 @@
|
|||||||
/*
|
/*
|
||||||
* @author max
|
* @author alex.tkachman
|
||||||
*/
|
*/
|
||||||
package jet;
|
package jet;
|
||||||
|
|
||||||
import jet.typeinfo.TypeInfo;
|
import jet.typeinfo.TypeInfo;
|
||||||
|
public abstract class ExtensionFunction1<E, D1, R> extends DefaultJetObject {
|
||||||
public abstract class ExtensionFunction1<E, D, R> extends DefaultJetObject{
|
|
||||||
protected ExtensionFunction1(TypeInfo<?> typeInfo) {
|
protected ExtensionFunction1(TypeInfo<?> typeInfo) {
|
||||||
super(typeInfo);
|
super(typeInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
public abstract R invoke(E receiver, D d);
|
public abstract R invoke(E receiver, D1 d1);
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return "{E.(d: D) : R}";
|
return "{E.(d1: D1) : R)}";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,19 @@
|
|||||||
|
/*
|
||||||
|
* @author alex.tkachman
|
||||||
|
*/
|
||||||
|
package jet;
|
||||||
|
|
||||||
|
import jet.typeinfo.TypeInfo;
|
||||||
|
public abstract class ExtensionFunction10<E, D1, D2, D3, D4, D5, D6, D7, D8, D9, D10, R> extends DefaultJetObject {
|
||||||
|
protected ExtensionFunction10(TypeInfo<?> typeInfo) {
|
||||||
|
super(typeInfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
public abstract R invoke(E receiver, D1 d1, D2 d2, D3 d3, D4 d4, D5 d5, D6 d6, D7 d7, D8 d8, D9 d9, D10 d10);
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "{E.(d1: D1, d2: D2, d3: D3, d4: D4, d5: D5, d6: D6, d7: D7, d8: D8, d9: D9, d10: D10) : R)}";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
/*
|
||||||
|
* @author alex.tkachman
|
||||||
|
*/
|
||||||
|
package jet;
|
||||||
|
|
||||||
|
import jet.typeinfo.TypeInfo;
|
||||||
|
public abstract class ExtensionFunction11<E, D1, D2, D3, D4, D5, D6, D7, D8, D9, D10, D11, R> extends DefaultJetObject {
|
||||||
|
protected ExtensionFunction11(TypeInfo<?> typeInfo) {
|
||||||
|
super(typeInfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
public abstract R invoke(E receiver, D1 d1, D2 d2, D3 d3, D4 d4, D5 d5, D6 d6, D7 d7, D8 d8, D9 d9, D10 d10, D11 d11);
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "{E.(d1: D1, d2: D2, d3: D3, d4: D4, d5: D5, d6: D6, d7: D7, d8: D8, d9: D9, d10: D10, d11: D11) : R)}";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
/*
|
||||||
|
* @author alex.tkachman
|
||||||
|
*/
|
||||||
|
package jet;
|
||||||
|
|
||||||
|
import jet.typeinfo.TypeInfo;
|
||||||
|
public abstract class ExtensionFunction12<E, D1, D2, D3, D4, D5, D6, D7, D8, D9, D10, D11, D12, R> extends DefaultJetObject {
|
||||||
|
protected ExtensionFunction12(TypeInfo<?> typeInfo) {
|
||||||
|
super(typeInfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
public abstract R invoke(E receiver, D1 d1, D2 d2, D3 d3, D4 d4, D5 d5, D6 d6, D7 d7, D8 d8, D9 d9, D10 d10, D11 d11, D12 d12);
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "{E.(d1: D1, d2: D2, d3: D3, d4: D4, d5: D5, d6: D6, d7: D7, d8: D8, d9: D9, d10: D10, d11: D11, d12: D12) : R)}";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
/*
|
||||||
|
* @author alex.tkachman
|
||||||
|
*/
|
||||||
|
package jet;
|
||||||
|
|
||||||
|
import jet.typeinfo.TypeInfo;
|
||||||
|
public abstract class ExtensionFunction13<E, D1, D2, D3, D4, D5, D6, D7, D8, D9, D10, D11, D12, D13, R> extends DefaultJetObject {
|
||||||
|
protected ExtensionFunction13(TypeInfo<?> typeInfo) {
|
||||||
|
super(typeInfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
public abstract R invoke(E receiver, D1 d1, D2 d2, D3 d3, D4 d4, D5 d5, D6 d6, D7 d7, D8 d8, D9 d9, D10 d10, D11 d11, D12 d12, D13 d13);
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "{E.(d1: D1, d2: D2, d3: D3, d4: D4, d5: D5, d6: D6, d7: D7, d8: D8, d9: D9, d10: D10, d11: D11, d12: D12, d13: D13) : R)}";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
/*
|
||||||
|
* @author alex.tkachman
|
||||||
|
*/
|
||||||
|
package jet;
|
||||||
|
|
||||||
|
import jet.typeinfo.TypeInfo;
|
||||||
|
public abstract class ExtensionFunction14<E, D1, D2, D3, D4, D5, D6, D7, D8, D9, D10, D11, D12, D13, D14, R> extends DefaultJetObject {
|
||||||
|
protected ExtensionFunction14(TypeInfo<?> typeInfo) {
|
||||||
|
super(typeInfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
public abstract R invoke(E receiver, D1 d1, D2 d2, D3 d3, D4 d4, D5 d5, D6 d6, D7 d7, D8 d8, D9 d9, D10 d10, D11 d11, D12 d12, D13 d13, D14 d14);
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "{E.(d1: D1, d2: D2, d3: D3, d4: D4, d5: D5, d6: D6, d7: D7, d8: D8, d9: D9, d10: D10, d11: D11, d12: D12, d13: D13, d14: D14) : R)}";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
/*
|
||||||
|
* @author alex.tkachman
|
||||||
|
*/
|
||||||
|
package jet;
|
||||||
|
|
||||||
|
import jet.typeinfo.TypeInfo;
|
||||||
|
public abstract class ExtensionFunction15<E, D1, D2, D3, D4, D5, D6, D7, D8, D9, D10, D11, D12, D13, D14, D15, R> extends DefaultJetObject {
|
||||||
|
protected ExtensionFunction15(TypeInfo<?> typeInfo) {
|
||||||
|
super(typeInfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
public abstract R invoke(E receiver, D1 d1, D2 d2, D3 d3, D4 d4, D5 d5, D6 d6, D7 d7, D8 d8, D9 d9, D10 d10, D11 d11, D12 d12, D13 d13, D14 d14, D15 d15);
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "{E.(d1: D1, d2: D2, d3: D3, d4: D4, d5: D5, d6: D6, d7: D7, d8: D8, d9: D9, d10: D10, d11: D11, d12: D12, d13: D13, d14: D14, d15: D15) : R)}";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
/*
|
||||||
|
* @author alex.tkachman
|
||||||
|
*/
|
||||||
|
package jet;
|
||||||
|
|
||||||
|
import jet.typeinfo.TypeInfo;
|
||||||
|
public abstract class ExtensionFunction16<E, D1, D2, D3, D4, D5, D6, D7, D8, D9, D10, D11, D12, D13, D14, D15, D16, R> extends DefaultJetObject {
|
||||||
|
protected ExtensionFunction16(TypeInfo<?> typeInfo) {
|
||||||
|
super(typeInfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
public abstract R invoke(E receiver, D1 d1, D2 d2, D3 d3, D4 d4, D5 d5, D6 d6, D7 d7, D8 d8, D9 d9, D10 d10, D11 d11, D12 d12, D13 d13, D14 d14, D15 d15, D16 d16);
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "{E.(d1: D1, d2: D2, d3: D3, d4: D4, d5: D5, d6: D6, d7: D7, d8: D8, d9: D9, d10: D10, d11: D11, d12: D12, d13: D13, d14: D14, d15: D15, d16: D16) : R)}";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
/*
|
||||||
|
* @author alex.tkachman
|
||||||
|
*/
|
||||||
|
package jet;
|
||||||
|
|
||||||
|
import jet.typeinfo.TypeInfo;
|
||||||
|
public abstract class ExtensionFunction17<E, D1, D2, D3, D4, D5, D6, D7, D8, D9, D10, D11, D12, D13, D14, D15, D16, D17, R> extends DefaultJetObject {
|
||||||
|
protected ExtensionFunction17(TypeInfo<?> typeInfo) {
|
||||||
|
super(typeInfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
public abstract R invoke(E receiver, D1 d1, D2 d2, D3 d3, D4 d4, D5 d5, D6 d6, D7 d7, D8 d8, D9 d9, D10 d10, D11 d11, D12 d12, D13 d13, D14 d14, D15 d15, D16 d16, D17 d17);
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "{E.(d1: D1, d2: D2, d3: D3, d4: D4, d5: D5, d6: D6, d7: D7, d8: D8, d9: D9, d10: D10, d11: D11, d12: D12, d13: D13, d14: D14, d15: D15, d16: D16, d17: D17) : R)}";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
/*
|
||||||
|
* @author alex.tkachman
|
||||||
|
*/
|
||||||
|
package jet;
|
||||||
|
|
||||||
|
import jet.typeinfo.TypeInfo;
|
||||||
|
public abstract class ExtensionFunction18<E, D1, D2, D3, D4, D5, D6, D7, D8, D9, D10, D11, D12, D13, D14, D15, D16, D17, D18, R> extends DefaultJetObject {
|
||||||
|
protected ExtensionFunction18(TypeInfo<?> typeInfo) {
|
||||||
|
super(typeInfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
public abstract R invoke(E receiver, D1 d1, D2 d2, D3 d3, D4 d4, D5 d5, D6 d6, D7 d7, D8 d8, D9 d9, D10 d10, D11 d11, D12 d12, D13 d13, D14 d14, D15 d15, D16 d16, D17 d17, D18 d18);
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "{E.(d1: D1, d2: D2, d3: D3, d4: D4, d5: D5, d6: D6, d7: D7, d8: D8, d9: D9, d10: D10, d11: D11, d12: D12, d13: D13, d14: D14, d15: D15, d16: D16, d17: D17, d18: D18) : R)}";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
/*
|
||||||
|
* @author alex.tkachman
|
||||||
|
*/
|
||||||
|
package jet;
|
||||||
|
|
||||||
|
import jet.typeinfo.TypeInfo;
|
||||||
|
public abstract class ExtensionFunction19<E, D1, D2, D3, D4, D5, D6, D7, D8, D9, D10, D11, D12, D13, D14, D15, D16, D17, D18, D19, R> extends DefaultJetObject {
|
||||||
|
protected ExtensionFunction19(TypeInfo<?> typeInfo) {
|
||||||
|
super(typeInfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
public abstract R invoke(E receiver, D1 d1, D2 d2, D3 d3, D4 d4, D5 d5, D6 d6, D7 d7, D8 d8, D9 d9, D10 d10, D11 d11, D12 d12, D13 d13, D14 d14, D15 d15, D16 d16, D17 d17, D18 d18, D19 d19);
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "{E.(d1: D1, d2: D2, d3: D3, d4: D4, d5: D5, d6: D6, d7: D7, d8: D8, d9: D9, d10: D10, d11: D11, d12: D12, d13: D13, d14: D14, d15: D15, d16: D16, d17: D17, d18: D18, d19: D19) : R)}";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@@ -1,11 +1,10 @@
|
|||||||
/*
|
/*
|
||||||
* @author max
|
* @author alex.tkachman
|
||||||
*/
|
*/
|
||||||
package jet;
|
package jet;
|
||||||
|
|
||||||
import jet.typeinfo.TypeInfo;
|
import jet.typeinfo.TypeInfo;
|
||||||
|
public abstract class ExtensionFunction2<E, D1, D2, R> extends DefaultJetObject {
|
||||||
public abstract class ExtensionFunction2<E, D1, D2, R> extends DefaultJetObject{
|
|
||||||
protected ExtensionFunction2(TypeInfo<?> typeInfo) {
|
protected ExtensionFunction2(TypeInfo<?> typeInfo) {
|
||||||
super(typeInfo);
|
super(typeInfo);
|
||||||
}
|
}
|
||||||
@@ -14,6 +13,7 @@ public abstract class ExtensionFunction2<E, D1, D2, R> extends DefaultJetObjec
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return "{E.(d1: D1, d2: D2) : R}";
|
return "{E.(d1: D1, d2: D2) : R)}";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,19 @@
|
|||||||
|
/*
|
||||||
|
* @author alex.tkachman
|
||||||
|
*/
|
||||||
|
package jet;
|
||||||
|
|
||||||
|
import jet.typeinfo.TypeInfo;
|
||||||
|
public abstract class ExtensionFunction20<E, D1, D2, D3, D4, D5, D6, D7, D8, D9, D10, D11, D12, D13, D14, D15, D16, D17, D18, D19, D20, R> extends DefaultJetObject {
|
||||||
|
protected ExtensionFunction20(TypeInfo<?> typeInfo) {
|
||||||
|
super(typeInfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
public abstract R invoke(E receiver, D1 d1, D2 d2, D3 d3, D4 d4, D5 d5, D6 d6, D7 d7, D8 d8, D9 d9, D10 d10, D11 d11, D12 d12, D13 d13, D14 d14, D15 d15, D16 d16, D17 d17, D18 d18, D19 d19, D20 d20);
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "{E.(d1: D1, d2: D2, d3: D3, d4: D4, d5: D5, d6: D6, d7: D7, d8: D8, d9: D9, d10: D10, d11: D11, d12: D12, d13: D13, d14: D14, d15: D15, d16: D16, d17: D17, d18: D18, d19: D19, d20: D20) : R)}";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
/*
|
||||||
|
* @author alex.tkachman
|
||||||
|
*/
|
||||||
|
package jet;
|
||||||
|
|
||||||
|
import jet.typeinfo.TypeInfo;
|
||||||
|
public abstract class ExtensionFunction21<E, D1, D2, D3, D4, D5, D6, D7, D8, D9, D10, D11, D12, D13, D14, D15, D16, D17, D18, D19, D20, D21, R> extends DefaultJetObject {
|
||||||
|
protected ExtensionFunction21(TypeInfo<?> typeInfo) {
|
||||||
|
super(typeInfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
public abstract R invoke(E receiver, D1 d1, D2 d2, D3 d3, D4 d4, D5 d5, D6 d6, D7 d7, D8 d8, D9 d9, D10 d10, D11 d11, D12 d12, D13 d13, D14 d14, D15 d15, D16 d16, D17 d17, D18 d18, D19 d19, D20 d20, D21 d21);
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "{E.(d1: D1, d2: D2, d3: D3, d4: D4, d5: D5, d6: D6, d7: D7, d8: D8, d9: D9, d10: D10, d11: D11, d12: D12, d13: D13, d14: D14, d15: D15, d16: D16, d17: D17, d18: D18, d19: D19, d20: D20, d21: D21) : R)}";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
/*
|
||||||
|
* @author alex.tkachman
|
||||||
|
*/
|
||||||
|
package jet;
|
||||||
|
|
||||||
|
import jet.typeinfo.TypeInfo;
|
||||||
|
public abstract class ExtensionFunction22<E, D1, D2, D3, D4, D5, D6, D7, D8, D9, D10, D11, D12, D13, D14, D15, D16, D17, D18, D19, D20, D21, D22, R> extends DefaultJetObject {
|
||||||
|
protected ExtensionFunction22(TypeInfo<?> typeInfo) {
|
||||||
|
super(typeInfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
public abstract R invoke(E receiver, D1 d1, D2 d2, D3 d3, D4 d4, D5 d5, D6 d6, D7 d7, D8 d8, D9 d9, D10 d10, D11 d11, D12 d12, D13 d13, D14 d14, D15 d15, D16 d16, D17 d17, D18 d18, D19 d19, D20 d20, D21 d21, D22 d22);
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "{E.(d1: D1, d2: D2, d3: D3, d4: D4, d5: D5, d6: D6, d7: D7, d8: D8, d9: D9, d10: D10, d11: D11, d12: D12, d13: D13, d14: D14, d15: D15, d16: D16, d17: D17, d18: D18, d19: D19, d20: D20, d21: D21, d22: D22) : R)}";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@@ -1,11 +1,10 @@
|
|||||||
/*
|
/*
|
||||||
* @author max
|
* @author alex.tkachman
|
||||||
*/
|
*/
|
||||||
package jet;
|
package jet;
|
||||||
|
|
||||||
import jet.typeinfo.TypeInfo;
|
import jet.typeinfo.TypeInfo;
|
||||||
|
public abstract class ExtensionFunction3<E, D1, D2, D3, R> extends DefaultJetObject {
|
||||||
public abstract class ExtensionFunction3<E, D1, D2, D3, R> extends DefaultJetObject{
|
|
||||||
protected ExtensionFunction3(TypeInfo<?> typeInfo) {
|
protected ExtensionFunction3(TypeInfo<?> typeInfo) {
|
||||||
super(typeInfo);
|
super(typeInfo);
|
||||||
}
|
}
|
||||||
@@ -14,6 +13,7 @@ public abstract class ExtensionFunction3<E, D1, D2, D3, R> extends DefaultJetOb
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return "{E.(d1: D1, d2: D2, d3: D3) : R}";
|
return "{E.(d1: D1, d2: D2, d3: D3) : R)}";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,19 @@
|
|||||||
|
/*
|
||||||
|
* @author alex.tkachman
|
||||||
|
*/
|
||||||
|
package jet;
|
||||||
|
|
||||||
|
import jet.typeinfo.TypeInfo;
|
||||||
|
public abstract class ExtensionFunction4<E, D1, D2, D3, D4, R> extends DefaultJetObject {
|
||||||
|
protected ExtensionFunction4(TypeInfo<?> typeInfo) {
|
||||||
|
super(typeInfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
public abstract R invoke(E receiver, D1 d1, D2 d2, D3 d3, D4 d4);
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "{E.(d1: D1, d2: D2, d3: D3, d4: D4) : R)}";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
/*
|
||||||
|
* @author alex.tkachman
|
||||||
|
*/
|
||||||
|
package jet;
|
||||||
|
|
||||||
|
import jet.typeinfo.TypeInfo;
|
||||||
|
public abstract class ExtensionFunction5<E, D1, D2, D3, D4, D5, R> extends DefaultJetObject {
|
||||||
|
protected ExtensionFunction5(TypeInfo<?> typeInfo) {
|
||||||
|
super(typeInfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
public abstract R invoke(E receiver, D1 d1, D2 d2, D3 d3, D4 d4, D5 d5);
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "{E.(d1: D1, d2: D2, d3: D3, d4: D4, d5: D5) : R)}";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
/*
|
||||||
|
* @author alex.tkachman
|
||||||
|
*/
|
||||||
|
package jet;
|
||||||
|
|
||||||
|
import jet.typeinfo.TypeInfo;
|
||||||
|
public abstract class ExtensionFunction6<E, D1, D2, D3, D4, D5, D6, R> extends DefaultJetObject {
|
||||||
|
protected ExtensionFunction6(TypeInfo<?> typeInfo) {
|
||||||
|
super(typeInfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
public abstract R invoke(E receiver, D1 d1, D2 d2, D3 d3, D4 d4, D5 d5, D6 d6);
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "{E.(d1: D1, d2: D2, d3: D3, d4: D4, d5: D5, d6: D6) : R)}";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
/*
|
||||||
|
* @author alex.tkachman
|
||||||
|
*/
|
||||||
|
package jet;
|
||||||
|
|
||||||
|
import jet.typeinfo.TypeInfo;
|
||||||
|
public abstract class ExtensionFunction7<E, D1, D2, D3, D4, D5, D6, D7, R> extends DefaultJetObject {
|
||||||
|
protected ExtensionFunction7(TypeInfo<?> typeInfo) {
|
||||||
|
super(typeInfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
public abstract R invoke(E receiver, D1 d1, D2 d2, D3 d3, D4 d4, D5 d5, D6 d6, D7 d7);
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "{E.(d1: D1, d2: D2, d3: D3, d4: D4, d5: D5, d6: D6, d7: D7) : R)}";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
/*
|
||||||
|
* @author alex.tkachman
|
||||||
|
*/
|
||||||
|
package jet;
|
||||||
|
|
||||||
|
import jet.typeinfo.TypeInfo;
|
||||||
|
public abstract class ExtensionFunction8<E, D1, D2, D3, D4, D5, D6, D7, D8, R> extends DefaultJetObject {
|
||||||
|
protected ExtensionFunction8(TypeInfo<?> typeInfo) {
|
||||||
|
super(typeInfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
public abstract R invoke(E receiver, D1 d1, D2 d2, D3 d3, D4 d4, D5 d5, D6 d6, D7 d7, D8 d8);
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "{E.(d1: D1, d2: D2, d3: D3, d4: D4, d5: D5, d6: D6, d7: D7, d8: D8) : R)}";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
/*
|
||||||
|
* @author alex.tkachman
|
||||||
|
*/
|
||||||
|
package jet;
|
||||||
|
|
||||||
|
import jet.typeinfo.TypeInfo;
|
||||||
|
public abstract class ExtensionFunction9<E, D1, D2, D3, D4, D5, D6, D7, D8, D9, R> extends DefaultJetObject {
|
||||||
|
protected ExtensionFunction9(TypeInfo<?> typeInfo) {
|
||||||
|
super(typeInfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
public abstract R invoke(E receiver, D1 d1, D2 d2, D3 d3, D4 d4, D5 d5, D6 d6, D7 d7, D8 d8, D9 d9);
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "{E.(d1: D1, d2: D2, d3: D3, d4: D4, d5: D5, d6: D6, d7: D7, d8: D8, d9: D9) : R)}";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@@ -5,8 +5,13 @@ package jet;
|
|||||||
|
|
||||||
import jet.typeinfo.TypeInfo;
|
import jet.typeinfo.TypeInfo;
|
||||||
|
|
||||||
public abstract class Function0<R> extends DefaultJetObject {
|
import java.io.File;
|
||||||
protected Function0(TypeInfo<?> typeInfo) {
|
import java.io.FileWriter;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.PrintStream;
|
||||||
|
|
||||||
|
public abstract class Function0<R> extends DefaultJetObject {
|
||||||
|
protected Function0(TypeInfo typeInfo) {
|
||||||
super(typeInfo);
|
super(typeInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -16,4 +21,68 @@ public abstract class Function0<R> extends DefaultJetObject {
|
|||||||
public String toString() {
|
public String toString() {
|
||||||
return "{() : R}";
|
return "{() : R}";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// public static void main(String[] args) throws IOException {
|
||||||
|
// for(int i = 1; i <= 22; i++) {
|
||||||
|
// PrintStream out = new PrintStream(new File("/Development/Dev.Git/jet/stdlib/src/jet/Function" + i + ".java"));
|
||||||
|
// out.print("/*\n" +
|
||||||
|
// " * @author alex.tkachman\n" +
|
||||||
|
// " */\n" +
|
||||||
|
// "package jet;\n" +
|
||||||
|
// "\n" +
|
||||||
|
// "import jet.typeinfo.TypeInfo;\n" +
|
||||||
|
// "public abstract class Function" + i + "<");
|
||||||
|
// for(int k = 1; k <= i; k++)
|
||||||
|
// out.print("D" + k + ", ");
|
||||||
|
// out.println("R> extends DefaultJetObject {\n" +
|
||||||
|
// " protected Function" + i + "(TypeInfo<?> typeInfo) {\n" +
|
||||||
|
// " super(typeInfo);\n" +
|
||||||
|
// " }");
|
||||||
|
//
|
||||||
|
// out.print("\n public abstract R invoke(");
|
||||||
|
// for(int k = 1; k <= i; k++)
|
||||||
|
// out.print("D" + k + " d" + k + (k != i ? ", " : ");\n\n"));
|
||||||
|
//
|
||||||
|
// out.println(" @Override\n" +
|
||||||
|
// " public String toString() {");
|
||||||
|
// out.print(" return \"{(");
|
||||||
|
// for(int k = 1; k <= i; k++)
|
||||||
|
// out.print("d" + k + ": D" + k + (k != i ? ", " : ") : R)}\";\n"));
|
||||||
|
// out.println(" }");
|
||||||
|
//
|
||||||
|
// out.println("}\n");
|
||||||
|
// out.close();
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// for(int i = 1; i <= 22; i++) {
|
||||||
|
// PrintStream out = new PrintStream(new File("/Development/Dev.Git/jet/stdlib/src/jet/ExtensionFunction" + i + ".java"));
|
||||||
|
// out.print("/*\n" +
|
||||||
|
// " * @author alex.tkachman\n" +
|
||||||
|
// " */\n" +
|
||||||
|
// "package jet;\n" +
|
||||||
|
// "\n" +
|
||||||
|
// "import jet.typeinfo.TypeInfo;\n" +
|
||||||
|
// "public abstract class ExtensionFunction" + i + "<E, ");
|
||||||
|
// for(int k = 1; k <= i; k++)
|
||||||
|
// out.print("D" + k + ", ");
|
||||||
|
// out.println("R> extends DefaultJetObject {\n" +
|
||||||
|
// " protected ExtensionFunction" + i + "(TypeInfo<?> typeInfo) {\n" +
|
||||||
|
// " super(typeInfo);\n" +
|
||||||
|
// " }");
|
||||||
|
//
|
||||||
|
// out.print("\n public abstract R invoke(E receiver, ");
|
||||||
|
// for(int k = 1; k <= i; k++)
|
||||||
|
// out.print("D" + k + " d" + k + (k != i ? ", " : ");\n\n"));
|
||||||
|
//
|
||||||
|
// out.println(" @Override\n" +
|
||||||
|
// " public String toString() {");
|
||||||
|
// out.print(" return \"{E.(");
|
||||||
|
// for(int k = 1; k <= i; k++)
|
||||||
|
// out.print("d" + k + ": D" + k + (k != i ? ", " : ") : R)}\";\n"));
|
||||||
|
// out.println(" }");
|
||||||
|
//
|
||||||
|
// out.println("}\n");
|
||||||
|
// out.close();
|
||||||
|
// }
|
||||||
|
// }
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,19 +1,19 @@
|
|||||||
/*
|
/*
|
||||||
* @author max
|
* @author alex.tkachman
|
||||||
*/
|
*/
|
||||||
package jet;
|
package jet;
|
||||||
|
|
||||||
import jet.typeinfo.TypeInfo;
|
import jet.typeinfo.TypeInfo;
|
||||||
|
public abstract class Function1<D1, R> extends DefaultJetObject {
|
||||||
public abstract class Function1<D, R> extends DefaultJetObject {
|
|
||||||
protected Function1(TypeInfo<?> typeInfo) {
|
protected Function1(TypeInfo<?> typeInfo) {
|
||||||
super(typeInfo);
|
super(typeInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
public abstract R invoke(D d);
|
public abstract R invoke(D1 d1);
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return "{(d: D) : R}";
|
return "{(d1: D1) : R)}";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,19 @@
|
|||||||
|
/*
|
||||||
|
* @author alex.tkachman
|
||||||
|
*/
|
||||||
|
package jet;
|
||||||
|
|
||||||
|
import jet.typeinfo.TypeInfo;
|
||||||
|
public abstract class Function10<D1, D2, D3, D4, D5, D6, D7, D8, D9, D10, R> extends DefaultJetObject {
|
||||||
|
protected Function10(TypeInfo<?> typeInfo) {
|
||||||
|
super(typeInfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
public abstract R invoke(D1 d1, D2 d2, D3 d3, D4 d4, D5 d5, D6 d6, D7 d7, D8 d8, D9 d9, D10 d10);
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "{(d1: D1, d2: D2, d3: D3, d4: D4, d5: D5, d6: D6, d7: D7, d8: D8, d9: D9, d10: D10) : R)}";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
/*
|
||||||
|
* @author alex.tkachman
|
||||||
|
*/
|
||||||
|
package jet;
|
||||||
|
|
||||||
|
import jet.typeinfo.TypeInfo;
|
||||||
|
public abstract class Function11<D1, D2, D3, D4, D5, D6, D7, D8, D9, D10, D11, R> extends DefaultJetObject {
|
||||||
|
protected Function11(TypeInfo<?> typeInfo) {
|
||||||
|
super(typeInfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
public abstract R invoke(D1 d1, D2 d2, D3 d3, D4 d4, D5 d5, D6 d6, D7 d7, D8 d8, D9 d9, D10 d10, D11 d11);
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "{(d1: D1, d2: D2, d3: D3, d4: D4, d5: D5, d6: D6, d7: D7, d8: D8, d9: D9, d10: D10, d11: D11) : R)}";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
/*
|
||||||
|
* @author alex.tkachman
|
||||||
|
*/
|
||||||
|
package jet;
|
||||||
|
|
||||||
|
import jet.typeinfo.TypeInfo;
|
||||||
|
public abstract class Function12<D1, D2, D3, D4, D5, D6, D7, D8, D9, D10, D11, D12, R> extends DefaultJetObject {
|
||||||
|
protected Function12(TypeInfo<?> typeInfo) {
|
||||||
|
super(typeInfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
public abstract R invoke(D1 d1, D2 d2, D3 d3, D4 d4, D5 d5, D6 d6, D7 d7, D8 d8, D9 d9, D10 d10, D11 d11, D12 d12);
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "{(d1: D1, d2: D2, d3: D3, d4: D4, d5: D5, d6: D6, d7: D7, d8: D8, d9: D9, d10: D10, d11: D11, d12: D12) : R)}";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
/*
|
||||||
|
* @author alex.tkachman
|
||||||
|
*/
|
||||||
|
package jet;
|
||||||
|
|
||||||
|
import jet.typeinfo.TypeInfo;
|
||||||
|
public abstract class Function13<D1, D2, D3, D4, D5, D6, D7, D8, D9, D10, D11, D12, D13, R> extends DefaultJetObject {
|
||||||
|
protected Function13(TypeInfo<?> typeInfo) {
|
||||||
|
super(typeInfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
public abstract R invoke(D1 d1, D2 d2, D3 d3, D4 d4, D5 d5, D6 d6, D7 d7, D8 d8, D9 d9, D10 d10, D11 d11, D12 d12, D13 d13);
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "{(d1: D1, d2: D2, d3: D3, d4: D4, d5: D5, d6: D6, d7: D7, d8: D8, d9: D9, d10: D10, d11: D11, d12: D12, d13: D13) : R)}";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
/*
|
||||||
|
* @author alex.tkachman
|
||||||
|
*/
|
||||||
|
package jet;
|
||||||
|
|
||||||
|
import jet.typeinfo.TypeInfo;
|
||||||
|
public abstract class Function14<D1, D2, D3, D4, D5, D6, D7, D8, D9, D10, D11, D12, D13, D14, R> extends DefaultJetObject {
|
||||||
|
protected Function14(TypeInfo<?> typeInfo) {
|
||||||
|
super(typeInfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
public abstract R invoke(D1 d1, D2 d2, D3 d3, D4 d4, D5 d5, D6 d6, D7 d7, D8 d8, D9 d9, D10 d10, D11 d11, D12 d12, D13 d13, D14 d14);
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "{(d1: D1, d2: D2, d3: D3, d4: D4, d5: D5, d6: D6, d7: D7, d8: D8, d9: D9, d10: D10, d11: D11, d12: D12, d13: D13, d14: D14) : R)}";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
/*
|
||||||
|
* @author alex.tkachman
|
||||||
|
*/
|
||||||
|
package jet;
|
||||||
|
|
||||||
|
import jet.typeinfo.TypeInfo;
|
||||||
|
public abstract class Function15<D1, D2, D3, D4, D5, D6, D7, D8, D9, D10, D11, D12, D13, D14, D15, R> extends DefaultJetObject {
|
||||||
|
protected Function15(TypeInfo<?> typeInfo) {
|
||||||
|
super(typeInfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
public abstract R invoke(D1 d1, D2 d2, D3 d3, D4 d4, D5 d5, D6 d6, D7 d7, D8 d8, D9 d9, D10 d10, D11 d11, D12 d12, D13 d13, D14 d14, D15 d15);
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "{(d1: D1, d2: D2, d3: D3, d4: D4, d5: D5, d6: D6, d7: D7, d8: D8, d9: D9, d10: D10, d11: D11, d12: D12, d13: D13, d14: D14, d15: D15) : R)}";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
/*
|
||||||
|
* @author alex.tkachman
|
||||||
|
*/
|
||||||
|
package jet;
|
||||||
|
|
||||||
|
import jet.typeinfo.TypeInfo;
|
||||||
|
public abstract class Function16<D1, D2, D3, D4, D5, D6, D7, D8, D9, D10, D11, D12, D13, D14, D15, D16, R> extends DefaultJetObject {
|
||||||
|
protected Function16(TypeInfo<?> typeInfo) {
|
||||||
|
super(typeInfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
public abstract R invoke(D1 d1, D2 d2, D3 d3, D4 d4, D5 d5, D6 d6, D7 d7, D8 d8, D9 d9, D10 d10, D11 d11, D12 d12, D13 d13, D14 d14, D15 d15, D16 d16);
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "{(d1: D1, d2: D2, d3: D3, d4: D4, d5: D5, d6: D6, d7: D7, d8: D8, d9: D9, d10: D10, d11: D11, d12: D12, d13: D13, d14: D14, d15: D15, d16: D16) : R)}";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
/*
|
||||||
|
* @author alex.tkachman
|
||||||
|
*/
|
||||||
|
package jet;
|
||||||
|
|
||||||
|
import jet.typeinfo.TypeInfo;
|
||||||
|
public abstract class Function17<D1, D2, D3, D4, D5, D6, D7, D8, D9, D10, D11, D12, D13, D14, D15, D16, D17, R> extends DefaultJetObject {
|
||||||
|
protected Function17(TypeInfo<?> typeInfo) {
|
||||||
|
super(typeInfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
public abstract R invoke(D1 d1, D2 d2, D3 d3, D4 d4, D5 d5, D6 d6, D7 d7, D8 d8, D9 d9, D10 d10, D11 d11, D12 d12, D13 d13, D14 d14, D15 d15, D16 d16, D17 d17);
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "{(d1: D1, d2: D2, d3: D3, d4: D4, d5: D5, d6: D6, d7: D7, d8: D8, d9: D9, d10: D10, d11: D11, d12: D12, d13: D13, d14: D14, d15: D15, d16: D16, d17: D17) : R)}";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user