From fb971ff7cbc94e4217b5c4297ff06347290785bc Mon Sep 17 00:00:00 2001 From: Andrey Breslav Date: Fri, 21 Oct 2011 13:37:14 +0400 Subject: [PATCH 01/23] Tests moved to appropriate locations --- compiler/testData/checkerWithErrorTypes/quick/Super.jet | 2 +- {idea => compiler}/testData/psi/Super.jet | 0 {idea => compiler}/testData/psi/Super.txt | 0 {idea => compiler}/testData/resolve/Super.jet | 0 4 files changed, 1 insertion(+), 1 deletion(-) rename {idea => compiler}/testData/psi/Super.jet (100%) rename {idea => compiler}/testData/psi/Super.txt (100%) rename {idea => compiler}/testData/resolve/Super.jet (100%) diff --git a/compiler/testData/checkerWithErrorTypes/quick/Super.jet b/compiler/testData/checkerWithErrorTypes/quick/Super.jet index 5ec4cfdcb00..e6d1146fd3c 100644 --- a/compiler/testData/checkerWithErrorTypes/quick/Super.jet +++ b/compiler/testData/checkerWithErrorTypes/quick/Super.jet @@ -72,6 +72,6 @@ class ERROR() : UR { // No supertype at all class A1 { fun test() { - super.equals(null) + super.equals(null) } } \ No newline at end of file diff --git a/idea/testData/psi/Super.jet b/compiler/testData/psi/Super.jet similarity index 100% rename from idea/testData/psi/Super.jet rename to compiler/testData/psi/Super.jet diff --git a/idea/testData/psi/Super.txt b/compiler/testData/psi/Super.txt similarity index 100% rename from idea/testData/psi/Super.txt rename to compiler/testData/psi/Super.txt diff --git a/idea/testData/resolve/Super.jet b/compiler/testData/resolve/Super.jet similarity index 100% rename from idea/testData/resolve/Super.jet rename to compiler/testData/resolve/Super.jet From 142322d3a18bc6a0b395f2b1cc5b15faa92351ae Mon Sep 17 00:00:00 2001 From: Alex Tkachman Date: Fri, 21 Oct 2011 17:40:52 +0200 Subject: [PATCH 02/23] ArrayIterator is JetObject --- stdlib/src/jet/arrays/ArrayIterator.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/stdlib/src/jet/arrays/ArrayIterator.java b/stdlib/src/jet/arrays/ArrayIterator.java index 3bbfac045f3..761a153d474 100644 --- a/stdlib/src/jet/arrays/ArrayIterator.java +++ b/stdlib/src/jet/arrays/ArrayIterator.java @@ -1,6 +1,7 @@ package jet.arrays; import jet.Iterator; +import jet.JetObject; import jet.typeinfo.TypeInfo; import jet.typeinfo.TypeInfoProjection; @@ -10,7 +11,7 @@ import java.util.Arrays; /** * @author alex.tkachman */ -public abstract class ArrayIterator implements Iterator { +public abstract class ArrayIterator implements Iterator, JetObject { private final int size; protected int index; From 23c72f4e2778083907e1180c09c3c85d27c38b0f Mon Sep 17 00:00:00 2001 From: Alex Tkachman Date: Fri, 21 Oct 2011 18:37:36 +0200 Subject: [PATCH 03/23] KotlinCompiler accepts directory --- .../org/jetbrains/jet/cli/KotlinCompiler.java | 112 +++++++++++------- 1 file changed, 71 insertions(+), 41 deletions(-) diff --git a/compiler/cli/src/org/jetbrains/jet/cli/KotlinCompiler.java b/compiler/cli/src/org/jetbrains/jet/cli/KotlinCompiler.java index 9d943679e2b..67d88d00740 100644 --- a/compiler/cli/src/org/jetbrains/jet/cli/KotlinCompiler.java +++ b/compiler/cli/src/org/jetbrains/jet/cli/KotlinCompiler.java @@ -6,6 +6,7 @@ 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.PsiDirectory; import com.intellij.psi.PsiFile; import com.intellij.psi.PsiManager; import org.jetbrains.jet.codegen.ClassFileFactory; @@ -28,12 +29,13 @@ import java.util.List; /** * @author yole + * @author alex.tkachman */ public class KotlinCompiler { public static void main(String[] args) { System.setProperty("java.awt.headless", "true"); if (args.length < 1) { - System.out.println("Usage: KotlinCompiler "); + System.out.println("Usage: KotlinCompiler or "); return; } @@ -44,61 +46,36 @@ public class KotlinCompiler { }; JavaCoreEnvironment environment = new JavaCoreEnvironment(root); - String javaHome = System.getenv("JAVA_HOME"); - File rtJar = null; - if (javaHome == null) { - ClassLoader systemClassLoader = ClassLoader.getSystemClassLoader(); - if(systemClassLoader instanceof URLClassLoader) { - URLClassLoader loader = (URLClassLoader) systemClassLoader; - for(URL url: loader.getURLs()) { - if("file".equals(url.getProtocol())) { - if(url.getFile().endsWith("/lib/rt.jar")) { - rtJar = new File(url.getFile()); - break; - } - if(url.getFile().endsWith("/Classes/classes.jar")) { - rtJar = new File(url.getFile()).getAbsoluteFile(); - break; - } - } - } - } - - if(rtJar == null) { - System.out.println("JAVA_HOME environment variable needs to be defined"); - return; - } - } - else { - rtJar = findRtJar(javaHome); - } - - if (rtJar == null || !rtJar.exists()) { - System.out.print("No rt.jar found under JAVA_HOME=" + javaHome); - return; - } + File rtJar = initJdk(); + if (rtJar == null) return; environment.addToClasspath(rtJar); environment.registerFileType(JetFileType.INSTANCE, "kt"); - environment.registerFileType(JetFileType.INSTANCE, "jet"); environment.registerParserDefinition(new JetParserDefinition()); + VirtualFile vFile = environment.getLocalFileSystem().findFileByPath(args [0]); if (vFile == null) { - System.out.print("File not found: " + args[0]); + System.out.print("File/directory not found: " + args[0]); return; } Project project = environment.getProject(); GenerationState generationState = new GenerationState(project, false); List namespaces = Lists.newArrayList(); - PsiFile psiFile = PsiManager.getInstance(project).findFile(vFile); - if (psiFile instanceof JetFile) { - namespaces.add(((JetFile) psiFile).getRootNamespace()); + if(vFile.isDirectory()) { + File dir = new File(vFile.getPath()); + addFiles(environment, project, namespaces, dir); } else { - System.out.print("Not a Kotlin file: " + vFile.getPath()); - return; + 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); @@ -137,6 +114,59 @@ public class KotlinCompiler { } + private static void addFiles(JavaCoreEnvironment environment, Project project, List 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()); + System.out.println(file.getAbsolutePath()); + } + } + else { + addFiles(environment, project, namespaces, file); + } + } + } + + private static File initJdk() { + String javaHome = System.getenv("JAVA_HOME"); + File rtJar = null; + if (javaHome == null) { + ClassLoader systemClassLoader = ClassLoader.getSystemClassLoader(); + if(systemClassLoader instanceof URLClassLoader) { + URLClassLoader loader = (URLClassLoader) systemClassLoader; + for(URL url: loader.getURLs()) { + if("file".equals(url.getProtocol())) { + if(url.getFile().endsWith("/lib/rt.jar")) { + rtJar = new File(url.getFile()); + break; + } + if(url.getFile().endsWith("/Classes/classes.jar")) { + rtJar = new File(url.getFile()).getAbsoluteFile(); + break; + } + } + } + } + + if(rtJar == null) { + System.out.println("JAVA_HOME environment variable needs to be defined"); + return null; + } + } + else { + rtJar = findRtJar(javaHome); + } + + if (rtJar == null || !rtJar.exists()) { + System.out.print("No rt.jar found under JAVA_HOME=" + javaHome); + return null; + } + return rtJar; + } + private static void report(Diagnostic diagnostic) { System.out.println(diagnostic.getMessage()); } From fe869a236dac6467c6f1a3dd03cc49578fe7c549 Mon Sep 17 00:00:00 2001 From: Alex Tkachman Date: Fri, 21 Oct 2011 18:41:27 +0200 Subject: [PATCH 04/23] Any.equals & Any.toString --- .../jet/codegen/ExpressionCodegen.java | 2 +- .../jetbrains/jet/codegen/JetTypeMapper.java | 1 + .../jet/codegen/intrinsics/Equals.java | 43 +++++++++++++++++++ .../codegen/intrinsics/IntrinsicMethods.java | 5 +++ .../jet/codegen/intrinsics/ToString.java | 24 +++++++++++ .../jet/codegen/FunctionGenTest.java | 28 ++++++++++++ 6 files changed, 102 insertions(+), 1 deletion(-) create mode 100644 compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/Equals.java create mode 100644 compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/ToString.java diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java index 0b577fedb1c..baddde3e04c 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java @@ -1462,7 +1462,7 @@ public class ExpressionCodegen extends JetVisitor { 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); } diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/JetTypeMapper.java b/compiler/backend/src/org/jetbrains/jet/codegen/JetTypeMapper.java index 926b496e243..3d674335c81 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/JetTypeMapper.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/JetTypeMapper.java @@ -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); diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/Equals.java b/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/Equals.java new file mode 100644 index 00000000000..8a9280c0102 --- /dev/null +++ b/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/Equals.java @@ -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 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()); + } +} diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/IntrinsicMethods.java b/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/IntrinsicMethods.java index b1efba96116..edda1e0f96b 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/IntrinsicMethods.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/IntrinsicMethods.java @@ -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()); diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/ToString.java b/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/ToString.java new file mode 100644 index 00000000000..18e706a4b1f --- /dev/null +++ b/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/ToString.java @@ -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 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); + } +} diff --git a/compiler/tests/org/jetbrains/jet/codegen/FunctionGenTest.java b/compiler/tests/org/jetbrains/jet/codegen/FunctionGenTest.java index 130148eb40b..da0ecc0dd4b 100644 --- a/compiler/tests/org/jetbrains/jet/codegen/FunctionGenTest.java +++ b/compiler/tests/org/jetbrains/jet/codegen/FunctionGenTest.java @@ -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")); + } } From a67b76d105392b0e59a72ac631519bc03c696349 Mon Sep 17 00:00:00 2001 From: Andrey Breslav Date: Fri, 21 Oct 2011 21:43:08 +0400 Subject: [PATCH 05/23] KT-377 Prohibit 'super' as a receiver argument to extension functions + SEVERITY_LEVELS added instead of hardcoding weak errors + commit() in temporary trace removed the data, so that double commit does not cause duplication of data --- .../lang/resolve/DelegatingBindingTrace.java | 5 + .../lang/resolve/TemporaryBindingTrace.java | 2 + .../jet/lang/resolve/calls/CallResolver.java | 95 ++++++++++--------- .../lang/resolve/calls/ResolutionStatus.java | 25 ++++- .../lang/resolve/calls/TaskPrioritizer.java | 29 +++++- .../lang/resolve/calls/TracingStrategy.java | 9 +- .../jet/util/slicedmap/MutableSlicedMap.java | 2 + .../jet/util/slicedmap/SlicedMapImpl.java | 5 + .../quick/ExtensionsCalledOnSuper.jet | 21 ++++ .../checkerWithErrorTypes/quick/Super.jet | 12 +++ 10 files changed, 152 insertions(+), 53 deletions(-) create mode 100644 compiler/testData/checkerWithErrorTypes/quick/ExtensionsCalledOnSuper.jet diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/DelegatingBindingTrace.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/DelegatingBindingTrace.java index 9b00c34e64a..416a0b54e5d 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/DelegatingBindingTrace.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/DelegatingBindingTrace.java @@ -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); diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/TemporaryBindingTrace.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/TemporaryBindingTrace.java index 9d7f3fd1a18..fef2b6a9e1a 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/TemporaryBindingTrace.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/TemporaryBindingTrace.java @@ -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(); } } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/CallResolver.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/CallResolver.java index 3840d59e444..976d5b9c070 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/CallResolver.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/CallResolver.java @@ -206,8 +206,6 @@ public class CallResolver { @NotNull JetType expectedType, @NotNull final List> prioritizedTasks, // high to low priority @NotNull final JetReferenceExpression reference) { - TemporaryBindingTrace traceForFirstNonemptyCandidateSet = null; - OverloadResolutionResults resultsForFirstNonemptyCandidateSet = null; TracingStrategy tracing = new TracingStrategy() { @Override public void bindReference(@NotNull BindingTrace trace, @NotNull ResolvedCallImpl resolvedCall) { @@ -272,12 +270,12 @@ public class CallResolver { } @Override - public void ambiguity(@NotNull BindingTrace trace, @NotNull Set> descriptors) { + public void ambiguity(@NotNull BindingTrace trace, @NotNull Collection> descriptors) { trace.report(OVERLOAD_RESOLUTION_AMBIGUITY.on(call.getCallNode(), descriptors)); } @Override - public void noneApplicable(@NotNull BindingTrace trace, @NotNull Set> descriptors) { + public void noneApplicable(@NotNull BindingTrace trace, @NotNull Collection> 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 resultsForFirstNonemptyCandidateSet = null; for (ResolutionTask task : prioritizedTasks) { TemporaryBindingTrace temporaryTrace = TemporaryBindingTrace.create(trace); OverloadResolutionResults 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 Function createMapFunction(D substitutedFunctionDescriptor) { -// assert substitutedFunctionDescriptor != null; -// final Map parameterMap = Maps.newHashMap(); -// for (ValueParameterDescriptor valueParameterDescriptor : substitutedFunctionDescriptor.getValueParameters()) { -// parameterMap.put(valueParameterDescriptor.getOriginal(), valueParameterDescriptor); -// } -// -// return new Function() { -// @Override -// public ValueParameterDescriptor apply(ValueParameterDescriptor input) { -// return parameterMap.get(input.getOriginal()); -// } -// }; -// } - private void replaceValueParametersWithSubstitutedOnes(ResolvedCallImpl candidateCall, @NotNull D substitutedDescriptor) { Map parameterMap = Maps.newHashMap(); for (ValueParameterDescriptor valueParameterDescriptor : substitutedDescriptor.getValueParameters()) { @@ -656,30 +650,47 @@ public class CallResolver { Set> successfulCandidates, Set> 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 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> weakErrors = Sets.newLinkedHashSet(); - for (ResolvedCallImpl candidate : failedCandidates) { - if (candidate.getStatus().isWeakError()) { - weakErrors.add(candidate); - } - } - if (!weakErrors.isEmpty()) { - OverloadResolutionResults 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 severityLevel : SEVERITY_LEVELS) { + Set> thisLevel = Sets.newLinkedHashSet(); + for (ResolvedCallImpl candidate : failedCandidates) { + if (severityLevel.contains(candidate.getStatus())) { + thisLevel.add(candidate); + } } + if (!thisLevel.isEmpty()) { + OverloadResolutionResults 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> 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 OverloadResolutionResults chooseAndReportMaximallySpecific(BindingTrace trace, TracingStrategy tracing, Set> candidates) { + private boolean allClean(Collection> results) { + for (ResolvedCallImpl result : results) { + if (result.isDirty()) return false; + } + return true; + } + + private OverloadResolutionResults chooseAndReportMaximallySpecific(Set> candidates) { if (candidates.size() != 1) { Set> cleanCandidates = Sets.newLinkedHashSet(candidates); - boolean allClean = true; for (Iterator> iterator = cleanCandidates.iterator(); iterator.hasNext(); ) { ResolvedCallImpl candidate = iterator.next(); if (candidate.isDirty()) { iterator.remove(); - allClean = false; } } @@ -722,13 +738,6 @@ public class CallResolver { } Set> 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); } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/ResolutionStatus.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/ResolutionStatus.java index 7c9c5406285..78253d24466 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/ResolutionStatus.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/ResolutionStatus.java @@ -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[] 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; } } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/TaskPrioritizer.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/TaskPrioritizer.java index 5bfc0947a8e..3b02eb27f0e 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/TaskPrioritizer.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/TaskPrioritizer.java @@ -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> computePrioritizedTasks(@NotNull JetScope scope, @NotNull Call call, @NotNull String name, @NotNull BindingContext bindingContext, @NotNull DataFlowInfo dataFlowInfo) { List> 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 memberExtensions = getExtensionsByName(implicitReceiver.getType().getMemberScope(), name); diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/TracingStrategy.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/TracingStrategy.java index 6284ccb5b0d..d06b99d2068 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/TracingStrategy.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/TracingStrategy.java @@ -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 void ambiguity(@NotNull BindingTrace trace, @NotNull Set> descriptors) {} + public void ambiguity(@NotNull BindingTrace trace, @NotNull Collection> descriptors) {} @Override - public void noneApplicable(@NotNull BindingTrace trace, @NotNull Set> descriptors) {} + public void noneApplicable(@NotNull BindingTrace trace, @NotNull Collection> descriptors) {} @Override public void instantiationOfAbstractClass(@NotNull BindingTrace trace) {} @@ -74,9 +73,9 @@ import java.util.Set; void wrongNumberOfTypeArguments(@NotNull BindingTrace trace, int expectedTypeArgumentCount); - void ambiguity(@NotNull BindingTrace trace, @NotNull Set> descriptors); + void ambiguity(@NotNull BindingTrace trace, @NotNull Collection> descriptors); - void noneApplicable(@NotNull BindingTrace trace, @NotNull Set> descriptors); + void noneApplicable(@NotNull BindingTrace trace, @NotNull Collection> descriptors); void instantiationOfAbstractClass(@NotNull BindingTrace trace); diff --git a/compiler/frontend/src/org/jetbrains/jet/util/slicedmap/MutableSlicedMap.java b/compiler/frontend/src/org/jetbrains/jet/util/slicedmap/MutableSlicedMap.java index a3706523fbf..32dfe3d17bf 100644 --- a/compiler/frontend/src/org/jetbrains/jet/util/slicedmap/MutableSlicedMap.java +++ b/compiler/frontend/src/org/jetbrains/jet/util/slicedmap/MutableSlicedMap.java @@ -8,4 +8,6 @@ public interface MutableSlicedMap extends SlicedMap { void put(WritableSlice slice, K key, V value); V remove(RemovableSlice slice, K key); + + void clear(); } diff --git a/compiler/frontend/src/org/jetbrains/jet/util/slicedmap/SlicedMapImpl.java b/compiler/frontend/src/org/jetbrains/jet/util/slicedmap/SlicedMapImpl.java index 36dbf297929..70182bb6ee4 100644 --- a/compiler/frontend/src/org/jetbrains/jet/util/slicedmap/SlicedMapImpl.java +++ b/compiler/frontend/src/org/jetbrains/jet/util/slicedmap/SlicedMapImpl.java @@ -47,6 +47,11 @@ public class SlicedMapImpl implements MutableSlicedMap { slice.afterPut(this, key, value); } + @Override + public void clear() { + map.clear(); + } + @Override public V get(ReadOnlySlice slice, K key) { SlicedMapKey slicedMapKey = slice.makeKey(key); diff --git a/compiler/testData/checkerWithErrorTypes/quick/ExtensionsCalledOnSuper.jet b/compiler/testData/checkerWithErrorTypes/quick/ExtensionsCalledOnSuper.jet new file mode 100644 index 00000000000..fe072bcc632 --- /dev/null +++ b/compiler/testData/checkerWithErrorTypes/quick/ExtensionsCalledOnSuper.jet @@ -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.bar() // Error + super.buzz() // OK, resolved to a member + super.buzz1() // Resolved to a member, but error: no parameter passed where required + } +} \ No newline at end of file diff --git a/compiler/testData/checkerWithErrorTypes/quick/Super.jet b/compiler/testData/checkerWithErrorTypes/quick/Super.jet index e6d1146fd3c..5841b9108f3 100644 --- a/compiler/testData/checkerWithErrorTypes/quick/Super.jet +++ b/compiler/testData/checkerWithErrorTypes/quick/Super.jet @@ -1,5 +1,17 @@ namespace example; +fun any(a : Any) {} + +fun notAnExpression() { + any(super) // not an expression + if (super) {} else {} // not an expression + val x = super // not an expression + when (1) { + super => 1 // not an expression + } + +} + trait T { fun foo() {} } From b9055681477eb9624a7186c006a1f1faac37cfe1 Mon Sep 17 00:00:00 2001 From: Andrey Breslav Date: Fri, 21 Oct 2011 21:51:17 +0400 Subject: [PATCH 06/23] KT-339 Allow to omit Unit return type from function types --- .../jet/lang/parsing/JetParsing.java | 21 +++++++------------ .../jet/lang/resolve/TypeResolver.java | 11 +++++----- .../quick/UnitByDefaultForFunctionTypes.jet | 3 +++ grammar/src/types.grm | 6 +----- 4 files changed, 17 insertions(+), 24 deletions(-) create mode 100644 compiler/testData/checkerWithErrorTypes/quick/UnitByDefaultForFunctionTypes.jet diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/parsing/JetParsing.java b/compiler/frontend/src/org/jetbrains/jet/lang/parsing/JetParsing.java index 6637d0bedec..9ab713325aa 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/parsing/JetParsing.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/parsing/JetParsing.java @@ -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); } /* diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/TypeResolver.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/TypeResolver.java index 76c23ca970d..fd60a354043 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/TypeResolver.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/TypeResolver.java @@ -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 diff --git a/compiler/testData/checkerWithErrorTypes/quick/UnitByDefaultForFunctionTypes.jet b/compiler/testData/checkerWithErrorTypes/quick/UnitByDefaultForFunctionTypes.jet new file mode 100644 index 00000000000..383e67e16c4 --- /dev/null +++ b/compiler/testData/checkerWithErrorTypes/quick/UnitByDefaultForFunctionTypes.jet @@ -0,0 +1,3 @@ +fun foo(f : fun()) { + val x : Unit = f() +} \ No newline at end of file diff --git a/grammar/src/types.grm b/grammar/src/types.grm index a0c3ce44679..b92457e67ce 100644 --- a/grammar/src/types.grm +++ b/grammar/src/types.grm @@ -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 From d76c5d47fd8f3eda30eed6bce396ae1f1f14e7ed Mon Sep 17 00:00:00 2001 From: Alex Tkachman Date: Sat, 22 Oct 2011 20:22:41 +0200 Subject: [PATCH 07/23] compiler options --- .../org/jetbrains/jet/cli/KotlinCompiler.java | 44 +++++++++++++------ examples/src/collections/ISized.kt | 3 ++ 2 files changed, 34 insertions(+), 13 deletions(-) create mode 100644 examples/src/collections/ISized.kt diff --git a/compiler/cli/src/org/jetbrains/jet/cli/KotlinCompiler.java b/compiler/cli/src/org/jetbrains/jet/cli/KotlinCompiler.java index 67d88d00740..83189a963fa 100644 --- a/compiler/cli/src/org/jetbrains/jet/cli/KotlinCompiler.java +++ b/compiler/cli/src/org/jetbrains/jet/cli/KotlinCompiler.java @@ -6,9 +6,10 @@ 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.PsiDirectory; import com.intellij.psi.PsiFile; import com.intellij.psi.PsiManager; +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; @@ -32,10 +33,22 @@ import java.util.List; * @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 or "); + Arguments arguments = new Arguments(); + try { + Args.parse(arguments, args); + } + catch (Throwable t) { + System.out.println("Usage: KotlinCompiler -output -src "); + t.printStackTrace(); return; } @@ -54,9 +67,9 @@ public class KotlinCompiler { environment.registerFileType(JetFileType.INSTANCE, "kt"); environment.registerParserDefinition(new JetParserDefinition()); - VirtualFile vFile = environment.getLocalFileSystem().findFileByPath(args [0]); + VirtualFile vFile = environment.getLocalFileSystem().findFileByPath(arguments.src); if (vFile == null) { - System.out.print("File/directory not found: " + args[0]); + System.out.print("File/directory not found: " + arguments.src); return; } @@ -100,14 +113,19 @@ public class KotlinCompiler { generationState.compileCorrectNamespaces(bindingContext, namespaces); final ClassFileFactory factory = generationState.getFactory(); - List 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()); + if(arguments.outputDir == null) { + System.out.println("Output directory is not specified - no files will be saved to the disk"); + } + else { + List 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()); + } } } } diff --git a/examples/src/collections/ISized.kt b/examples/src/collections/ISized.kt new file mode 100644 index 00000000000..e1b25190ae0 --- /dev/null +++ b/examples/src/collections/ISized.kt @@ -0,0 +1,3 @@ +trait ISized { + val size : Int +} \ No newline at end of file From 20bb2242fecad23aab20e4a47901bbfa4cd3d167 Mon Sep 17 00:00:00 2001 From: Alex Tkachman Date: Sun, 23 Oct 2011 08:29:05 +0200 Subject: [PATCH 08/23] private constructor added --- .../jetbrains/jet/lang/resolve/java/JavaDefaultImports.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaDefaultImports.java b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaDefaultImports.java index f6d6f2f001d..2176cb879b3 100644 --- a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaDefaultImports.java +++ b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaDefaultImports.java @@ -20,4 +20,7 @@ public class JavaDefaultImports { rootScope.importScope(new JavaPackageScope("java.lang", null, javaSemanticServices)); } }; + + private JavaDefaultImports() { + } } From 63bc261be24890e99e511189a985d2ea8debd010 Mon Sep 17 00:00:00 2001 From: Alex Tkachman Date: Sun, 23 Oct 2011 12:08:30 +0200 Subject: [PATCH 09/23] better error reporting in cli-compiler --- .../org/jetbrains/jet/cli/KotlinCompiler.java | 79 +++++++++++++------ 1 file changed, 57 insertions(+), 22 deletions(-) diff --git a/compiler/cli/src/org/jetbrains/jet/cli/KotlinCompiler.java b/compiler/cli/src/org/jetbrains/jet/cli/KotlinCompiler.java index 83189a963fa..4d5e5cfa5e6 100644 --- a/compiler/cli/src/org/jetbrains/jet/cli/KotlinCompiler.java +++ b/compiler/cli/src/org/jetbrains/jet/cli/KotlinCompiler.java @@ -1,8 +1,9 @@ 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.editor.Document; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.io.FileUtil; import com.intellij.openapi.vfs.VirtualFile; @@ -14,6 +15,8 @@ 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.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; @@ -26,6 +29,7 @@ import java.io.File; import java.io.IOException; import java.net.URL; import java.net.URLClassLoader; +import java.util.Collection; import java.util.List; /** @@ -93,23 +97,10 @@ public class KotlinCompiler { 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; - } - } + ErrorCollector errorCollector = new ErrorCollector(bindingContext); + errorCollector.report(); - if (!errors) { + if (!errorCollector.hasErrors) { generationState.compileCorrectNamespaces(bindingContext, namespaces); final ClassFileFactory factory = generationState.getFactory(); @@ -132,6 +123,55 @@ public class KotlinCompiler { } + private static class ErrorCollector { + Multimap maps = LinkedHashMultimap.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 diagnosticWithTextRanges = maps.get(psiFile); + for (DiagnosticWithTextRange diagnosticWithTextRange : diagnosticWithTextRanges) { + PsiFile file = diagnosticWithTextRange.getPsiFile(); + Document document = file.getViewProvider().getDocument(); + String result; + int offset = diagnosticWithTextRange.getTextRange().getStartOffset(); + if (document != null) { + int lineNumber = document.getLineNumber(offset); + int lineStartOffset = document.getLineStartOffset(lineNumber); + int column = offset - lineStartOffset; + + result = "(" + (lineNumber + 1) + "," + column + ")"; + } + else { + result = "(offset: " + offset + " line unknown)"; + } + System.out.println("\t" + diagnosticWithTextRange.getSeverity().toString() + ": " + result + " " + diagnosticWithTextRange.getMessage()); + } + } + } + } + } + private static void addFiles(JavaCoreEnvironment environment, Project project, List namespaces, File dir) { for(File file : dir.listFiles()) { if(!file.isDirectory()) { @@ -139,7 +179,6 @@ public class KotlinCompiler { PsiFile psiFile = PsiManager.getInstance(project).findFile(virtualFile); if (psiFile instanceof JetFile) { namespaces.add(((JetFile) psiFile).getRootNamespace()); - System.out.println(file.getAbsolutePath()); } } else { @@ -185,10 +224,6 @@ public class KotlinCompiler { return rtJar; } - private static void report(Diagnostic diagnostic) { - System.out.println(diagnostic.getMessage()); - } - private static File findRtJar(String javaHome) { File rtJar = new File(javaHome, "jre/lib/rt.jar"); if (rtJar.exists()) { From 469ea25b13ada9e08ef040bd1f02d6b9bfe73356 Mon Sep 17 00:00:00 2001 From: Alex Tkachman Date: Sun, 23 Oct 2011 12:27:58 +0200 Subject: [PATCH 10/23] method extracted --- .../org/jetbrains/jet/cli/KotlinCompiler.java | 20 ++++--------------- .../jet/lang/diagnostics/DiagnosticUtils.java | 18 +++++++++++++++++ 2 files changed, 22 insertions(+), 16 deletions(-) diff --git a/compiler/cli/src/org/jetbrains/jet/cli/KotlinCompiler.java b/compiler/cli/src/org/jetbrains/jet/cli/KotlinCompiler.java index 4d5e5cfa5e6..cc998dd0ac8 100644 --- a/compiler/cli/src/org/jetbrains/jet/cli/KotlinCompiler.java +++ b/compiler/cli/src/org/jetbrains/jet/cli/KotlinCompiler.java @@ -3,7 +3,6 @@ package org.jetbrains.jet.cli; import com.google.common.collect.*; import com.intellij.core.JavaCoreEnvironment; import com.intellij.openapi.Disposable; -import com.intellij.openapi.editor.Document; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.io.FileUtil; import com.intellij.openapi.vfs.VirtualFile; @@ -15,6 +14,7 @@ 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; @@ -151,25 +151,13 @@ public class KotlinCompiler { System.out.println(psiFile.getVirtualFile().getPath()); Collection diagnosticWithTextRanges = maps.get(psiFile); for (DiagnosticWithTextRange diagnosticWithTextRange : diagnosticWithTextRanges) { - PsiFile file = diagnosticWithTextRange.getPsiFile(); - Document document = file.getViewProvider().getDocument(); - String result; - int offset = diagnosticWithTextRange.getTextRange().getStartOffset(); - if (document != null) { - int lineNumber = document.getLineNumber(offset); - int lineStartOffset = document.getLineStartOffset(lineNumber); - int column = offset - lineStartOffset; - - result = "(" + (lineNumber + 1) + "," + column + ")"; - } - else { - result = "(offset: " + offset + " line unknown)"; - } - System.out.println("\t" + diagnosticWithTextRange.getSeverity().toString() + ": " + result + " " + diagnosticWithTextRange.getMessage()); + String position = DiagnosticUtils.formatPosition(diagnosticWithTextRange); + System.out.println("\t" + diagnosticWithTextRange.getSeverity().toString() + ": " + position + " " + diagnosticWithTextRange.getMessage()); } } } } + } private static void addFiles(JavaCoreEnvironment environment, Project project, List namespaces, File dir) { diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/diagnostics/DiagnosticUtils.java b/compiler/frontend/src/org/jetbrains/jet/lang/diagnostics/DiagnosticUtils.java index ea3d2d57700..0ff433add71 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/diagnostics/DiagnosticUtils.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/diagnostics/DiagnosticUtils.java @@ -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; + } } From a62fb23e1500f7ca1c947bc3c85916f99ea66a95 Mon Sep 17 00:00:00 2001 From: Alex Tkachman Date: Sun, 23 Oct 2011 13:15:37 +0200 Subject: [PATCH 11/23] work in progress on examples --- examples/src/collections/HashMap.jetl | 8 ++++---- examples/src/collections/IIterable.jetl | 3 --- examples/src/collections/IIterable.kt | 9 +++++++++ .../{IIterator.jetl => IIterator.kt} | 17 ++++++++++++++++- examples/src/collections/IList.jetl | 4 ---- examples/src/collections/IList.kt | 3 +++ examples/src/collections/ISet.jetl | 3 --- examples/src/collections/ISet.kt | 8 ++++++++ examples/src/collections/ISized.jetl | 3 --- examples/src/collections/ISized.kt | 8 ++++++++ 10 files changed, 48 insertions(+), 18 deletions(-) delete mode 100644 examples/src/collections/IIterable.jetl create mode 100644 examples/src/collections/IIterable.kt rename examples/src/collections/{IIterator.jetl => IIterator.kt} (59%) delete mode 100644 examples/src/collections/IList.jetl create mode 100644 examples/src/collections/IList.kt delete mode 100644 examples/src/collections/ISet.jetl create mode 100644 examples/src/collections/ISet.kt delete mode 100644 examples/src/collections/ISized.jetl diff --git a/examples/src/collections/HashMap.jetl b/examples/src/collections/HashMap.jetl index ac690682d89..b7dc8d37f46 100644 --- a/examples/src/collections/HashMap.jetl +++ b/examples/src/collections/HashMap.jetl @@ -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 { +trait IMap { 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 { +trait IHashingStrategy { fun equals(a : K, b : K) : Boolean fun hashCode(a : K) : Integer } diff --git a/examples/src/collections/IIterable.jetl b/examples/src/collections/IIterable.jetl deleted file mode 100644 index c9a55af4058..00000000000 --- a/examples/src/collections/IIterable.jetl +++ /dev/null @@ -1,3 +0,0 @@ -open class IIterable { - fun iterator() : IIterator -} diff --git a/examples/src/collections/IIterable.kt b/examples/src/collections/IIterable.kt new file mode 100644 index 00000000000..ae5dbdc0a51 --- /dev/null +++ b/examples/src/collections/IIterable.kt @@ -0,0 +1,9 @@ +namespace jet.collections.iterable + +import jet.collections.iterator.IIterator + +trait IIterable { + fun iterator() : IIterator + + inline fun foreach(operation: fun(element: T) : Unit) = iterator() foreach operation +} diff --git a/examples/src/collections/IIterator.jetl b/examples/src/collections/IIterator.kt similarity index 59% rename from examples/src/collections/IIterator.jetl rename to examples/src/collections/IIterator.kt index 1739eae7a01..0acccda5f47 100644 --- a/examples/src/collections/IIterator.jetl +++ b/examples/src/collections/IIterator.kt @@ -1,7 +1,21 @@ -open class IIterator { +namespace jet.collections.iterator + +trait IIterator { fun next() : T val hasNext : Boolean + inline fun foreach(operation: fun(element: T) : Unit) = while(hasNext) operation(next()) + + inline fun map(transform: fun(element: T) : R) : IIterator { + val that = this + return object : IIterator { + override fun next() : R = transform(that.next()) + + override val hasNext : Boolean + get() = that.hasNext + } + } +/* fun toArray(buffer : MutableArray) : Int { // T is still an in-parameter return fillBuffer(buffer, 0, buffer.size) } @@ -22,4 +36,5 @@ open class IIterator { } return count } +*/ } diff --git a/examples/src/collections/IList.jetl b/examples/src/collections/IList.jetl deleted file mode 100644 index 69fff05ca87..00000000000 --- a/examples/src/collections/IList.jetl +++ /dev/null @@ -1,4 +0,0 @@ -open class IList : IIterable, ISized { - [operator] fun get(index : Int) : T - val isEmpty : Boolean -} \ No newline at end of file diff --git a/examples/src/collections/IList.kt b/examples/src/collections/IList.kt new file mode 100644 index 00000000000..7f887a3a539 --- /dev/null +++ b/examples/src/collections/IList.kt @@ -0,0 +1,3 @@ +trait IList : IIterable, ISized { + fun get(index : Int) : T +} \ No newline at end of file diff --git a/examples/src/collections/ISet.jetl b/examples/src/collections/ISet.jetl deleted file mode 100644 index 0b6741470fd..00000000000 --- a/examples/src/collections/ISet.jetl +++ /dev/null @@ -1,3 +0,0 @@ -open class ISet : IIterable, ISized { - fun contains(item : T) : Boolean -} diff --git a/examples/src/collections/ISet.kt b/examples/src/collections/ISet.kt new file mode 100644 index 00000000000..8b3b375fa32 --- /dev/null +++ b/examples/src/collections/ISet.kt @@ -0,0 +1,8 @@ +namespace jet.collections.set + +import jet.collections.sized.ISized +import jet.collections.iterable.IIterable + +trait ISet : IIterable, ISized { + fun contains(item : T) : Boolean +} diff --git a/examples/src/collections/ISized.jetl b/examples/src/collections/ISized.jetl deleted file mode 100644 index 5e5977f253e..00000000000 --- a/examples/src/collections/ISized.jetl +++ /dev/null @@ -1,3 +0,0 @@ -open class ISized { - val size : Int -} \ No newline at end of file diff --git a/examples/src/collections/ISized.kt b/examples/src/collections/ISized.kt index e1b25190ae0..80f6fdd6a05 100644 --- a/examples/src/collections/ISized.kt +++ b/examples/src/collections/ISized.kt @@ -1,3 +1,11 @@ +namespace jet.collections.sized + trait ISized { val size : Int + + val isEmpty : Boolean + get() = size == 0 + + val isNonEmpty : Boolean + get() = size != 0 } \ No newline at end of file From 5b1d6052d5707ce44eca143cae37742be0dd9b4a Mon Sep 17 00:00:00 2001 From: Alex Tkachman Date: Sun, 23 Oct 2011 15:20:54 +0200 Subject: [PATCH 12/23] small bug-fix --- .../jet/codegen/ExpressionCodegen.java | 6 +- .../codegen/ImplementationBodyCodegen.java | 5 +- .../lang/types/expressions/LabelResolver.java | 6 ++ examples/src/collections/IIterator.kt | 71 ++++++++++++++++++- 4 files changed, 82 insertions(+), 6 deletions(-) diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java index baddde3e04c..775027e40c6 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java @@ -598,8 +598,10 @@ public class ExpressionCodegen extends JetVisitor { } 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); } diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/ImplementationBodyCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/ImplementationBodyCodegen.java index 5dd9bf9f711..97ea22a1428 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/ImplementationBodyCodegen.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/ImplementationBodyCodegen.java @@ -342,7 +342,10 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { Map 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()); diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/LabelResolver.java b/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/LabelResolver.java index bcf5b82dcd3..faec5d1a359 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/LabelResolver.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/LabelResolver.java @@ -119,6 +119,12 @@ public class LabelResolver { else if (declarationDescriptor instanceof FunctionDescriptor) { FunctionDescriptor functionDescriptor = (FunctionDescriptor) declarationDescriptor; thisReceiver = functionDescriptor.getReceiverParameter(); + if(!thisReceiver.exists()) { + DeclarationDescriptor containingDeclaration = functionDescriptor.getContainingDeclaration(); + if(containingDeclaration instanceof ClassDescriptor) { + thisReceiver = ((ClassDescriptor)containingDeclaration).getImplicitReceiver(); + } + } } else { throw new UnsupportedOperationException(); // TODO diff --git a/examples/src/collections/IIterator.kt b/examples/src/collections/IIterator.kt index 0acccda5f47..5677a6fc407 100644 --- a/examples/src/collections/IIterator.kt +++ b/examples/src/collections/IIterator.kt @@ -1,18 +1,83 @@ namespace jet.collections.iterator +import java.util.NoSuchElementException + trait IIterator { fun next() : T val hasNext : Boolean + inline fun foldLeft(init: R, operation: fun(accumulated: R, element: T) : R) : R { + while(hasNext) + init = operation(init, next()) + return init + } + + inline fun 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 + } + inline fun foreach(operation: fun(element: T) : Unit) = while(hasNext) operation(next()) + inline fun foreach(operation: fun(index: Int, element: T) : Unit) : Unit { + var k = 0 + while(hasNext) + operation(k++, next()) + } + inline fun map(transform: fun(element: T) : R) : IIterator { - val that = this return object : IIterator { - override fun next() : R = transform(that.next()) + override fun next() : R = transform(this@map.next()) override val hasNext : Boolean - get() = that.hasNext + get() = this@map.hasNext + } + } + + inline fun plus(other: IIterator) : IIterator = + object : IIterator { + override fun next() : T = if(this@plus.hasNext) this@plus.next() else other.next() + + override val hasNext : Boolean + get() = this@plus.hasNext || other.hasNext + } + + inline fun filter(condition: fun(element: T) : Boolean) : IIterator { + return object : IIterator { + 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() } } /* From 2010d770b59e589c304b521491383ec929dadcf5 Mon Sep 17 00:00:00 2001 From: Alex Tkachman Date: Sun, 23 Oct 2011 20:20:41 +0200 Subject: [PATCH 13/23] Iterator.hasNext() becomes property --- .../jet/codegen/ExpressionCodegen.java | 11 +- compiler/frontend/src/jet/Library.jet | 4 +- .../codegen/controlStructures/forUserType.jet | 6 +- .../jetbrains/jet/codegen/ArrayGenTest.java | 12 +- examples/src/collections/IIterator.kt | 105 -------------- examples/src/collections/Iterator.kt | 134 ++++++++++++++++++ stdlib/src/jet/IntRange.java | 2 +- stdlib/src/jet/Iterator.java | 2 +- stdlib/src/jet/LongRange.java | 2 +- stdlib/src/jet/arrays/ArrayIterator.java | 2 +- 10 files changed, 157 insertions(+), 123 deletions(-) delete mode 100644 examples/src/collections/IIterator.kt create mode 100644 examples/src/collections/Iterator.kt diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java index 775027e40c6..e9483184889 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java @@ -277,14 +277,17 @@ public class ExpressionCodegen extends JetVisitor { 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()); diff --git a/compiler/frontend/src/jet/Library.jet b/compiler/frontend/src/jet/Library.jet index 0a57bbf4c91..296cd1038e6 100644 --- a/compiler/frontend/src/jet/Library.jet +++ b/compiler/frontend/src/jet/Library.jet @@ -41,8 +41,8 @@ fun Any?.equals(other : Any?) : Boolean// = this === other fun Any?.toString() : String// = this === other trait Iterator { - fun next() : T - fun hasNext() : Boolean + fun next() : T + val hasNext : Boolean } trait Iterable { diff --git a/compiler/testData/codegen/controlStructures/forUserType.jet b/compiler/testData/codegen/controlStructures/forUserType.jet index 0332dc28bf1..cd2e335196d 100644 --- a/compiler/testData/codegen/controlStructures/forUserType.jet +++ b/compiler/testData/codegen/controlStructures/forUserType.jet @@ -88,7 +88,8 @@ class MyCollection2(): Iterable { 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 } } diff --git a/compiler/tests/org/jetbrains/jet/codegen/ArrayGenTest.java b/compiler/tests/org/jetbrains/jet/codegen/ArrayGenTest.java index f5f89630aa5..76d4f93928c 100644 --- a/compiler/tests/org/jetbrains/jet/codegen/ArrayGenTest.java +++ b/compiler/tests/org/jetbrains/jet/codegen/ArrayGenTest.java @@ -56,42 +56,42 @@ public class ArrayGenTest extends CodegenTestCase { } public void testIterator () throws Exception { - loadText("fun box() { val x = Array(5, { it } ).iterator(); while(x.hasNext()) { java.lang.System.out?.println(x.next()) } }"); + loadText("fun box() { val x = Array(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(5, {it}).indices.iterator(); while(x.hasNext()) { java.lang.System.out?.println(x.next()) } }"); + loadText("fun box() { val x = Array(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); diff --git a/examples/src/collections/IIterator.kt b/examples/src/collections/IIterator.kt deleted file mode 100644 index 5677a6fc407..00000000000 --- a/examples/src/collections/IIterator.kt +++ /dev/null @@ -1,105 +0,0 @@ -namespace jet.collections.iterator - -import java.util.NoSuchElementException - -trait IIterator { - fun next() : T - val hasNext : Boolean - - inline fun foldLeft(init: R, operation: fun(accumulated: R, element: T) : R) : R { - while(hasNext) - init = operation(init, next()) - return init - } - - inline fun 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 - } - - inline fun foreach(operation: fun(element: T) : Unit) = while(hasNext) operation(next()) - - inline fun foreach(operation: fun(index: Int, element: T) : Unit) : Unit { - var k = 0 - while(hasNext) - operation(k++, next()) - } - - inline fun map(transform: fun(element: T) : R) : IIterator { - return object : IIterator { - override fun next() : R = transform(this@map.next()) - - override val hasNext : Boolean - get() = this@map.hasNext - } - } - - inline fun plus(other: IIterator) : IIterator = - object : IIterator { - override fun next() : T = if(this@plus.hasNext) this@plus.next() else other.next() - - override val hasNext : Boolean - get() = this@plus.hasNext || other.hasNext - } - - inline fun filter(condition: fun(element: T) : Boolean) : IIterator { - return object : IIterator { - 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) : Int { // T is still an in-parameter - return fillBuffer(buffer, 0, buffer.size) - } - - fun toArray(buffer : MutableArray, 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 - } -*/ -} diff --git a/examples/src/collections/Iterator.kt b/examples/src/collections/Iterator.kt new file mode 100644 index 00000000000..8fedf34a2d9 --- /dev/null +++ b/examples/src/collections/Iterator.kt @@ -0,0 +1,134 @@ +namespace jet.collections + +import java.util.NoSuchElementException + +trait ISized { + val size : Int +} + +val ISized.isEmpty : Boolean + get() = size == 0 + +val ISized.isNonEmpty : Boolean + get() = size != 0 + +trait ISet : Iterable, ISized { + fun contains(item : T) : Boolean +} + +fun Iterator.foreach(operation: fun(element: T) : Unit) : Unit = while(hasNext) operation(next()) + +fun Iterator.foreach(operation: fun(index: Int, element: T) : Unit) : Unit { + var k = 0 + while(hasNext) + operation(k++, next()) +} + +fun Iterable.foreach(operation: fun(element: T) : Unit) : Unit = iterator() foreach operation + +fun Iterable.foreach(operation: fun(index: Int, element: T) : Unit) : Unit = iterator() foreach operation + +fun Iterable.foldLeft(init: R, operation: fun(accumulated: R, element: T) : R) : R = + iterator () foreach operation + +fun Iterable.foldLeft(init: R, operation: fun(accumulated: R, index: Int, element: T) : R) : R = + iterator () foreach operation + +fun Iterator.foldLeft(init: R, operation: fun(accumulated: R, element: T) : R) : R { + while(hasNext) + init = operation(init, next()) + return init +} + +fun Iterator.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 Iterator.map(transform: fun(element: T) : R) : Iterator = + object : Iterator { + override fun next() : R = transform(this@map.next()) + + override val hasNext : Boolean + get() = this@map.hasNext + } + +fun Iterator.map(transform: fun(index: Int, element: T) : R) : Iterator { + return object : Iterator { + var index = 0 + + override fun next() : R = transform(index++, this@map.next()) + + override val hasNext : Boolean + get() = this@map.hasNext + } +} + +fun Iterator.plus(other: Iterator) : Iterator = + object : Iterator { + 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 Iterator.filter(condition: fun(element: T) : Boolean) : Iterator { + return object : Iterator { + 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) : Int { // T is still an in-parameter + return fillBuffer(buffer, 0, buffer.size) + } + + fun toArray(buffer : MutableArray, 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 + } +*/ diff --git a/stdlib/src/jet/IntRange.java b/stdlib/src/jet/IntRange.java index abeb2a0f696..71d49ed0a73 100644 --- a/stdlib/src/jet/IntRange.java +++ b/stdlib/src/jet/IntRange.java @@ -76,7 +76,7 @@ public final class IntRange implements Range, Iterable, JetObj } @Override - public boolean hasNext() { + public boolean getHasNext() { return count > 0; } diff --git a/stdlib/src/jet/Iterator.java b/stdlib/src/jet/Iterator.java index 001bdd83863..f476440b7c4 100644 --- a/stdlib/src/jet/Iterator.java +++ b/stdlib/src/jet/Iterator.java @@ -1,6 +1,6 @@ package jet; public interface Iterator extends JetObject { - boolean hasNext(); + boolean getHasNext(); T next (); } diff --git a/stdlib/src/jet/LongRange.java b/stdlib/src/jet/LongRange.java index 7932f7d0b5d..e0a358599fb 100644 --- a/stdlib/src/jet/LongRange.java +++ b/stdlib/src/jet/LongRange.java @@ -76,7 +76,7 @@ public final class LongRange implements Range, Iterable, JetObject { } @Override - public boolean hasNext() { + public boolean getHasNext() { return count > 0; } diff --git a/stdlib/src/jet/arrays/ArrayIterator.java b/stdlib/src/jet/arrays/ArrayIterator.java index 761a153d474..79f3bd2a15a 100644 --- a/stdlib/src/jet/arrays/ArrayIterator.java +++ b/stdlib/src/jet/arrays/ArrayIterator.java @@ -20,7 +20,7 @@ public abstract class ArrayIterator implements Iterator, JetObject { } @Override - public boolean hasNext() { + public boolean getHasNext() { return index < size; } From 292a41ec15469251fd54afebcdafb75aaea89d17 Mon Sep 17 00:00:00 2001 From: Andrey Breslav Date: Mon, 24 Oct 2011 11:34:07 +0400 Subject: [PATCH 14/23] Erroneous fix reverted. Test added --- .../jet/lang/types/expressions/LabelResolver.java | 6 ------ .../quick/regressions/UnavaliableQualifiedThis.jet | 13 +++++++++++++ 2 files changed, 13 insertions(+), 6 deletions(-) create mode 100644 compiler/testData/checkerWithErrorTypes/quick/regressions/UnavaliableQualifiedThis.jet diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/LabelResolver.java b/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/LabelResolver.java index faec5d1a359..bcf5b82dcd3 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/LabelResolver.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/LabelResolver.java @@ -119,12 +119,6 @@ public class LabelResolver { else if (declarationDescriptor instanceof FunctionDescriptor) { FunctionDescriptor functionDescriptor = (FunctionDescriptor) declarationDescriptor; thisReceiver = functionDescriptor.getReceiverParameter(); - if(!thisReceiver.exists()) { - DeclarationDescriptor containingDeclaration = functionDescriptor.getContainingDeclaration(); - if(containingDeclaration instanceof ClassDescriptor) { - thisReceiver = ((ClassDescriptor)containingDeclaration).getImplicitReceiver(); - } - } } else { throw new UnsupportedOperationException(); // TODO diff --git a/compiler/testData/checkerWithErrorTypes/quick/regressions/UnavaliableQualifiedThis.jet b/compiler/testData/checkerWithErrorTypes/quick/regressions/UnavaliableQualifiedThis.jet new file mode 100644 index 00000000000..301ded436a1 --- /dev/null +++ b/compiler/testData/checkerWithErrorTypes/quick/regressions/UnavaliableQualifiedThis.jet @@ -0,0 +1,13 @@ +trait Iterator { + fun next() : T + val hasNext : Boolean + + fun map(transform: fun(element: T) : R) : Iterator = + object : Iterator { + override fun next() : R = transform(this@map.next()) + + override val hasNext : Boolean + // There's no 'this' associated with the map() function, only this of the Iterator class + get() = this@map.hasNext + } +} From 23278d14274bff891207cdeb2190e454f4331275 Mon Sep 17 00:00:00 2001 From: svtk Date: Mon, 24 Oct 2011 13:01:02 +0400 Subject: [PATCH 15/23] Dead code finding moved to pseudocode construction --- .../lang/cfg/JetFlowInformationProvider.java | 69 +++++++++++++------ .../lang/cfg/pseudocode/InstructionImpl.java | 8 +++ .../jet/lang/cfg/pseudocode/Pseudocode.java | 33 +++++++++ 3 files changed, 89 insertions(+), 21 deletions(-) diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/cfg/JetFlowInformationProvider.java b/compiler/frontend/src/org/jetbrains/jet/lang/cfg/JetFlowInformationProvider.java index 80f8d5b1b0f..88dd8b70018 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/cfg/JetFlowInformationProvider.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/cfg/JetFlowInformationProvider.java @@ -118,18 +118,26 @@ public class JetFlowInformationProvider { Pseudocode pseudocode = pseudocodeMap.get(subroutine); assert pseudocode != null; - SubroutineEnterInstruction enterInstruction = pseudocode.getEnterInstruction(); - Set visited = new HashSet(); - 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 visited = new HashSet(); +// 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 dominated) { // Instruction dominatorInstruction = representativeInstructions.get(dominator); @@ -248,7 +256,11 @@ public class JetFlowInformationProvider { // } // } - private Map traverseInstructionGraphUntilFactsStabilization(Pseudocode pseudocode, InstructionsMergeHandler instructionsMergeHandler, D initialDataValue, boolean straightDirection) { + private Map traverseInstructionGraphUntilFactsStabilization( + Pseudocode pseudocode, + InstructionsMergeHandler instructionsMergeHandler, + D initialDataValue, + boolean straightDirection) { Map dataMap = Maps.newHashMap(); initializeDataMap(dataMap, pseudocode, initialDataValue); @@ -261,7 +273,10 @@ public class JetFlowInformationProvider { return dataMap; } - private void initializeDataMap(Map dataMap, Pseudocode pseudocode, D initialDataValue) { + private void initializeDataMap( + Map dataMap, + Pseudocode pseudocode, + D initialDataValue) { List instructions = pseudocode.getInstructions(); for (Instruction instruction : instructions) { dataMap.put(instruction, initialDataValue); @@ -271,7 +286,13 @@ public class JetFlowInformationProvider { } } - private void traverseSubGraph(Pseudocode pseudocode, InstructionsMergeHandler instructionsMergeHandler, Collection previousSubGraphInstructions, boolean straightDirection, Map dataMap, boolean[] changed) { + private void traverseSubGraph( + Pseudocode pseudocode, + InstructionsMergeHandler instructionsMergeHandler, + Collection previousSubGraphInstructions, + boolean straightDirection, + Map dataMap, + boolean[] changed) { List instructions = pseudocode.getInstructions(); SubroutineEnterInstruction enterInstruction = pseudocode.getEnterInstruction(); for (Instruction instruction : instructions) { @@ -317,22 +338,28 @@ public class JetFlowInformationProvider { public Set merge(Instruction instruction, Set previousDataValue, Collection> incomingEdgesData) { Set initializedVariables = Sets.newHashSet(); initializedVariables.addAll(previousDataValue); - for (Set edgeDataValue : incomingEdgesData) { - initializedVariables.addAll(edgeDataValue); + Set edgesDataIntersection = Sets.newHashSet(); + boolean isFirst = true; + for (Set edgeData : incomingEdgesData) { + if (isFirst) { + edgesDataIntersection.addAll(edgeData); + } + else { + edgesDataIntersection = Sets.intersection(edgesDataIntersection, edgeData).immutableCopy(); + } + isFirst = false; } + initializedVariables.addAll(edgesDataIntersection); if (instruction instanceof WriteValueInstruction) { DeclarationDescriptor descriptor = null; JetElement lValue = ((WriteValueInstruction) instruction).getlValue(); - if (lValue instanceof JetProperty) { + 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); } - else if (lValue instanceof JetParameter) { - descriptor = trace.get(BindingContext.DECLARATION_TO_DESCRIPTOR, lValue); - } if (descriptor instanceof LocalVariableDescriptor) { initializedVariables.add((LocalVariableDescriptor) descriptor); } @@ -357,16 +384,16 @@ public class JetFlowInformationProvider { } } else if (instruction instanceof WriteValueInstruction) { - JetElement element = ((WriteValueInstruction) instruction).getElement(); + JetElement element = ((WriteValueInstruction) instruction).getlValue(); if (element instanceof JetSimpleNameExpression) { DeclarationDescriptor descriptor = trace.get(BindingContext.REFERENCE_TARGET, (JetSimpleNameExpression) element); if (descriptor instanceof LocalVariableDescriptor) { - if (initializedVariables.contains(descriptor) && ((LocalVariableDescriptor) descriptor).isVar()) { + if (initializedVariables.contains(descriptor) && !((LocalVariableDescriptor) descriptor).isVar()) { trace.report(Errors.VAL_REASSIGNMENT.on((JetSimpleNameExpression) element, descriptor)); } } } - } + } } }; traverseInstructionGraphAndReportErrors(instructions, dataMap, instructionDataAnalyzer); diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/cfg/pseudocode/InstructionImpl.java b/compiler/frontend/src/org/jetbrains/jet/lang/cfg/pseudocode/InstructionImpl.java index 65fadb3b5a3..07179794241 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/cfg/pseudocode/InstructionImpl.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/cfg/pseudocode/InstructionImpl.java @@ -12,6 +12,7 @@ import java.util.LinkedHashSet; public abstract class InstructionImpl implements Instruction { private Pseudocode owner; private final Collection previousInstructions = new LinkedHashSet(); + 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; + } } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/cfg/pseudocode/Pseudocode.java b/compiler/frontend/src/org/jetbrains/jet/lang/cfg/pseudocode/Pseudocode.java index 9a7f0087050..630199c91e8 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/cfg/pseudocode/Pseudocode.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/cfg/pseudocode/Pseudocode.java @@ -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 getInstructions() { return instructions; } + + @NotNull + public List getDeadInstructions() { + List deadInstructions = Lists.newArrayList(); + for (Instruction instruction : instructions) { + if (((InstructionImpl)instruction).isDead()) { + deadInstructions.add(instruction); + } + } + return deadInstructions; + } @Deprecated //for tests only public List getLabels() { @@ -166,6 +179,26 @@ public class Pseudocode { } }); } + removeDeadInstructions(); + } + + private void removeDeadInstructions() { + boolean hasRemovedInstruction = true; + Collection 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 From f074366694de39c5081c77b650427d46a2d2d067 Mon Sep 17 00:00:00 2001 From: svtk Date: Mon, 24 Oct 2011 13:01:46 +0400 Subject: [PATCH 16/23] tests fixed --- .../org/jetbrains/jet/lang/diagnostics/Errors.java | 2 +- .../regression/AssignmentsUnderOperators.jet | 2 +- .../full/regression/AssignmentsUnderOperators.jet | 2 +- .../org/jetbrains/jet/cfg/JetControlFlowTest.java | 14 +++++++++----- 4 files changed, 12 insertions(+), 8 deletions(-) diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/diagnostics/Errors.java b/compiler/frontend/src/org/jetbrains/jet/lang/diagnostics/Errors.java index 4f4cfb16e36..ede21587970 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/diagnostics/Errors.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/diagnostics/Errors.java @@ -142,7 +142,7 @@ public interface Errors { }; PsiElementOnlyDiagnosticFactory3 VIRTUAL_MEMBER_HIDDEN = PsiElementOnlyDiagnosticFactory3.create(ERROR, "''{0}'' hides ''{1}'' in class {2} and needs 'override' modifier", DescriptorRenderer.TEXT); - PsiElementOnlyDiagnosticFactory1 UNINITIALIZED_VARIABLE = PsiElementOnlyDiagnosticFactory1.create(ERROR, "Variable ''{0}'' must be uninitialized", NAME); + PsiElementOnlyDiagnosticFactory1 UNINITIALIZED_VARIABLE = PsiElementOnlyDiagnosticFactory1.create(ERROR, "Variable ''{0}'' must be initialized", NAME); PsiElementOnlyDiagnosticFactory1 VAL_REASSIGNMENT = PsiElementOnlyDiagnosticFactory1.create(ERROR, "Val can not be reassigned", NAME); SimpleDiagnosticFactory UNREACHABLE_CODE = SimpleDiagnosticFactory.create(ERROR, "Unreachable code"); diff --git a/compiler/testData/checker/regression/AssignmentsUnderOperators.jet b/compiler/testData/checker/regression/AssignmentsUnderOperators.jet index 5a7c24b7fd0..2acdbfdd984 100644 --- a/compiler/testData/checker/regression/AssignmentsUnderOperators.jet +++ b/compiler/testData/checker/regression/AssignmentsUnderOperators.jet @@ -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 diff --git a/compiler/testData/checkerWithErrorTypes/full/regression/AssignmentsUnderOperators.jet b/compiler/testData/checkerWithErrorTypes/full/regression/AssignmentsUnderOperators.jet index 5a7c24b7fd0..2acdbfdd984 100644 --- a/compiler/testData/checkerWithErrorTypes/full/regression/AssignmentsUnderOperators.jet +++ b/compiler/testData/checkerWithErrorTypes/full/regression/AssignmentsUnderOperators.jet @@ -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 diff --git a/compiler/tests/org/jetbrains/jet/cfg/JetControlFlowTest.java b/compiler/tests/org/jetbrains/jet/cfg/JetControlFlowTest.java index 4fa45ef3ed8..5d82577cda5 100644 --- a/compiler/tests/org/jetbrains/jet/cfg/JetControlFlowTest.java +++ b/compiler/tests/org/jetbrains/jet/cfg/JetControlFlowTest.java @@ -107,11 +107,15 @@ public class JetControlFlowTest extends JetTestCaseBase { //check edges directions Collection 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)); + } } } } From b230b3494d1c5d2a2b61f9845b6f36a6b85dede9 Mon Sep 17 00:00:00 2001 From: svtk Date: Mon, 24 Oct 2011 13:03:02 +0400 Subject: [PATCH 17/23] Added tests for control flow graph construction --- compiler/testData/cfg/For.instructions | 40 +++++++++++ compiler/testData/cfg/For.jet | 7 ++ compiler/testData/cfg/If.instructions | 98 ++++++++++++++++++++++++++ compiler/testData/cfg/If.jet | 31 ++++++++ 4 files changed, 176 insertions(+) create mode 100644 compiler/testData/cfg/For.instructions create mode 100644 compiler/testData/cfg/For.jet create mode 100644 compiler/testData/cfg/If.instructions create mode 100644 compiler/testData/cfg/If.jet diff --git a/compiler/testData/cfg/For.instructions b/compiler/testData/cfg/For.instructions new file mode 100644 index 00000000000..4e19aac83c9 --- /dev/null +++ b/compiler/testData/cfg/For.instructions @@ -0,0 +1,40 @@ +== t1 == +fun t1() { + for (i in 1..2) { + doSmth(i) + } +} +--------------------- +l0: + NEXT:[r(1)] PREV:[] + r(1) NEXT:[r(2)] PREV:[] + 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:[] PREV:[jmp?(l2), jmp?(l4)] +l1: + NEXT:[] PREV:[read (Unit)] +error: + NEXT:[] PREV:[] +===================== +== doSmth == +fun doSmth(i: Int) {} +--------------------- +l0: + NEXT:[read (Unit)] PREV:[] + read (Unit) NEXT:[] PREV:[] +l1: + NEXT:[] PREV:[read (Unit)] +error: + NEXT:[] PREV:[] +===================== diff --git a/compiler/testData/cfg/For.jet b/compiler/testData/cfg/For.jet new file mode 100644 index 00000000000..35dab23bf0c --- /dev/null +++ b/compiler/testData/cfg/For.jet @@ -0,0 +1,7 @@ +fun t1() { + for (i in 1..2) { + doSmth(i) + } +} + +fun doSmth(i: Int) {} diff --git a/compiler/testData/cfg/If.instructions b/compiler/testData/cfg/If.instructions new file mode 100644 index 00000000000..c4d5a9a542c --- /dev/null +++ b/compiler/testData/cfg/If.instructions @@ -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: + NEXT:[r(b)] PREV:[] + r(b) NEXT:[jf(l2)] PREV:[] + 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:[] PREV:[r(doSmth)] +l1: + NEXT:[] PREV:[r(doSmth(r))] +error: + NEXT:[] PREV:[] +===================== +== t2 == +fun t2(b: Boolean) { + val i = 3 + if (b) { + return; + } + doSmth(i) + if (i is Int) { + return; + } +} +--------------------- +l0: + NEXT:[r(3)] PREV:[] + r(3) NEXT:[w(i)] PREV:[] + 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:[] 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:[jmp(l3), 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:[] PREV:[jf(l4)] + jmp(l5) NEXT:[] PREV:[] +l4: + read (Unit) NEXT:[] PREV:[jf(l4)] +l1: +l5: + NEXT:[] PREV:[ret l1, ret l1, jmp(l5), read (Unit)] +error: + NEXT:[] PREV:[] +===================== +== doSmth == +fun doSmth(s: String) {} +--------------------- +l0: + NEXT:[read (Unit)] PREV:[] + read (Unit) NEXT:[] PREV:[] +l1: + NEXT:[] PREV:[read (Unit)] +error: + NEXT:[] PREV:[] +===================== diff --git a/compiler/testData/cfg/If.jet b/compiler/testData/cfg/If.jet new file mode 100644 index 00000000000..26e9276b66d --- /dev/null +++ b/compiler/testData/cfg/If.jet @@ -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) {} + + From 5d2241dfbe9ba8c98dfade9aa22b80896458c85d Mon Sep 17 00:00:00 2001 From: Alex Tkachman Date: Mon, 24 Oct 2011 15:06:00 +0200 Subject: [PATCH 18/23] jet.runtime package introduced --- .../jetbrains/jet/codegen/JetTypeMapper.java | 31 ++++++++++------ .../jet/codegen/intrinsics/ArrayIterator.java | 18 +++++----- .../org/jetbrains/jet/codegen/VarArgTest.java | 29 +++++++++++++++ examples/src/collections/Iterator.kt | 36 +++++++++++++++++++ .../{arrays => runtime}/ArrayIterator.java | 5 +-- .../src/jet/{refs => runtime}/SharedVar.java | 2 +- 6 files changed, 96 insertions(+), 25 deletions(-) create mode 100644 compiler/tests/org/jetbrains/jet/codegen/VarArgTest.java rename stdlib/src/jet/{arrays => runtime}/ArrayIterator.java (98%) rename stdlib/src/jet/{refs => runtime}/SharedVar.java (96%) diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/JetTypeMapper.java b/compiler/backend/src/org/jetbrains/jet/codegen/JetTypeMapper.java index 3d674335c81..947cf407491 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/JetTypeMapper.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/JetTypeMapper.java @@ -60,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; @@ -461,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); } @@ -559,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()])); diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/ArrayIterator.java b/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/ArrayIterator.java index c61130a7b15..902026b2014 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/ArrayIterator.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/ArrayIterator.java @@ -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()); diff --git a/compiler/tests/org/jetbrains/jet/codegen/VarArgTest.java b/compiler/tests/org/jetbrains/jet/codegen/VarArgTest.java new file mode 100644 index 00000000000..9dca1094568 --- /dev/null +++ b/compiler/tests/org/jetbrains/jet/codegen/VarArgTest.java @@ -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)); + */ + } +} diff --git a/examples/src/collections/Iterator.kt b/examples/src/collections/Iterator.kt index 8fedf34a2d9..0e8bfac5277 100644 --- a/examples/src/collections/Iterator.kt +++ b/examples/src/collections/Iterator.kt @@ -2,6 +2,19 @@ namespace jet.collections import java.util.NoSuchElementException +trait Iterator { + fun next() : T + val hasNext : Boolean + + fun map(transform: fun(element: T) : R) : Iterator = + object : Iterator { + override fun next() : R = transform(this@map.next()) + + override val hasNext : Boolean + get() = this@map.hasNext + } +} + trait ISized { val size : Int } @@ -16,6 +29,29 @@ trait ISet : Iterable, ISized { fun contains(item : T) : Boolean } +trait IList : Iterable, ISized { + fun get(index : Int) : T + + fun iterator() : Iterator = + object Iterator { + var index = 0 + + override fun next() : T = get(index++) + + override val hasNext : Boolean + get() = index < size + } + + fun toArray() : Array = Array(size) { index => get(index) } +} + +fun Array.asList() : IList = object IList { + override val size + get() = this@Array.size + + override fun get(index: Int) = this@asList[index] +} + fun Iterator.foreach(operation: fun(element: T) : Unit) : Unit = while(hasNext) operation(next()) fun Iterator.foreach(operation: fun(index: Int, element: T) : Unit) : Unit { diff --git a/stdlib/src/jet/arrays/ArrayIterator.java b/stdlib/src/jet/runtime/ArrayIterator.java similarity index 98% rename from stdlib/src/jet/arrays/ArrayIterator.java rename to stdlib/src/jet/runtime/ArrayIterator.java index 79f3bd2a15a..3b57a17636a 100644 --- a/stdlib/src/jet/arrays/ArrayIterator.java +++ b/stdlib/src/jet/runtime/ArrayIterator.java @@ -1,13 +1,10 @@ -package jet.arrays; +package jet.runtime; import jet.Iterator; import jet.JetObject; import jet.typeinfo.TypeInfo; import jet.typeinfo.TypeInfoProjection; -import java.lang.reflect.GenericArrayType; -import java.util.Arrays; - /** * @author alex.tkachman */ diff --git a/stdlib/src/jet/refs/SharedVar.java b/stdlib/src/jet/runtime/SharedVar.java similarity index 96% rename from stdlib/src/jet/refs/SharedVar.java rename to stdlib/src/jet/runtime/SharedVar.java index 0bd99c66965..e0bc9e93d14 100644 --- a/stdlib/src/jet/refs/SharedVar.java +++ b/stdlib/src/jet/runtime/SharedVar.java @@ -1,4 +1,4 @@ -package jet.refs; +package jet.runtime; public final class SharedVar { public static final class Object { From 734e8ee3a284f3ff7eb3d45ce1b44581c1fec136 Mon Sep 17 00:00:00 2001 From: svtk Date: Mon, 24 Oct 2011 17:40:16 +0400 Subject: [PATCH 19/23] Existing tests correction: forbid val reassignment --- compiler/testData/checker/Unresolved.jet | 5 +++-- compiler/testData/checker/regression/Jet183-1.jet | 2 +- .../checkerWithErrorTypes/full/FunctionReturnTypes.jet | 8 ++++---- .../testData/checkerWithErrorTypes/full/Unresolved.jet | 5 +++-- .../checkerWithErrorTypes/full/regression/Jet183-1.jet | 2 +- compiler/testData/codegen/classes/overloadPlusAssign.jet | 2 +- .../testData/codegen/classes/overloadPlusAssignReturn.jet | 2 +- .../testData/codegen/classes/overloadPlusToPlusAssign.jet | 2 +- .../testData/codegen/controlStructures/forIntRange.jet | 2 +- .../tests/org/jetbrains/jet/codegen/NamespaceGenTest.java | 2 +- 10 files changed, 17 insertions(+), 15 deletions(-) diff --git a/compiler/testData/checker/Unresolved.jet b/compiler/testData/checker/Unresolved.jet index 9e361861010..2d56e915eb7 100644 --- a/compiler/testData/checker/Unresolved.jet +++ b/compiler/testData/checker/Unresolved.jet @@ -22,8 +22,9 @@ fun testUnresolved() { //TODO for (j in collection) { - val i: Int = j - j += 1 + var i: Int = j + i += 1 + foo1(j) } } diff --git a/compiler/testData/checker/regression/Jet183-1.jet b/compiler/testData/checker/regression/Jet183-1.jet index 37c72d83ef6..0199cd9fcb3 100644 --- a/compiler/testData/checker/regression/Jet183-1.jet +++ b/compiler/testData/checker/regression/Jet183-1.jet @@ -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() diff --git a/compiler/testData/checkerWithErrorTypes/full/FunctionReturnTypes.jet b/compiler/testData/checkerWithErrorTypes/full/FunctionReturnTypes.jet index 646a38f5b89..68b1803449f 100644 --- a/compiler/testData/checkerWithErrorTypes/full/FunctionReturnTypes.jet +++ b/compiler/testData/checkerWithErrorTypes/full/FunctionReturnTypes.jet @@ -176,23 +176,23 @@ fun testFunctionLiterals() { } val endsWithAssignment = { () : Int => - val x = 1 + var x = 1 x = 333 } val endsWithReAssignment = { () : Int => - val x = 1 + var x = 1 x += 333 } val endsWithFunDeclaration : fun() : String = { - val x = 1 + var x = 1 x = 333 fun meow() : Unit {} } val endsWithObjectDeclaration : fun() : Int = { - val x = 1 + var x = 1 x = 333 object A {} } diff --git a/compiler/testData/checkerWithErrorTypes/full/Unresolved.jet b/compiler/testData/checkerWithErrorTypes/full/Unresolved.jet index 48ea2a58e4d..9bd749a8372 100644 --- a/compiler/testData/checkerWithErrorTypes/full/Unresolved.jet +++ b/compiler/testData/checkerWithErrorTypes/full/Unresolved.jet @@ -22,8 +22,9 @@ fun testUnresolved() { //TODO for (j in collection) { - val i: Int = j - j += 1 + var i: Int = j + i += 1 + foo1(j) } } diff --git a/compiler/testData/checkerWithErrorTypes/full/regression/Jet183-1.jet b/compiler/testData/checkerWithErrorTypes/full/regression/Jet183-1.jet index 37c72d83ef6..0199cd9fcb3 100644 --- a/compiler/testData/checkerWithErrorTypes/full/regression/Jet183-1.jet +++ b/compiler/testData/checkerWithErrorTypes/full/regression/Jet183-1.jet @@ -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() diff --git a/compiler/testData/codegen/classes/overloadPlusAssign.jet b/compiler/testData/codegen/classes/overloadPlusAssign.jet index 21459ecff1e..5247973e8d6 100644 --- a/compiler/testData/codegen/classes/overloadPlusAssign.jet +++ b/compiler/testData/codegen/classes/overloadPlusAssign.jet @@ -17,7 +17,7 @@ class ArrayWrapper() { } fun box(): String { - val v1 = ArrayWrapper() + var v1 = ArrayWrapper() val v2 = ArrayWrapper() v1.add("foo") v2.add("bar") diff --git a/compiler/testData/codegen/classes/overloadPlusAssignReturn.jet b/compiler/testData/codegen/classes/overloadPlusAssignReturn.jet index 28fb9af2652..42671b9f138 100644 --- a/compiler/testData/codegen/classes/overloadPlusAssignReturn.jet +++ b/compiler/testData/codegen/classes/overloadPlusAssignReturn.jet @@ -20,7 +20,7 @@ class ArrayWrapper() { } fun box(): String { - val v1 = ArrayWrapper() + var v1 = ArrayWrapper() val v2 = ArrayWrapper() v1.add("foo") val v3 = v1 diff --git a/compiler/testData/codegen/classes/overloadPlusToPlusAssign.jet b/compiler/testData/codegen/classes/overloadPlusToPlusAssign.jet index e81515821b0..c5236b0ace4 100644 --- a/compiler/testData/codegen/classes/overloadPlusToPlusAssign.jet +++ b/compiler/testData/codegen/classes/overloadPlusToPlusAssign.jet @@ -20,7 +20,7 @@ class ArrayWrapper() { } fun box(): String { - val v1 = ArrayWrapper() + var v1 = ArrayWrapper() val v2 = ArrayWrapper() v1.add("foo") val v3 = v1 diff --git a/compiler/testData/codegen/controlStructures/forIntRange.jet b/compiler/testData/codegen/controlStructures/forIntRange.jet index 0fe391123eb..d215a925bb9 100644 --- a/compiler/testData/codegen/controlStructures/forIntRange.jet +++ b/compiler/testData/codegen/controlStructures/forIntRange.jet @@ -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 } diff --git a/compiler/tests/org/jetbrains/jet/codegen/NamespaceGenTest.java b/compiler/tests/org/jetbrains/jet/codegen/NamespaceGenTest.java index 5c4167442fa..5be2b30adca 100644 --- a/compiler/tests/org/jetbrains/jet/codegen/NamespaceGenTest.java +++ b/compiler/tests/org/jetbrains/jet/codegen/NamespaceGenTest.java @@ -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")); From b837a1ac14ad043c95f783e4bb71dbf78282fe8c Mon Sep 17 00:00:00 2001 From: Alex Tkachman Date: Mon, 24 Oct 2011 16:13:03 +0200 Subject: [PATCH 20/23] (Extension)FunctionN generated --- stdlib/src/jet/ExtensionFunction1.java | 10 ++-- stdlib/src/jet/ExtensionFunction10.java | 19 +++++++ stdlib/src/jet/ExtensionFunction11.java | 19 +++++++ stdlib/src/jet/ExtensionFunction12.java | 19 +++++++ stdlib/src/jet/ExtensionFunction13.java | 19 +++++++ stdlib/src/jet/ExtensionFunction14.java | 19 +++++++ stdlib/src/jet/ExtensionFunction15.java | 19 +++++++ stdlib/src/jet/ExtensionFunction16.java | 19 +++++++ stdlib/src/jet/ExtensionFunction17.java | 19 +++++++ stdlib/src/jet/ExtensionFunction18.java | 19 +++++++ stdlib/src/jet/ExtensionFunction19.java | 19 +++++++ stdlib/src/jet/ExtensionFunction2.java | 8 +-- stdlib/src/jet/ExtensionFunction20.java | 19 +++++++ stdlib/src/jet/ExtensionFunction21.java | 19 +++++++ stdlib/src/jet/ExtensionFunction22.java | 19 +++++++ stdlib/src/jet/ExtensionFunction3.java | 8 +-- stdlib/src/jet/ExtensionFunction4.java | 19 +++++++ stdlib/src/jet/ExtensionFunction5.java | 19 +++++++ stdlib/src/jet/ExtensionFunction6.java | 19 +++++++ stdlib/src/jet/ExtensionFunction7.java | 19 +++++++ stdlib/src/jet/ExtensionFunction8.java | 19 +++++++ stdlib/src/jet/ExtensionFunction9.java | 19 +++++++ stdlib/src/jet/Function0.java | 73 ++++++++++++++++++++++++- stdlib/src/jet/Function1.java | 10 ++-- stdlib/src/jet/Function10.java | 19 +++++++ stdlib/src/jet/Function11.java | 19 +++++++ stdlib/src/jet/Function12.java | 19 +++++++ stdlib/src/jet/Function13.java | 19 +++++++ stdlib/src/jet/Function14.java | 19 +++++++ stdlib/src/jet/Function15.java | 19 +++++++ stdlib/src/jet/Function16.java | 19 +++++++ stdlib/src/jet/Function17.java | 19 +++++++ stdlib/src/jet/Function18.java | 19 +++++++ stdlib/src/jet/Function19.java | 19 +++++++ stdlib/src/jet/Function2.java | 8 +-- stdlib/src/jet/Function20.java | 19 +++++++ stdlib/src/jet/Function21.java | 19 +++++++ stdlib/src/jet/Function22.java | 19 +++++++ stdlib/src/jet/Function3.java | 8 +-- stdlib/src/jet/Function4.java | 19 +++++++ stdlib/src/jet/Function5.java | 19 +++++++ stdlib/src/jet/Function6.java | 19 +++++++ stdlib/src/jet/Function7.java | 19 +++++++ stdlib/src/jet/Function8.java | 19 +++++++ stdlib/src/jet/Function9.java | 19 +++++++ 45 files changed, 819 insertions(+), 28 deletions(-) create mode 100644 stdlib/src/jet/ExtensionFunction10.java create mode 100644 stdlib/src/jet/ExtensionFunction11.java create mode 100644 stdlib/src/jet/ExtensionFunction12.java create mode 100644 stdlib/src/jet/ExtensionFunction13.java create mode 100644 stdlib/src/jet/ExtensionFunction14.java create mode 100644 stdlib/src/jet/ExtensionFunction15.java create mode 100644 stdlib/src/jet/ExtensionFunction16.java create mode 100644 stdlib/src/jet/ExtensionFunction17.java create mode 100644 stdlib/src/jet/ExtensionFunction18.java create mode 100644 stdlib/src/jet/ExtensionFunction19.java create mode 100644 stdlib/src/jet/ExtensionFunction20.java create mode 100644 stdlib/src/jet/ExtensionFunction21.java create mode 100644 stdlib/src/jet/ExtensionFunction22.java create mode 100644 stdlib/src/jet/ExtensionFunction4.java create mode 100644 stdlib/src/jet/ExtensionFunction5.java create mode 100644 stdlib/src/jet/ExtensionFunction6.java create mode 100644 stdlib/src/jet/ExtensionFunction7.java create mode 100644 stdlib/src/jet/ExtensionFunction8.java create mode 100644 stdlib/src/jet/ExtensionFunction9.java create mode 100644 stdlib/src/jet/Function10.java create mode 100644 stdlib/src/jet/Function11.java create mode 100644 stdlib/src/jet/Function12.java create mode 100644 stdlib/src/jet/Function13.java create mode 100644 stdlib/src/jet/Function14.java create mode 100644 stdlib/src/jet/Function15.java create mode 100644 stdlib/src/jet/Function16.java create mode 100644 stdlib/src/jet/Function17.java create mode 100644 stdlib/src/jet/Function18.java create mode 100644 stdlib/src/jet/Function19.java create mode 100644 stdlib/src/jet/Function20.java create mode 100644 stdlib/src/jet/Function21.java create mode 100644 stdlib/src/jet/Function22.java create mode 100644 stdlib/src/jet/Function4.java create mode 100644 stdlib/src/jet/Function5.java create mode 100644 stdlib/src/jet/Function6.java create mode 100644 stdlib/src/jet/Function7.java create mode 100644 stdlib/src/jet/Function8.java create mode 100644 stdlib/src/jet/Function9.java diff --git a/stdlib/src/jet/ExtensionFunction1.java b/stdlib/src/jet/ExtensionFunction1.java index 2a75a41acf6..3036473a0f6 100644 --- a/stdlib/src/jet/ExtensionFunction1.java +++ b/stdlib/src/jet/ExtensionFunction1.java @@ -1,19 +1,19 @@ /* - * @author max + * @author alex.tkachman */ package jet; import jet.typeinfo.TypeInfo; - -public abstract class ExtensionFunction1 extends DefaultJetObject{ +public abstract class ExtensionFunction1 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)}"; } } + diff --git a/stdlib/src/jet/ExtensionFunction10.java b/stdlib/src/jet/ExtensionFunction10.java new file mode 100644 index 00000000000..a840c84675c --- /dev/null +++ b/stdlib/src/jet/ExtensionFunction10.java @@ -0,0 +1,19 @@ +/* + * @author alex.tkachman + */ +package jet; + +import jet.typeinfo.TypeInfo; +public abstract class ExtensionFunction10 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)}"; + } +} + diff --git a/stdlib/src/jet/ExtensionFunction11.java b/stdlib/src/jet/ExtensionFunction11.java new file mode 100644 index 00000000000..161a2635dfc --- /dev/null +++ b/stdlib/src/jet/ExtensionFunction11.java @@ -0,0 +1,19 @@ +/* + * @author alex.tkachman + */ +package jet; + +import jet.typeinfo.TypeInfo; +public abstract class ExtensionFunction11 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)}"; + } +} + diff --git a/stdlib/src/jet/ExtensionFunction12.java b/stdlib/src/jet/ExtensionFunction12.java new file mode 100644 index 00000000000..286b76250f8 --- /dev/null +++ b/stdlib/src/jet/ExtensionFunction12.java @@ -0,0 +1,19 @@ +/* + * @author alex.tkachman + */ +package jet; + +import jet.typeinfo.TypeInfo; +public abstract class ExtensionFunction12 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)}"; + } +} + diff --git a/stdlib/src/jet/ExtensionFunction13.java b/stdlib/src/jet/ExtensionFunction13.java new file mode 100644 index 00000000000..6e498216343 --- /dev/null +++ b/stdlib/src/jet/ExtensionFunction13.java @@ -0,0 +1,19 @@ +/* + * @author alex.tkachman + */ +package jet; + +import jet.typeinfo.TypeInfo; +public abstract class ExtensionFunction13 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)}"; + } +} + diff --git a/stdlib/src/jet/ExtensionFunction14.java b/stdlib/src/jet/ExtensionFunction14.java new file mode 100644 index 00000000000..129899f7d23 --- /dev/null +++ b/stdlib/src/jet/ExtensionFunction14.java @@ -0,0 +1,19 @@ +/* + * @author alex.tkachman + */ +package jet; + +import jet.typeinfo.TypeInfo; +public abstract class ExtensionFunction14 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)}"; + } +} + diff --git a/stdlib/src/jet/ExtensionFunction15.java b/stdlib/src/jet/ExtensionFunction15.java new file mode 100644 index 00000000000..650b4597b3c --- /dev/null +++ b/stdlib/src/jet/ExtensionFunction15.java @@ -0,0 +1,19 @@ +/* + * @author alex.tkachman + */ +package jet; + +import jet.typeinfo.TypeInfo; +public abstract class ExtensionFunction15 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)}"; + } +} + diff --git a/stdlib/src/jet/ExtensionFunction16.java b/stdlib/src/jet/ExtensionFunction16.java new file mode 100644 index 00000000000..782911bb1b6 --- /dev/null +++ b/stdlib/src/jet/ExtensionFunction16.java @@ -0,0 +1,19 @@ +/* + * @author alex.tkachman + */ +package jet; + +import jet.typeinfo.TypeInfo; +public abstract class ExtensionFunction16 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)}"; + } +} + diff --git a/stdlib/src/jet/ExtensionFunction17.java b/stdlib/src/jet/ExtensionFunction17.java new file mode 100644 index 00000000000..9a690ecc852 --- /dev/null +++ b/stdlib/src/jet/ExtensionFunction17.java @@ -0,0 +1,19 @@ +/* + * @author alex.tkachman + */ +package jet; + +import jet.typeinfo.TypeInfo; +public abstract class ExtensionFunction17 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)}"; + } +} + diff --git a/stdlib/src/jet/ExtensionFunction18.java b/stdlib/src/jet/ExtensionFunction18.java new file mode 100644 index 00000000000..ed7fed24fdc --- /dev/null +++ b/stdlib/src/jet/ExtensionFunction18.java @@ -0,0 +1,19 @@ +/* + * @author alex.tkachman + */ +package jet; + +import jet.typeinfo.TypeInfo; +public abstract class ExtensionFunction18 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)}"; + } +} + diff --git a/stdlib/src/jet/ExtensionFunction19.java b/stdlib/src/jet/ExtensionFunction19.java new file mode 100644 index 00000000000..2db3e66aaa2 --- /dev/null +++ b/stdlib/src/jet/ExtensionFunction19.java @@ -0,0 +1,19 @@ +/* + * @author alex.tkachman + */ +package jet; + +import jet.typeinfo.TypeInfo; +public abstract class ExtensionFunction19 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)}"; + } +} + diff --git a/stdlib/src/jet/ExtensionFunction2.java b/stdlib/src/jet/ExtensionFunction2.java index a7ffa19687a..bf5ccd43d4e 100644 --- a/stdlib/src/jet/ExtensionFunction2.java +++ b/stdlib/src/jet/ExtensionFunction2.java @@ -1,11 +1,10 @@ /* - * @author max + * @author alex.tkachman */ package jet; import jet.typeinfo.TypeInfo; - -public abstract class ExtensionFunction2 extends DefaultJetObject{ +public abstract class ExtensionFunction2 extends DefaultJetObject { protected ExtensionFunction2(TypeInfo typeInfo) { super(typeInfo); } @@ -14,6 +13,7 @@ public abstract class ExtensionFunction2 extends DefaultJetObjec @Override public String toString() { - return "{E.(d1: D1, d2: D2) : R}"; + return "{E.(d1: D1, d2: D2) : R)}"; } } + diff --git a/stdlib/src/jet/ExtensionFunction20.java b/stdlib/src/jet/ExtensionFunction20.java new file mode 100644 index 00000000000..f3466d13499 --- /dev/null +++ b/stdlib/src/jet/ExtensionFunction20.java @@ -0,0 +1,19 @@ +/* + * @author alex.tkachman + */ +package jet; + +import jet.typeinfo.TypeInfo; +public abstract class ExtensionFunction20 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)}"; + } +} + diff --git a/stdlib/src/jet/ExtensionFunction21.java b/stdlib/src/jet/ExtensionFunction21.java new file mode 100644 index 00000000000..43f7bb1bde0 --- /dev/null +++ b/stdlib/src/jet/ExtensionFunction21.java @@ -0,0 +1,19 @@ +/* + * @author alex.tkachman + */ +package jet; + +import jet.typeinfo.TypeInfo; +public abstract class ExtensionFunction21 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)}"; + } +} + diff --git a/stdlib/src/jet/ExtensionFunction22.java b/stdlib/src/jet/ExtensionFunction22.java new file mode 100644 index 00000000000..04296ce8b0e --- /dev/null +++ b/stdlib/src/jet/ExtensionFunction22.java @@ -0,0 +1,19 @@ +/* + * @author alex.tkachman + */ +package jet; + +import jet.typeinfo.TypeInfo; +public abstract class ExtensionFunction22 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)}"; + } +} + diff --git a/stdlib/src/jet/ExtensionFunction3.java b/stdlib/src/jet/ExtensionFunction3.java index 54dd96f5f32..8c5518f8c4c 100644 --- a/stdlib/src/jet/ExtensionFunction3.java +++ b/stdlib/src/jet/ExtensionFunction3.java @@ -1,11 +1,10 @@ /* - * @author max + * @author alex.tkachman */ package jet; import jet.typeinfo.TypeInfo; - -public abstract class ExtensionFunction3 extends DefaultJetObject{ +public abstract class ExtensionFunction3 extends DefaultJetObject { protected ExtensionFunction3(TypeInfo typeInfo) { super(typeInfo); } @@ -14,6 +13,7 @@ public abstract class ExtensionFunction3 extends DefaultJetOb @Override public String toString() { - return "{E.(d1: D1, d2: D2, d3: D3) : R}"; + return "{E.(d1: D1, d2: D2, d3: D3) : R)}"; } } + diff --git a/stdlib/src/jet/ExtensionFunction4.java b/stdlib/src/jet/ExtensionFunction4.java new file mode 100644 index 00000000000..67f85720049 --- /dev/null +++ b/stdlib/src/jet/ExtensionFunction4.java @@ -0,0 +1,19 @@ +/* + * @author alex.tkachman + */ +package jet; + +import jet.typeinfo.TypeInfo; +public abstract class ExtensionFunction4 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)}"; + } +} + diff --git a/stdlib/src/jet/ExtensionFunction5.java b/stdlib/src/jet/ExtensionFunction5.java new file mode 100644 index 00000000000..702db6aa429 --- /dev/null +++ b/stdlib/src/jet/ExtensionFunction5.java @@ -0,0 +1,19 @@ +/* + * @author alex.tkachman + */ +package jet; + +import jet.typeinfo.TypeInfo; +public abstract class ExtensionFunction5 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)}"; + } +} + diff --git a/stdlib/src/jet/ExtensionFunction6.java b/stdlib/src/jet/ExtensionFunction6.java new file mode 100644 index 00000000000..b5be7b846a3 --- /dev/null +++ b/stdlib/src/jet/ExtensionFunction6.java @@ -0,0 +1,19 @@ +/* + * @author alex.tkachman + */ +package jet; + +import jet.typeinfo.TypeInfo; +public abstract class ExtensionFunction6 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)}"; + } +} + diff --git a/stdlib/src/jet/ExtensionFunction7.java b/stdlib/src/jet/ExtensionFunction7.java new file mode 100644 index 00000000000..2e854e49b25 --- /dev/null +++ b/stdlib/src/jet/ExtensionFunction7.java @@ -0,0 +1,19 @@ +/* + * @author alex.tkachman + */ +package jet; + +import jet.typeinfo.TypeInfo; +public abstract class ExtensionFunction7 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)}"; + } +} + diff --git a/stdlib/src/jet/ExtensionFunction8.java b/stdlib/src/jet/ExtensionFunction8.java new file mode 100644 index 00000000000..d633773ea78 --- /dev/null +++ b/stdlib/src/jet/ExtensionFunction8.java @@ -0,0 +1,19 @@ +/* + * @author alex.tkachman + */ +package jet; + +import jet.typeinfo.TypeInfo; +public abstract class ExtensionFunction8 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)}"; + } +} + diff --git a/stdlib/src/jet/ExtensionFunction9.java b/stdlib/src/jet/ExtensionFunction9.java new file mode 100644 index 00000000000..1c65840d5ae --- /dev/null +++ b/stdlib/src/jet/ExtensionFunction9.java @@ -0,0 +1,19 @@ +/* + * @author alex.tkachman + */ +package jet; + +import jet.typeinfo.TypeInfo; +public abstract class ExtensionFunction9 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)}"; + } +} + diff --git a/stdlib/src/jet/Function0.java b/stdlib/src/jet/Function0.java index 67515b604e1..81d32b0b281 100644 --- a/stdlib/src/jet/Function0.java +++ b/stdlib/src/jet/Function0.java @@ -5,8 +5,13 @@ package jet; import jet.typeinfo.TypeInfo; -public abstract class Function0 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 extends DefaultJetObject { + protected Function0(TypeInfo typeInfo) { super(typeInfo); } @@ -16,4 +21,68 @@ public abstract class Function0 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 + " 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(); +// } +// } } diff --git a/stdlib/src/jet/Function1.java b/stdlib/src/jet/Function1.java index 345a47cb0a2..3991ba51dd7 100644 --- a/stdlib/src/jet/Function1.java +++ b/stdlib/src/jet/Function1.java @@ -1,19 +1,19 @@ /* - * @author max + * @author alex.tkachman */ package jet; import jet.typeinfo.TypeInfo; - -public abstract class Function1 extends DefaultJetObject { +public abstract class Function1 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)}"; } } + diff --git a/stdlib/src/jet/Function10.java b/stdlib/src/jet/Function10.java new file mode 100644 index 00000000000..3d5633fe157 --- /dev/null +++ b/stdlib/src/jet/Function10.java @@ -0,0 +1,19 @@ +/* + * @author alex.tkachman + */ +package jet; + +import jet.typeinfo.TypeInfo; +public abstract class Function10 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)}"; + } +} + diff --git a/stdlib/src/jet/Function11.java b/stdlib/src/jet/Function11.java new file mode 100644 index 00000000000..23ae003d045 --- /dev/null +++ b/stdlib/src/jet/Function11.java @@ -0,0 +1,19 @@ +/* + * @author alex.tkachman + */ +package jet; + +import jet.typeinfo.TypeInfo; +public abstract class Function11 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)}"; + } +} + diff --git a/stdlib/src/jet/Function12.java b/stdlib/src/jet/Function12.java new file mode 100644 index 00000000000..5e7d39422c2 --- /dev/null +++ b/stdlib/src/jet/Function12.java @@ -0,0 +1,19 @@ +/* + * @author alex.tkachman + */ +package jet; + +import jet.typeinfo.TypeInfo; +public abstract class Function12 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)}"; + } +} + diff --git a/stdlib/src/jet/Function13.java b/stdlib/src/jet/Function13.java new file mode 100644 index 00000000000..fe41e408dc6 --- /dev/null +++ b/stdlib/src/jet/Function13.java @@ -0,0 +1,19 @@ +/* + * @author alex.tkachman + */ +package jet; + +import jet.typeinfo.TypeInfo; +public abstract class Function13 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)}"; + } +} + diff --git a/stdlib/src/jet/Function14.java b/stdlib/src/jet/Function14.java new file mode 100644 index 00000000000..9c678ede552 --- /dev/null +++ b/stdlib/src/jet/Function14.java @@ -0,0 +1,19 @@ +/* + * @author alex.tkachman + */ +package jet; + +import jet.typeinfo.TypeInfo; +public abstract class Function14 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)}"; + } +} + diff --git a/stdlib/src/jet/Function15.java b/stdlib/src/jet/Function15.java new file mode 100644 index 00000000000..9bbc6b85394 --- /dev/null +++ b/stdlib/src/jet/Function15.java @@ -0,0 +1,19 @@ +/* + * @author alex.tkachman + */ +package jet; + +import jet.typeinfo.TypeInfo; +public abstract class Function15 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)}"; + } +} + diff --git a/stdlib/src/jet/Function16.java b/stdlib/src/jet/Function16.java new file mode 100644 index 00000000000..7e401a94242 --- /dev/null +++ b/stdlib/src/jet/Function16.java @@ -0,0 +1,19 @@ +/* + * @author alex.tkachman + */ +package jet; + +import jet.typeinfo.TypeInfo; +public abstract class Function16 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)}"; + } +} + diff --git a/stdlib/src/jet/Function17.java b/stdlib/src/jet/Function17.java new file mode 100644 index 00000000000..2c75ba63d76 --- /dev/null +++ b/stdlib/src/jet/Function17.java @@ -0,0 +1,19 @@ +/* + * @author alex.tkachman + */ +package jet; + +import jet.typeinfo.TypeInfo; +public abstract class Function17 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)}"; + } +} + diff --git a/stdlib/src/jet/Function18.java b/stdlib/src/jet/Function18.java new file mode 100644 index 00000000000..1c95e9e8e39 --- /dev/null +++ b/stdlib/src/jet/Function18.java @@ -0,0 +1,19 @@ +/* + * @author alex.tkachman + */ +package jet; + +import jet.typeinfo.TypeInfo; +public abstract class Function18 extends DefaultJetObject { + protected Function18(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, D18 d18); + + @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, d18: D18) : R)}"; + } +} + diff --git a/stdlib/src/jet/Function19.java b/stdlib/src/jet/Function19.java new file mode 100644 index 00000000000..8f8d5a030a3 --- /dev/null +++ b/stdlib/src/jet/Function19.java @@ -0,0 +1,19 @@ +/* + * @author alex.tkachman + */ +package jet; + +import jet.typeinfo.TypeInfo; +public abstract class Function19 extends DefaultJetObject { + protected Function19(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, D18 d18, D19 d19); + + @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, d18: D18, d19: D19) : R)}"; + } +} + diff --git a/stdlib/src/jet/Function2.java b/stdlib/src/jet/Function2.java index 170b1969d0e..21f32978e29 100644 --- a/stdlib/src/jet/Function2.java +++ b/stdlib/src/jet/Function2.java @@ -1,11 +1,10 @@ /* - * @author max + * @author alex.tkachman */ package jet; import jet.typeinfo.TypeInfo; - -public abstract class Function2 extends DefaultJetObject { +public abstract class Function2 extends DefaultJetObject { protected Function2(TypeInfo typeInfo) { super(typeInfo); } @@ -14,6 +13,7 @@ public abstract class Function2 extends DefaultJetObject { @Override public String toString() { - return "{(d1: D1, d2: D2) : R}"; + return "{(d1: D1, d2: D2) : R)}"; } } + diff --git a/stdlib/src/jet/Function20.java b/stdlib/src/jet/Function20.java new file mode 100644 index 00000000000..cdf5b11a16e --- /dev/null +++ b/stdlib/src/jet/Function20.java @@ -0,0 +1,19 @@ +/* + * @author alex.tkachman + */ +package jet; + +import jet.typeinfo.TypeInfo; +public abstract class Function20 extends DefaultJetObject { + protected Function20(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, D18 d18, D19 d19, D20 d20); + + @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, d18: D18, d19: D19, d20: D20) : R)}"; + } +} + diff --git a/stdlib/src/jet/Function21.java b/stdlib/src/jet/Function21.java new file mode 100644 index 00000000000..c213b6079b7 --- /dev/null +++ b/stdlib/src/jet/Function21.java @@ -0,0 +1,19 @@ +/* + * @author alex.tkachman + */ +package jet; + +import jet.typeinfo.TypeInfo; +public abstract class Function21 extends DefaultJetObject { + protected Function21(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, D18 d18, D19 d19, D20 d20, D21 d21); + + @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, d18: D18, d19: D19, d20: D20, d21: D21) : R)}"; + } +} + diff --git a/stdlib/src/jet/Function22.java b/stdlib/src/jet/Function22.java new file mode 100644 index 00000000000..6aacfa26e84 --- /dev/null +++ b/stdlib/src/jet/Function22.java @@ -0,0 +1,19 @@ +/* + * @author alex.tkachman + */ +package jet; + +import jet.typeinfo.TypeInfo; +public abstract class Function22 extends DefaultJetObject { + protected Function22(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, D18 d18, D19 d19, D20 d20, D21 d21, D22 d22); + + @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, d18: D18, d19: D19, d20: D20, d21: D21, d22: D22) : R)}"; + } +} + diff --git a/stdlib/src/jet/Function3.java b/stdlib/src/jet/Function3.java index 54380062e6e..ffecf8c9ad1 100644 --- a/stdlib/src/jet/Function3.java +++ b/stdlib/src/jet/Function3.java @@ -1,11 +1,10 @@ /* - * @author max + * @author alex.tkachman */ package jet; import jet.typeinfo.TypeInfo; - -public abstract class Function3 extends DefaultJetObject{ +public abstract class Function3 extends DefaultJetObject { protected Function3(TypeInfo typeInfo) { super(typeInfo); } @@ -14,6 +13,7 @@ public abstract class Function3 extends DefaultJetObject{ @Override public String toString() { - return "{(d1: D1, d2: D2, d3: D3) : R}"; + return "{(d1: D1, d2: D2, d3: D3) : R)}"; } } + diff --git a/stdlib/src/jet/Function4.java b/stdlib/src/jet/Function4.java new file mode 100644 index 00000000000..31fc584ad8f --- /dev/null +++ b/stdlib/src/jet/Function4.java @@ -0,0 +1,19 @@ +/* + * @author alex.tkachman + */ +package jet; + +import jet.typeinfo.TypeInfo; +public abstract class Function4 extends DefaultJetObject { + protected Function4(TypeInfo typeInfo) { + super(typeInfo); + } + + public abstract R invoke(D1 d1, D2 d2, D3 d3, D4 d4); + + @Override + public String toString() { + return "{(d1: D1, d2: D2, d3: D3, d4: D4) : R)}"; + } +} + diff --git a/stdlib/src/jet/Function5.java b/stdlib/src/jet/Function5.java new file mode 100644 index 00000000000..85655ac1e7e --- /dev/null +++ b/stdlib/src/jet/Function5.java @@ -0,0 +1,19 @@ +/* + * @author alex.tkachman + */ +package jet; + +import jet.typeinfo.TypeInfo; +public abstract class Function5 extends DefaultJetObject { + protected Function5(TypeInfo typeInfo) { + super(typeInfo); + } + + public abstract R invoke(D1 d1, D2 d2, D3 d3, D4 d4, D5 d5); + + @Override + public String toString() { + return "{(d1: D1, d2: D2, d3: D3, d4: D4, d5: D5) : R)}"; + } +} + diff --git a/stdlib/src/jet/Function6.java b/stdlib/src/jet/Function6.java new file mode 100644 index 00000000000..bf4dfadf09d --- /dev/null +++ b/stdlib/src/jet/Function6.java @@ -0,0 +1,19 @@ +/* + * @author alex.tkachman + */ +package jet; + +import jet.typeinfo.TypeInfo; +public abstract class Function6 extends DefaultJetObject { + protected Function6(TypeInfo typeInfo) { + super(typeInfo); + } + + public abstract R invoke(D1 d1, D2 d2, D3 d3, D4 d4, D5 d5, D6 d6); + + @Override + public String toString() { + return "{(d1: D1, d2: D2, d3: D3, d4: D4, d5: D5, d6: D6) : R)}"; + } +} + diff --git a/stdlib/src/jet/Function7.java b/stdlib/src/jet/Function7.java new file mode 100644 index 00000000000..ef3691024d4 --- /dev/null +++ b/stdlib/src/jet/Function7.java @@ -0,0 +1,19 @@ +/* + * @author alex.tkachman + */ +package jet; + +import jet.typeinfo.TypeInfo; +public abstract class Function7 extends DefaultJetObject { + protected Function7(TypeInfo typeInfo) { + super(typeInfo); + } + + public abstract R invoke(D1 d1, D2 d2, D3 d3, D4 d4, D5 d5, D6 d6, D7 d7); + + @Override + public String toString() { + return "{(d1: D1, d2: D2, d3: D3, d4: D4, d5: D5, d6: D6, d7: D7) : R)}"; + } +} + diff --git a/stdlib/src/jet/Function8.java b/stdlib/src/jet/Function8.java new file mode 100644 index 00000000000..0b261a57dfb --- /dev/null +++ b/stdlib/src/jet/Function8.java @@ -0,0 +1,19 @@ +/* + * @author alex.tkachman + */ +package jet; + +import jet.typeinfo.TypeInfo; +public abstract class Function8 extends DefaultJetObject { + protected Function8(TypeInfo typeInfo) { + super(typeInfo); + } + + public abstract R invoke(D1 d1, D2 d2, D3 d3, D4 d4, D5 d5, D6 d6, D7 d7, D8 d8); + + @Override + public String toString() { + return "{(d1: D1, d2: D2, d3: D3, d4: D4, d5: D5, d6: D6, d7: D7, d8: D8) : R)}"; + } +} + diff --git a/stdlib/src/jet/Function9.java b/stdlib/src/jet/Function9.java new file mode 100644 index 00000000000..5334531aa97 --- /dev/null +++ b/stdlib/src/jet/Function9.java @@ -0,0 +1,19 @@ +/* + * @author alex.tkachman + */ +package jet; + +import jet.typeinfo.TypeInfo; +public abstract class Function9 extends DefaultJetObject { + protected Function9(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); + + @Override + public String toString() { + return "{(d1: D1, d2: D2, d3: D3, d4: D4, d5: D5, d6: D6, d7: D7, d8: D8, d9: D9) : R)}"; + } +} + From 38464d4e57988bee17fd4ed89c36bd4872d778e6 Mon Sep 17 00:00:00 2001 From: svtk Date: Mon, 24 Oct 2011 18:40:23 +0400 Subject: [PATCH 21/23] Added mark '*' for dead instructions while visualizing cfg --- compiler/testData/cfg/Finally.instructions | 48 +++++++++---------- compiler/testData/cfg/If.instructions | 8 ++-- .../cfg/OnlyWhileInFunctionBody.instructions | 16 +++---- .../jetbrains/jet/cfg/JetControlFlowTest.java | 9 ++-- 4 files changed, 42 insertions(+), 39 deletions(-) diff --git a/compiler/testData/cfg/Finally.instructions b/compiler/testData/cfg/Finally.instructions index 652eed75a12..8500acbd625 100644 --- a/compiler/testData/cfg/Finally.instructions +++ b/compiler/testData/cfg/Finally.instructions @@ -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:[] 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:[] PREV:[jmp?(l2), jmp(l4), read (Unit)] + r(2) NEXT:[] PREV:[jmp?(l2), read (Unit)] l1: 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:[] PREV:[jf(l5)] - jmp(l6) NEXT:[] PREV:[] +* jmp(l6) NEXT:[] PREV:[] l5: read (Unit) NEXT:[] PREV:[jf(l5)] l4: l6: - NEXT:[] PREV:[ret l4, jmp(l6), read (Unit)] + NEXT:[] PREV:[ret l4, read (Unit)] 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:[] PREV:[jf(l5)] - jmp(l6) NEXT:[] PREV:[] +* jmp(l6) NEXT:[] PREV:[] l5: read (Unit) NEXT:[] PREV:[jf(l5)] l4: l6: - NEXT:[] PREV:[ret l4, jmp(l6), read (Unit)] + NEXT:[] PREV:[ret l4, read (Unit)] 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:[] 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:[] PREV:[jmp?(l4), jmp(l6), read (Unit)] + r(2) NEXT:[] PREV:[jmp?(l4), read (Unit)] l3: 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:[] 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:[] PREV:[jmp?(l4), jmp(l6), read (Unit)] + r(2) NEXT:[] PREV:[jmp?(l4), read (Unit)] l3: 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:[] 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:[] 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:[] PREV:[r(2)] - ret(*) l1 NEXT:[] PREV:[] +* ret(*) l1 NEXT:[] PREV:[] l2: r(2) NEXT:[ret(*) l1] PREV:[jmp?(l2)] ret(*) l1 NEXT:[] PREV:[r(2)] l1: - NEXT:[] PREV:[ret(*) l1, ret(*) l1, ret(*) l1] + NEXT:[] PREV:[ret(*) l1, ret(*) l1] error: NEXT:[] PREV:[] ===================== diff --git a/compiler/testData/cfg/If.instructions b/compiler/testData/cfg/If.instructions index c4d5a9a542c..d075477d559 100644 --- a/compiler/testData/cfg/If.instructions +++ b/compiler/testData/cfg/If.instructions @@ -65,23 +65,23 @@ l0: r(b) NEXT:[jf(l2)] PREV:[w(i)] jf(l2) NEXT:[read (Unit), ret l1] PREV:[r(b)] ret l1 NEXT:[] PREV:[jf(l2)] - jmp(l3) NEXT:[r(i)] PREV:[] +* jmp(l3) NEXT:[r(i)] PREV:[] l2: read (Unit) NEXT:[r(i)] PREV:[jf(l2)] l3: - r(i) NEXT:[r(doSmth)] PREV:[jmp(l3), read (Unit)] + 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:[] PREV:[jf(l4)] - jmp(l5) NEXT:[] PREV:[] +* jmp(l5) NEXT:[] PREV:[] l4: read (Unit) NEXT:[] PREV:[jf(l4)] l1: l5: - NEXT:[] PREV:[ret l1, ret l1, jmp(l5), read (Unit)] + NEXT:[] PREV:[ret l1, ret l1, read (Unit)] error: NEXT:[] PREV:[] ===================== diff --git a/compiler/testData/cfg/OnlyWhileInFunctionBody.instructions b/compiler/testData/cfg/OnlyWhileInFunctionBody.instructions index c0e4641ad03..bdad7a8566b 100644 --- a/compiler/testData/cfg/OnlyWhileInFunctionBody.instructions +++ b/compiler/testData/cfg/OnlyWhileInFunctionBody.instructions @@ -34,17 +34,17 @@ l0: NEXT:[ret l1] PREV:[] l2: l4: - ret l1 NEXT:[] PREV:[, jt(l2)] + ret l1 NEXT:[] PREV:[] 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:[] PREV:[jt(l2)] +* read (Unit) NEXT:[] PREV:[] l1: - NEXT:[] PREV:[ret l1, read (Unit)] + NEXT:[] PREV:[ret l1] error: NEXT:[] PREV:[] ===================== diff --git a/compiler/tests/org/jetbrains/jet/cfg/JetControlFlowTest.java b/compiler/tests/org/jetbrains/jet/cfg/JetControlFlowTest.java index 5d82577cda5..b9efa562bcf 100644 --- a/compiler/tests/org/jetbrains/jet/cfg/JetControlFlowTest.java +++ b/compiler/tests/org/jetbrains/jet/cfg/JetControlFlowTest.java @@ -154,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(); @@ -214,7 +215,9 @@ public class JetControlFlowTest extends JetTestCaseBase { } } else { - maxLength = instuctionText.length(); + if (instuctionText.length() > maxLength) { + maxLength = instuctionText.length(); + } } } String instructionListText = formatInstructionList(instruction.getNextInstructions()); From 3b8819ad24a26fa68f085faa90888699f1f42065 Mon Sep 17 00:00:00 2001 From: svtk Date: Mon, 24 Oct 2011 18:52:29 +0400 Subject: [PATCH 22/23] cfg traversal enhancement --- .../lang/cfg/JetFlowInformationProvider.java | 264 +++++++++++++----- 1 file changed, 193 insertions(+), 71 deletions(-) diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/cfg/JetFlowInformationProvider.java b/compiler/frontend/src/org/jetbrains/jet/lang/cfg/JetFlowInformationProvider.java index 88dd8b70018..5880ad7fc20 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/cfg/JetFlowInformationProvider.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/cfg/JetFlowInformationProvider.java @@ -183,17 +183,17 @@ public class JetFlowInformationProvider { // } // } - private boolean collectReachable(Instruction current, Set 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 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 visited, final Collection returnedExpressions, final Collection elementsReturningUnit) { // if (!visited.add(previousFor)) return; @@ -259,16 +259,18 @@ public class JetFlowInformationProvider { private Map traverseInstructionGraphUntilFactsStabilization( Pseudocode pseudocode, InstructionsMergeHandler instructionsMergeHandler, - D initialDataValue, + D initialDataValue, + D initialDataValueForEnterInstruction, boolean straightDirection) { Map 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.emptyList(), straightDirection, dataMap, changed); + traverseSubGraph(pseudocode, instructionsMergeHandler, Collections.emptyList(), straightDirection, dataMap, changed, false); } return dataMap; } @@ -287,15 +289,18 @@ public class JetFlowInformationProvider { } private void traverseSubGraph( - Pseudocode pseudocode, - InstructionsMergeHandler instructionsMergeHandler, - Collection previousSubGraphInstructions, - boolean straightDirection, - Map dataMap, - boolean[] changed) { + Pseudocode pseudocode, + InstructionsMergeHandler instructionsMergeHandler, + Collection previousSubGraphInstructions, + boolean straightDirection, + Map dataMap, + boolean[] changed, + boolean isLocal) { List instructions = pseudocode.getInstructions(); SubroutineEnterInstruction enterInstruction = pseudocode.getEnterInstruction(); for (Instruction instruction : instructions) { + if (!isLocal && instruction instanceof SubroutineEnterInstruction) continue; + Collection allPreviousInstructions; Collection previousInstructions = straightDirection ? instruction.getPreviousInstructions() @@ -311,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); @@ -320,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); @@ -333,86 +338,203 @@ public class JetFlowInformationProvider { assert pseudocode != null; Collection instructions = pseudocode.getInstructions(); - InstructionsMergeHandler> instructionsMergeHandler = new InstructionsMergeHandler>() { + InstructionsMergeHandler> instructionsMergeHandler = new InstructionsMergeHandler>() { @Override - public Set merge(Instruction instruction, Set previousDataValue, Collection> incomingEdgesData) { - Set initializedVariables = Sets.newHashSet(); - initializedVariables.addAll(previousDataValue); - Set edgesDataIntersection = Sets.newHashSet(); - boolean isFirst = true; - for (Set edgeData : incomingEdgesData) { - if (isFirst) { - edgesDataIntersection.addAll(edgeData); - } - else { - edgesDataIntersection = Sets.intersection(edgesDataIntersection, edgeData).immutableCopy(); - } - isFirst = false; - } - initializedVariables.addAll(edgesDataIntersection); + public Map merge( + Instruction instruction, + Collection> incomingEdgesData) { - 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) { - initializedVariables.add((LocalVariableDescriptor) descriptor); - } + Set variablesInScope = Sets.newHashSet(); + for (Map edgePointsMap : incomingEdgesData) { + variablesInScope.addAll(edgePointsMap.keySet()); } - return initializedVariables; + + Map pointsMap = Maps.newHashMap(); + for (LocalVariableDescriptor variable : variablesInScope) { + Set edgesDataForVariable = Sets.newHashSet(); + for (Map edgePointsMap : incomingEdgesData) { + InitializationPoints points = edgePointsMap.get(variable); + if (points != null) { + edgesDataForVariable.add(points); + } + } + pointsMap.put(variable, new InitializationPoints(edgesDataForVariable)); + } + + 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> dataMap = traverseInstructionGraphUntilFactsStabilization(pseudocode, instructionsMergeHandler, Collections.emptySet(), true); - InstructionDataAnalyzer instructionDataAnalyzer = new InstructionDataAnalyzer>() { + + Set localVariables = collectAllLocalVariables(pseudocode); + Map initialMapForStartInstruction = Maps.newHashMap(); + InitializationPoints initialPoints = new InitializationPoints(); + for (LocalVariableDescriptor variable : localVariables) { + initialMapForStartInstruction.put(variable, initialPoints); + } + Map> dataMap = + traverseInstructionGraphUntilFactsStabilization(pseudocode, instructionsMergeHandler, Collections.emptyMap(), initialMapForStartInstruction, true); + + InstructionDataAnalyzer> instructionDataAnalyzer = new InstructionDataAnalyzer>() { @Override - public void analyze(Instruction instruction, Map> dataMap) { - Set initializedVariables = dataMap.get(instruction); + public void analyze(Instruction instruction, Map> dataMap) { + Map 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).getlValue(); - 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)); - } + 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 instructions, Map> dataMap, InstructionDataAnalyzer> 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 collectAllLocalVariables(Pseudocode pseudocode) { + final Set localVariables = Sets.newHashSet(); + InstructionDataAnalyzer analyzer = new InstructionDataAnalyzer() { + @Override + public void analyze(Instruction instruction, Map dataMap) { + LocalVariableDescriptor variableDescriptor = extractVariableDescriptorIfAny(instruction); + if (variableDescriptor != null) { + localVariables.add(variableDescriptor); + } + } + }; + traverseAndAnalyzeInstructionGraph(pseudocode.getInstructions(), Collections.emptyMap(), analyzer); + return localVariables; + } + + private void traverseAndAnalyzeInstructionGraph(Collection instructions, Map dataMap, InstructionDataAnalyzer 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 merge(Instruction instruction, D previousDataValue, Collection incomingEdgesData); + D merge(Instruction instruction, Collection incomingEdgesData); } interface InstructionDataAnalyzer { void analyze(Instruction instruction, Map dataMap); } -} + + private static class InitializationPoints { + private Set possiblePoints = Sets.newHashSet(); + private boolean canBeUninitialized; + + public InitializationPoints() { + canBeUninitialized = true; + } + + public InitializationPoints(JetElement element) { + canBeUninitialized = false; + possiblePoints.add(element); + } + + public InitializationPoints(Set 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; + } + } +} \ No newline at end of file From 9122bb373faa999e0ed2659adc8ae40d17b2dcf4 Mon Sep 17 00:00:00 2001 From: svtk Date: Mon, 24 Oct 2011 18:53:51 +0400 Subject: [PATCH 23/23] Added tests for 'uninitialized vars'; 'vals reassignment' (for simple flow) --- .../full/FlowAnalyseVariables.jet | 99 +++++++++++++++++++ 1 file changed, 99 insertions(+) create mode 100644 compiler/testData/checkerWithErrorTypes/full/FlowAnalyseVariables.jet diff --git a/compiler/testData/checkerWithErrorTypes/full/FlowAnalyseVariables.jet b/compiler/testData/checkerWithErrorTypes/full/FlowAnalyseVariables.jet new file mode 100644 index 00000000000..81a49d26b02 --- /dev/null +++ b/compiler/testData/checkerWithErrorTypes/full/FlowAnalyseVariables.jet @@ -0,0 +1,99 @@ +namespace uninitialized_vals { + +fun t1(b : Boolean) { + val v : Int + if (v == 0) {} + + var u: String + if (b) { + u = "s" + } + doSmth(u) + + var r: String + if (b) { + r = "s" + } + else { + r = "tg" + } + doSmth(r) + + var t: String + if (b) + doSmth(t) + else + t = "ss" + doSmth(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 + 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 + x = x.signal() + x = x.signal() +} + +fun t3() { + val x = 1 + x += 2 + val y = 3 + y *= 4 + var z = 5 + z -= y +} + +fun t4() { + for (i in 0..2) { + i += 1 + fun t5() { + i += 3 + } + } +} + +} \ No newline at end of file