Merge remote branch 'origin/master'

Conflicts:
	compiler/cli/src/org/jetbrains/jet/cli/KotlinCompiler.java
This commit is contained in:
Dmitry Jemerov
2011-10-24 17:33:43 +02:00
118 changed files with 2167 additions and 390 deletions
@@ -277,14 +277,17 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
v.mark(begin);
v.load(iteratorVar, asmIterType);
FunctionDescriptor hND;
if(hasNextDescriptor instanceof FunctionDescriptor) {
hND = (FunctionDescriptor) hasNextDescriptor;
FunctionDescriptor hND = (FunctionDescriptor) hasNextDescriptor;
invokeFunctionNoParams(hND, Type.BOOLEAN_TYPE, v);
}
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);
myMap.enter(parameterDescriptor, asmParamType.getSize());
@@ -598,8 +601,10 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
}
for (DeclarationDescriptor descriptor : closureCodegen.closure.keySet()) {
final Type sharedVarType = getSharedVarType(descriptor);
consArgTypes.add(sharedVarType != null ? sharedVarType : state.getTypeMapper().mapType(((VariableDescriptor) descriptor).getOutType()));
Type sharedVarType = getSharedVarType(descriptor);
if(sharedVarType == null)
sharedVarType = state.getTypeMapper().mapType(((VariableDescriptor) descriptor).getOutType());
consArgTypes.add(sharedVarType);
final EnclosedValueDescriptor valueDescriptor = closureCodegen.closure.get(descriptor);
valueDescriptor.getOuterValue().put(sharedVarType, v);
}
@@ -1462,7 +1467,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
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) {
return compareExpressionsOnStack(opToken, leftType);
}
@@ -342,7 +342,10 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
Map<DeclarationDescriptor, EnclosedValueDescriptor> closure = context.closure.closure;
int k = 0;
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(firstClosureIndex + k, StackValue.refType(sharedVarType));
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_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_TYPE = Type.getObjectType("java/lang/String");
public static final Type ARRAY_INT_TYPE = Type.getType(int[].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_ITERATOR = Type.getObjectType("jet/Iterator");
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_INT = Type.getObjectType("jet/refs/SharedVar$Int");
public static final Type TYPE_SHARED_DOUBLE = Type.getObjectType("jet/refs/SharedVar$Double");
public static final Type TYPE_SHARED_FLOAT = Type.getObjectType("jet/refs/SharedVar$Float");
public static final Type TYPE_SHARED_BYTE = Type.getObjectType("jet/refs/SharedVar$Byte");
public static final Type TYPE_SHARED_SHORT = Type.getObjectType("jet/refs/SharedVar$Short");
public static final Type TYPE_SHARED_CHAR = Type.getObjectType("jet/refs/SharedVar$Char");
public static final Type TYPE_SHARED_LONG = Type.getObjectType("jet/refs/SharedVar$Long");
public static final Type TYPE_SHARED_BOOLEAN = Type.getObjectType("jet/refs/SharedVar$Boolean");
public static final Type TYPE_SHARED_VAR = Type.getObjectType("jet/runtime/SharedVar$Object");
public static final Type TYPE_SHARED_INT = Type.getObjectType("jet/runtime/SharedVar$Int");
public static final Type TYPE_SHARED_DOUBLE = Type.getObjectType("jet/runtime/SharedVar$Double");
public static final Type TYPE_SHARED_FLOAT = Type.getObjectType("jet/runtime/SharedVar$Float");
public static final Type TYPE_SHARED_BYTE = Type.getObjectType("jet/runtime/SharedVar$Byte");
public static final Type TYPE_SHARED_SHORT = Type.getObjectType("jet/runtime/SharedVar$Short");
public static final Type TYPE_SHARED_CHAR = Type.getObjectType("jet/runtime/SharedVar$Char");
public static final Type TYPE_SHARED_LONG = Type.getObjectType("jet/runtime/SharedVar$Long");
public static final Type TYPE_SHARED_BOOLEAN = Type.getObjectType("jet/runtime/SharedVar$Boolean");
public JetTypeMapper(JetStandardLibrary standardLibrary, BindingContext bindingContext) {
this.standardLibrary = standardLibrary;
@@ -460,7 +461,10 @@ public class JetTypeMapper {
parameterTypes.add(type);
}
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);
parameterTypes.add(type);
}
@@ -558,7 +562,13 @@ public class JetTypeMapper {
parameterTypes.add(mapType(receiver.getType()));
}
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());
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();
if(containingDeclaration.equals(standardLibrary.getArray())) {
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())) {
v.invokestatic("jet/arrays/ArrayIterator", "iterator", "([B)Ljet/Iterator;");
v.invokestatic("jet/runtime/ArrayIterator", "iterator", "([B)Ljet/Iterator;");
}
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())) {
v.invokestatic("jet/arrays/ArrayIterator", "iterator", "([I)Ljet/Iterator;");
v.invokestatic("jet/runtime/ArrayIterator", "iterator", "([I)Ljet/Iterator;");
}
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())) {
v.invokestatic("jet/arrays/ArrayIterator", "iterator", "([F)Ljet/Iterator;");
v.invokestatic("jet/runtime/ArrayIterator", "iterator", "([F)Ljet/Iterator;");
}
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())) {
v.invokestatic("jet/arrays/ArrayIterator", "iterator", "([C)Ljet/Iterator;");
v.invokestatic("jet/runtime/ArrayIterator", "iterator", "([C)Ljet/Iterator;");
}
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 {
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());
declareOverload(myStdLib.getLibraryScope().getFunctions("toString"), 0, new ToString());
declareOverload(myStdLib.getLibraryScope().getFunctions("equals"), 1, new Equals());
// declareIntrinsicFunction("Any", "equals", 1, new Equals());
//
declareIntrinsicStringMethods();
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;
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.project.Project;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.PsiFile;
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.GenerationState;
import org.jetbrains.jet.lang.cfg.pseudocode.JetControlFlowDataTraceFactory;
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.JetNamespace;
import org.jetbrains.jet.lang.resolve.AnalyzingUtils;
import org.jetbrains.jet.lang.resolve.BindingContext;
import org.jetbrains.jet.lang.resolve.java.JavaDefaultImports;
import org.jetbrains.jet.plugin.JetFileType;
import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.Collection;
import java.util.List;
/**
* @author yole
* @author alex.tkachman
*/
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) {
System.setProperty("java.awt.headless", "true");
if (args.length < 1) {
System.out.println("Usage: KotlinCompiler <filename>");
Arguments arguments = new Arguments();
try {
Args.parse(arguments, args);
}
catch (Throwable t) {
System.out.println("Usage: KotlinCompiler -output <outputDir> -src <filename or dirname>");
t.printStackTrace();
return;
}
@@ -40,8 +61,121 @@ public class KotlinCompiler {
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");
File rtJar = null;
if (javaHome == null) {
@@ -64,7 +198,7 @@ public class KotlinCompiler {
if(rtJar == null) {
System.out.println("JAVA_HOME environment variable needs to be defined");
return;
return null;
}
}
else {
@@ -73,67 +207,9 @@ public class KotlinCompiler {
if (rtJar == null || !rtJar.exists()) {
System.out.print("No rt.jar found under JAVA_HOME=" + javaHome);
return;
return null;
}
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());
return rtJar;
}
private static File findRtJar(String javaHome) {
@@ -20,4 +20,7 @@ public class JavaDefaultImports {
rootScope.importScope(new JavaPackageScope("java.lang", null, javaSemanticServices));
}
};
private JavaDefaultImports() {
}
}
+2 -2
View File
@@ -41,8 +41,8 @@ fun Any?.equals(other : Any?) : Boolean// = this === other
fun Any?.toString() : String// = this === other
trait Iterator<out T> {
fun next() : T
fun hasNext() : Boolean
fun next() : T
val hasNext : Boolean
}
trait Iterable<out T> {
@@ -118,18 +118,26 @@ public class JetFlowInformationProvider {
Pseudocode pseudocode = pseudocodeMap.get(subroutine);
assert pseudocode != null;
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 &&
for (Instruction deadInstruction : pseudocode.getDeadInstructions()) {
if (deadInstruction instanceof JetElementInstruction &&
// TODO : do {return} while (1 > a)
!(instruction instanceof ReadUnitValueInstruction)) {
unreachableElements.add(((JetElementInstruction) instruction).getElement());
!(deadInstruction instanceof ReadUnitValueInstruction)) {
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) {
// Instruction dominatorInstruction = representativeInstructions.get(dominator);
@@ -175,17 +183,17 @@ public class JetFlowInformationProvider {
// }
// }
private boolean collectReachable(Instruction current, Set<Instruction> visited, @Nullable Instruction lookFor) {
if (!visited.add(current)) return false;
if (current == lookFor) return true;
for (Instruction nextInstruction : current.getNextInstructions()) {
if (collectReachable(nextInstruction, visited, lookFor)) {
return true;
}
}
return false;
}
// private boolean collectReachable(Instruction current, Set<Instruction> visited, @Nullable Instruction lookFor) {
// if (!visited.add(current)) return false;
// if (current == lookFor) return true;
//
// for (Instruction nextInstruction : current.getNextInstructions()) {
// if (collectReachable(nextInstruction, visited, lookFor)) {
// return true;
// }
// }
// return false;
// }
// private void processPreviousInstructions(Instruction previousFor, final Set<Instruction> visited, final Collection<JetExpression> returnedExpressions, final Collection<JetElement> elementsReturningUnit) {
// 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();
initializeDataMap(dataMap, pseudocode, initialDataValue);
dataMap.put(pseudocode.getEnterInstruction(), initialDataValueForEnterInstruction);
boolean[] changed = new boolean[1];
changed[0] = true;
while (changed[0]) {
changed[0] = false;
traverseSubGraph(pseudocode, instructionsMergeHandler, Collections.<Instruction>emptyList(), straightDirection, dataMap, changed);
traverseSubGraph(pseudocode, instructionsMergeHandler, Collections.<Instruction>emptyList(), straightDirection, dataMap, changed, false);
}
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();
for (Instruction instruction : instructions) {
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();
SubroutineEnterInstruction enterInstruction = pseudocode.getEnterInstruction();
for (Instruction instruction : instructions) {
if (!isLocal && instruction instanceof SubroutineEnterInstruction) continue;
Collection<Instruction> allPreviousInstructions;
Collection<Instruction> previousInstructions = straightDirection
? instruction.getPreviousInstructions()
@@ -290,7 +316,7 @@ public class JetFlowInformationProvider {
if (instruction instanceof LocalDeclarationInstruction) {
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);
@@ -299,7 +325,7 @@ public class JetFlowInformationProvider {
for (Instruction previousInstruction : allPreviousInstructions) {
incomingEdgesData.add(dataMap.get(previousInstruction));
}
D mergedData = instructionsMergeHandler.merge(instruction, previousDataValue, incomingEdgesData);
D mergedData = instructionsMergeHandler.merge(instruction, incomingEdgesData);
if (!mergedData.equals(previousDataValue)) {
changed[0] = true;
dataMap.put(instruction, mergedData);
@@ -312,80 +338,203 @@ public class JetFlowInformationProvider {
assert pseudocode != null;
Collection<Instruction> instructions = pseudocode.getInstructions();
InstructionsMergeHandler<Set<LocalVariableDescriptor>> instructionsMergeHandler = new InstructionsMergeHandler<Set<LocalVariableDescriptor>>() {
InstructionsMergeHandler<Map<LocalVariableDescriptor, InitializationPoints>> instructionsMergeHandler = new InstructionsMergeHandler<Map<LocalVariableDescriptor, InitializationPoints>>() {
@Override
public Set<LocalVariableDescriptor> merge(Instruction instruction, Set<LocalVariableDescriptor> previousDataValue, Collection<Set<LocalVariableDescriptor>> incomingEdgesData) {
Set<LocalVariableDescriptor> initializedVariables = Sets.newHashSet();
initializedVariables.addAll(previousDataValue);
for (Set<LocalVariableDescriptor> edgeDataValue : incomingEdgesData) {
initializedVariables.addAll(edgeDataValue);
public Map<LocalVariableDescriptor, InitializationPoints> merge(
Instruction instruction,
Collection<Map<LocalVariableDescriptor, InitializationPoints>> incomingEdgesData) {
Set<LocalVariableDescriptor> variablesInScope = Sets.newHashSet();
for (Map<LocalVariableDescriptor, InitializationPoints> edgePointsMap : incomingEdgesData) {
variablesInScope.addAll(edgePointsMap.keySet());
}
if (instruction instanceof WriteValueInstruction) {
DeclarationDescriptor descriptor = null;
JetElement lValue = ((WriteValueInstruction) instruction).getlValue();
if (lValue instanceof JetProperty) {
descriptor = trace.get(BindingContext.DECLARATION_TO_DESCRIPTOR, lValue);
}
else if (lValue instanceof JetSimpleNameExpression) {
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);
Map<LocalVariableDescriptor, InitializationPoints> pointsMap = Maps.newHashMap();
for (LocalVariableDescriptor variable : variablesInScope) {
Set<InitializationPoints> edgesDataForVariable = Sets.newHashSet();
for (Map<LocalVariableDescriptor, InitializationPoints> edgePointsMap : incomingEdgesData) {
InitializationPoints points = edgePointsMap.get(variable);
if (points != null) {
edgesDataForVariable.add(points);
}
}
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
public void analyze(Instruction instruction, Map<Instruction, Set<LocalVariableDescriptor>> dataMap) {
Set<LocalVariableDescriptor> initializedVariables = dataMap.get(instruction);
public void analyze(Instruction instruction, Map<Instruction, Map<LocalVariableDescriptor, InitializationPoints>> dataMap) {
Map<LocalVariableDescriptor, InitializationPoints> variablesData = dataMap.get(instruction);
if (instruction instanceof ReadValueInstruction) {
LocalVariableDescriptor variableDescriptor = extractVariableDescriptorIfAny(instruction);
JetElement element = ((ReadValueInstruction) instruction).getElement();
if (element instanceof JetSimpleNameExpression) {
DeclarationDescriptor descriptor = trace.get(BindingContext.REFERENCE_TARGET, (JetSimpleNameExpression) element);
if (descriptor instanceof LocalVariableDescriptor) {
if (!initializedVariables.contains(descriptor)) {
trace.report(Errors.UNINITIALIZED_VARIABLE.on((JetSimpleNameExpression) element, descriptor));
}
if (element instanceof JetSimpleNameExpression && variableDescriptor != null) {
// DeclarationDescriptor descriptor = trace.get(BindingContext.REFERENCE_TARGET, (JetSimpleNameExpression) element);
// if (descriptor instanceof LocalVariableDescriptor) {
InitializationPoints initializationPoints = variablesData.get(variableDescriptor);
assert initializationPoints != null;
if (initializationPoints.canBeUninitialized) {
trace.report(Errors.UNINITIALIZED_VARIABLE.on((JetSimpleNameExpression) element, variableDescriptor));
}
// }
}
}
else if (instruction instanceof WriteValueInstruction) {
JetElement element = ((WriteValueInstruction) instruction).getElement();
if (element instanceof JetSimpleNameExpression) {
DeclarationDescriptor descriptor = trace.get(BindingContext.REFERENCE_TARGET, (JetSimpleNameExpression) element);
if (descriptor instanceof LocalVariableDescriptor) {
if (initializedVariables.contains(descriptor) && ((LocalVariableDescriptor) descriptor).isVar()) {
trace.report(Errors.VAL_REASSIGNMENT.on((JetSimpleNameExpression) element, descriptor));
}
JetElement element = ((WriteValueInstruction) instruction).getlValue();
LocalVariableDescriptor variableDescriptor = extractVariableDescriptorIfAny(instruction);
if (element instanceof JetSimpleNameExpression && variableDescriptor != null) {
// DeclarationDescriptor descriptor = trace.get(BindingContext.REFERENCE_TARGET, (JetSimpleNameExpression) element);
// if (descriptor instanceof LocalVariableDescriptor) {
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) {
if (instruction instanceof LocalDeclarationInstruction) {
traverseInstructionGraphAndReportErrors(((LocalDeclarationInstruction) instruction).getBody().getInstructions(), dataMap, instructionDataAnalyzer);
traverseAndAnalyzeInstructionGraph(((LocalDeclarationInstruction) instruction).getBody().getInstructions(), dataMap, instructionDataAnalyzer);
}
instructionDataAnalyzer.analyze(instruction, dataMap);
}
}
interface InstructionsMergeHandler<D> {
D merge(Instruction instruction, D previousDataValue, Collection<D> incomingEdgesData);
D merge(Instruction instruction, Collection<D> incomingEdgesData);
}
interface InstructionDataAnalyzer<D> {
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 {
private Pseudocode owner;
private final Collection<Instruction> previousInstructions = new LinkedHashSet<Instruction>();
protected boolean isDead = false;
protected InstructionImpl() {
}
@@ -42,4 +43,11 @@ public abstract class InstructionImpl implements Instruction {
return target;
}
public void die() {
isDead = true;
}
public boolean isDead() {
return isDead;
}
}
@@ -1,5 +1,7 @@
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.Nullable;
import org.jetbrains.jet.lang.cfg.Label;
@@ -77,6 +79,17 @@ public class Pseudocode {
public List<Instruction> getInstructions() {
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
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
@@ -63,4 +63,22 @@ public class DiagnosticUtils {
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);
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);
SimpleDiagnosticFactory UNREACHABLE_CODE = SimpleDiagnosticFactory.create(ERROR, "Unreachable code");
@@ -1429,7 +1429,7 @@ public class JetParsing extends AbstractJetParsing {
/*
* functionType
* : "fun" (type ".")? functionTypeContents
* : "fun" (type ".")? "(" (parameter | modifiers type){","} ")" (":" type)? // Unit by default
* ;
*/
private void parseFunctionType() {
@@ -1446,22 +1446,15 @@ public class JetParsing extends AbstractJetParsing {
advance(); // DOT
}
parseFunctionTypeContents();
functionType.done(FUNCTION_TYPE);
}
/*
* functionTypeContents
* : "(" (parameter | type){","} ")" ":" type
* ;
*/
private void parseFunctionTypeContents() {
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
public void report(@NotNull Diagnostic diagnostic) {
diagnostics.add(diagnostic);
@@ -11,6 +11,7 @@ public class TemporaryBindingTrace extends DelegatingBindingTrace {
private final BindingTrace trace;
private TemporaryBindingTrace(BindingTrace trace) {
super(trace.getBindingContext());
this.trace = trace;
@@ -18,5 +19,6 @@ public class TemporaryBindingTrace extends DelegatingBindingTrace {
public void commit() {
addAllMyDataTo(trace);
clear();
}
}
@@ -105,12 +105,9 @@ public class TypeResolver {
}
else {
if (actualArgumentCount != expectedArgumentCount) {
// String errorMessage = (expectedArgumentCount == 0 ? "No" : expectedArgumentCount) + " type arguments expected";
if (actualArgumentCount == 0) {
// trace.getErrorHandler().genericError(type.getNode(), errorMessage);
trace.report(WRONG_NUMBER_OF_TYPE_ARGUMENTS.on(type, expectedArgumentCount));
} else {
// trace.getErrorHandler().genericError(type.getTypeArgumentList().getNode(), errorMessage);
trace.report(WRONG_NUMBER_OF_TYPE_ARGUMENTS.on(type.getTypeArgumentList(), expectedArgumentCount));
}
} else {
@@ -160,10 +157,14 @@ public class TypeResolver {
}
JetTypeReference returnTypeRef = type.getReturnTypeRef();
JetType returnType;
if (returnTypeRef != null) {
JetType returnType = resolveType(scope, returnTypeRef);
result[0] = JetStandardClasses.getFunctionType(annotations, receiverType, parameterTypes, returnType);
returnType = resolveType(scope, returnTypeRef);
}
else {
returnType = JetStandardClasses.getUnitType();
}
result[0] = JetStandardClasses.getFunctionType(annotations, receiverType, parameterTypes, returnType);
}
@Override
@@ -206,8 +206,6 @@ public class CallResolver {
@NotNull JetType expectedType,
@NotNull final List<ResolutionTask<D>> prioritizedTasks, // high to low priority
@NotNull final JetReferenceExpression reference) {
TemporaryBindingTrace traceForFirstNonemptyCandidateSet = null;
OverloadResolutionResults<D> resultsForFirstNonemptyCandidateSet = null;
TracingStrategy tracing = new TracingStrategy() {
@Override
public <D extends CallableDescriptor> void bindReference(@NotNull BindingTrace trace, @NotNull ResolvedCallImpl<D> resolvedCall) {
@@ -272,12 +270,12 @@ public class CallResolver {
}
@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));
}
@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));
}
@@ -323,6 +321,9 @@ public class CallResolver {
trace.report(UNNECESSARY_SAFE_CALL.on((JetElement) callOperationNode.getTreeParent().getPsi(), callOperationNode, type));
}
};
TemporaryBindingTrace traceForFirstNonemptyCandidateSet = null;
OverloadResolutionResults<D> resultsForFirstNonemptyCandidateSet = null;
for (ResolutionTask<D> task : prioritizedTasks) {
TemporaryBindingTrace temporaryTrace = TemporaryBindingTrace.create(trace);
OverloadResolutionResults<D> results = performResolution(temporaryTrace, scope, expectedType, task, tracing);
@@ -479,6 +480,14 @@ public class CallResolver {
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.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) {
Map<ValueParameterDescriptor, ValueParameterDescriptor> parameterMap = Maps.newHashMap();
for (ValueParameterDescriptor valueParameterDescriptor : substitutedDescriptor.getValueParameters()) {
@@ -656,30 +650,47 @@ public class CallResolver {
Set<ResolvedCallImpl<D>> successfulCandidates,
Set<ResolvedCallImpl<D>> failedCandidates) {
// TODO : maybe it's better to filter overrides out first, and only then look for the maximally specific
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()) {
if (failedCandidates.size() != 1) {
Set<ResolvedCallImpl<D>> weakErrors = Sets.newLinkedHashSet();
for (ResolvedCallImpl<D> candidate : failedCandidates) {
if (candidate.getStatus().isWeakError()) {
weakErrors.add(candidate);
}
}
if (!weakErrors.isEmpty()) {
OverloadResolutionResults<D> results = chooseAndReportMaximallySpecific(trace, tracing, weakErrors);
if (results.isSuccess()) {
return OverloadResolutionResults.singleFailedCandidate(results.getResult());
// This is needed when there are several overloads some of which are OK but for nullability of the receiver,
// and some are not OK at all. In this case we'd like to say "unsafe call" rather than "none applicable"
// Used to be: weak errors. Generalized for future extensions
for (EnumSet<ResolutionStatus> severityLevel : SEVERITY_LEVELS) {
Set<ResolvedCallImpl<D>> thisLevel = Sets.newLinkedHashSet();
for (ResolvedCallImpl<D> candidate : failedCandidates) {
if (severityLevel.contains(candidate.getStatus())) {
thisLevel.add(candidate);
}
}
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);
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.recordAmbiguity(trace, 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) {
Set<ResolvedCallImpl<D>> cleanCandidates = Sets.newLinkedHashSet(candidates);
boolean allClean = true;
for (Iterator<ResolvedCallImpl<D>> iterator = cleanCandidates.iterator(); iterator.hasNext(); ) {
ResolvedCallImpl<D> candidate = iterator.next();
if (candidate.isDirty()) {
iterator.remove();
allClean = false;
}
}
@@ -722,13 +738,6 @@ public class CallResolver {
}
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);
}
@@ -1,5 +1,7 @@
package org.jetbrains.jet.lang.resolve.calls;
import java.util.EnumSet;
/**
* @author abreslav
*/
@@ -9,7 +11,14 @@ public enum ResolutionStatus {
OTHER_ERROR,
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 int severityIndex = -1;
private ResolutionStatus(boolean success) {
this.success = success;
@@ -25,11 +34,21 @@ public enum ResolutionStatus {
public ResolutionStatus combine(ResolutionStatus other) {
if (this.isSuccess()) return other;
if (this.isWeakError() && !other.isSuccess()) return other;
if (!other.isSuccess() && this.getSeverityIndex() < other.getSeverityIndex()) return other;
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 this == UNSAFE_CALL_ERROR;
return severityIndex;
}
}
@@ -2,16 +2,20 @@ package org.jetbrains.jet.lang.resolve.calls;
import com.google.common.collect.Lists;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.lang.descriptors.CallableDescriptor;
import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor;
import org.jetbrains.jet.lang.descriptors.FunctionDescriptor;
import org.jetbrains.jet.lang.descriptors.ValueParameterDescriptor;
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.calls.autocasts.AutoCastService;
import org.jetbrains.jet.lang.resolve.calls.autocasts.AutoCastServiceImpl;
import org.jetbrains.jet.lang.resolve.calls.autocasts.DataFlowInfo;
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.types.JetType;
import org.jetbrains.jet.lang.types.JetTypeChecker;
@@ -72,6 +76,18 @@ import static org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor
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) {
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);
}
addTask(result, call, locals, dataFlowInfo);
addTask(result, call, members, dataFlowInfo);
if (getReceiverSuper(receiver) != null) {
// 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) {
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 java.util.Collection;
import java.util.Set;
/**
* @author abreslav
@@ -40,10 +39,10 @@ import java.util.Set;
public void wrongNumberOfTypeArguments(@NotNull BindingTrace trace, int expectedTypeArgumentCount) {}
@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
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
public void instantiationOfAbstractClass(@NotNull BindingTrace trace) {}
@@ -74,9 +73,9 @@ import java.util.Set;
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);
@@ -8,4 +8,6 @@ public interface MutableSlicedMap extends SlicedMap {
<K, V> void put(WritableSlice<K, V> slice, K key, V value);
<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);
}
@Override
public void clear() {
map.clear();
}
@Override
public <K, V> V get(ReadOnlySlice<K, V> slice, K key) {
SlicedMapKey<K, V> slicedMapKey = slice.makeKey(key);
+24 -24
View File
@@ -41,12 +41,12 @@ l0:
jf(l3) NEXT:[read (Unit), r(2)] PREV:[r(2 > 3)]
r(2) NEXT:[ret l1] PREV:[jf(l3)]
ret l1 NEXT:[<END>] PREV:[r(2)]
jmp(l4) NEXT:[r(2)] PREV:[]
* jmp(l4) NEXT:[r(2)] PREV:[]
l3:
read (Unit) NEXT:[r(2)] PREV:[jf(l3)]
l2:
l4:
r(2) NEXT:[<END>] PREV:[jmp?(l2), jmp(l4), read (Unit)]
r(2) NEXT:[<END>] PREV:[jmp?(l2), read (Unit)]
l1:
<END> NEXT:[] PREV:[ret l1, r(2)]
error:
@@ -67,12 +67,12 @@ l3:
r(2 > 3) NEXT:[jf(l5)] PREV:[r(>)]
jf(l5) NEXT:[read (Unit), ret l4] PREV:[r(2 > 3)]
ret l4 NEXT:[<END>] PREV:[jf(l5)]
jmp(l6) NEXT:[<END>] PREV:[]
* jmp(l6) NEXT:[<END>] PREV:[]
l5:
read (Unit) NEXT:[<END>] PREV:[jf(l5)]
l4:
l6:
<END> NEXT:[] PREV:[ret l4, jmp(l6), read (Unit)]
<END> NEXT:[] PREV:[ret l4, read (Unit)]
error:
<ERROR> NEXT:[] PREV:[]
=====================
@@ -113,12 +113,12 @@ l3:
r(2 > 3) NEXT:[jf(l5)] PREV:[r(>)]
jf(l5) NEXT:[read (Unit), ret l4] PREV:[r(2 > 3)]
ret l4 NEXT:[<END>] PREV:[jf(l5)]
jmp(l6) NEXT:[<END>] PREV:[]
* jmp(l6) NEXT:[<END>] PREV:[]
l5:
read (Unit) NEXT:[<END>] PREV:[jf(l5)]
l4:
l6:
<END> NEXT:[] PREV:[ret l4, jmp(l6), read (Unit)]
<END> NEXT:[] PREV:[ret l4, read (Unit)]
error:
<ERROR> NEXT:[] PREV:[]
=====================
@@ -145,12 +145,12 @@ l2:
jf(l5) NEXT:[read (Unit), r(2)] PREV:[r(2 > 3)]
r(2) NEXT:[ret l3] PREV:[jf(l5)]
ret l3 NEXT:[<END>] PREV:[r(2)]
jmp(l6) NEXT:[r(2)] PREV:[]
* jmp(l6) NEXT:[r(2)] PREV:[]
l5:
read (Unit) NEXT:[r(2)] PREV:[jf(l5)]
l4:
l6:
r(2) NEXT:[<END>] PREV:[jmp?(l4), jmp(l6), read (Unit)]
r(2) NEXT:[<END>] PREV:[jmp?(l4), read (Unit)]
l3:
<END> NEXT:[] PREV:[ret l3, r(2)]
error:
@@ -197,12 +197,12 @@ l2:
jf(l5) NEXT:[read (Unit), r(2)] PREV:[r(2 > 3)]
r(2) NEXT:[ret l3] PREV:[jf(l5)]
ret l3 NEXT:[<END>] PREV:[r(2)]
jmp(l6) NEXT:[r(2)] PREV:[]
* jmp(l6) NEXT:[r(2)] PREV:[]
l5:
read (Unit) NEXT:[r(2)] PREV:[jf(l5)]
l4:
l6:
r(2) NEXT:[<END>] PREV:[jmp?(l4), jmp(l6), read (Unit)]
r(2) NEXT:[<END>] PREV:[jmp?(l4), read (Unit)]
l3:
<END> NEXT:[] PREV:[ret l3, r(2)]
error:
@@ -238,12 +238,12 @@ l4:
jf(l7) NEXT:[read (Unit), r(2)] PREV:[r(2 > 3)]
r(2) NEXT:[jmp(l3)] PREV:[jf(l7)]
jmp(l3) NEXT:[read (Unit)] PREV:[r(2)]
jmp(l8) NEXT:[r(2)] PREV:[]
* jmp(l8) NEXT:[r(2)] PREV:[]
l7:
read (Unit) NEXT:[r(2)] PREV:[jf(l7)]
l6:
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)]
l3:
read (Unit) NEXT:[<END>] PREV:[jf(l3), jmp(l3)]
@@ -282,11 +282,11 @@ l5:
r(2 > 3) NEXT:[jf(l7)] PREV:[r(>)]
jf(l7) NEXT:[read (Unit), jmp(l4)] PREV:[r(2 > 3)]
jmp(l4) NEXT:[read (Unit)] PREV:[jf(l7)]
jmp(l8) NEXT:[jmp(l3)] PREV:[]
* jmp(l8) NEXT:[jmp(l3)] PREV:[]
l7:
read (Unit) NEXT:[jmp(l3)] PREV:[jf(l7)]
l8:
jmp(l3) NEXT:[r(true)] PREV:[jmp(l8), read (Unit)]
jmp(l3) NEXT:[r(true)] PREV:[read (Unit)]
l4:
read (Unit) NEXT:[r(5)] PREV:[jf(l4), jmp(l4)]
r(5) NEXT:[r(2)] PREV:[read (Unit)]
@@ -326,11 +326,11 @@ l5:
r(2 > 3) NEXT:[jf(l7)] PREV:[r(>)]
jf(l7) NEXT:[read (Unit), jmp(l4)] PREV:[r(2 > 3)]
jmp(l4) NEXT:[read (Unit)] PREV:[jf(l7)]
jmp(l8) NEXT:[jmp(l3)] PREV:[]
* jmp(l8) NEXT:[jmp(l3)] PREV:[]
l7:
read (Unit) NEXT:[jmp(l3)] PREV:[jf(l7)]
l8:
jmp(l3) NEXT:[r(true)] PREV:[jmp(l8), read (Unit)]
jmp(l3) NEXT:[r(true)] PREV:[read (Unit)]
l4:
read (Unit) NEXT:[r(2)] PREV:[jf(l4), jmp(l4)]
l2:
@@ -374,12 +374,12 @@ l5:
jf(l7) NEXT:[read (Unit), r(2)] PREV:[r(2 > 3)]
r(2) NEXT:[jmp(l4)] PREV:[jf(l7)]
jmp(l4) NEXT:[jmp?(l6)] PREV:[r(2)]
jmp(l8) NEXT:[r(2)] PREV:[]
* jmp(l8) NEXT:[r(2)] PREV:[]
l7:
read (Unit) NEXT:[r(2)] PREV:[jf(l7)]
l6:
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)]
l2:
read (Unit) NEXT:[<END>] PREV:[jmp?(l2), jmp?(l4)]
@@ -422,11 +422,11 @@ l6:
r(2 > 3) NEXT:[jf(l7)] PREV:[r(>)]
jf(l7) NEXT:[read (Unit), jmp(l5)] PREV:[r(2 > 3)]
jmp(l5) NEXT:[r(1)] PREV:[jf(l7)]
jmp(l8) NEXT:[jmp?(l5)] PREV:[]
* jmp(l8) NEXT:[jmp?(l5)] PREV:[]
l7:
read (Unit) NEXT:[jmp?(l5)] PREV:[jf(l7)]
l8:
jmp?(l5) NEXT:[r(1), read (Unit)] PREV:[jmp(l8), read (Unit)]
jmp?(l5) NEXT:[r(1), read (Unit)] PREV:[read (Unit)]
l3:
read (Unit) NEXT:[r(5)] PREV:[jmp?(l3), jmp?(l5)]
r(5) NEXT:[r(2)] PREV:[read (Unit)]
@@ -470,11 +470,11 @@ l6:
r(2 > 3) NEXT:[jf(l7)] PREV:[r(>)]
jf(l7) NEXT:[read (Unit), jmp(l5)] PREV:[r(2 > 3)]
jmp(l5) NEXT:[r(1)] PREV:[jf(l7)]
jmp(l8) NEXT:[jmp?(l5)] PREV:[]
* jmp(l8) NEXT:[jmp?(l5)] PREV:[]
l7:
read (Unit) NEXT:[jmp?(l5)] PREV:[jf(l7)]
l8:
jmp?(l5) NEXT:[r(1), read (Unit)] PREV:[jmp(l8), read (Unit)]
jmp?(l5) NEXT:[r(1), read (Unit)] PREV:[read (Unit)]
l3:
read (Unit) NEXT:[r(2)] PREV:[jmp?(l3), jmp?(l5)]
l2:
@@ -500,12 +500,12 @@ l0:
r(1) NEXT:[r(2)] PREV:[jmp?(l2)]
r(2) NEXT:[ret(*) l1] PREV:[r(1)]
ret(*) l1 NEXT:[<END>] PREV:[r(2)]
ret(*) l1 NEXT:[<END>] PREV:[]
* ret(*) l1 NEXT:[<END>] PREV:[]
l2:
r(2) NEXT:[ret(*) l1] PREV:[jmp?(l2)]
ret(*) l1 NEXT:[<END>] PREV:[r(2)]
l1:
<END> NEXT:[] PREV:[ret(*) l1, ret(*) l1, ret(*) l1]
<END> NEXT:[] PREV:[ret(*) l1, ret(*) l1]
error:
<ERROR> NEXT:[] PREV:[]
=====================
+40
View File
@@ -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:[]
=====================
+7
View File
@@ -0,0 +1,7 @@
fun t1() {
for (i in 1..2) {
doSmth(i)
}
}
fun doSmth(i: Int) {}
+98
View File
@@ -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:[]
=====================
+31
View File
@@ -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:[]
l2:
l4:
ret l1 NEXT:[<END>] PREV:[<START>, jt(l2)]
ret l1 NEXT:[<END>] PREV:[<START>]
l5:
r(1) NEXT:[r(0)] PREV:[]
r(0) NEXT:[r(>)] PREV:[r(1)]
r(>) NEXT:[r(1 > 0)] PREV:[r(0)]
r(1 > 0) NEXT:[jt(l2)] PREV:[r(>)]
jt(l2) NEXT:[read (Unit), ret l1] PREV:[r(1 > 0)]
* r(1) NEXT:[r(0)] PREV:[]
* r(0) NEXT:[r(>)] PREV:[]
* r(>) NEXT:[r(1 > 0)] PREV:[]
* r(1 > 0) NEXT:[jt(l2)] PREV:[]
* jt(l2) NEXT:[read (Unit), ret l1] PREV:[]
l3:
read (Unit) NEXT:[<END>] PREV:[jt(l2)]
* read (Unit) NEXT:[<END>] PREV:[]
l1:
<END> NEXT:[] PREV:[ret l1, read (Unit)]
<END> NEXT:[] PREV:[ret l1]
error:
<ERROR> NEXT:[] PREV:[]
=====================
+3 -2
View File
@@ -22,8 +22,9 @@ fun testUnresolved() {
//TODO
for (j in <error>collection</error>) {
val i: Int = j
j += 1
var i: Int = j
i += 1
foo1(j)
}
}
@@ -1,5 +1,5 @@
fun test() {
val a : Any? = null
var a : Any? = null
if (a is Any) else a = null;
while (a is Any) a = null
while (true) a = null
@@ -12,7 +12,7 @@ abstract enum class ProtocolState {
fun box(): String {
val x: ProtocolState = ProtocolState.WAITING
var x: ProtocolState = ProtocolState.WAITING
x = x.signal()
if (x != ProtocolState.TALKING) return "fail 1"
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 x = 1
var x = 1
<!EXPECTED_TYPE_MISMATCH!>x = 333<!>
}
val endsWithReAssignment = { () : Int =>
val x = 1
var x = 1
<!EXPECTED_TYPE_MISMATCH!>x += 333<!>
}
val endsWithFunDeclaration : fun() : String = {
val x = 1
var x = 1
x = 333
<!EXPECTED_TYPE_MISMATCH!>fun meow() : Unit {}<!>
}
val endsWithObjectDeclaration : fun() : Int = {
val x = 1
var x = 1
x = 333
<!EXPECTED_TYPE_MISMATCH!>object A {}<!>
}
@@ -22,8 +22,9 @@ fun testUnresolved() {
//TODO
for (j in <!UNRESOLVED_REFERENCE!>collection<!>) {
val i: Int = j
j += 1
var i: Int = j
i += 1
foo1(j)
}
}
@@ -1,5 +1,5 @@
fun test() {
val a : Any? = null
var a : Any? = null
if (a is Any) else a = null;
while (a is Any) a = null
while (true) a = null
@@ -12,7 +12,7 @@ abstract enum class ProtocolState {
fun box(): String {
val x: ProtocolState = ProtocolState.WAITING
var x: ProtocolState = ProtocolState.WAITING
x = x.signal()
if (x != ProtocolState.TALKING) return "fail 1"
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;
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 {
fun foo() {}
}
@@ -72,6 +84,6 @@ class ERROR<E>() : <!UNRESOLVED_REFERENCE!>UR<!> {
// No supertype at all
class A1 {
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()
}
@@ -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 {
val v1 = ArrayWrapper<String>()
var v1 = ArrayWrapper<String>()
val v2 = ArrayWrapper<String>()
v1.add("foo")
v2.add("bar")
@@ -20,7 +20,7 @@ class ArrayWrapper<T>() {
}
fun box(): String {
val v1 = ArrayWrapper<String>()
var v1 = ArrayWrapper<String>()
val v2 = ArrayWrapper<String>()
v1.add("foo")
val v3 = v1
@@ -20,7 +20,7 @@ class ArrayWrapper<T>() {
}
fun box(): String {
val v1 = ArrayWrapper<String>()
var v1 = ArrayWrapper<String>()
val v2 = ArrayWrapper<String>()
v1.add("foo")
val v3 = v1
@@ -4,7 +4,7 @@ fun box() : String {
a[1] = "b"
a[2] = "c"
val result = 0
var result = 0
for(i in a.indices) {
result += i
}
@@ -88,7 +88,8 @@ class MyCollection2(): Iterable<Int> {
var k : Int = 5
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
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
Collection<Instruction> instructions = pseudocode.getInstructions();
for (Instruction instruction : instructions) {
for (Instruction nextInstruction : instruction.getNextInstructions()) {
assertTrue("instruction: " + instruction + " next: " + nextInstruction, nextInstruction.getPreviousInstructions().contains(instruction));
}
for (Instruction prevInstruction : instruction.getPreviousInstructions()) {
assertTrue("instruction: " + instruction + " prev: " + prevInstruction, prevInstruction.getNextInstructions().contains(instruction));
if (!((InstructionImpl) instruction).isDead()) {
for (Instruction nextInstruction : instruction.getNextInstructions()) {
assertTrue("instruction '" + instruction + "' has '" + nextInstruction + "' among next instructions list, but not vice versa",
nextInstruction.getPreviousInstructions().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) {
String[] parts = instruction.toString().split("\n");
String prefix = ((InstructionImpl)instruction).isDead() ? "* " : " ";
if (parts.length == 1) {
return " " + String.format("%1$-" + maxLength + "s", instruction);
return prefix + String.format("%1$-" + maxLength + "s", instruction);
}
StringBuilder sb = new StringBuilder();
for (int i = 0, partsLength = parts.length; i < partsLength; 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");
}
return sb.toString();
@@ -210,7 +215,9 @@ public class JetControlFlowTest extends JetTestCaseBase {
}
}
else {
maxLength = instuctionText.length();
if (instuctionText.length() > maxLength) {
maxLength = instuctionText.length();
}
}
}
String instructionListText = formatInstructionList(instruction.getNextInstructions());
@@ -56,42 +56,42 @@ public class ArrayGenTest extends CodegenTestCase {
}
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());
Method foo = generateFunction();
foo.invoke(null);
}
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());
Method foo = generateFunction();
foo.invoke(null);
}
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());
Method foo = generateFunction();
foo.invoke(null);
}
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());
Method foo = generateFunction();
foo.invoke(null);
}
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());
Method foo = generateFunction();
foo.invoke(null);
}
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());
Method foo = generateFunction();
foo.invoke(null);
@@ -1,5 +1,8 @@
package org.jetbrains.jet.codegen;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
/**
* @author alex.tkachman
*/
@@ -13,4 +16,29 @@ public class FunctionGenTest extends CodegenTestCase {
blackBoxFile("functions/nothisnoclosure.jet");
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 {
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());
final Method main = generateFunction();
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));
*/
}
}
+4 -4
View File
@@ -1,15 +1,15 @@
open class IEquality {
trait IEquality {
fun equals(other : Any) : Boolean
= (this as java.lang.Object).equals(other as java.lang.Object)
}
open class IHashable : IEquality {
trait IHashable : IEquality {
val hashCode : Integer
get() = (this as java.lang.Object).hashCode()
}
open class IMap<K, V> {
trait IMap<K : IHashable, V> {
fun get(key : K) : V
fun set(key : K, value : V) : 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)
open class IHashingStrategy<K> {
trait IHashingStrategy<K : IHashable> {
fun equals(a : K, b : K) : Boolean
fun hashCode(a : K) : Integer
}
-3
View File
@@ -1,3 +0,0 @@
open class IIterable<out T> {
fun iterator() : IIterator<T>
}
+9
View File
@@ -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
}
-25
View File
@@ -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
}
}
-4
View File
@@ -1,4 +0,0 @@
open class IList<out T> : IIterable<T>, ISized {
[operator] fun get(index : Int) : T
val isEmpty : Boolean
}
+3
View File
@@ -0,0 +1,3 @@
trait IList<out T> : IIterable<T>, ISized {
fun get(index : Int) : T
}
-3
View File
@@ -1,3 +0,0 @@
open class ISet<T> : IIterable<T>, ISized {
fun contains(item : T) : Boolean
}
+8
View File
@@ -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
}
-3
View File
@@ -1,3 +0,0 @@
open class ISized {
val size : Int
}
+11
View File
@@ -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
}
+170
View File
@@ -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
}
*/
+1 -5
View File
@@ -47,11 +47,7 @@ optionalProjection
;
functionType
: "fun" (type ".")? functionTypeContents
;
functionTypeContents
: "(" (parameter | modifiers /*lazy out ref*/ type){","} ")" ":" type
: "fun" (type ".")? "(" (parameter | modifiers /*lazy out ref*/ type){","} ")" (":" type)? // Unit by default
;
tupleType
+5 -5
View File
@@ -1,19 +1,19 @@
/*
* @author max
* @author alex.tkachman
*/
package jet;
import jet.typeinfo.TypeInfo;
public abstract class ExtensionFunction1<E, D, R> extends DefaultJetObject{
public abstract class ExtensionFunction1<E, D1, R> extends DefaultJetObject {
protected ExtensionFunction1(TypeInfo<?> typeInfo) {
super(typeInfo);
}
public abstract R invoke(E receiver, D d);
public abstract R invoke(E receiver, D1 d1);
@Override
public String toString() {
return "{E.(d: D) : R}";
return "{E.(d1: D1) : R)}";
}
}
+19
View File
@@ -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)}";
}
}
+19
View File
@@ -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)}";
}
}
+19
View File
@@ -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)}";
}
}
+19
View File
@@ -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)}";
}
}
+19
View File
@@ -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)}";
}
}
+19
View File
@@ -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)}";
}
}
+19
View File
@@ -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)}";
}
}
+19
View File
@@ -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)}";
}
}
+19
View File
@@ -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)}";
}
}
+19
View File
@@ -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)}";
}
}
+4 -4
View File
@@ -1,11 +1,10 @@
/*
* @author max
* @author alex.tkachman
*/
package jet;
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) {
super(typeInfo);
}
@@ -14,6 +13,7 @@ public abstract class ExtensionFunction2<E, D1, D2, R> extends DefaultJetObjec
@Override
public String toString() {
return "{E.(d1: D1, d2: D2) : R}";
return "{E.(d1: D1, d2: D2) : R)}";
}
}
+19
View File
@@ -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)}";
}
}
+19
View File
@@ -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)}";
}
}
+19
View File
@@ -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)}";
}
}
+4 -4
View File
@@ -1,11 +1,10 @@
/*
* @author max
* @author alex.tkachman
*/
package jet;
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) {
super(typeInfo);
}
@@ -14,6 +13,7 @@ public abstract class ExtensionFunction3<E, D1, D2, D3, R> extends DefaultJetOb
@Override
public String toString() {
return "{E.(d1: D1, d2: D2, d3: D3) : R}";
return "{E.(d1: D1, d2: D2, d3: D3) : R)}";
}
}
+19
View File
@@ -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)}";
}
}
+19
View File
@@ -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)}";
}
}
+19
View File
@@ -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)}";
}
}
+19
View File
@@ -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)}";
}
}
+19
View File
@@ -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)}";
}
}
+19
View File
@@ -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)}";
}
}
+71 -2
View File
@@ -5,8 +5,13 @@ package jet;
import jet.typeinfo.TypeInfo;
public abstract class Function0<R> extends DefaultJetObject {
protected Function0(TypeInfo<?> typeInfo) {
import java.io.File;
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);
}
@@ -16,4 +21,68 @@ public abstract class Function0<R> extends DefaultJetObject {
public String toString() {
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();
// }
// }
}
+5 -5
View File
@@ -1,19 +1,19 @@
/*
* @author max
* @author alex.tkachman
*/
package jet;
import jet.typeinfo.TypeInfo;
public abstract class Function1<D, R> extends DefaultJetObject {
public abstract class Function1<D1, R> extends DefaultJetObject {
protected Function1(TypeInfo<?> typeInfo) {
super(typeInfo);
}
public abstract R invoke(D d);
public abstract R invoke(D1 d1);
@Override
public String toString() {
return "{(d: D) : R}";
return "{(d1: D1) : R)}";
}
}
+19
View File
@@ -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)}";
}
}
+19
View File
@@ -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)}";
}
}
+19
View File
@@ -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)}";
}
}
+19
View File
@@ -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)}";
}
}
+19
View File
@@ -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)}";
}
}
+19
View File
@@ -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)}";
}
}
+19
View File
@@ -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)}";
}
}
+19
View File
@@ -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