From e351dfca1206f682416e916a8a25a5e791d45ea7 Mon Sep 17 00:00:00 2001 From: Andrey Breslav Date: Thu, 9 May 2013 11:21:05 +0300 Subject: [PATCH 001/249] Measuring time in ForTestCompileRuntime --- .../jet/codegen/forTestCompile/ForTestCompileRuntime.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/compiler/tests/org/jetbrains/jet/codegen/forTestCompile/ForTestCompileRuntime.java b/compiler/tests/org/jetbrains/jet/codegen/forTestCompile/ForTestCompileRuntime.java index 7aa470e7038..04bbb916487 100644 --- a/compiler/tests/org/jetbrains/jet/codegen/forTestCompile/ForTestCompileRuntime.java +++ b/compiler/tests/org/jetbrains/jet/codegen/forTestCompile/ForTestCompileRuntime.java @@ -22,6 +22,7 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.jet.JetTestUtils; import org.jetbrains.jet.cli.common.ExitCode; import org.jetbrains.jet.cli.jvm.K2JVMCompiler; +import org.jetbrains.jet.utils.Profiler; import org.junit.Assert; import javax.tools.*; @@ -120,7 +121,9 @@ public class ForTestCompileRuntime { // This method is very convenient when you have trouble compiling runtime in tests public static void main(String[] args) throws IOException { + Profiler stdlib = Profiler.create("compileStdlib").start(); compileStdlib(JetTestUtils.tmpDir("runtime")); + stdlib.end(); } } From ba4c012000dcfd2619633a89f7a0f09ec68eca42 Mon Sep 17 00:00:00 2001 From: Andrey Breslav Date: Thu, 9 May 2013 12:01:17 +0300 Subject: [PATCH 002/249] Profiler can be paused --- .../src/org/jetbrains/jet/utils/Profiler.java | 26 ++++++++++++++++--- 1 file changed, 22 insertions(+), 4 deletions(-) diff --git a/compiler/util/src/org/jetbrains/jet/utils/Profiler.java b/compiler/util/src/org/jetbrains/jet/utils/Profiler.java index 84621742021..06f4a68dde2 100644 --- a/compiler/util/src/org/jetbrains/jet/utils/Profiler.java +++ b/compiler/util/src/org/jetbrains/jet/utils/Profiler.java @@ -57,7 +57,9 @@ public class Profiler { private final String name; private final PrintStream out; - private long start; + private long start = Long.MAX_VALUE; + private long cumulative = 0; + private boolean paused = true; private StackTraceElement[] stackTrace; private boolean mute; @@ -114,16 +116,24 @@ public class Profiler { } public Profiler start() { - start = System.nanoTime(); + if (!paused) { + start = System.nanoTime(); + paused = false; + } return this; } public Profiler end() { - long delta = System.nanoTime() - start; + long result = cumulative; + if (!paused) { + result += System.nanoTime() - start; + } + paused = true; + cumulative = 0; OUT_LOCK.lock(); try { - println(name, " took ", format(delta)); + println(name, " took ", format(result)); printStackTrace(); } finally { @@ -133,6 +143,14 @@ public class Profiler { return this; } + public Profiler pause() { + if (!paused) { + cumulative += System.nanoTime() - start; + paused = true; + } + return this; + } + public Profiler mute() { mute = true; return this; From 63f7b4c51d30376820beab1bf7f086b1d95b795c Mon Sep 17 00:00:00 2001 From: Andrey Breslav Date: Sat, 11 May 2013 00:06:33 +0300 Subject: [PATCH 003/249] Replacing all occurences of the package name, not only the first one --- update_dependencies.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/update_dependencies.xml b/update_dependencies.xml index 82a48a528a2..3fc8c81ac46 100644 --- a/update_dependencies.xml +++ b/update_dependencies.xml @@ -150,7 +150,7 @@ - + From df557faa09dfcb2d17a8aa3414046cc858e2d7ff Mon Sep 17 00:00:00 2001 From: Andrey Breslav Date: Sat, 11 May 2013 11:15:31 +0300 Subject: [PATCH 004/249] Support done() in class handler --- .../jet/preloading/ClassPreloadingUtils.java | 2 ++ .../jetbrains/jet/preloading/Preloader.java | 34 ++++++++++++------- 2 files changed, 24 insertions(+), 12 deletions(-) diff --git a/compiler/preloader/src/org/jetbrains/jet/preloading/ClassPreloadingUtils.java b/compiler/preloader/src/org/jetbrains/jet/preloading/ClassPreloadingUtils.java index 733a166d230..340bc1bcded 100644 --- a/compiler/preloader/src/org/jetbrains/jet/preloading/ClassPreloadingUtils.java +++ b/compiler/preloader/src/org/jetbrains/jet/preloading/ClassPreloadingUtils.java @@ -35,6 +35,8 @@ public class ClassPreloadingUtils { public void beforeLoadJar(File jarFile) {} public void afterLoadJar(File jarFile) {} + + public void done() {} } /** diff --git a/compiler/preloader/src/org/jetbrains/jet/preloading/Preloader.java b/compiler/preloader/src/org/jetbrains/jet/preloading/Preloader.java index 4c32ea9ccce..5f5155fc6c4 100644 --- a/compiler/preloader/src/org/jetbrains/jet/preloading/Preloader.java +++ b/compiler/preloader/src/org/jetbrains/jet/preloading/Preloader.java @@ -44,17 +44,9 @@ public class Preloader { ClassLoader parent = Preloader.class.getClassLoader(); - final int[] counter = new int[1]; - final int[] size = new int[1]; - ClassLoader preloaded = ClassPreloadingUtils.preloadClasses(files, classNumber, parent, - !printTime ? null : - new ClassPreloadingUtils.ClassHandler() { - @Override - public void beforeDefineClass(String name, int sizeInBytes) { - counter[0]++; - size[0] += sizeInBytes; - } - }); + ClassPreloadingUtils.ClassHandler handler = getHandler(printTime); + ClassLoader preloaded = ClassPreloadingUtils.preloadClasses(files, classNumber, parent, handler); + handler.done(); Class mainClass = preloaded.loadClass(mainClassCanonicalName); Method mainMethod = mainClass.getMethod("main", String[].class); @@ -66,10 +58,28 @@ public class Preloader { if (printTime) { long dt = System.nanoTime() - startTime; System.out.format("Total time: %.3fs\n", dt / 1e9); + } + } + } + + private static ClassPreloadingUtils.ClassHandler getHandler(boolean printTime) { + if (printTime) return new ClassPreloadingUtils.ClassHandler() {}; + + final int[] counter = new int[1]; + final int[] size = new int[1]; + return new ClassPreloadingUtils.ClassHandler() { + @Override + public void beforeDefineClass(String name, int sizeInBytes) { + counter[0]++; + size[0] += sizeInBytes; + } + + @Override + public void done() { System.out.println("Loaded classes: " + counter[0]); System.out.println("Loaded classes size: " + size[0]); } - } + }; } private static boolean parseMeasureTime(String arg) { From 2e1a7179f0691b17529b3b41c37f266c8e0210c1 Mon Sep 17 00:00:00 2001 From: Andrey Breslav Date: Sat, 11 May 2013 11:11:14 +0300 Subject: [PATCH 005/249] Allow instrumentation in preloader --- .../jet/preloading/ClassPreloadingUtils.java | 11 +- .../jetbrains/jet/preloading/Preloader.java | 105 +++++++++++++----- .../instrumentation/Instrumenter.java | 37 ++++++ 3 files changed, 126 insertions(+), 27 deletions(-) create mode 100644 compiler/preloader/src/org/jetbrains/jet/preloading/instrumentation/Instrumenter.java diff --git a/compiler/preloader/src/org/jetbrains/jet/preloading/ClassPreloadingUtils.java b/compiler/preloader/src/org/jetbrains/jet/preloading/ClassPreloadingUtils.java index 340bc1bcded..97adf0965b5 100644 --- a/compiler/preloader/src/org/jetbrains/jet/preloading/ClassPreloadingUtils.java +++ b/compiler/preloader/src/org/jetbrains/jet/preloading/ClassPreloadingUtils.java @@ -30,6 +30,10 @@ import java.util.zip.ZipInputStream; public class ClassPreloadingUtils { public static abstract class ClassHandler { + public byte[] instrument(String resourceName, byte[] data) { + return data; + } + public void beforeDefineClass(String name, int sizeInBytes) {} public void afterDefineClass(String name) {} @@ -152,7 +156,12 @@ public class ClassPreloadingUtils { bytes.write(buffer, 0, count); } - resources.put(name, new ResourceData(jarFile, name, bytes.toByteArray())); + byte[] data = bytes.toByteArray(); + if (handler != null) { + data = handler.instrument(name, data); + } + + resources.put(name, new ResourceData(jarFile, name, data)); } } finally { diff --git a/compiler/preloader/src/org/jetbrains/jet/preloading/Preloader.java b/compiler/preloader/src/org/jetbrains/jet/preloading/Preloader.java index 5f5155fc6c4..640e9a41374 100644 --- a/compiler/preloader/src/org/jetbrains/jet/preloading/Preloader.java +++ b/compiler/preloader/src/org/jetbrains/jet/preloading/Preloader.java @@ -1,31 +1,25 @@ package org.jetbrains.jet.preloading; +import org.jetbrains.jet.preloading.instrumentation.Instrumenter; + import java.io.File; import java.lang.reflect.Method; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; +import java.net.MalformedURLException; +import java.net.URL; +import java.net.URLClassLoader; +import java.util.*; public class Preloader { public static final int PRELOADER_ARG_COUNT = 4; + private static final String PROFILE = "profile="; public static void main(String[] args) throws Exception { if (args.length < PRELOADER_ARG_COUNT) { printUsageAndExit(); } - String classpath = args[0]; - String[] paths = classpath.split("\\" + File.pathSeparator); - List files = new ArrayList(paths.length); - for (String path : paths) { - File file = new File(path); - if (!file.exists()) { - System.out.println("File does not exist: " + file); - printUsageAndExit(); - } - files.add(file); - } + List files = parseClassPath(args[0]); String mainClassCanonicalName = args[1]; @@ -39,14 +33,18 @@ public class Preloader { return; } - boolean printTime = parseMeasureTime(args[3]); + String profilingModeStr = args[3]; + ProfilingMode profilingMode = parseMeasureTime(profilingModeStr); + URL[] instrumentersClasspath = parseInstrumentersClasspath(profilingMode, profilingModeStr); + long startTime = System.nanoTime(); ClassLoader parent = Preloader.class.getClassLoader(); - ClassPreloadingUtils.ClassHandler handler = getHandler(printTime); - ClassLoader preloaded = ClassPreloadingUtils.preloadClasses(files, classNumber, parent, handler); - handler.done(); + ClassLoader withInstrumenter = instrumentersClasspath.length > 0 ? new URLClassLoader(instrumentersClasspath, parent) : parent; + + ClassPreloadingUtils.ClassHandler handler = getHandler(profilingMode, withInstrumenter); + ClassLoader preloaded = ClassPreloadingUtils.preloadClasses(files, classNumber, withInstrumenter, handler); Class mainClass = preloaded.loadClass(mainClassCanonicalName); Method mainMethod = mainClass.getMethod("main", String[].class); @@ -55,15 +53,55 @@ public class Preloader { mainMethod.invoke(0, new Object[] {Arrays.copyOfRange(args, PRELOADER_ARG_COUNT, args.length)}); } finally { - if (printTime) { + if (profilingMode != ProfilingMode.NO_TIME) { long dt = System.nanoTime() - startTime; System.out.format("Total time: %.3fs\n", dt / 1e9); } + handler.done(); } } - private static ClassPreloadingUtils.ClassHandler getHandler(boolean printTime) { - if (printTime) return new ClassPreloadingUtils.ClassHandler() {}; + private static URL[] parseInstrumentersClasspath(ProfilingMode profilingMode, String profilingModeStr) + throws MalformedURLException { + URL[] instrumentersClasspath; + if (profilingMode == ProfilingMode.PROFILE) { + List instrumentersClassPathFiles = parseClassPath(getClassPath(profilingModeStr)); + instrumentersClasspath = new URL[instrumentersClassPathFiles.size()]; + for (int i = 0; i < instrumentersClassPathFiles.size(); i++) { + File file = instrumentersClassPathFiles.get(i); + instrumentersClasspath[i] = file.toURI().toURL(); + } + } + else { + instrumentersClasspath = new URL[0]; + } + return instrumentersClasspath; + } + + private static String getClassPath(String profilingModeStr) { + return profilingModeStr.substring(PROFILE.length()); + } + + private static List parseClassPath(String classpath) { + String[] paths = classpath.split("\\" + File.pathSeparator); + List files = new ArrayList(paths.length); + for (String path : paths) { + File file = new File(path); + if (!file.exists()) { + System.out.println("File does not exist: " + file); + printUsageAndExit(); + } + files.add(file); + } + return files; + } + + private static ClassPreloadingUtils.ClassHandler getHandler(ProfilingMode profilingMode, ClassLoader withInstrumenter) { + if (profilingMode == ProfilingMode.NO_TIME) return new ClassPreloadingUtils.ClassHandler() {}; + + ServiceLoader loader = ServiceLoader.load(Instrumenter.class, withInstrumenter); + Iterator instrumenters = loader.iterator(); + final Instrumenter instrumenter = instrumenters.hasNext() ? instrumenters.next() : Instrumenter.DO_NOTHING; final int[] counter = new int[1]; final int[] size = new int[1]; @@ -78,20 +116,35 @@ public class Preloader { public void done() { System.out.println("Loaded classes: " + counter[0]); System.out.println("Loaded classes size: " + size[0]); + + instrumenter.dump(System.out); + } + + @Override + public byte[] instrument(String resourceName, byte[] data) { + return instrumenter.instrument(resourceName, data); } }; } - private static boolean parseMeasureTime(String arg) { - if ("time".equals(arg)) return true; - if ("notime".equals(arg)) return false; + private enum ProfilingMode { + NO_TIME, + TIME, + PROFILE + } + + private static ProfilingMode parseMeasureTime(String arg) { + if ("time".equals(arg)) return ProfilingMode.TIME; + if ("notime".equals(arg)) return ProfilingMode.NO_TIME; + if (arg.startsWith(PROFILE)) return ProfilingMode.PROFILE; + System.out.println("Unrecognized argument: " + arg); printUsageAndExit(); - return false; + return ProfilingMode.NO_TIME; } private static void printUsageAndExit() { - System.out.println("Usage: Preloader
"); + System.out.println("Usage: Preloader
> "); System.exit(1); } } diff --git a/compiler/preloader/src/org/jetbrains/jet/preloading/instrumentation/Instrumenter.java b/compiler/preloader/src/org/jetbrains/jet/preloading/instrumentation/Instrumenter.java new file mode 100644 index 00000000000..a23cf2b5e3e --- /dev/null +++ b/compiler/preloader/src/org/jetbrains/jet/preloading/instrumentation/Instrumenter.java @@ -0,0 +1,37 @@ +/* + * Copyright 2010-2013 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.jetbrains.jet.preloading.instrumentation; + +import java.io.PrintStream; + +public interface Instrumenter { + + Instrumenter DO_NOTHING = new Instrumenter() { + @Override + public byte[] instrument(String resourceName, byte[] data) { + return data; + } + + @Override + public void dump(PrintStream out) { + // Do nothing + } + }; + + byte[] instrument(String resourceName, byte[] data); + void dump(PrintStream out); +} From 90661e8706229af5e4ddac7d492b8675bf6cfb9d Mon Sep 17 00:00:00 2001 From: Andrey Breslav Date: Sat, 11 May 2013 17:29:57 +0300 Subject: [PATCH 006/249] Instrumenting interceptors module --- .idea/artifacts/instrumentation_jar.xml | 10 + .idea/libraries/asm.xml | 11 + .idea/libraries/guava.xml | 11 + .idea/modules.xml | 1 + .../instrumentation/instrumentation.iml | 15 + .../preloading/instrumentation/FieldData.java | 23 ++ .../instrumentation/FieldDataImpl.java | 34 ++ .../InterceptionInstrumenter.java | 319 ++++++++++++++++++ .../InterceptionInstrumenterAdaptor.java | 39 +++ .../instrumentation/MemberData.java | 23 ++ .../instrumentation/MemberDataImpl.java | 45 +++ .../instrumentation/MethodData.java | 22 ++ .../instrumentation/MethodDataImpl.java | 44 +++ .../instrumentation/MethodInstrumenter.java | 29 ++ .../MethodInstrumenterImpl.java | 67 ++++ .../instrumentation/MethodInterceptor.java | 38 +++ 16 files changed, 731 insertions(+) create mode 100644 .idea/artifacts/instrumentation_jar.xml create mode 100644 .idea/libraries/asm.xml create mode 100644 .idea/libraries/guava.xml create mode 100644 compiler/preloader/instrumentation/instrumentation.iml create mode 100644 compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/FieldData.java create mode 100644 compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/FieldDataImpl.java create mode 100644 compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/InterceptionInstrumenter.java create mode 100644 compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/InterceptionInstrumenterAdaptor.java create mode 100644 compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/MemberData.java create mode 100644 compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/MemberDataImpl.java create mode 100644 compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/MethodData.java create mode 100644 compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/MethodDataImpl.java create mode 100644 compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/MethodInstrumenter.java create mode 100644 compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/MethodInstrumenterImpl.java create mode 100644 compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/MethodInterceptor.java diff --git a/.idea/artifacts/instrumentation_jar.xml b/.idea/artifacts/instrumentation_jar.xml new file mode 100644 index 00000000000..5e0f98bc70e --- /dev/null +++ b/.idea/artifacts/instrumentation_jar.xml @@ -0,0 +1,10 @@ + + + $PROJECT_DIR$/out/artifacts/instrumentation_jar + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/asm.xml b/.idea/libraries/asm.xml new file mode 100644 index 00000000000..8968222f967 --- /dev/null +++ b/.idea/libraries/asm.xml @@ -0,0 +1,11 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/libraries/guava.xml b/.idea/libraries/guava.xml new file mode 100644 index 00000000000..c89b3a6c6b1 --- /dev/null +++ b/.idea/libraries/guava.xml @@ -0,0 +1,11 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml index 687c7133d79..19cb344b290 100644 --- a/.idea/modules.xml +++ b/.idea/modules.xml @@ -19,6 +19,7 @@ + diff --git a/compiler/preloader/instrumentation/instrumentation.iml b/compiler/preloader/instrumentation/instrumentation.iml new file mode 100644 index 00000000000..d7a80fb225f --- /dev/null +++ b/compiler/preloader/instrumentation/instrumentation.iml @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + diff --git a/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/FieldData.java b/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/FieldData.java new file mode 100644 index 00000000000..082d97936f2 --- /dev/null +++ b/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/FieldData.java @@ -0,0 +1,23 @@ +/* + * Copyright 2010-2013 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.jetbrains.jet.preloading.instrumentation; + +import org.jetbrains.asm4.Type; + +interface FieldData extends MemberData { + Type getRuntimeType(); +} diff --git a/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/FieldDataImpl.java b/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/FieldDataImpl.java new file mode 100644 index 00000000000..0164699d8ab --- /dev/null +++ b/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/FieldDataImpl.java @@ -0,0 +1,34 @@ +/* + * Copyright 2010-2013 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.jetbrains.jet.preloading.instrumentation; + +import org.jetbrains.asm4.Type; + +class FieldDataImpl extends MemberDataImpl implements FieldData { + + private final Type runtimeType; + + public FieldDataImpl(String declaringClass, String name, String desc, Type runtimeType) { + super(declaringClass, name, desc); + this.runtimeType = runtimeType; + } + + @Override + public Type getRuntimeType() { + return runtimeType; + } +} diff --git a/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/InterceptionInstrumenter.java b/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/InterceptionInstrumenter.java new file mode 100644 index 00000000000..39311f59573 --- /dev/null +++ b/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/InterceptionInstrumenter.java @@ -0,0 +1,319 @@ +/* + * Copyright 2010-2013 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.jetbrains.jet.preloading.instrumentation; + +import org.jetbrains.asm4.*; +import org.jetbrains.asm4.commons.InstructionAdapter; + +import java.io.PrintStream; +import java.lang.reflect.Field; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.lang.reflect.Modifier; +import java.util.*; +import java.util.regex.Pattern; + +import static org.jetbrains.asm4.Opcodes.*; + +public class InterceptionInstrumenter implements Instrumenter { + private final Map classPatterns = new LinkedHashMap(); + + private final Set neverMatchedClassPatterns = new LinkedHashSet(); + private final Set neverMatchedInstrumenters = new LinkedHashSet(); + + interface DumpAction { + void dump(PrintStream out); + } + private final List dumpTasks = new ArrayList(); + + public InterceptionInstrumenter(List> handlerClasses) { + for (Class handlerClass : handlerClasses) { + addHandlerClass(handlerClass); + } + } + + private void addHandlerClass(Class handlerClass) { + for (Field field : handlerClass.getFields()) { + MethodInterceptor annotation = field.getAnnotation(MethodInterceptor.class); + if (annotation == null) continue; + + if ((field.getModifiers() & Modifier.STATIC) == 0) { + throw new IllegalArgumentException("Non-static field annotated @MethodInterceptor: " + field); + } + + Pattern classPattern = Pattern.compile(annotation.className()); + List instrumenters = addClassPattern(classPattern.pattern()); + + try { + Object interceptor = field.get(null); + if (interceptor == null) { + throw new IllegalArgumentException("Interceptor is null: " + field); + } + + Class interceptorClass = interceptor.getClass(); + + FieldData fieldData = getFieldData(field, interceptorClass); + + List enterData = new ArrayList(); + List exitData = new ArrayList(); + Method[] methods = interceptorClass.getMethods(); + for (Method method : methods) { + String name = method.getName(); + if (name.startsWith("enter")) { + enterData.add(getMethodData(fieldData, method)); + } + else if (name.startsWith("exit")) { + exitData.add(getMethodData(fieldData, method)); + } + else if (name.startsWith("dump")) { + Class[] parameterTypes = method.getParameterTypes(); + // Dump must have no parameters or one PrintStream parameter + if (parameterTypes.length > 1) continue; + if (parameterTypes.length == 1 && parameterTypes[0] != PrintStream.class) { + continue; + } + addDumpTask(interceptor, method); + } + } + + String nameFromAnnotation = annotation.methodName(); + String methodName = nameFromAnnotation.isEmpty() ? field.getName() : nameFromAnnotation; + MethodInstrumenterImpl instrumenter = new MethodInstrumenterImpl( + Pattern.compile(methodName), + Pattern.compile(annotation.erasedSignature()), + annotation.allowMultipleMatches(), + enterData, + exitData); + instrumenters.add(instrumenter); + neverMatchedInstrumenters.add(instrumenter); + } + catch (IllegalAccessException e) { + throw new IllegalArgumentException(e); + } + + } + } + + private List addClassPattern(String classPattern) { + ClassMatcher classMatcher = classPatterns.get(classPattern); + if (classMatcher == null) { + classMatcher = new ClassMatcher(Pattern.compile(classPattern)); + classPatterns.put(classPattern, classMatcher); + neverMatchedClassPatterns.add(classPattern); + } + return classMatcher.instrumenters; + } + + private static FieldData getFieldData(Field field, Class runtimeType) { + return new FieldDataImpl( + Type.getInternalName(field.getDeclaringClass()), + field.getName(), + Type.getDescriptor(field.getType()), + Type.getType(runtimeType)); + } + + private static MethodData getMethodData(FieldData interceptorField, Method method) { + return new MethodDataImpl( + interceptorField, + Type.getInternalName(method.getDeclaringClass()), + method.getName(), + Type.getMethodDescriptor(method), + method.getParameterTypes().length + ); + } + + private void addDumpTask(final Object interceptor, final Method method) { + dumpTasks.add(new DumpAction() { + @Override + public void dump(PrintStream out) { + try { + if (method.getParameterTypes().length == 0) { + method.invoke(interceptor); + } + else { + method.invoke(interceptor, out); + } + } + catch (IllegalAccessException e) { + throw new IllegalStateException(e); + } + catch (InvocationTargetException e) { + throw new IllegalStateException(e); + } + } + }); + } + + public byte[] instrument(String resourceName, byte[] data) { + List applicableInstrumenters = new ArrayList(); + String className = stripClassSuffix(resourceName); + for (Map.Entry classPatternEntry : classPatterns.entrySet()) { + String classPattern = classPatternEntry.getKey(); + ClassMatcher classMatcher = classPatternEntry.getValue(); + if (classMatcher.classPattern.matcher(className).matches()) { + neverMatchedClassPatterns.remove(classPattern); + applicableInstrumenters.addAll(classMatcher.instrumenters); + } + } + + if (applicableInstrumenters.isEmpty()) return data; + + return instrument(data, applicableInstrumenters); + } + + private static String stripClassSuffix(String name) { + String suffix = ".class"; + if (!name.endsWith(suffix)) return name; + return name.substring(0, name.length() - suffix.length()); + } + + private byte[] instrument(byte[] classData, final List instrumenters) { + final ClassReader cr = new ClassReader(classData); + ClassWriter cw = new ClassWriter(cr, ClassWriter.COMPUTE_FRAMES); + cr.accept(new ClassVisitor(ASM4, cw) { + private final Map matchedMethods = new HashMap(); + + @Override + public MethodVisitor visitMethod( + final int access, + final String name, + final String desc, + String signature, + String[] exceptions + ) { + MethodVisitor mv = super.visitMethod(access, name, desc, signature, exceptions); + // Do not instrument synthetic methods + if ((access & (ACC_BRIDGE | ACC_SYNTHETIC)) != 0) return mv; + + List applicableInstrumenters = new ArrayList(); + for (MethodInstrumenter instrumenter : instrumenters) { + if (instrumenter.isApplicable(name, desc)) { + applicableInstrumenters.add(instrumenter); + + checkMultipleMatches(instrumenter, name, desc); + neverMatchedInstrumenters.remove(instrumenter); + } + } + + if (applicableInstrumenters.isEmpty()) return mv; + + InstructionAdapter ia = new InstructionAdapter(mv); + + final List exitData = new ArrayList(); + for (MethodInstrumenter instrumenter : applicableInstrumenters) { + for (MethodData enterData : instrumenter.getEnterData()) { + invokeMethod(access, name, desc, ia, enterData); + } + + exitData.addAll(instrumenter.getExitData()); + } + + if (exitData.isEmpty()) return mv; + + return new MethodVisitor(ASM4, mv) { + + private InstructionAdapter ia = null; + + private InstructionAdapter getInstructionAdapter() { + if (ia == null) { + ia = new InstructionAdapter(this); + } + return ia; + } + + @Override + public void visitInsn(int opcode) { + switch (opcode) { + case RETURN: + case IRETURN: + case LRETURN: + case FRETURN: + case DRETURN: + case ARETURN: + case ATHROW: + for (MethodData methodData : exitData) { + invokeMethod(access, name, desc, getInstructionAdapter(), methodData); + } + break; + } + super.visitInsn(opcode); + } + }; + } + + private void checkMultipleMatches(MethodInstrumenter instrumenter, String name, String desc) { + if (!instrumenter.allowsMultipleMatches()) { + String erasedSignature = name + desc; + String alreadyMatched = matchedMethods.put(instrumenter, erasedSignature); + if (alreadyMatched != null) { + throw new IllegalStateException(instrumenter + " matched two methods in " + cr.getClassName() + ":\n" + + alreadyMatched + "\n" + + erasedSignature); + } + } + } + }, 0); + return cw.toByteArray(); + } + + private static void invokeMethod(int access, String name, String desc, InstructionAdapter ia, MethodData methodData) { + FieldData field = methodData.getOwnerField(); + ia.getstatic(field.getDeclaringClass(), field.getName(), field.getDesc()); + ia.checkcast(field.getRuntimeType()); + + int parameterCount = methodData.getParameterCount(); + if (parameterCount > 0) { + org.jetbrains.asm4.commons.Method method = new org.jetbrains.asm4.commons.Method(name, desc); + Type[] parameterTypes = method.getArgumentTypes(); + int base = (access & ACC_STATIC) != 0 ? 0 : 1; + for (int i = 0; i < parameterCount; i++) { + ia.load(base + i, parameterTypes[i]); + } + } + ia.invokevirtual(methodData.getDeclaringClass(), methodData.getName(), methodData.getDesc()); + } + + public void dump(PrintStream out) { + for (DumpAction task : dumpTasks) { + task.dump(out); + } + + if (!neverMatchedClassPatterns.isEmpty()) { + out.println("Class patterns never matched:"); + for (String classPattern : neverMatchedClassPatterns) { + out.println(" " + classPattern); + neverMatchedInstrumenters.removeAll(classPatterns.get(classPattern).instrumenters); + } + } + + if (!neverMatchedInstrumenters.isEmpty()) { + out.println("Instrumenters never matched: "); + for (MethodInstrumenter instrumenter : neverMatchedInstrumenters) { + out.println(" " + instrumenter); + } + } + } + + private static class ClassMatcher { + private final Pattern classPattern; + private final List instrumenters = new ArrayList(); + + private ClassMatcher(Pattern classPattern) { + this.classPattern = classPattern; + } + } +} diff --git a/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/InterceptionInstrumenterAdaptor.java b/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/InterceptionInstrumenterAdaptor.java new file mode 100644 index 00000000000..87527e242ab --- /dev/null +++ b/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/InterceptionInstrumenterAdaptor.java @@ -0,0 +1,39 @@ +/* + * Copyright 2010-2013 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.jetbrains.jet.preloading.instrumentation; + +import java.io.PrintStream; +import java.util.Collections; + +public abstract class InterceptionInstrumenterAdaptor implements Instrumenter { + + private final InterceptionInstrumenter instrumenter; + + public InterceptionInstrumenterAdaptor() { + this.instrumenter = new InterceptionInstrumenter(Collections.>singletonList(getClass())); + } + + @Override + public byte[] instrument(String resourceName, byte[] data) { + return instrumenter.instrument(resourceName, data); + } + + @Override + public void dump(PrintStream out) { + instrumenter.dump(out); + } +} diff --git a/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/MemberData.java b/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/MemberData.java new file mode 100644 index 00000000000..31b4641776e --- /dev/null +++ b/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/MemberData.java @@ -0,0 +1,23 @@ +/* + * Copyright 2010-2013 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.jetbrains.jet.preloading.instrumentation; + +interface MemberData { + String getDeclaringClass(); + String getName(); + String getDesc(); +} diff --git a/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/MemberDataImpl.java b/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/MemberDataImpl.java new file mode 100644 index 00000000000..f2cc1f00c58 --- /dev/null +++ b/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/MemberDataImpl.java @@ -0,0 +1,45 @@ +/* + * Copyright 2010-2013 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.jetbrains.jet.preloading.instrumentation; + +class MemberDataImpl implements MemberData { + + private final String declaringClass; + private final String name; + private final String desc; + + public MemberDataImpl(String declaringClass, String name, String desc) { + this.declaringClass = declaringClass; + this.name = name; + this.desc = desc; + } + + @Override + public String getDeclaringClass() { + return declaringClass; + } + + @Override + public String getName() { + return name; + } + + @Override + public String getDesc() { + return desc; + } +} diff --git a/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/MethodData.java b/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/MethodData.java new file mode 100644 index 00000000000..fb35f57c9fd --- /dev/null +++ b/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/MethodData.java @@ -0,0 +1,22 @@ +/* + * Copyright 2010-2013 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.jetbrains.jet.preloading.instrumentation; + +interface MethodData extends MemberData { + FieldData getOwnerField(); + int getParameterCount(); +} diff --git a/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/MethodDataImpl.java b/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/MethodDataImpl.java new file mode 100644 index 00000000000..2a3d172e425 --- /dev/null +++ b/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/MethodDataImpl.java @@ -0,0 +1,44 @@ +/* + * Copyright 2010-2013 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.jetbrains.jet.preloading.instrumentation; + +public class MethodDataImpl extends MemberDataImpl implements MethodData { + private final FieldData ownerField; + private final int parameterCount; + + MethodDataImpl( + FieldData ownerField, + String declaringClass, + String name, + String desc, + int parameterCount + ) { + super(declaringClass, name, desc); + this.ownerField = ownerField; + this.parameterCount = parameterCount; + } + + @Override + public FieldData getOwnerField() { + return ownerField; + } + + @Override + public int getParameterCount() { + return parameterCount; + } +} diff --git a/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/MethodInstrumenter.java b/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/MethodInstrumenter.java new file mode 100644 index 00000000000..6310f311100 --- /dev/null +++ b/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/MethodInstrumenter.java @@ -0,0 +1,29 @@ +/* + * Copyright 2010-2013 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.jetbrains.jet.preloading.instrumentation; + +import java.util.List; + +interface MethodInstrumenter { + boolean isApplicable(String name, String desc); + + List getExitData(); + + List getEnterData(); + + boolean allowsMultipleMatches(); +} diff --git a/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/MethodInstrumenterImpl.java b/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/MethodInstrumenterImpl.java new file mode 100644 index 00000000000..9d711d2472a --- /dev/null +++ b/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/MethodInstrumenterImpl.java @@ -0,0 +1,67 @@ +/* + * Copyright 2010-2013 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.jetbrains.jet.preloading.instrumentation; + +import java.util.List; +import java.util.regex.Pattern; + +class MethodInstrumenterImpl implements MethodInstrumenter { + private final Pattern namePattern; + private final Pattern descPattern; + private final boolean allowMultipleMatches; + private final List enterData; + private final List exitData; + + public MethodInstrumenterImpl( + Pattern namePattern, + Pattern descPattern, + boolean allowMultipleMatches, + List enterData, + List exitData + ) { + this.namePattern = namePattern; + this.descPattern = descPattern; + this.allowMultipleMatches = allowMultipleMatches; + this.enterData = enterData; + this.exitData = exitData; + } + + @Override + public boolean allowsMultipleMatches() { + return allowMultipleMatches; + } + + @Override + public boolean isApplicable(String name, String desc) { + return namePattern.matcher(name).matches() && descPattern.matcher(desc).matches(); + } + + @Override + public List getEnterData() { + return enterData; + } + + @Override + public List getExitData() { + return exitData; + } + + @Override + public String toString() { + return namePattern + " " + descPattern + (allowMultipleMatches ? "[multiple]" : ""); + } +} diff --git a/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/MethodInterceptor.java b/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/MethodInterceptor.java new file mode 100644 index 00000000000..9f0790081d3 --- /dev/null +++ b/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/MethodInterceptor.java @@ -0,0 +1,38 @@ +/* + * Copyright 2010-2013 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.jetbrains.jet.preloading.instrumentation; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Target(ElementType.FIELD) +@Retention(RetentionPolicy.RUNTIME) +public @interface MethodInterceptor { + // JVM internal name like java/util/Map$Entry or short name like FooBar + String className(); + + // regexp, if omitted, field name is used + String methodName() default ""; + + // regexp + String erasedSignature() default ""; + + // if this is false, an exception is thrown when more than one method in the same class matches + boolean allowMultipleMatches() default false; +} From 35f2993ec94a690077239126e9e82672feab0d40 Mon Sep 17 00:00:00 2001 From: Andrey Breslav Date: Sun, 12 May 2013 10:44:19 +0200 Subject: [PATCH 007/249] Empty string means '.*' pattern --- .../InterceptionInstrumenter.java | 31 ++++++++++++------- 1 file changed, 19 insertions(+), 12 deletions(-) diff --git a/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/InterceptionInstrumenter.java b/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/InterceptionInstrumenter.java index 39311f59573..52867d92d83 100644 --- a/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/InterceptionInstrumenter.java +++ b/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/InterceptionInstrumenter.java @@ -30,6 +30,7 @@ import java.util.regex.Pattern; import static org.jetbrains.asm4.Opcodes.*; public class InterceptionInstrumenter implements Instrumenter { + private static final Pattern ANYTHING = Pattern.compile(".*"); private final Map classPatterns = new LinkedHashMap(); private final Set neverMatchedClassPatterns = new LinkedHashSet(); @@ -55,8 +56,8 @@ public class InterceptionInstrumenter implements Instrumenter { throw new IllegalArgumentException("Non-static field annotated @MethodInterceptor: " + field); } - Pattern classPattern = Pattern.compile(annotation.className()); - List instrumenters = addClassPattern(classPattern.pattern()); + Pattern classPattern = compilePattern(annotation.className()); + List instrumenters = addClassPattern(classPattern); try { Object interceptor = field.get(null); @@ -93,11 +94,12 @@ public class InterceptionInstrumenter implements Instrumenter { String nameFromAnnotation = annotation.methodName(); String methodName = nameFromAnnotation.isEmpty() ? field.getName() : nameFromAnnotation; MethodInstrumenterImpl instrumenter = new MethodInstrumenterImpl( - Pattern.compile(methodName), - Pattern.compile(annotation.erasedSignature()), - annotation.allowMultipleMatches(), - enterData, - exitData); + compilePattern(methodName), + compilePattern(annotation.erasedSignature()), + annotation.allowMultipleMatches(), + enterData, + exitData + ); instrumenters.add(instrumenter); neverMatchedInstrumenters.add(instrumenter); } @@ -108,12 +110,12 @@ public class InterceptionInstrumenter implements Instrumenter { } } - private List addClassPattern(String classPattern) { - ClassMatcher classMatcher = classPatterns.get(classPattern); + private List addClassPattern(Pattern classPattern) { + ClassMatcher classMatcher = classPatterns.get(classPattern.pattern()); if (classMatcher == null) { - classMatcher = new ClassMatcher(Pattern.compile(classPattern)); - classPatterns.put(classPattern, classMatcher); - neverMatchedClassPatterns.add(classPattern); + classMatcher = new ClassMatcher(classPattern); + classPatterns.put(classPattern.pattern(), classMatcher); + neverMatchedClassPatterns.add(classPattern.pattern()); } return classMatcher.instrumenters; } @@ -308,6 +310,11 @@ public class InterceptionInstrumenter implements Instrumenter { } } + private static Pattern compilePattern(String regex) { + if (regex.isEmpty()) return ANYTHING; + return Pattern.compile(regex); + } + private static class ClassMatcher { private final Pattern classPattern; private final List instrumenters = new ArrayList(); From 6c603839786612a5f153e61d24fd7b1a965d25c6 Mon Sep 17 00:00:00 2001 From: Andrey Breslav Date: Sun, 12 May 2013 10:44:42 +0200 Subject: [PATCH 008/249] Fix entry point instrumentation --- .../InterceptionInstrumenter.java | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/InterceptionInstrumenter.java b/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/InterceptionInstrumenter.java index 52867d92d83..507cb388478 100644 --- a/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/InterceptionInstrumenter.java +++ b/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/InterceptionInstrumenter.java @@ -213,18 +213,14 @@ public class InterceptionInstrumenter implements Instrumenter { if (applicableInstrumenters.isEmpty()) return mv; - InstructionAdapter ia = new InstructionAdapter(mv); - final List exitData = new ArrayList(); + final List enterData = new ArrayList(); for (MethodInstrumenter instrumenter : applicableInstrumenters) { - for (MethodData enterData : instrumenter.getEnterData()) { - invokeMethod(access, name, desc, ia, enterData); - } - + enterData.addAll(instrumenter.getEnterData()); exitData.addAll(instrumenter.getExitData()); } - if (exitData.isEmpty()) return mv; + if (enterData.isEmpty() && exitData.isEmpty()) return mv; return new MethodVisitor(ASM4, mv) { @@ -237,6 +233,14 @@ public class InterceptionInstrumenter implements Instrumenter { return ia; } + @Override + public void visitCode() { + for (MethodData methodData : enterData) { + invokeMethod(access, name, desc, getInstructionAdapter(), methodData); + } + super.visitCode(); + } + @Override public void visitInsn(int opcode) { switch (opcode) { From c960dff16666d81092c5a46a9d481a0862149d7e Mon Sep 17 00:00:00 2001 From: Andrey Breslav Date: Sun, 12 May 2013 10:47:58 +0200 Subject: [PATCH 009/249] Support logging interceptions --- .../instrumentation/InterceptionInstrumenter.java | 5 +++-- .../instrumentation/MethodInstrumenter.java | 2 ++ .../instrumentation/MethodInstrumenterImpl.java | 14 ++++++++++++-- .../instrumentation/MethodInterceptor.java | 3 +++ 4 files changed, 20 insertions(+), 4 deletions(-) diff --git a/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/InterceptionInstrumenter.java b/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/InterceptionInstrumenter.java index 507cb388478..c24a3e7d85b 100644 --- a/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/InterceptionInstrumenter.java +++ b/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/InterceptionInstrumenter.java @@ -98,8 +98,8 @@ public class InterceptionInstrumenter implements Instrumenter { compilePattern(annotation.erasedSignature()), annotation.allowMultipleMatches(), enterData, - exitData - ); + exitData, + annotation.logInterceptions()); instrumenters.add(instrumenter); neverMatchedInstrumenters.add(instrumenter); } @@ -205,6 +205,7 @@ public class InterceptionInstrumenter implements Instrumenter { for (MethodInstrumenter instrumenter : instrumenters) { if (instrumenter.isApplicable(name, desc)) { applicableInstrumenters.add(instrumenter); + instrumenter.reportApplication(cr.getClassName(), name, desc); checkMultipleMatches(instrumenter, name, desc); neverMatchedInstrumenters.remove(instrumenter); diff --git a/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/MethodInstrumenter.java b/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/MethodInstrumenter.java index 6310f311100..c67c39fa8c5 100644 --- a/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/MethodInstrumenter.java +++ b/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/MethodInstrumenter.java @@ -26,4 +26,6 @@ interface MethodInstrumenter { List getEnterData(); boolean allowsMultipleMatches(); + + void reportApplication(String className, String methodName, String methodDesc); } diff --git a/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/MethodInstrumenterImpl.java b/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/MethodInstrumenterImpl.java index 9d711d2472a..4ac32bb29fc 100644 --- a/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/MethodInstrumenterImpl.java +++ b/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/MethodInstrumenterImpl.java @@ -25,19 +25,22 @@ class MethodInstrumenterImpl implements MethodInstrumenter { private final boolean allowMultipleMatches; private final List enterData; private final List exitData; + private final boolean logApplications; public MethodInstrumenterImpl( Pattern namePattern, Pattern descPattern, boolean allowMultipleMatches, List enterData, - List exitData + List exitData, + boolean logApplications ) { this.namePattern = namePattern; this.descPattern = descPattern; this.allowMultipleMatches = allowMultipleMatches; this.enterData = enterData; this.exitData = exitData; + this.logApplications = logApplications; } @Override @@ -45,6 +48,13 @@ class MethodInstrumenterImpl implements MethodInstrumenter { return allowMultipleMatches; } + @Override + public void reportApplication(String className, String methodName, String methodDesc) { + if (logApplications) { + System.out.println(toString() + " applied to " + className + ":" + methodName + methodDesc); + } + } + @Override public boolean isApplicable(String name, String desc) { return namePattern.matcher(name).matches() && descPattern.matcher(desc).matches(); @@ -62,6 +72,6 @@ class MethodInstrumenterImpl implements MethodInstrumenter { @Override public String toString() { - return namePattern + " " + descPattern + (allowMultipleMatches ? "[multiple]" : ""); + return namePattern + " " + descPattern + (allowMultipleMatches ? " [multiple]" : ""); } } diff --git a/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/MethodInterceptor.java b/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/MethodInterceptor.java index 9f0790081d3..0740b17c54e 100644 --- a/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/MethodInterceptor.java +++ b/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/MethodInterceptor.java @@ -35,4 +35,7 @@ public @interface MethodInterceptor { // if this is false, an exception is thrown when more than one method in the same class matches boolean allowMultipleMatches() default false; + + // if true, every method instrumented with this interceptor will be logged to stdout + boolean logInterceptions() default false; } From 113864fc8848aac9fdfb6b43e73c96e416c00741 Mon Sep 17 00:00:00 2001 From: Andrey Breslav Date: Sun, 12 May 2013 10:51:28 +0200 Subject: [PATCH 010/249] Proper debug names for instrumenters --- .../instrumentation/InterceptionInstrumenter.java | 1 + .../preloading/instrumentation/MethodInstrumenterImpl.java | 6 ++++-- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/InterceptionInstrumenter.java b/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/InterceptionInstrumenter.java index c24a3e7d85b..fe7112c4b2b 100644 --- a/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/InterceptionInstrumenter.java +++ b/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/InterceptionInstrumenter.java @@ -94,6 +94,7 @@ public class InterceptionInstrumenter implements Instrumenter { String nameFromAnnotation = annotation.methodName(); String methodName = nameFromAnnotation.isEmpty() ? field.getName() : nameFromAnnotation; MethodInstrumenterImpl instrumenter = new MethodInstrumenterImpl( + field.getDeclaringClass().getSimpleName() + "." + field.getName(), compilePattern(methodName), compilePattern(annotation.erasedSignature()), annotation.allowMultipleMatches(), diff --git a/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/MethodInstrumenterImpl.java b/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/MethodInstrumenterImpl.java index 4ac32bb29fc..c0ded7a4b61 100644 --- a/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/MethodInstrumenterImpl.java +++ b/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/MethodInstrumenterImpl.java @@ -20,6 +20,7 @@ import java.util.List; import java.util.regex.Pattern; class MethodInstrumenterImpl implements MethodInstrumenter { + private final String debugName; private final Pattern namePattern; private final Pattern descPattern; private final boolean allowMultipleMatches; @@ -28,13 +29,14 @@ class MethodInstrumenterImpl implements MethodInstrumenter { private final boolean logApplications; public MethodInstrumenterImpl( - Pattern namePattern, + String debugName, Pattern namePattern, Pattern descPattern, boolean allowMultipleMatches, List enterData, List exitData, boolean logApplications ) { + this.debugName = debugName; this.namePattern = namePattern; this.descPattern = descPattern; this.allowMultipleMatches = allowMultipleMatches; @@ -72,6 +74,6 @@ class MethodInstrumenterImpl implements MethodInstrumenter { @Override public String toString() { - return namePattern + " " + descPattern + (allowMultipleMatches ? " [multiple]" : ""); + return debugName + "[" + namePattern + " " + descPattern + (allowMultipleMatches ? " multiple" : "") + "]"; } } From 3440b8586774c0d4bd3555664c62f1d13fed1f4d Mon Sep 17 00:00:00 2001 From: Andrey Breslav Date: Sun, 12 May 2013 10:52:44 +0200 Subject: [PATCH 011/249] Remove unneeded interface --- .../preloading/instrumentation/InterceptionInstrumenter.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/InterceptionInstrumenter.java b/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/InterceptionInstrumenter.java index fe7112c4b2b..8de43ea87e6 100644 --- a/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/InterceptionInstrumenter.java +++ b/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/InterceptionInstrumenter.java @@ -29,7 +29,7 @@ import java.util.regex.Pattern; import static org.jetbrains.asm4.Opcodes.*; -public class InterceptionInstrumenter implements Instrumenter { +public class InterceptionInstrumenter { private static final Pattern ANYTHING = Pattern.compile(".*"); private final Map classPatterns = new LinkedHashMap(); From 8d22c038d532a1e14bef71c2b38350ac0039a7c8 Mon Sep 17 00:00:00 2001 From: Andrey Breslav Date: Sun, 12 May 2013 11:06:30 +0200 Subject: [PATCH 012/249] Include interceptor data into console output --- .../instrumentation/InterceptionInstrumenter.java | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/InterceptionInstrumenter.java b/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/InterceptionInstrumenter.java index 8de43ea87e6..33474822fbf 100644 --- a/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/InterceptionInstrumenter.java +++ b/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/InterceptionInstrumenter.java @@ -71,8 +71,8 @@ public class InterceptionInstrumenter { List enterData = new ArrayList(); List exitData = new ArrayList(); - Method[] methods = interceptorClass.getMethods(); - for (Method method : methods) { + List dumpMethods = new ArrayList(); + for (Method method : interceptorClass.getMethods()) { String name = method.getName(); if (name.startsWith("enter")) { enterData.add(getMethodData(fieldData, method)); @@ -87,7 +87,7 @@ public class InterceptionInstrumenter { if (parameterTypes.length == 1 && parameterTypes[0] != PrintStream.class) { continue; } - addDumpTask(interceptor, method); + dumpMethods.add(method); } } @@ -101,6 +101,11 @@ public class InterceptionInstrumenter { enterData, exitData, annotation.logInterceptions()); + + for (Method dumpMethod : dumpMethods) { + addDumpTask(interceptor, dumpMethod, instrumenter); + } + instrumenters.add(instrumenter); neverMatchedInstrumenters.add(instrumenter); } @@ -139,10 +144,11 @@ public class InterceptionInstrumenter { ); } - private void addDumpTask(final Object interceptor, final Method method) { + private void addDumpTask(final Object interceptor, final Method method, final MethodInstrumenter instrumenter) { dumpTasks.add(new DumpAction() { @Override public void dump(PrintStream out) { + out.println("<<< " + instrumenter + ": " + interceptor.getClass().getCanonicalName() + " says:"); try { if (method.getParameterTypes().length == 0) { method.invoke(interceptor); @@ -157,6 +163,7 @@ public class InterceptionInstrumenter { catch (InvocationTargetException e) { throw new IllegalStateException(e); } + out.println(">>>"); } }); } From 17ddfb6f592236f225b9250ec5bde3701ba733a0 Mon Sep 17 00:00:00 2001 From: Andrey Breslav Date: Sun, 12 May 2013 11:09:41 +0200 Subject: [PATCH 013/249] Include class patterns into interceptor's toString --- .../instrumentation/InterceptionInstrumenter.java | 1 + .../preloading/instrumentation/MethodInstrumenterImpl.java | 7 +++++-- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/InterceptionInstrumenter.java b/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/InterceptionInstrumenter.java index 33474822fbf..3184f6015e0 100644 --- a/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/InterceptionInstrumenter.java +++ b/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/InterceptionInstrumenter.java @@ -95,6 +95,7 @@ public class InterceptionInstrumenter { String methodName = nameFromAnnotation.isEmpty() ? field.getName() : nameFromAnnotation; MethodInstrumenterImpl instrumenter = new MethodInstrumenterImpl( field.getDeclaringClass().getSimpleName() + "." + field.getName(), + classPattern, compilePattern(methodName), compilePattern(annotation.erasedSignature()), annotation.allowMultipleMatches(), diff --git a/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/MethodInstrumenterImpl.java b/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/MethodInstrumenterImpl.java index c0ded7a4b61..7f3ddb51093 100644 --- a/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/MethodInstrumenterImpl.java +++ b/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/MethodInstrumenterImpl.java @@ -21,6 +21,7 @@ import java.util.regex.Pattern; class MethodInstrumenterImpl implements MethodInstrumenter { private final String debugName; + private final Pattern classPattern; private final Pattern namePattern; private final Pattern descPattern; private final boolean allowMultipleMatches; @@ -29,7 +30,8 @@ class MethodInstrumenterImpl implements MethodInstrumenter { private final boolean logApplications; public MethodInstrumenterImpl( - String debugName, Pattern namePattern, + String debugName, + Pattern classPattern, Pattern namePattern, Pattern descPattern, boolean allowMultipleMatches, List enterData, @@ -37,6 +39,7 @@ class MethodInstrumenterImpl implements MethodInstrumenter { boolean logApplications ) { this.debugName = debugName; + this.classPattern = classPattern; this.namePattern = namePattern; this.descPattern = descPattern; this.allowMultipleMatches = allowMultipleMatches; @@ -74,6 +77,6 @@ class MethodInstrumenterImpl implements MethodInstrumenter { @Override public String toString() { - return debugName + "[" + namePattern + " " + descPattern + (allowMultipleMatches ? " multiple" : "") + "]"; + return debugName + "[" + classPattern + ":" + namePattern + " " + descPattern + (allowMultipleMatches ? " multiple" : "") + "]"; } } From 5fd193d88de3f5f3d5bd5facced72a23d959f43c Mon Sep 17 00:00:00 2001 From: Andrey Breslav Date: Sun, 12 May 2013 12:00:58 +0200 Subject: [PATCH 014/249] Account for maximum stack size Just using ClassWriter.COMPUTE_FRAMES does not work: it end up with ClassNotFound from somewhere withing ASM --- .../instrumentation/InterceptionInstrumenter.java | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/InterceptionInstrumenter.java b/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/InterceptionInstrumenter.java index 3184f6015e0..656b9efe5d1 100644 --- a/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/InterceptionInstrumenter.java +++ b/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/InterceptionInstrumenter.java @@ -194,7 +194,7 @@ public class InterceptionInstrumenter { private byte[] instrument(byte[] classData, final List instrumenters) { final ClassReader cr = new ClassReader(classData); - ClassWriter cw = new ClassWriter(cr, ClassWriter.COMPUTE_FRAMES); + ClassWriter cw = new ClassWriter(cr, 0); cr.accept(new ClassVisitor(ASM4, cw) { private final Map matchedMethods = new HashMap(); @@ -243,6 +243,12 @@ public class InterceptionInstrumenter { return ia; } + @Override + public void visitMaxs(int maxStack, int maxLocals) { + int sizes = Type.getArgumentsAndReturnSizes(desc); + super.visitMaxs(Math.max(maxStack, sizes + 1), maxLocals); + } + @Override public void visitCode() { for (MethodData methodData : enterData) { From 8dfb39ec19683ae99c787d33ea8644d71fd7c771 Mon Sep 17 00:00:00 2001 From: Andrey Breslav Date: Sun, 12 May 2013 14:50:00 +0200 Subject: [PATCH 015/249] Allow to dump byte codes of instrumented methods --- .../InterceptionInstrumenter.java | 24 +++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/InterceptionInstrumenter.java b/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/InterceptionInstrumenter.java index 656b9efe5d1..fd6e8acf178 100644 --- a/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/InterceptionInstrumenter.java +++ b/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/InterceptionInstrumenter.java @@ -18,6 +18,8 @@ package org.jetbrains.jet.preloading.instrumentation; import org.jetbrains.asm4.*; import org.jetbrains.asm4.commons.InstructionAdapter; +import org.jetbrains.asm4.util.Textifier; +import org.jetbrains.asm4.util.TraceMethodVisitor; import java.io.PrintStream; import java.lang.reflect.Field; @@ -31,6 +33,9 @@ import static org.jetbrains.asm4.Opcodes.*; public class InterceptionInstrumenter { private static final Pattern ANYTHING = Pattern.compile(".*"); + + private final boolean dumpInstrumentedMethods = false; + private final Map classPatterns = new LinkedHashMap(); private final Set neverMatchedClassPatterns = new LinkedHashSet(); @@ -232,6 +237,10 @@ public class InterceptionInstrumenter { if (enterData.isEmpty() && exitData.isEmpty()) return mv; + if (dumpInstrumentedMethods) { + mv = getDumpingVisitorWrapper(mv, name, desc); + } + return new MethodVisitor(ASM4, mv) { private InstructionAdapter ia = null; @@ -288,6 +297,21 @@ public class InterceptionInstrumenter { } } } + + private TraceMethodVisitor getDumpingVisitorWrapper(MethodVisitor mv, final String name, final String desc) { + return new TraceMethodVisitor(mv, new Textifier() { + @Override + public void visitMethodEnd() { + System.out.println(cr.getClassName() + ":" + name + desc); + for (Object line : getText()) { + System.out.print(line); + } + System.out.println(); + System.out.println(); + super.visitMethodEnd(); + } + }); + } }, 0); return cw.toByteArray(); } From d99ea2a783461b2499a9eeab03a06a0a497006b5 Mon Sep 17 00:00:00 2001 From: Andrey Breslav Date: Sun, 12 May 2013 14:51:22 +0200 Subject: [PATCH 016/249] Only instrument .class files + Report exceptions thrown by the instrumenter with the info of the class name --- .../InterceptionInstrumenter.java | 36 ++++++++++++------- 1 file changed, 23 insertions(+), 13 deletions(-) diff --git a/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/InterceptionInstrumenter.java b/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/InterceptionInstrumenter.java index fd6e8acf178..3224ab4c8ac 100644 --- a/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/InterceptionInstrumenter.java +++ b/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/InterceptionInstrumenter.java @@ -175,25 +175,35 @@ public class InterceptionInstrumenter { } public byte[] instrument(String resourceName, byte[] data) { - List applicableInstrumenters = new ArrayList(); - String className = stripClassSuffix(resourceName); - for (Map.Entry classPatternEntry : classPatterns.entrySet()) { - String classPattern = classPatternEntry.getKey(); - ClassMatcher classMatcher = classPatternEntry.getValue(); - if (classMatcher.classPattern.matcher(className).matches()) { - neverMatchedClassPatterns.remove(classPattern); - applicableInstrumenters.addAll(classMatcher.instrumenters); + try { + String className = stripClassSuffix(resourceName); + if (className == null) { + // Not a .class file + return data; } + + List applicableInstrumenters = new ArrayList(); + for (Map.Entry classPatternEntry : classPatterns.entrySet()) { + String classPattern = classPatternEntry.getKey(); + ClassMatcher classMatcher = classPatternEntry.getValue(); + if (classMatcher.classPattern.matcher(className).matches()) { + neverMatchedClassPatterns.remove(classPattern); + applicableInstrumenters.addAll(classMatcher.instrumenters); + } + } + + if (applicableInstrumenters.isEmpty()) return data; + + return instrument(data, applicableInstrumenters); + } + catch (Throwable e) { + throw new IllegalStateException("Exception while instrumenting " + resourceName, e); } - - if (applicableInstrumenters.isEmpty()) return data; - - return instrument(data, applicableInstrumenters); } private static String stripClassSuffix(String name) { String suffix = ".class"; - if (!name.endsWith(suffix)) return name; + if (!name.endsWith(suffix)) return null; return name.substring(0, name.length() - suffix.length()); } From 3cd1cf0807e1d03821bf1c6b95ab6d87779aabec Mon Sep 17 00:00:00 2001 From: Andrey Breslav Date: Sun, 12 May 2013 14:52:32 +0200 Subject: [PATCH 017/249] Support @This parameters --- .../InterceptionInstrumenter.java | 61 ++++++++-- .../instrumentation/MethodData.java | 3 + .../instrumentation/MethodDataImpl.java | 10 +- .../MethodVisitorWithUniversalHandler.java | 114 ++++++++++++++++++ .../jet/preloading/instrumentation/This.java | 27 +++++ 5 files changed, 202 insertions(+), 13 deletions(-) create mode 100644 compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/MethodVisitorWithUniversalHandler.java create mode 100644 compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/This.java diff --git a/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/InterceptionInstrumenter.java b/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/InterceptionInstrumenter.java index 3224ab4c8ac..7d4a04a68ea 100644 --- a/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/InterceptionInstrumenter.java +++ b/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/InterceptionInstrumenter.java @@ -22,6 +22,7 @@ import org.jetbrains.asm4.util.Textifier; import org.jetbrains.asm4.util.TraceMethodVisitor; import java.io.PrintStream; +import java.lang.annotation.Annotation; import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; @@ -33,6 +34,7 @@ import static org.jetbrains.asm4.Opcodes.*; public class InterceptionInstrumenter { private static final Pattern ANYTHING = Pattern.compile(".*"); + private static final Type OBJECT_TYPE = Type.getType(Object.class); private final boolean dumpInstrumentedMethods = false; @@ -141,13 +143,25 @@ public class InterceptionInstrumenter { } private static MethodData getMethodData(FieldData interceptorField, Method method) { + Annotation[][] parameterAnnotations = method.getParameterAnnotations(); + int thisParameterIndex = -1; + for (int i = 0; i < parameterAnnotations.length; i++) { + for (Annotation annotation : parameterAnnotations[i]) { + if (annotation instanceof This) { + if (thisParameterIndex > -1) { + throw new IllegalArgumentException("Multiple @This parameters in " + method); + } + thisParameterIndex = i; + } + } + } return new MethodDataImpl( interceptorField, Type.getInternalName(method.getDeclaringClass()), method.getName(), Type.getMethodDescriptor(method), - method.getParameterTypes().length - ); + method.getParameterTypes().length, + thisParameterIndex); } private void addDumpTask(final Object interceptor, final Method method, final MethodInstrumenter instrumenter) { @@ -251,9 +265,10 @@ public class InterceptionInstrumenter { mv = getDumpingVisitorWrapper(mv, name, desc); } - return new MethodVisitor(ASM4, mv) { + return new MethodVisitorWithUniversalHandler(ASM4, mv) { private InstructionAdapter ia = null; + private boolean enterDataWritten = false; private InstructionAdapter getInstructionAdapter() { if (ia == null) { @@ -269,15 +284,22 @@ public class InterceptionInstrumenter { } @Override - public void visitCode() { + protected boolean visitAnyInsn(int opcode) { + writeEnterData(); + return true; + } + + private void writeEnterData() { + if (enterDataWritten) return; + enterDataWritten = true; for (MethodData methodData : enterData) { - invokeMethod(access, name, desc, getInstructionAdapter(), methodData); + invokeMethod(access, desc, getInstructionAdapter(), methodData); } - super.visitCode(); } @Override public void visitInsn(int opcode) { + writeEnterData(); switch (opcode) { case RETURN: case IRETURN: @@ -287,7 +309,7 @@ public class InterceptionInstrumenter { case ARETURN: case ATHROW: for (MethodData methodData : exitData) { - invokeMethod(access, name, desc, getInstructionAdapter(), methodData); + invokeMethod(access, desc, getInstructionAdapter(), methodData); } break; } @@ -326,18 +348,33 @@ public class InterceptionInstrumenter { return cw.toByteArray(); } - private static void invokeMethod(int access, String name, String desc, InstructionAdapter ia, MethodData methodData) { + private static void invokeMethod(int access, String instrumentedMethodDesc, InstructionAdapter ia, MethodData methodData) { FieldData field = methodData.getOwnerField(); ia.getstatic(field.getDeclaringClass(), field.getName(), field.getDesc()); ia.checkcast(field.getRuntimeType()); int parameterCount = methodData.getParameterCount(); if (parameterCount > 0) { - org.jetbrains.asm4.commons.Method method = new org.jetbrains.asm4.commons.Method(name, desc); - Type[] parameterTypes = method.getArgumentTypes(); - int base = (access & ACC_STATIC) != 0 ? 0 : 1; + Type[] parameterTypes = Type.getArgumentTypes(instrumentedMethodDesc); + boolean isStatic = (access & ACC_STATIC) != 0; + int base = isStatic ? 0 : 1; + int parametersUsed = 0; for (int i = 0; i < parameterCount; i++) { - ia.load(base + i, parameterTypes[i]); + if (methodData.getThisParameterIndex() == i) { + if (isStatic) { + // static method, 'this' is null + ia.aconst(null); + } + else { + // load 'this' + ia.load(0, OBJECT_TYPE); + } + } + else { + ia.load(base + parametersUsed, parameterTypes[parametersUsed]); + parametersUsed++; + } + } } ia.invokevirtual(methodData.getDeclaringClass(), methodData.getName(), methodData.getDesc()); diff --git a/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/MethodData.java b/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/MethodData.java index fb35f57c9fd..8340bcb05ff 100644 --- a/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/MethodData.java +++ b/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/MethodData.java @@ -19,4 +19,7 @@ package org.jetbrains.jet.preloading.instrumentation; interface MethodData extends MemberData { FieldData getOwnerField(); int getParameterCount(); + + // -1 for no @This parameter + int getThisParameterIndex(); } diff --git a/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/MethodDataImpl.java b/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/MethodDataImpl.java index 2a3d172e425..5b59c0f2f91 100644 --- a/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/MethodDataImpl.java +++ b/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/MethodDataImpl.java @@ -19,17 +19,20 @@ package org.jetbrains.jet.preloading.instrumentation; public class MethodDataImpl extends MemberDataImpl implements MethodData { private final FieldData ownerField; private final int parameterCount; + private final int thisParameterIndex; MethodDataImpl( FieldData ownerField, String declaringClass, String name, String desc, - int parameterCount + int parameterCount, + int thisParameterIndex ) { super(declaringClass, name, desc); this.ownerField = ownerField; this.parameterCount = parameterCount; + this.thisParameterIndex = thisParameterIndex; } @Override @@ -41,4 +44,9 @@ public class MethodDataImpl extends MemberDataImpl implements MethodData { public int getParameterCount() { return parameterCount; } + + @Override + public int getThisParameterIndex() { + return thisParameterIndex; + } } diff --git a/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/MethodVisitorWithUniversalHandler.java b/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/MethodVisitorWithUniversalHandler.java new file mode 100644 index 00000000000..78448ad7f39 --- /dev/null +++ b/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/MethodVisitorWithUniversalHandler.java @@ -0,0 +1,114 @@ +/* + * Copyright 2010-2013 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.jetbrains.jet.preloading.instrumentation; + +import org.jetbrains.asm4.Handle; +import org.jetbrains.asm4.Label; +import org.jetbrains.asm4.MethodVisitor; +import org.jetbrains.asm4.Opcodes; + +public class MethodVisitorWithUniversalHandler extends MethodVisitor { + public MethodVisitorWithUniversalHandler(int api) { + super(api); + } + + public MethodVisitorWithUniversalHandler(int api, MethodVisitor mv) { + super(api, mv); + } + + protected boolean visitAnyInsn(int opcode) { + return true; + } + + @Override + public void visitInsn(int opcode) { + if (!visitAnyInsn(opcode)) return; + super.visitInsn(opcode); + } + + @Override + public void visitIntInsn(int opcode, int operand) { + if (!visitAnyInsn(opcode)) return; + super.visitIntInsn(opcode, operand); + } + + @Override + public void visitVarInsn(int opcode, int var) { + if (!visitAnyInsn(opcode)) return; + super.visitVarInsn(opcode, var); + } + + @Override + public void visitTypeInsn(int opcode, String type) { + if (!visitAnyInsn(opcode)) return; + super.visitTypeInsn(opcode, type); + } + + @Override + public void visitFieldInsn(int opcode, String owner, String name, String desc) { + if (!visitAnyInsn(opcode)) return; + super.visitFieldInsn(opcode, owner, name, desc); + } + + @Override + public void visitMethodInsn(int opcode, String owner, String name, String desc) { + if (!visitAnyInsn(opcode)) return; + super.visitMethodInsn(opcode, owner, name, desc); + } + + @Override + public void visitInvokeDynamicInsn(String name, String desc, Handle bsm, Object... bsmArgs) { + if (!visitAnyInsn(Opcodes.INVOKEDYNAMIC)) return; + super.visitInvokeDynamicInsn(name, desc, bsm, bsmArgs); + } + + @Override + public void visitJumpInsn(int opcode, Label label) { + if (!visitAnyInsn(opcode)) return; + super.visitJumpInsn(opcode, label); + } + + @Override + public void visitLdcInsn(Object cst) { + if (!visitAnyInsn(Opcodes.LDC)) return; + super.visitLdcInsn(cst); + } + + @Override + public void visitIincInsn(int var, int increment) { + if (!visitAnyInsn(Opcodes.IINC)) return; + super.visitIincInsn(var, increment); + } + + @Override + public void visitTableSwitchInsn(int min, int max, Label dflt, Label... labels) { + if (!visitAnyInsn(Opcodes.TABLESWITCH)) return; + super.visitTableSwitchInsn(min, max, dflt, labels); + } + + @Override + public void visitLookupSwitchInsn(Label dflt, int[] keys, Label[] labels) { + if (!visitAnyInsn(Opcodes.LOOKUPSWITCH)) return; + super.visitLookupSwitchInsn(dflt, keys, labels); + } + + @Override + public void visitMultiANewArrayInsn(String desc, int dims) { + if (!visitAnyInsn(Opcodes.MULTIANEWARRAY)) return; + super.visitMultiANewArrayInsn(desc, dims); + } +} diff --git a/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/This.java b/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/This.java new file mode 100644 index 00000000000..67f67c5585d --- /dev/null +++ b/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/This.java @@ -0,0 +1,27 @@ +/* + * Copyright 2010-2013 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.jetbrains.jet.preloading.instrumentation; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Target(ElementType.PARAMETER) +@Retention(RetentionPolicy.RUNTIME) +public @interface This { +} From b748315304f29dc05a996b024e858e0ff1f73744 Mon Sep 17 00:00:00 2001 From: Andrey Breslav Date: Sun, 12 May 2013 14:59:27 +0200 Subject: [PATCH 018/249] Support @MethodName and @MethodDesc --- .../InterceptionInstrumenter.java | 33 ++++++++++++++++--- .../instrumentation/MethodData.java | 6 ++++ .../instrumentation/MethodDataImpl.java | 18 +++++++++- .../instrumentation/MethodDesc.java | 27 +++++++++++++++ .../instrumentation/MethodName.java | 27 +++++++++++++++ 5 files changed, 105 insertions(+), 6 deletions(-) create mode 100644 compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/MethodDesc.java create mode 100644 compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/MethodName.java diff --git a/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/InterceptionInstrumenter.java b/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/InterceptionInstrumenter.java index 7d4a04a68ea..a539293fbe4 100644 --- a/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/InterceptionInstrumenter.java +++ b/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/InterceptionInstrumenter.java @@ -145,6 +145,8 @@ public class InterceptionInstrumenter { private static MethodData getMethodData(FieldData interceptorField, Method method) { Annotation[][] parameterAnnotations = method.getParameterAnnotations(); int thisParameterIndex = -1; + int methodNameParameterIndex = -1; + int methodDescParameterIndex = -1; for (int i = 0; i < parameterAnnotations.length; i++) { for (Annotation annotation : parameterAnnotations[i]) { if (annotation instanceof This) { @@ -153,6 +155,18 @@ public class InterceptionInstrumenter { } thisParameterIndex = i; } + else if (annotation instanceof MethodName) { + if (methodNameParameterIndex > -1) { + throw new IllegalArgumentException("Multiple @MethodName parameters in " + method); + } + methodNameParameterIndex = i; + } + else if (annotation instanceof MethodDesc) { + if (methodDescParameterIndex > -1) { + throw new IllegalArgumentException("Multiple @MethodDesc parameters in " + method); + } + methodDescParameterIndex = i; + } } } return new MethodDataImpl( @@ -161,7 +175,10 @@ public class InterceptionInstrumenter { method.getName(), Type.getMethodDescriptor(method), method.getParameterTypes().length, - thisParameterIndex); + thisParameterIndex, + methodNameParameterIndex, + methodDescParameterIndex + ); } private void addDumpTask(final Object interceptor, final Method method, final MethodInstrumenter instrumenter) { @@ -293,7 +310,7 @@ public class InterceptionInstrumenter { if (enterDataWritten) return; enterDataWritten = true; for (MethodData methodData : enterData) { - invokeMethod(access, desc, getInstructionAdapter(), methodData); + invokeMethod(access, name, desc, getInstructionAdapter(), methodData); } } @@ -309,7 +326,7 @@ public class InterceptionInstrumenter { case ARETURN: case ATHROW: for (MethodData methodData : exitData) { - invokeMethod(access, desc, getInstructionAdapter(), methodData); + invokeMethod(access, name, desc, getInstructionAdapter(), methodData); } break; } @@ -348,7 +365,7 @@ public class InterceptionInstrumenter { return cw.toByteArray(); } - private static void invokeMethod(int access, String instrumentedMethodDesc, InstructionAdapter ia, MethodData methodData) { + private static void invokeMethod(int access, String instrumentedMethodName, String instrumentedMethodDesc, InstructionAdapter ia, MethodData methodData) { FieldData field = methodData.getOwnerField(); ia.getstatic(field.getDeclaringClass(), field.getName(), field.getDesc()); ia.checkcast(field.getRuntimeType()); @@ -360,7 +377,7 @@ public class InterceptionInstrumenter { int base = isStatic ? 0 : 1; int parametersUsed = 0; for (int i = 0; i < parameterCount; i++) { - if (methodData.getThisParameterIndex() == i) { + if (i == methodData.getThisParameterIndex()) { if (isStatic) { // static method, 'this' is null ia.aconst(null); @@ -370,6 +387,12 @@ public class InterceptionInstrumenter { ia.load(0, OBJECT_TYPE); } } + else if (i == methodData.getMethodNameParameterIndex()) { + ia.aconst(instrumentedMethodName); + } + else if (i == methodData.getMethodDescParameterIndex()) { + ia.aconst(instrumentedMethodDesc); + } else { ia.load(base + parametersUsed, parameterTypes[parametersUsed]); parametersUsed++; diff --git a/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/MethodData.java b/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/MethodData.java index 8340bcb05ff..1d7f266b0ad 100644 --- a/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/MethodData.java +++ b/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/MethodData.java @@ -22,4 +22,10 @@ interface MethodData extends MemberData { // -1 for no @This parameter int getThisParameterIndex(); + + // -1 for no @MethodName + int getMethodNameParameterIndex(); + + // -1 for no @MethodDesc + int getMethodDescParameterIndex(); } diff --git a/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/MethodDataImpl.java b/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/MethodDataImpl.java index 5b59c0f2f91..fa2b385441e 100644 --- a/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/MethodDataImpl.java +++ b/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/MethodDataImpl.java @@ -20,6 +20,8 @@ public class MethodDataImpl extends MemberDataImpl implements MethodData { private final FieldData ownerField; private final int parameterCount; private final int thisParameterIndex; + private final int methodNameParameterIndex; + private final int methodDescParameterIndex; MethodDataImpl( FieldData ownerField, @@ -27,12 +29,16 @@ public class MethodDataImpl extends MemberDataImpl implements MethodData { String name, String desc, int parameterCount, - int thisParameterIndex + int thisParameterIndex, + int methodNameParameterIndex, + int methodDescParameterIndex ) { super(declaringClass, name, desc); this.ownerField = ownerField; this.parameterCount = parameterCount; this.thisParameterIndex = thisParameterIndex; + this.methodNameParameterIndex = methodNameParameterIndex; + this.methodDescParameterIndex = methodDescParameterIndex; } @Override @@ -49,4 +55,14 @@ public class MethodDataImpl extends MemberDataImpl implements MethodData { public int getThisParameterIndex() { return thisParameterIndex; } + + @Override + public int getMethodNameParameterIndex() { + return methodNameParameterIndex; + } + + @Override + public int getMethodDescParameterIndex() { + return methodDescParameterIndex; + } } diff --git a/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/MethodDesc.java b/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/MethodDesc.java new file mode 100644 index 00000000000..b0d7ba77786 --- /dev/null +++ b/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/MethodDesc.java @@ -0,0 +1,27 @@ +/* + * Copyright 2010-2013 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.jetbrains.jet.preloading.instrumentation; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Target(ElementType.PARAMETER) +@Retention(RetentionPolicy.RUNTIME) +public @interface MethodDesc { +} diff --git a/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/MethodName.java b/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/MethodName.java new file mode 100644 index 00000000000..38c4bdbbca2 --- /dev/null +++ b/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/MethodName.java @@ -0,0 +1,27 @@ +/* + * Copyright 2010-2013 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.jetbrains.jet.preloading.instrumentation; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Target(ElementType.PARAMETER) +@Retention(RetentionPolicy.RUNTIME) +public @interface MethodName { +} From cae2a5e96f714031eab4aca301df4c3d0faa09ce Mon Sep 17 00:00:00 2001 From: Andrey Breslav Date: Sun, 12 May 2013 15:03:58 +0200 Subject: [PATCH 019/249] Computing stack depth depending on the actual number of parameters of methods being called --- .../InterceptionInstrumenter.java | 22 +++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/InterceptionInstrumenter.java b/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/InterceptionInstrumenter.java index a539293fbe4..700f2db3046 100644 --- a/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/InterceptionInstrumenter.java +++ b/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/InterceptionInstrumenter.java @@ -271,9 +271,22 @@ public class InterceptionInstrumenter { final List exitData = new ArrayList(); final List enterData = new ArrayList(); + + int maxParamCount = 0; for (MethodInstrumenter instrumenter : applicableInstrumenters) { - enterData.addAll(instrumenter.getEnterData()); - exitData.addAll(instrumenter.getExitData()); + for (MethodData methodData : instrumenter.getEnterData()) { + if (maxParamCount < methodData.getParameterCount()) { + maxParamCount = methodData.getParameterCount(); + } + enterData.add(methodData); + } + + for (MethodData methodData : instrumenter.getExitData()) { + if (maxParamCount < methodData.getParameterCount()) { + maxParamCount = methodData.getParameterCount(); + } + exitData.add(methodData); + } } if (enterData.isEmpty() && exitData.isEmpty()) return mv; @@ -282,6 +295,7 @@ public class InterceptionInstrumenter { mv = getDumpingVisitorWrapper(mv, name, desc); } + final int finalMaxParamCount = maxParamCount; return new MethodVisitorWithUniversalHandler(ASM4, mv) { private InstructionAdapter ia = null; @@ -296,8 +310,8 @@ public class InterceptionInstrumenter { @Override public void visitMaxs(int maxStack, int maxLocals) { - int sizes = Type.getArgumentsAndReturnSizes(desc); - super.visitMaxs(Math.max(maxStack, sizes + 1), maxLocals); + int maxInstrumentedStack = finalMaxParamCount + 2; // +1 for receiver +1 for returned value on the stack + super.visitMaxs(Math.max(maxStack, maxInstrumentedStack), maxLocals); } @Override From 098cf477f4572547358586c65a09127e5a6fa2e8 Mon Sep 17 00:00:00 2001 From: Andrey Breslav Date: Sun, 12 May 2013 16:05:47 +0200 Subject: [PATCH 020/249] Fix parameter indexing for longs and doubles --- .../instrumentation/InterceptionInstrumenter.java | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/InterceptionInstrumenter.java b/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/InterceptionInstrumenter.java index 700f2db3046..b35bd2ccea6 100644 --- a/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/InterceptionInstrumenter.java +++ b/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/InterceptionInstrumenter.java @@ -389,7 +389,7 @@ public class InterceptionInstrumenter { Type[] parameterTypes = Type.getArgumentTypes(instrumentedMethodDesc); boolean isStatic = (access & ACC_STATIC) != 0; int base = isStatic ? 0 : 1; - int parametersUsed = 0; + int parameterOffset = 0; for (int i = 0; i < parameterCount; i++) { if (i == methodData.getThisParameterIndex()) { if (isStatic) { @@ -408,8 +408,9 @@ public class InterceptionInstrumenter { ia.aconst(instrumentedMethodDesc); } else { - ia.load(base + parametersUsed, parameterTypes[parametersUsed]); - parametersUsed++; + Type type = parameterTypes[parameterOffset]; + ia.load(base + parameterOffset, type); + parameterOffset += type.getSize(); } } From 31ce4d85e87be4bcabdf3c8e2b4faf5c3d19aefb Mon Sep 17 00:00:00 2001 From: Andrey Breslav Date: Sun, 12 May 2013 17:59:42 +0300 Subject: [PATCH 021/249] The case of @This at constructor entry point fixed --- .../InterceptionInstrumenter.java | 23 +++++++++++++------ 1 file changed, 16 insertions(+), 7 deletions(-) diff --git a/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/InterceptionInstrumenter.java b/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/InterceptionInstrumenter.java index b35bd2ccea6..3edf226f608 100644 --- a/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/InterceptionInstrumenter.java +++ b/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/InterceptionInstrumenter.java @@ -324,7 +324,7 @@ public class InterceptionInstrumenter { if (enterDataWritten) return; enterDataWritten = true; for (MethodData methodData : enterData) { - invokeMethod(access, name, desc, getInstructionAdapter(), methodData); + invokeMethod(access, name, desc, getInstructionAdapter(), methodData, "".equals(name)); } } @@ -340,7 +340,7 @@ public class InterceptionInstrumenter { case ARETURN: case ATHROW: for (MethodData methodData : exitData) { - invokeMethod(access, name, desc, getInstructionAdapter(), methodData); + invokeMethod(access, name, desc, getInstructionAdapter(), methodData, false); } break; } @@ -361,11 +361,11 @@ public class InterceptionInstrumenter { } } - private TraceMethodVisitor getDumpingVisitorWrapper(MethodVisitor mv, final String name, final String desc) { + private TraceMethodVisitor getDumpingVisitorWrapper(MethodVisitor mv, final String methodName, final String methodDesc) { return new TraceMethodVisitor(mv, new Textifier() { @Override public void visitMethodEnd() { - System.out.println(cr.getClassName() + ":" + name + desc); + System.out.println(cr.getClassName() + ":" + methodName + methodDesc); for (Object line : getText()) { System.out.print(line); } @@ -379,7 +379,14 @@ public class InterceptionInstrumenter { return cw.toByteArray(); } - private static void invokeMethod(int access, String instrumentedMethodName, String instrumentedMethodDesc, InstructionAdapter ia, MethodData methodData) { + private static void invokeMethod( + int access, + String instrumentedMethodName, + String instrumentedMethodDesc, + InstructionAdapter ia, + MethodData methodData, + boolean constructorEntryPoint + ) { FieldData field = methodData.getOwnerField(); ia.getstatic(field.getDeclaringClass(), field.getName(), field.getDesc()); ia.checkcast(field.getRuntimeType()); @@ -392,8 +399,10 @@ public class InterceptionInstrumenter { int parameterOffset = 0; for (int i = 0; i < parameterCount; i++) { if (i == methodData.getThisParameterIndex()) { - if (isStatic) { - // static method, 'this' is null + if (isStatic || constructorEntryPoint) { + // a) static method, 'this' is null + // b) At the very beginning of a constructor, i.e. before any super() call, 'this' is not available + // It's too hard to detect a place right after the super() call, so we just put null instead of 'this' in such cases ia.aconst(null); } else { From dc8fca2532e537a83c9605a732b8114896a0a3f1 Mon Sep 17 00:00:00 2001 From: Andrey Breslav Date: Sun, 12 May 2013 18:01:53 +0300 Subject: [PATCH 022/249] Support @AllArgs --- .../preloading/instrumentation/AllArgs.java | 27 +++++++ .../InterceptionInstrumenter.java | 77 +++++++++++++++++-- .../instrumentation/MethodData.java | 3 + .../instrumentation/MethodDataImpl.java | 10 ++- 4 files changed, 109 insertions(+), 8 deletions(-) create mode 100644 compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/AllArgs.java diff --git a/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/AllArgs.java b/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/AllArgs.java new file mode 100644 index 00000000000..134da385b23 --- /dev/null +++ b/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/AllArgs.java @@ -0,0 +1,27 @@ +/* + * Copyright 2010-2013 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.jetbrains.jet.preloading.instrumentation; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Target(ElementType.PARAMETER) +@Retention(RetentionPolicy.RUNTIME) +public @interface AllArgs { +} diff --git a/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/InterceptionInstrumenter.java b/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/InterceptionInstrumenter.java index 3edf226f608..780613d264a 100644 --- a/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/InterceptionInstrumenter.java +++ b/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/InterceptionInstrumenter.java @@ -147,6 +147,7 @@ public class InterceptionInstrumenter { int thisParameterIndex = -1; int methodNameParameterIndex = -1; int methodDescParameterIndex = -1; + int allArgsParameterIndex = -1; for (int i = 0; i < parameterAnnotations.length; i++) { for (Annotation annotation : parameterAnnotations[i]) { if (annotation instanceof This) { @@ -167,6 +168,12 @@ public class InterceptionInstrumenter { } methodDescParameterIndex = i; } + else if (annotation instanceof AllArgs) { + if (allArgsParameterIndex > -1) { + throw new IllegalArgumentException("Multiple @AllArgs parameters in " + method); + } + allArgsParameterIndex = i; + } } } return new MethodDataImpl( @@ -177,8 +184,8 @@ public class InterceptionInstrumenter { method.getParameterTypes().length, thisParameterIndex, methodNameParameterIndex, - methodDescParameterIndex - ); + methodDescParameterIndex, + allArgsParameterIndex); } private void addDumpTask(final Object interceptor, final Method method, final MethodInstrumenter instrumenter) { @@ -275,15 +282,15 @@ public class InterceptionInstrumenter { int maxParamCount = 0; for (MethodInstrumenter instrumenter : applicableInstrumenters) { for (MethodData methodData : instrumenter.getEnterData()) { - if (maxParamCount < methodData.getParameterCount()) { - maxParamCount = methodData.getParameterCount(); + if (maxParamCount < stackDepth(methodData)) { + maxParamCount = stackDepth(methodData); } enterData.add(methodData); } for (MethodData methodData : instrumenter.getExitData()) { - if (maxParamCount < methodData.getParameterCount()) { - maxParamCount = methodData.getParameterCount(); + if (maxParamCount < stackDepth(methodData)) { + maxParamCount = stackDepth(methodData); } exitData.add(methodData); } @@ -310,7 +317,7 @@ public class InterceptionInstrumenter { @Override public void visitMaxs(int maxStack, int maxLocals) { - int maxInstrumentedStack = finalMaxParamCount + 2; // +1 for receiver +1 for returned value on the stack + int maxInstrumentedStack = finalMaxParamCount + 1; // +1 for returned value on the stack super.visitMaxs(Math.max(maxStack, maxInstrumentedStack), maxLocals); } @@ -349,6 +356,12 @@ public class InterceptionInstrumenter { }; } + private int stackDepth(MethodData methodData) { + // array + index + value + int allArgsStackDepth = methodData.getAllArgsParameterIndex() >= 0 ? 3 : 0; + return methodData.getParameterCount() + 1 /*receiver*/ + allArgsStackDepth; + } + private void checkMultipleMatches(MethodInstrumenter instrumenter, String name, String desc) { if (!instrumenter.allowsMultipleMatches()) { String erasedSignature = name + desc; @@ -416,6 +429,20 @@ public class InterceptionInstrumenter { else if (i == methodData.getMethodDescParameterIndex()) { ia.aconst(instrumentedMethodDesc); } + else if (i == methodData.getAllArgsParameterIndex()) { + ia.aconst(parameterTypes.length); + ia.newarray(OBJECT_TYPE); + int offset = 0; + for (int parameterIndex = 0; parameterIndex < parameterTypes.length; parameterIndex++) { + ia.dup(); + Type type = parameterTypes[parameterIndex]; + ia.iconst(parameterIndex); + ia.load(base + offset, type); + offset += type.getSize(); + applyBoxingIfNeeded(ia, type); + ia.astore(OBJECT_TYPE); + } + } else { Type type = parameterTypes[parameterOffset]; ia.load(base + parameterOffset, type); @@ -427,6 +454,42 @@ public class InterceptionInstrumenter { ia.invokevirtual(methodData.getDeclaringClass(), methodData.getName(), methodData.getDesc()); } + private static void applyBoxingIfNeeded(InstructionAdapter ia, Type type) { + switch (type.getSort()) { + case Type.BOOLEAN: + box(ia, type, Boolean.class); + break; + case Type.CHAR: + box(ia, type, Character.class); + break; + case Type.BYTE: + box(ia, type, Byte.class); + break; + case Type.SHORT: + box(ia, type, Short.class); + break; + case Type.INT: + box(ia, type, Integer.class); + break; + case Type.FLOAT: + box(ia, type, Float.class); + break; + case Type.LONG: + box(ia, type, Long.class); + break; + case Type.DOUBLE: + box(ia, type, Double.class); + break; + default: + // Nothing to do, it's an object already + } + } + + private static void box(InstructionAdapter ia, Type from, Class boxedClass) { + Type boxedType = Type.getType(boxedClass); + ia.invokestatic(boxedType.getInternalName(), "valueOf", "(" + from.getDescriptor() + ")" + boxedType.getDescriptor()); + } + public void dump(PrintStream out) { for (DumpAction task : dumpTasks) { task.dump(out); diff --git a/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/MethodData.java b/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/MethodData.java index 1d7f266b0ad..5cb50fc5d01 100644 --- a/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/MethodData.java +++ b/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/MethodData.java @@ -28,4 +28,7 @@ interface MethodData extends MemberData { // -1 for no @MethodDesc int getMethodDescParameterIndex(); + + // -1 for no @AllArgs + int getAllArgsParameterIndex(); } diff --git a/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/MethodDataImpl.java b/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/MethodDataImpl.java index fa2b385441e..ee4cb491df2 100644 --- a/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/MethodDataImpl.java +++ b/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/MethodDataImpl.java @@ -22,6 +22,7 @@ public class MethodDataImpl extends MemberDataImpl implements MethodData { private final int thisParameterIndex; private final int methodNameParameterIndex; private final int methodDescParameterIndex; + private final int allArgsParameterIndex; MethodDataImpl( FieldData ownerField, @@ -31,7 +32,8 @@ public class MethodDataImpl extends MemberDataImpl implements MethodData { int parameterCount, int thisParameterIndex, int methodNameParameterIndex, - int methodDescParameterIndex + int methodDescParameterIndex, + int allArgsParameterIndex ) { super(declaringClass, name, desc); this.ownerField = ownerField; @@ -39,6 +41,7 @@ public class MethodDataImpl extends MemberDataImpl implements MethodData { this.thisParameterIndex = thisParameterIndex; this.methodNameParameterIndex = methodNameParameterIndex; this.methodDescParameterIndex = methodDescParameterIndex; + this.allArgsParameterIndex = allArgsParameterIndex; } @Override @@ -65,4 +68,9 @@ public class MethodDataImpl extends MemberDataImpl implements MethodData { public int getMethodDescParameterIndex() { return methodDescParameterIndex; } + + @Override + public int getAllArgsParameterIndex() { + return allArgsParameterIndex; + } } From 23be9f8d44d7f5f0982281f782ab96942bc2a220 Mon Sep 17 00:00:00 2001 From: Andrey Breslav Date: Sun, 12 May 2013 18:09:31 +0300 Subject: [PATCH 023/249] Fixed the case of using 'this' before throw in constructor --- .../InterceptionInstrumenter.java | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/InterceptionInstrumenter.java b/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/InterceptionInstrumenter.java index 780613d264a..f95973fb2c6 100644 --- a/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/InterceptionInstrumenter.java +++ b/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/InterceptionInstrumenter.java @@ -302,6 +302,8 @@ public class InterceptionInstrumenter { mv = getDumpingVisitorWrapper(mv, name, desc); } + final boolean isConstructor = "".equals(name); + final int finalMaxParamCount = maxParamCount; return new MethodVisitorWithUniversalHandler(ASM4, mv) { @@ -331,7 +333,9 @@ public class InterceptionInstrumenter { if (enterDataWritten) return; enterDataWritten = true; for (MethodData methodData : enterData) { - invokeMethod(access, name, desc, getInstructionAdapter(), methodData, "".equals(name)); + // At the very beginning of a constructor, i.e. before any super() call, 'this' is not available + // It's too hard to detect a place right after the super() call, so we just put null instead of 'this' in such cases + invokeMethod(access, name, desc, getInstructionAdapter(), methodData, isConstructor); } } @@ -347,7 +351,9 @@ public class InterceptionInstrumenter { case ARETURN: case ATHROW: for (MethodData methodData : exitData) { - invokeMethod(access, name, desc, getInstructionAdapter(), methodData, false); + // A constructor may throw before calling super(), 'this' is not available in this case + boolean beforeThrowInConstructor = opcode == ATHROW && isConstructor; + invokeMethod(access, name, desc, getInstructionAdapter(), methodData, beforeThrowInConstructor); } break; } @@ -398,7 +404,7 @@ public class InterceptionInstrumenter { String instrumentedMethodDesc, InstructionAdapter ia, MethodData methodData, - boolean constructorEntryPoint + boolean thisUnavailable ) { FieldData field = methodData.getOwnerField(); ia.getstatic(field.getDeclaringClass(), field.getName(), field.getDesc()); @@ -412,10 +418,9 @@ public class InterceptionInstrumenter { int parameterOffset = 0; for (int i = 0; i < parameterCount; i++) { if (i == methodData.getThisParameterIndex()) { - if (isStatic || constructorEntryPoint) { + if (isStatic || thisUnavailable) { // a) static method, 'this' is null - // b) At the very beginning of a constructor, i.e. before any super() call, 'this' is not available - // It's too hard to detect a place right after the super() call, so we just put null instead of 'this' in such cases + // b) this is not available (some locations in constructors ia.aconst(null); } else { From 4d8dcb5ea885b344f94d73a14ea020847558abc8 Mon Sep 17 00:00:00 2001 From: Andrey Breslav Date: Sun, 12 May 2013 18:14:16 +0300 Subject: [PATCH 024/249] Stack size for @AllArgs fixed --- .../InterceptionInstrumenter.java | 52 ++++++++++++++----- .../instrumentation/MethodData.java | 1 - .../instrumentation/MethodDataImpl.java | 8 --- 3 files changed, 38 insertions(+), 23 deletions(-) diff --git a/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/InterceptionInstrumenter.java b/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/InterceptionInstrumenter.java index f95973fb2c6..e1aa33deca3 100644 --- a/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/InterceptionInstrumenter.java +++ b/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/InterceptionInstrumenter.java @@ -36,6 +36,7 @@ public class InterceptionInstrumenter { private static final Pattern ANYTHING = Pattern.compile(".*"); private static final Type OBJECT_TYPE = Type.getType(Object.class); + //private final boolean dumpInstrumentedMethods = true; private final boolean dumpInstrumentedMethods = false; private final Map classPatterns = new LinkedHashMap(); @@ -181,7 +182,6 @@ public class InterceptionInstrumenter { Type.getInternalName(method.getDeclaringClass()), method.getName(), Type.getMethodDescriptor(method), - method.getParameterTypes().length, thisParameterIndex, methodNameParameterIndex, methodDescParameterIndex, @@ -279,18 +279,22 @@ public class InterceptionInstrumenter { final List exitData = new ArrayList(); final List enterData = new ArrayList(); - int maxParamCount = 0; + org.jetbrains.asm4.commons.Method methodBeingInstrumented = new org.jetbrains.asm4.commons.Method(name, desc); + + int maxStackDepth = 0; for (MethodInstrumenter instrumenter : applicableInstrumenters) { for (MethodData methodData : instrumenter.getEnterData()) { - if (maxParamCount < stackDepth(methodData)) { - maxParamCount = stackDepth(methodData); + int depth = stackDepth(methodData, methodBeingInstrumented); + if (maxStackDepth < depth) { + maxStackDepth = depth; } enterData.add(methodData); } for (MethodData methodData : instrumenter.getExitData()) { - if (maxParamCount < stackDepth(methodData)) { - maxParamCount = stackDepth(methodData); + int depth = stackDepth(methodData, methodBeingInstrumented); + if (maxStackDepth < depth) { + maxStackDepth = depth; } exitData.add(methodData); } @@ -304,7 +308,7 @@ public class InterceptionInstrumenter { final boolean isConstructor = "".equals(name); - final int finalMaxParamCount = maxParamCount; + final int finalMaxStackDepth = maxStackDepth; return new MethodVisitorWithUniversalHandler(ASM4, mv) { private InstructionAdapter ia = null; @@ -319,8 +323,7 @@ public class InterceptionInstrumenter { @Override public void visitMaxs(int maxStack, int maxLocals) { - int maxInstrumentedStack = finalMaxParamCount + 1; // +1 for returned value on the stack - super.visitMaxs(Math.max(maxStack, maxInstrumentedStack), maxLocals); + super.visitMaxs(Math.max(maxStack, finalMaxStackDepth), maxLocals); } @Override @@ -362,10 +365,16 @@ public class InterceptionInstrumenter { }; } - private int stackDepth(MethodData methodData) { - // array + index + value - int allArgsStackDepth = methodData.getAllArgsParameterIndex() >= 0 ? 3 : 0; - return methodData.getParameterCount() + 1 /*receiver*/ + allArgsStackDepth; + private int stackDepth(MethodData methodData, org.jetbrains.asm4.commons.Method methodBeingInstrumented) { + org.jetbrains.asm4.commons.Method method = getAsmMethod(methodData); + // array * 2 (dup) + index + value (may be long/double) + int allArgsStackDepth = methodData.getAllArgsParameterIndex() >= 0 ? 5 : 0; + // receiver + return value must be kept on the stack OR exception, so we have to reserve at least 1 + int totalSize = 1 + Math.max(methodBeingInstrumented.getReturnType().getSize(), 1); + for (Type type : method.getArgumentTypes()) { + totalSize += type.getSize(); + } + return totalSize + allArgsStackDepth + method.getReturnType().getSize(); } private void checkMultipleMatches(MethodInstrumenter instrumenter, String name, String desc) { @@ -398,6 +407,10 @@ public class InterceptionInstrumenter { return cw.toByteArray(); } + private static org.jetbrains.asm4.commons.Method getAsmMethod(MethodData methodData) { + return new org.jetbrains.asm4.commons.Method(methodData.getName(), methodData.getDesc()); + } + private static void invokeMethod( int access, String instrumentedMethodName, @@ -410,7 +423,9 @@ public class InterceptionInstrumenter { ia.getstatic(field.getDeclaringClass(), field.getName(), field.getDesc()); ia.checkcast(field.getRuntimeType()); - int parameterCount = methodData.getParameterCount(); + org.jetbrains.asm4.commons.Method asmMethod = getAsmMethod(methodData); + + int parameterCount = asmMethod.getArgumentTypes().length; if (parameterCount > 0) { Type[] parameterTypes = Type.getArgumentTypes(instrumentedMethodDesc); boolean isStatic = (access & ACC_STATIC) != 0; @@ -457,6 +472,15 @@ public class InterceptionInstrumenter { } } ia.invokevirtual(methodData.getDeclaringClass(), methodData.getName(), methodData.getDesc()); + Type type = asmMethod.getReturnType(); + if (type.getSort() != Type.VOID) { + if (type.getSize() == 1) { + ia.pop(); + } + else { + ia.pop2(); + } + } } private static void applyBoxingIfNeeded(InstructionAdapter ia, Type type) { diff --git a/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/MethodData.java b/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/MethodData.java index 5cb50fc5d01..4be00c227cf 100644 --- a/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/MethodData.java +++ b/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/MethodData.java @@ -18,7 +18,6 @@ package org.jetbrains.jet.preloading.instrumentation; interface MethodData extends MemberData { FieldData getOwnerField(); - int getParameterCount(); // -1 for no @This parameter int getThisParameterIndex(); diff --git a/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/MethodDataImpl.java b/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/MethodDataImpl.java index ee4cb491df2..0f738409885 100644 --- a/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/MethodDataImpl.java +++ b/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/MethodDataImpl.java @@ -18,7 +18,6 @@ package org.jetbrains.jet.preloading.instrumentation; public class MethodDataImpl extends MemberDataImpl implements MethodData { private final FieldData ownerField; - private final int parameterCount; private final int thisParameterIndex; private final int methodNameParameterIndex; private final int methodDescParameterIndex; @@ -29,7 +28,6 @@ public class MethodDataImpl extends MemberDataImpl implements MethodData { String declaringClass, String name, String desc, - int parameterCount, int thisParameterIndex, int methodNameParameterIndex, int methodDescParameterIndex, @@ -37,7 +35,6 @@ public class MethodDataImpl extends MemberDataImpl implements MethodData { ) { super(declaringClass, name, desc); this.ownerField = ownerField; - this.parameterCount = parameterCount; this.thisParameterIndex = thisParameterIndex; this.methodNameParameterIndex = methodNameParameterIndex; this.methodDescParameterIndex = methodDescParameterIndex; @@ -49,11 +46,6 @@ public class MethodDataImpl extends MemberDataImpl implements MethodData { return ownerField; } - @Override - public int getParameterCount() { - return parameterCount; - } - @Override public int getThisParameterIndex() { return thisParameterIndex; From fe0ec5aafb03e17e0567707cff0c075823e66476 Mon Sep 17 00:00:00 2001 From: Andrey Breslav Date: Sun, 12 May 2013 19:20:28 +0300 Subject: [PATCH 025/249] Support error*() methods --- .../InterceptionInstrumenter.java | 32 ++++++++++++++++--- .../instrumentation/MethodInstrumenter.java | 2 ++ .../MethodInstrumenterImpl.java | 9 +++++- 3 files changed, 37 insertions(+), 6 deletions(-) diff --git a/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/InterceptionInstrumenter.java b/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/InterceptionInstrumenter.java index e1aa33deca3..6004e2a0529 100644 --- a/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/InterceptionInstrumenter.java +++ b/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/InterceptionInstrumenter.java @@ -79,14 +79,23 @@ public class InterceptionInstrumenter { List enterData = new ArrayList(); List exitData = new ArrayList(); + List errorData = new ArrayList(); List dumpMethods = new ArrayList(); for (Method method : interceptorClass.getMethods()) { String name = method.getName(); + MethodData methodData = getMethodData(fieldData, method); if (name.startsWith("enter")) { - enterData.add(getMethodData(fieldData, method)); + enterData.add(methodData); } else if (name.startsWith("exit")) { - exitData.add(getMethodData(fieldData, method)); + exitData.add(methodData); + } + else if (name.startsWith("error")) { + errorData.add(methodData); + } + else if (name.startsWith("anyExit")) { + exitData.add(methodData); + errorData.add(methodData); } else if (name.startsWith("dump")) { Class[] parameterTypes = method.getParameterTypes(); @@ -109,6 +118,7 @@ public class InterceptionInstrumenter { annotation.allowMultipleMatches(), enterData, exitData, + errorData, annotation.logInterceptions()); for (Method dumpMethod : dumpMethods) { @@ -278,6 +288,7 @@ public class InterceptionInstrumenter { final List exitData = new ArrayList(); final List enterData = new ArrayList(); + final List errorData = new ArrayList(); org.jetbrains.asm4.commons.Method methodBeingInstrumented = new org.jetbrains.asm4.commons.Method(name, desc); @@ -298,6 +309,14 @@ public class InterceptionInstrumenter { } exitData.add(methodData); } + + for (MethodData methodData : instrumenter.getErrorData()) { + int depth = stackDepth(methodData, methodBeingInstrumented); + if (maxStackDepth < depth) { + maxStackDepth = depth; + } + errorData.add(methodData); + } } if (enterData.isEmpty() && exitData.isEmpty()) return mv; @@ -352,11 +371,14 @@ public class InterceptionInstrumenter { case FRETURN: case DRETURN: case ARETURN: - case ATHROW: for (MethodData methodData : exitData) { + invokeMethod(access, name, desc, getInstructionAdapter(), methodData, false); + } + break; + case ATHROW: + for (MethodData methodData : errorData) { // A constructor may throw before calling super(), 'this' is not available in this case - boolean beforeThrowInConstructor = opcode == ATHROW && isConstructor; - invokeMethod(access, name, desc, getInstructionAdapter(), methodData, beforeThrowInConstructor); + invokeMethod(access, name, desc, getInstructionAdapter(), methodData, isConstructor); } break; } diff --git a/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/MethodInstrumenter.java b/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/MethodInstrumenter.java index c67c39fa8c5..bb1efea3b36 100644 --- a/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/MethodInstrumenter.java +++ b/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/MethodInstrumenter.java @@ -23,6 +23,8 @@ interface MethodInstrumenter { List getExitData(); + List getErrorData(); + List getEnterData(); boolean allowsMultipleMatches(); diff --git a/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/MethodInstrumenterImpl.java b/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/MethodInstrumenterImpl.java index 7f3ddb51093..beeba444424 100644 --- a/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/MethodInstrumenterImpl.java +++ b/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/MethodInstrumenterImpl.java @@ -27,6 +27,7 @@ class MethodInstrumenterImpl implements MethodInstrumenter { private final boolean allowMultipleMatches; private final List enterData; private final List exitData; + private final List errorData; private final boolean logApplications; public MethodInstrumenterImpl( @@ -36,7 +37,7 @@ class MethodInstrumenterImpl implements MethodInstrumenter { boolean allowMultipleMatches, List enterData, List exitData, - boolean logApplications + List errorData, boolean logApplications ) { this.debugName = debugName; this.classPattern = classPattern; @@ -45,6 +46,7 @@ class MethodInstrumenterImpl implements MethodInstrumenter { this.allowMultipleMatches = allowMultipleMatches; this.enterData = enterData; this.exitData = exitData; + this.errorData = errorData; this.logApplications = logApplications; } @@ -75,6 +77,11 @@ class MethodInstrumenterImpl implements MethodInstrumenter { return exitData; } + @Override + public List getErrorData() { + return errorData; + } + @Override public String toString() { return debugName + "[" + classPattern + ":" + namePattern + " " + descPattern + (allowMultipleMatches ? " multiple" : "") + "]"; From ea7e6a1c124ebb40a008605d8fae59447b5e471f Mon Sep 17 00:00:00 2001 From: Andrey Breslav Date: Sun, 12 May 2013 19:28:12 +0300 Subject: [PATCH 026/249] Unneeded hack removed --- .../InterceptionInstrumenter.java | 13 +- .../MethodVisitorWithUniversalHandler.java | 114 ------------------ 2 files changed, 2 insertions(+), 125 deletions(-) delete mode 100644 compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/MethodVisitorWithUniversalHandler.java diff --git a/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/InterceptionInstrumenter.java b/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/InterceptionInstrumenter.java index 6004e2a0529..83bcb53e3cc 100644 --- a/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/InterceptionInstrumenter.java +++ b/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/InterceptionInstrumenter.java @@ -328,10 +328,9 @@ public class InterceptionInstrumenter { final boolean isConstructor = "".equals(name); final int finalMaxStackDepth = maxStackDepth; - return new MethodVisitorWithUniversalHandler(ASM4, mv) { + return new MethodVisitor(ASM4, mv) { private InstructionAdapter ia = null; - private boolean enterDataWritten = false; private InstructionAdapter getInstructionAdapter() { if (ia == null) { @@ -346,14 +345,7 @@ public class InterceptionInstrumenter { } @Override - protected boolean visitAnyInsn(int opcode) { - writeEnterData(); - return true; - } - - private void writeEnterData() { - if (enterDataWritten) return; - enterDataWritten = true; + public void visitCode() { for (MethodData methodData : enterData) { // At the very beginning of a constructor, i.e. before any super() call, 'this' is not available // It's too hard to detect a place right after the super() call, so we just put null instead of 'this' in such cases @@ -363,7 +355,6 @@ public class InterceptionInstrumenter { @Override public void visitInsn(int opcode) { - writeEnterData(); switch (opcode) { case RETURN: case IRETURN: diff --git a/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/MethodVisitorWithUniversalHandler.java b/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/MethodVisitorWithUniversalHandler.java deleted file mode 100644 index 78448ad7f39..00000000000 --- a/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/MethodVisitorWithUniversalHandler.java +++ /dev/null @@ -1,114 +0,0 @@ -/* - * Copyright 2010-2013 JetBrains s.r.o. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.jetbrains.jet.preloading.instrumentation; - -import org.jetbrains.asm4.Handle; -import org.jetbrains.asm4.Label; -import org.jetbrains.asm4.MethodVisitor; -import org.jetbrains.asm4.Opcodes; - -public class MethodVisitorWithUniversalHandler extends MethodVisitor { - public MethodVisitorWithUniversalHandler(int api) { - super(api); - } - - public MethodVisitorWithUniversalHandler(int api, MethodVisitor mv) { - super(api, mv); - } - - protected boolean visitAnyInsn(int opcode) { - return true; - } - - @Override - public void visitInsn(int opcode) { - if (!visitAnyInsn(opcode)) return; - super.visitInsn(opcode); - } - - @Override - public void visitIntInsn(int opcode, int operand) { - if (!visitAnyInsn(opcode)) return; - super.visitIntInsn(opcode, operand); - } - - @Override - public void visitVarInsn(int opcode, int var) { - if (!visitAnyInsn(opcode)) return; - super.visitVarInsn(opcode, var); - } - - @Override - public void visitTypeInsn(int opcode, String type) { - if (!visitAnyInsn(opcode)) return; - super.visitTypeInsn(opcode, type); - } - - @Override - public void visitFieldInsn(int opcode, String owner, String name, String desc) { - if (!visitAnyInsn(opcode)) return; - super.visitFieldInsn(opcode, owner, name, desc); - } - - @Override - public void visitMethodInsn(int opcode, String owner, String name, String desc) { - if (!visitAnyInsn(opcode)) return; - super.visitMethodInsn(opcode, owner, name, desc); - } - - @Override - public void visitInvokeDynamicInsn(String name, String desc, Handle bsm, Object... bsmArgs) { - if (!visitAnyInsn(Opcodes.INVOKEDYNAMIC)) return; - super.visitInvokeDynamicInsn(name, desc, bsm, bsmArgs); - } - - @Override - public void visitJumpInsn(int opcode, Label label) { - if (!visitAnyInsn(opcode)) return; - super.visitJumpInsn(opcode, label); - } - - @Override - public void visitLdcInsn(Object cst) { - if (!visitAnyInsn(Opcodes.LDC)) return; - super.visitLdcInsn(cst); - } - - @Override - public void visitIincInsn(int var, int increment) { - if (!visitAnyInsn(Opcodes.IINC)) return; - super.visitIincInsn(var, increment); - } - - @Override - public void visitTableSwitchInsn(int min, int max, Label dflt, Label... labels) { - if (!visitAnyInsn(Opcodes.TABLESWITCH)) return; - super.visitTableSwitchInsn(min, max, dflt, labels); - } - - @Override - public void visitLookupSwitchInsn(Label dflt, int[] keys, Label[] labels) { - if (!visitAnyInsn(Opcodes.LOOKUPSWITCH)) return; - super.visitLookupSwitchInsn(dflt, keys, labels); - } - - @Override - public void visitMultiANewArrayInsn(String desc, int dims) { - if (!visitAnyInsn(Opcodes.MULTIANEWARRAY)) return; - super.visitMultiANewArrayInsn(desc, dims); - } -} From 81773a00121979b1f2cf0d2b2010d8150cbc4c24 Mon Sep 17 00:00:00 2001 From: Andrey Breslav Date: Sun, 12 May 2013 19:35:14 +0300 Subject: [PATCH 027/249] Conventions changed to normalReturn + exception = exit --- .../InterceptionInstrumenter.java | 42 +++++++++---------- .../instrumentation/MethodInstrumenter.java | 4 +- .../MethodInstrumenterImpl.java | 20 ++++----- 3 files changed, 33 insertions(+), 33 deletions(-) diff --git a/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/InterceptionInstrumenter.java b/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/InterceptionInstrumenter.java index 83bcb53e3cc..4802096ca2d 100644 --- a/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/InterceptionInstrumenter.java +++ b/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/InterceptionInstrumenter.java @@ -78,8 +78,8 @@ public class InterceptionInstrumenter { FieldData fieldData = getFieldData(field, interceptorClass); List enterData = new ArrayList(); - List exitData = new ArrayList(); - List errorData = new ArrayList(); + List normalReturnData = new ArrayList(); + List exceptionData = new ArrayList(); List dumpMethods = new ArrayList(); for (Method method : interceptorClass.getMethods()) { String name = method.getName(); @@ -87,15 +87,15 @@ public class InterceptionInstrumenter { if (name.startsWith("enter")) { enterData.add(methodData); } + else if (name.startsWith("normalReturn")) { + normalReturnData.add(methodData); + } + else if (name.startsWith("exception")) { + exceptionData.add(methodData); + } else if (name.startsWith("exit")) { - exitData.add(methodData); - } - else if (name.startsWith("error")) { - errorData.add(methodData); - } - else if (name.startsWith("anyExit")) { - exitData.add(methodData); - errorData.add(methodData); + normalReturnData.add(methodData); + exceptionData.add(methodData); } else if (name.startsWith("dump")) { Class[] parameterTypes = method.getParameterTypes(); @@ -117,8 +117,8 @@ public class InterceptionInstrumenter { compilePattern(annotation.erasedSignature()), annotation.allowMultipleMatches(), enterData, - exitData, - errorData, + normalReturnData, + exceptionData, annotation.logInterceptions()); for (Method dumpMethod : dumpMethods) { @@ -286,9 +286,9 @@ public class InterceptionInstrumenter { if (applicableInstrumenters.isEmpty()) return mv; - final List exitData = new ArrayList(); + final List normalReturnData = new ArrayList(); final List enterData = new ArrayList(); - final List errorData = new ArrayList(); + final List exceptionData = new ArrayList(); org.jetbrains.asm4.commons.Method methodBeingInstrumented = new org.jetbrains.asm4.commons.Method(name, desc); @@ -302,24 +302,24 @@ public class InterceptionInstrumenter { enterData.add(methodData); } - for (MethodData methodData : instrumenter.getExitData()) { + for (MethodData methodData : instrumenter.getNormalReturnData()) { int depth = stackDepth(methodData, methodBeingInstrumented); if (maxStackDepth < depth) { maxStackDepth = depth; } - exitData.add(methodData); + normalReturnData.add(methodData); } - for (MethodData methodData : instrumenter.getErrorData()) { + for (MethodData methodData : instrumenter.getExceptionData()) { int depth = stackDepth(methodData, methodBeingInstrumented); if (maxStackDepth < depth) { maxStackDepth = depth; } - errorData.add(methodData); + exceptionData.add(methodData); } } - if (enterData.isEmpty() && exitData.isEmpty()) return mv; + if (enterData.isEmpty() && normalReturnData.isEmpty()) return mv; if (dumpInstrumentedMethods) { mv = getDumpingVisitorWrapper(mv, name, desc); @@ -362,12 +362,12 @@ public class InterceptionInstrumenter { case FRETURN: case DRETURN: case ARETURN: - for (MethodData methodData : exitData) { + for (MethodData methodData : normalReturnData) { invokeMethod(access, name, desc, getInstructionAdapter(), methodData, false); } break; case ATHROW: - for (MethodData methodData : errorData) { + for (MethodData methodData : exceptionData) { // A constructor may throw before calling super(), 'this' is not available in this case invokeMethod(access, name, desc, getInstructionAdapter(), methodData, isConstructor); } diff --git a/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/MethodInstrumenter.java b/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/MethodInstrumenter.java index bb1efea3b36..c2c347ce60a 100644 --- a/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/MethodInstrumenter.java +++ b/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/MethodInstrumenter.java @@ -21,9 +21,9 @@ import java.util.List; interface MethodInstrumenter { boolean isApplicable(String name, String desc); - List getExitData(); + List getNormalReturnData(); - List getErrorData(); + List getExceptionData(); List getEnterData(); diff --git a/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/MethodInstrumenterImpl.java b/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/MethodInstrumenterImpl.java index beeba444424..8f666fc4412 100644 --- a/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/MethodInstrumenterImpl.java +++ b/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/MethodInstrumenterImpl.java @@ -26,8 +26,8 @@ class MethodInstrumenterImpl implements MethodInstrumenter { private final Pattern descPattern; private final boolean allowMultipleMatches; private final List enterData; - private final List exitData; - private final List errorData; + private final List normalReturnData; + private final List exceptionData; private final boolean logApplications; public MethodInstrumenterImpl( @@ -36,8 +36,8 @@ class MethodInstrumenterImpl implements MethodInstrumenter { Pattern descPattern, boolean allowMultipleMatches, List enterData, - List exitData, - List errorData, boolean logApplications + List normalReturnData, + List exceptionData, boolean logApplications ) { this.debugName = debugName; this.classPattern = classPattern; @@ -45,8 +45,8 @@ class MethodInstrumenterImpl implements MethodInstrumenter { this.descPattern = descPattern; this.allowMultipleMatches = allowMultipleMatches; this.enterData = enterData; - this.exitData = exitData; - this.errorData = errorData; + this.normalReturnData = normalReturnData; + this.exceptionData = exceptionData; this.logApplications = logApplications; } @@ -73,13 +73,13 @@ class MethodInstrumenterImpl implements MethodInstrumenter { } @Override - public List getExitData() { - return exitData; + public List getNormalReturnData() { + return normalReturnData; } @Override - public List getErrorData() { - return errorData; + public List getExceptionData() { + return exceptionData; } @Override From 42de8879fe88a65f04fd81c05950ca430ed30a8a Mon Sep 17 00:00:00 2001 From: Andrey Breslav Date: Mon, 13 May 2013 15:48:41 +0400 Subject: [PATCH 028/249] Code beautified a little --- .../InterceptionInstrumenter.java | 81 +++++++++++-------- 1 file changed, 46 insertions(+), 35 deletions(-) diff --git a/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/InterceptionInstrumenter.java b/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/InterceptionInstrumenter.java index 4802096ca2d..3314d87b3c8 100644 --- a/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/InterceptionInstrumenter.java +++ b/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/InterceptionInstrumenter.java @@ -289,45 +289,23 @@ public class InterceptionInstrumenter { final List normalReturnData = new ArrayList(); final List enterData = new ArrayList(); final List exceptionData = new ArrayList(); - - org.jetbrains.asm4.commons.Method methodBeingInstrumented = new org.jetbrains.asm4.commons.Method(name, desc); - - int maxStackDepth = 0; for (MethodInstrumenter instrumenter : applicableInstrumenters) { - for (MethodData methodData : instrumenter.getEnterData()) { - int depth = stackDepth(methodData, methodBeingInstrumented); - if (maxStackDepth < depth) { - maxStackDepth = depth; - } - enterData.add(methodData); - } + enterData.addAll(instrumenter.getEnterData()); - for (MethodData methodData : instrumenter.getNormalReturnData()) { - int depth = stackDepth(methodData, methodBeingInstrumented); - if (maxStackDepth < depth) { - maxStackDepth = depth; - } - normalReturnData.add(methodData); - } + normalReturnData.addAll(instrumenter.getNormalReturnData()); - for (MethodData methodData : instrumenter.getExceptionData()) { - int depth = stackDepth(methodData, methodBeingInstrumented); - if (maxStackDepth < depth) { - maxStackDepth = depth; - } - exceptionData.add(methodData); - } + exceptionData.addAll(instrumenter.getExceptionData()); } - if (enterData.isEmpty() && normalReturnData.isEmpty()) return mv; + if (enterData.isEmpty() && normalReturnData.isEmpty() && exceptionData.isEmpty()) return mv; if (dumpInstrumentedMethods) { mv = getDumpingVisitorWrapper(mv, name, desc); } + final int maxStackDepth = getMaxStackDepth(name, desc, normalReturnData, enterData, exceptionData); final boolean isConstructor = "".equals(name); - final int finalMaxStackDepth = maxStackDepth; return new MethodVisitor(ASM4, mv) { private InstructionAdapter ia = null; @@ -341,7 +319,7 @@ public class InterceptionInstrumenter { @Override public void visitMaxs(int maxStack, int maxLocals) { - super.visitMaxs(Math.max(maxStack, finalMaxStackDepth), maxLocals); + super.visitMaxs(Math.max(maxStack, maxStackDepth), maxLocals); } @Override @@ -351,6 +329,7 @@ public class InterceptionInstrumenter { // It's too hard to detect a place right after the super() call, so we just put null instead of 'this' in such cases invokeMethod(access, name, desc, getInstructionAdapter(), methodData, isConstructor); } + super.visitCode(); } @Override @@ -378,16 +357,45 @@ public class InterceptionInstrumenter { }; } + private int getMaxStackDepth( + String name, + String desc, + List normalReturnData, + List enterData, + List exceptionData + ) { + org.jetbrains.asm4.commons.Method methodBeingInstrumented = new org.jetbrains.asm4.commons.Method(name, desc); + + List allData = new ArrayList(); + allData.addAll(enterData); + allData.addAll(exceptionData); + allData.addAll(normalReturnData); + int maxStackDepth = 0; + for (MethodData methodData : allData) { + int depth = stackDepth(methodData, methodBeingInstrumented); + if (maxStackDepth < depth) { + maxStackDepth = depth; + } + } + return maxStackDepth; + } + private int stackDepth(MethodData methodData, org.jetbrains.asm4.commons.Method methodBeingInstrumented) { org.jetbrains.asm4.commons.Method method = getAsmMethod(methodData); + // array * 2 (dup) + index + value (may be long/double) int allArgsStackDepth = methodData.getAllArgsParameterIndex() >= 0 ? 5 : 0; - // receiver + return value must be kept on the stack OR exception, so we have to reserve at least 1 - int totalSize = 1 + Math.max(methodBeingInstrumented.getReturnType().getSize(), 1); + + int argsSize = 0; for (Type type : method.getArgumentTypes()) { - totalSize += type.getSize(); + argsSize += type.getSize(); } - return totalSize + allArgsStackDepth + method.getReturnType().getSize(); + + int receiverSize = 1; + // return value must be kept on the stack OR exception, so we have to reserve at least 1 + int exceptionSize = 1; + int returnValueSize = methodBeingInstrumented.getReturnType().getSize(); + return argsSize + allArgsStackDepth + receiverSize + Math.max(returnValueSize, exceptionSize); } private void checkMultipleMatches(MethodInstrumenter instrumenter, String name, String desc) { @@ -425,7 +433,7 @@ public class InterceptionInstrumenter { } private static void invokeMethod( - int access, + int instrumentedMethodAccess, String instrumentedMethodName, String instrumentedMethodDesc, InstructionAdapter ia, @@ -441,7 +449,7 @@ public class InterceptionInstrumenter { int parameterCount = asmMethod.getArgumentTypes().length; if (parameterCount > 0) { Type[] parameterTypes = Type.getArgumentTypes(instrumentedMethodDesc); - boolean isStatic = (access & ACC_STATIC) != 0; + boolean isStatic = (instrumentedMethodAccess & ACC_STATIC) != 0; int base = isStatic ? 0 : 1; int parameterOffset = 0; for (int i = 0; i < parameterCount; i++) { @@ -468,10 +476,13 @@ public class InterceptionInstrumenter { int offset = 0; for (int parameterIndex = 0; parameterIndex < parameterTypes.length; parameterIndex++) { ia.dup(); - Type type = parameterTypes[parameterIndex]; + ia.iconst(parameterIndex); + + Type type = parameterTypes[parameterIndex]; ia.load(base + offset, type); offset += type.getSize(); + applyBoxingIfNeeded(ia, type); ia.astore(OBJECT_TYPE); } From afe3ff9b6f06940b077e323c25257eb6ceb86939 Mon Sep 17 00:00:00 2001 From: Andrey Breslav Date: Mon, 13 May 2013 16:00:11 +0400 Subject: [PATCH 029/249] done() method moved to where it is used --- .../jet/preloading/ClassPreloadingUtils.java | 2 -- .../src/org/jetbrains/jet/preloading/Preloader.java | 12 ++++++++---- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/compiler/preloader/src/org/jetbrains/jet/preloading/ClassPreloadingUtils.java b/compiler/preloader/src/org/jetbrains/jet/preloading/ClassPreloadingUtils.java index 97adf0965b5..a9cf32480a8 100644 --- a/compiler/preloader/src/org/jetbrains/jet/preloading/ClassPreloadingUtils.java +++ b/compiler/preloader/src/org/jetbrains/jet/preloading/ClassPreloadingUtils.java @@ -39,8 +39,6 @@ public class ClassPreloadingUtils { public void beforeLoadJar(File jarFile) {} public void afterLoadJar(File jarFile) {} - - public void done() {} } /** diff --git a/compiler/preloader/src/org/jetbrains/jet/preloading/Preloader.java b/compiler/preloader/src/org/jetbrains/jet/preloading/Preloader.java index 640e9a41374..07d9b6e644d 100644 --- a/compiler/preloader/src/org/jetbrains/jet/preloading/Preloader.java +++ b/compiler/preloader/src/org/jetbrains/jet/preloading/Preloader.java @@ -43,7 +43,7 @@ public class Preloader { ClassLoader withInstrumenter = instrumentersClasspath.length > 0 ? new URLClassLoader(instrumentersClasspath, parent) : parent; - ClassPreloadingUtils.ClassHandler handler = getHandler(profilingMode, withInstrumenter); + Handler handler = getHandler(profilingMode, withInstrumenter); ClassLoader preloaded = ClassPreloadingUtils.preloadClasses(files, classNumber, withInstrumenter, handler); Class mainClass = preloaded.loadClass(mainClassCanonicalName); @@ -96,8 +96,8 @@ public class Preloader { return files; } - private static ClassPreloadingUtils.ClassHandler getHandler(ProfilingMode profilingMode, ClassLoader withInstrumenter) { - if (profilingMode == ProfilingMode.NO_TIME) return new ClassPreloadingUtils.ClassHandler() {}; + private static Handler getHandler(ProfilingMode profilingMode, ClassLoader withInstrumenter) { + if (profilingMode == ProfilingMode.NO_TIME) return new Handler(); ServiceLoader loader = ServiceLoader.load(Instrumenter.class, withInstrumenter); Iterator instrumenters = loader.iterator(); @@ -105,7 +105,7 @@ public class Preloader { final int[] counter = new int[1]; final int[] size = new int[1]; - return new ClassPreloadingUtils.ClassHandler() { + return new Handler() { @Override public void beforeDefineClass(String name, int sizeInBytes) { counter[0]++; @@ -147,4 +147,8 @@ public class Preloader { System.out.println("Usage: Preloader
> "); System.exit(1); } + + private static class Handler extends ClassPreloadingUtils.ClassHandler { + public void done() {} + } } From 7782621617f66e2bf4503094df22d6183e8a5957 Mon Sep 17 00:00:00 2001 From: Andrey Breslav Date: Mon, 13 May 2013 16:02:29 +0400 Subject: [PATCH 030/249] Do not look for instrumenters in TIME mode --- .../org/jetbrains/jet/preloading/Preloader.java | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/compiler/preloader/src/org/jetbrains/jet/preloading/Preloader.java b/compiler/preloader/src/org/jetbrains/jet/preloading/Preloader.java index 07d9b6e644d..d877a65e499 100644 --- a/compiler/preloader/src/org/jetbrains/jet/preloading/Preloader.java +++ b/compiler/preloader/src/org/jetbrains/jet/preloading/Preloader.java @@ -99,9 +99,7 @@ public class Preloader { private static Handler getHandler(ProfilingMode profilingMode, ClassLoader withInstrumenter) { if (profilingMode == ProfilingMode.NO_TIME) return new Handler(); - ServiceLoader loader = ServiceLoader.load(Instrumenter.class, withInstrumenter); - Iterator instrumenters = loader.iterator(); - final Instrumenter instrumenter = instrumenters.hasNext() ? instrumenters.next() : Instrumenter.DO_NOTHING; + final Instrumenter instrumenter = profilingMode == ProfilingMode.PROFILE ? loadInstrumenter(withInstrumenter) : null; final int[] counter = new int[1]; final int[] size = new int[1]; @@ -127,6 +125,18 @@ public class Preloader { }; } + private static Instrumenter loadInstrumenter(ClassLoader withInstrumenter) { + ServiceLoader loader = ServiceLoader.load(Instrumenter.class, withInstrumenter); + Iterator instrumenters = loader.iterator(); + if (instrumenters.hasNext()) { + return instrumenters.next(); + } + else { + System.err.println("No instrumenters found"); + return Instrumenter.DO_NOTHING; + } + } + private enum ProfilingMode { NO_TIME, TIME, From 9efc885c370b74657f372d592aa4efd58ddc78d8 Mon Sep 17 00:00:00 2001 From: Andrey Breslav Date: Mon, 13 May 2013 16:06:55 +0400 Subject: [PATCH 031/249] Instrumenter doesn't have to do profiling --- .../jetbrains/jet/preloading/Preloader.java | 44 +++++++++---------- 1 file changed, 22 insertions(+), 22 deletions(-) diff --git a/compiler/preloader/src/org/jetbrains/jet/preloading/Preloader.java b/compiler/preloader/src/org/jetbrains/jet/preloading/Preloader.java index d877a65e499..f632ba4fce3 100644 --- a/compiler/preloader/src/org/jetbrains/jet/preloading/Preloader.java +++ b/compiler/preloader/src/org/jetbrains/jet/preloading/Preloader.java @@ -12,7 +12,7 @@ import java.util.*; public class Preloader { public static final int PRELOADER_ARG_COUNT = 4; - private static final String PROFILE = "profile="; + private static final String INSTRUMENT_PREFIX = "instrument="; public static void main(String[] args) throws Exception { if (args.length < PRELOADER_ARG_COUNT) { @@ -33,9 +33,9 @@ public class Preloader { return; } - String profilingModeStr = args[3]; - ProfilingMode profilingMode = parseMeasureTime(profilingModeStr); - URL[] instrumentersClasspath = parseInstrumentersClasspath(profilingMode, profilingModeStr); + String modeStr = args[3]; + Mode mode = parseMode(modeStr); + URL[] instrumentersClasspath = parseInstrumentersClasspath(mode, modeStr); long startTime = System.nanoTime(); @@ -43,7 +43,7 @@ public class Preloader { ClassLoader withInstrumenter = instrumentersClasspath.length > 0 ? new URLClassLoader(instrumentersClasspath, parent) : parent; - Handler handler = getHandler(profilingMode, withInstrumenter); + Handler handler = getHandler(mode, withInstrumenter); ClassLoader preloaded = ClassPreloadingUtils.preloadClasses(files, classNumber, withInstrumenter, handler); Class mainClass = preloaded.loadClass(mainClassCanonicalName); @@ -53,7 +53,7 @@ public class Preloader { mainMethod.invoke(0, new Object[] {Arrays.copyOfRange(args, PRELOADER_ARG_COUNT, args.length)}); } finally { - if (profilingMode != ProfilingMode.NO_TIME) { + if (mode != Mode.NO_TIME) { long dt = System.nanoTime() - startTime; System.out.format("Total time: %.3fs\n", dt / 1e9); } @@ -61,11 +61,11 @@ public class Preloader { } } - private static URL[] parseInstrumentersClasspath(ProfilingMode profilingMode, String profilingModeStr) + private static URL[] parseInstrumentersClasspath(Mode mode, String modeStr) throws MalformedURLException { URL[] instrumentersClasspath; - if (profilingMode == ProfilingMode.PROFILE) { - List instrumentersClassPathFiles = parseClassPath(getClassPath(profilingModeStr)); + if (mode == Mode.INSTRUMENT) { + List instrumentersClassPathFiles = parseClassPath(getClassPath(modeStr)); instrumentersClasspath = new URL[instrumentersClassPathFiles.size()]; for (int i = 0; i < instrumentersClassPathFiles.size(); i++) { File file = instrumentersClassPathFiles.get(i); @@ -78,8 +78,8 @@ public class Preloader { return instrumentersClasspath; } - private static String getClassPath(String profilingModeStr) { - return profilingModeStr.substring(PROFILE.length()); + private static String getClassPath(String modeStr) { + return modeStr.substring(INSTRUMENT_PREFIX.length()); } private static List parseClassPath(String classpath) { @@ -96,10 +96,10 @@ public class Preloader { return files; } - private static Handler getHandler(ProfilingMode profilingMode, ClassLoader withInstrumenter) { - if (profilingMode == ProfilingMode.NO_TIME) return new Handler(); + private static Handler getHandler(Mode mode, ClassLoader withInstrumenter) { + if (mode == Mode.NO_TIME) return new Handler(); - final Instrumenter instrumenter = profilingMode == ProfilingMode.PROFILE ? loadInstrumenter(withInstrumenter) : null; + final Instrumenter instrumenter = mode == Mode.INSTRUMENT ? loadInstrumenter(withInstrumenter) : null; final int[] counter = new int[1]; final int[] size = new int[1]; @@ -137,24 +137,24 @@ public class Preloader { } } - private enum ProfilingMode { + private enum Mode { NO_TIME, TIME, - PROFILE + INSTRUMENT } - private static ProfilingMode parseMeasureTime(String arg) { - if ("time".equals(arg)) return ProfilingMode.TIME; - if ("notime".equals(arg)) return ProfilingMode.NO_TIME; - if (arg.startsWith(PROFILE)) return ProfilingMode.PROFILE; + private static Mode parseMode(String arg) { + if ("time".equals(arg)) return Mode.TIME; + if ("notime".equals(arg)) return Mode.NO_TIME; + if (arg.startsWith(INSTRUMENT_PREFIX)) return Mode.INSTRUMENT; System.out.println("Unrecognized argument: " + arg); printUsageAndExit(); - return ProfilingMode.NO_TIME; + return Mode.NO_TIME; } private static void printUsageAndExit() { - System.out.println("Usage: Preloader
> "); + System.out.println("Usage: Preloader
> "); System.exit(1); } From d689cc07419bec2bcd565b1460819bcd0cbd55ca Mon Sep 17 00:00:00 2001 From: Andrey Breslav Date: Mon, 13 May 2013 16:07:16 +0400 Subject: [PATCH 032/249] Using 'desc' instead of 'erasedSignature' --- .../preloading/instrumentation/InterceptionInstrumenter.java | 2 +- .../jet/preloading/instrumentation/MethodInterceptor.java | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/InterceptionInstrumenter.java b/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/InterceptionInstrumenter.java index 3314d87b3c8..8bbe961ae71 100644 --- a/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/InterceptionInstrumenter.java +++ b/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/InterceptionInstrumenter.java @@ -114,7 +114,7 @@ public class InterceptionInstrumenter { field.getDeclaringClass().getSimpleName() + "." + field.getName(), classPattern, compilePattern(methodName), - compilePattern(annotation.erasedSignature()), + compilePattern(annotation.methodDesc()), annotation.allowMultipleMatches(), enterData, normalReturnData, diff --git a/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/MethodInterceptor.java b/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/MethodInterceptor.java index 0740b17c54e..bdad692e2bb 100644 --- a/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/MethodInterceptor.java +++ b/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/MethodInterceptor.java @@ -30,8 +30,8 @@ public @interface MethodInterceptor { // regexp, if omitted, field name is used String methodName() default ""; - // regexp - String erasedSignature() default ""; + // regexp for method descriptor, like (ILjava/lang/Object;)V for void foo(int, Object) + String methodDesc() default ""; // if this is false, an exception is thrown when more than one method in the same class matches boolean allowMultipleMatches() default false; From 71791d608095c151d80b772ee74a9af34996fdfa Mon Sep 17 00:00:00 2001 From: Andrey Breslav Date: Mon, 13 May 2013 16:08:16 +0400 Subject: [PATCH 033/249] Annotations moved to a separate package --- .../preloading/instrumentation/InterceptionInstrumenter.java | 1 + .../preloading/instrumentation/{ => annotations}/AllArgs.java | 2 +- .../instrumentation/{ => annotations}/MethodDesc.java | 2 +- .../instrumentation/{ => annotations}/MethodInterceptor.java | 2 +- .../instrumentation/{ => annotations}/MethodName.java | 2 +- .../jet/preloading/instrumentation/{ => annotations}/This.java | 2 +- 6 files changed, 6 insertions(+), 5 deletions(-) rename compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/{ => annotations}/AllArgs.java (92%) rename compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/{ => annotations}/MethodDesc.java (92%) rename compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/{ => annotations}/MethodInterceptor.java (95%) rename compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/{ => annotations}/MethodName.java (92%) rename compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/{ => annotations}/This.java (92%) diff --git a/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/InterceptionInstrumenter.java b/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/InterceptionInstrumenter.java index 8bbe961ae71..2e56fab08a7 100644 --- a/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/InterceptionInstrumenter.java +++ b/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/InterceptionInstrumenter.java @@ -20,6 +20,7 @@ import org.jetbrains.asm4.*; import org.jetbrains.asm4.commons.InstructionAdapter; import org.jetbrains.asm4.util.Textifier; import org.jetbrains.asm4.util.TraceMethodVisitor; +import org.jetbrains.jet.preloading.instrumentation.annotations.*; import java.io.PrintStream; import java.lang.annotation.Annotation; diff --git a/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/AllArgs.java b/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/annotations/AllArgs.java similarity index 92% rename from compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/AllArgs.java rename to compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/annotations/AllArgs.java index 134da385b23..f78dee658c1 100644 --- a/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/AllArgs.java +++ b/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/annotations/AllArgs.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.jetbrains.jet.preloading.instrumentation; +package org.jetbrains.jet.preloading.instrumentation.annotations; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; diff --git a/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/MethodDesc.java b/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/annotations/MethodDesc.java similarity index 92% rename from compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/MethodDesc.java rename to compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/annotations/MethodDesc.java index b0d7ba77786..bdee48cd17a 100644 --- a/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/MethodDesc.java +++ b/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/annotations/MethodDesc.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.jetbrains.jet.preloading.instrumentation; +package org.jetbrains.jet.preloading.instrumentation.annotations; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; diff --git a/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/MethodInterceptor.java b/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/annotations/MethodInterceptor.java similarity index 95% rename from compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/MethodInterceptor.java rename to compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/annotations/MethodInterceptor.java index bdad692e2bb..20370f16514 100644 --- a/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/MethodInterceptor.java +++ b/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/annotations/MethodInterceptor.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.jetbrains.jet.preloading.instrumentation; +package org.jetbrains.jet.preloading.instrumentation.annotations; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; diff --git a/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/MethodName.java b/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/annotations/MethodName.java similarity index 92% rename from compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/MethodName.java rename to compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/annotations/MethodName.java index 38c4bdbbca2..c2d24a351e2 100644 --- a/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/MethodName.java +++ b/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/annotations/MethodName.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.jetbrains.jet.preloading.instrumentation; +package org.jetbrains.jet.preloading.instrumentation.annotations; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; diff --git a/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/This.java b/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/annotations/This.java similarity index 92% rename from compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/This.java rename to compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/annotations/This.java index 67f67c5585d..4776931816d 100644 --- a/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/This.java +++ b/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/annotations/This.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.jetbrains.jet.preloading.instrumentation; +package org.jetbrains.jet.preloading.instrumentation.annotations; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; From 9f7a4ffe562551737e962189cda2db1dff4f7598 Mon Sep 17 00:00:00 2001 From: Andrey Breslav Date: Mon, 13 May 2013 16:10:22 +0400 Subject: [PATCH 034/249] Unneeded interfaces removed --- .../preloading/instrumentation/FieldData.java | 14 ++- .../instrumentation/FieldDataImpl.java | 34 ------- .../InterceptionInstrumenter.java | 6 +- .../instrumentation/MemberData.java | 27 +++++- .../instrumentation/MemberDataImpl.java | 45 ---------- .../instrumentation/MethodData.java | 50 ++++++++--- .../instrumentation/MethodDataImpl.java | 68 -------------- .../instrumentation/MethodInstrumenter.java | 64 +++++++++++-- .../MethodInstrumenterImpl.java | 89 ------------------- 9 files changed, 135 insertions(+), 262 deletions(-) delete mode 100644 compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/FieldDataImpl.java delete mode 100644 compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/MemberDataImpl.java delete mode 100644 compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/MethodDataImpl.java delete mode 100644 compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/MethodInstrumenterImpl.java diff --git a/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/FieldData.java b/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/FieldData.java index 082d97936f2..219199d7134 100644 --- a/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/FieldData.java +++ b/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/FieldData.java @@ -18,6 +18,16 @@ package org.jetbrains.jet.preloading.instrumentation; import org.jetbrains.asm4.Type; -interface FieldData extends MemberData { - Type getRuntimeType(); +class FieldData extends MemberData { + + private final Type runtimeType; + + public FieldData(String declaringClass, String name, String desc, Type runtimeType) { + super(declaringClass, name, desc); + this.runtimeType = runtimeType; + } + + public Type getRuntimeType() { + return runtimeType; + } } diff --git a/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/FieldDataImpl.java b/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/FieldDataImpl.java deleted file mode 100644 index 0164699d8ab..00000000000 --- a/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/FieldDataImpl.java +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Copyright 2010-2013 JetBrains s.r.o. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.jetbrains.jet.preloading.instrumentation; - -import org.jetbrains.asm4.Type; - -class FieldDataImpl extends MemberDataImpl implements FieldData { - - private final Type runtimeType; - - public FieldDataImpl(String declaringClass, String name, String desc, Type runtimeType) { - super(declaringClass, name, desc); - this.runtimeType = runtimeType; - } - - @Override - public Type getRuntimeType() { - return runtimeType; - } -} diff --git a/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/InterceptionInstrumenter.java b/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/InterceptionInstrumenter.java index 2e56fab08a7..5ee478402a3 100644 --- a/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/InterceptionInstrumenter.java +++ b/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/InterceptionInstrumenter.java @@ -111,7 +111,7 @@ public class InterceptionInstrumenter { String nameFromAnnotation = annotation.methodName(); String methodName = nameFromAnnotation.isEmpty() ? field.getName() : nameFromAnnotation; - MethodInstrumenterImpl instrumenter = new MethodInstrumenterImpl( + MethodInstrumenter instrumenter = new MethodInstrumenter( field.getDeclaringClass().getSimpleName() + "." + field.getName(), classPattern, compilePattern(methodName), @@ -147,7 +147,7 @@ public class InterceptionInstrumenter { } private static FieldData getFieldData(Field field, Class runtimeType) { - return new FieldDataImpl( + return new FieldData( Type.getInternalName(field.getDeclaringClass()), field.getName(), Type.getDescriptor(field.getType()), @@ -188,7 +188,7 @@ public class InterceptionInstrumenter { } } } - return new MethodDataImpl( + return new MethodData( interceptorField, Type.getInternalName(method.getDeclaringClass()), method.getName(), diff --git a/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/MemberData.java b/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/MemberData.java index 31b4641776e..8a0537e0e0a 100644 --- a/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/MemberData.java +++ b/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/MemberData.java @@ -16,8 +16,27 @@ package org.jetbrains.jet.preloading.instrumentation; -interface MemberData { - String getDeclaringClass(); - String getName(); - String getDesc(); +class MemberData { + + private final String declaringClass; + private final String name; + private final String desc; + + public MemberData(String declaringClass, String name, String desc) { + this.declaringClass = declaringClass; + this.name = name; + this.desc = desc; + } + + public String getDeclaringClass() { + return declaringClass; + } + + public String getName() { + return name; + } + + public String getDesc() { + return desc; + } } diff --git a/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/MemberDataImpl.java b/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/MemberDataImpl.java deleted file mode 100644 index f2cc1f00c58..00000000000 --- a/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/MemberDataImpl.java +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright 2010-2013 JetBrains s.r.o. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.jetbrains.jet.preloading.instrumentation; - -class MemberDataImpl implements MemberData { - - private final String declaringClass; - private final String name; - private final String desc; - - public MemberDataImpl(String declaringClass, String name, String desc) { - this.declaringClass = declaringClass; - this.name = name; - this.desc = desc; - } - - @Override - public String getDeclaringClass() { - return declaringClass; - } - - @Override - public String getName() { - return name; - } - - @Override - public String getDesc() { - return desc; - } -} diff --git a/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/MethodData.java b/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/MethodData.java index 4be00c227cf..31936fea2fa 100644 --- a/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/MethodData.java +++ b/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/MethodData.java @@ -16,18 +16,48 @@ package org.jetbrains.jet.preloading.instrumentation; -interface MethodData extends MemberData { - FieldData getOwnerField(); +public class MethodData extends MemberData { + private final FieldData ownerField; + private final int thisParameterIndex; + private final int methodNameParameterIndex; + private final int methodDescParameterIndex; + private final int allArgsParameterIndex; - // -1 for no @This parameter - int getThisParameterIndex(); + MethodData( + FieldData ownerField, + String declaringClass, + String name, + String desc, + int thisParameterIndex, + int methodNameParameterIndex, + int methodDescParameterIndex, + int allArgsParameterIndex + ) { + super(declaringClass, name, desc); + this.ownerField = ownerField; + this.thisParameterIndex = thisParameterIndex; + this.methodNameParameterIndex = methodNameParameterIndex; + this.methodDescParameterIndex = methodDescParameterIndex; + this.allArgsParameterIndex = allArgsParameterIndex; + } - // -1 for no @MethodName - int getMethodNameParameterIndex(); + public FieldData getOwnerField() { + return ownerField; + } - // -1 for no @MethodDesc - int getMethodDescParameterIndex(); + public int getThisParameterIndex() { + return thisParameterIndex; + } - // -1 for no @AllArgs - int getAllArgsParameterIndex(); + public int getMethodNameParameterIndex() { + return methodNameParameterIndex; + } + + public int getMethodDescParameterIndex() { + return methodDescParameterIndex; + } + + public int getAllArgsParameterIndex() { + return allArgsParameterIndex; + } } diff --git a/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/MethodDataImpl.java b/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/MethodDataImpl.java deleted file mode 100644 index 0f738409885..00000000000 --- a/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/MethodDataImpl.java +++ /dev/null @@ -1,68 +0,0 @@ -/* - * Copyright 2010-2013 JetBrains s.r.o. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.jetbrains.jet.preloading.instrumentation; - -public class MethodDataImpl extends MemberDataImpl implements MethodData { - private final FieldData ownerField; - private final int thisParameterIndex; - private final int methodNameParameterIndex; - private final int methodDescParameterIndex; - private final int allArgsParameterIndex; - - MethodDataImpl( - FieldData ownerField, - String declaringClass, - String name, - String desc, - int thisParameterIndex, - int methodNameParameterIndex, - int methodDescParameterIndex, - int allArgsParameterIndex - ) { - super(declaringClass, name, desc); - this.ownerField = ownerField; - this.thisParameterIndex = thisParameterIndex; - this.methodNameParameterIndex = methodNameParameterIndex; - this.methodDescParameterIndex = methodDescParameterIndex; - this.allArgsParameterIndex = allArgsParameterIndex; - } - - @Override - public FieldData getOwnerField() { - return ownerField; - } - - @Override - public int getThisParameterIndex() { - return thisParameterIndex; - } - - @Override - public int getMethodNameParameterIndex() { - return methodNameParameterIndex; - } - - @Override - public int getMethodDescParameterIndex() { - return methodDescParameterIndex; - } - - @Override - public int getAllArgsParameterIndex() { - return allArgsParameterIndex; - } -} diff --git a/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/MethodInstrumenter.java b/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/MethodInstrumenter.java index c2c347ce60a..d1e4be18737 100644 --- a/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/MethodInstrumenter.java +++ b/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/MethodInstrumenter.java @@ -17,17 +17,67 @@ package org.jetbrains.jet.preloading.instrumentation; import java.util.List; +import java.util.regex.Pattern; -interface MethodInstrumenter { - boolean isApplicable(String name, String desc); +class MethodInstrumenter { + private final String debugName; + private final Pattern classPattern; + private final Pattern namePattern; + private final Pattern descPattern; + private final boolean allowMultipleMatches; + private final List enterData; + private final List normalReturnData; + private final List exceptionData; + private final boolean logApplications; - List getNormalReturnData(); + public MethodInstrumenter( + String debugName, + Pattern classPattern, Pattern namePattern, + Pattern descPattern, + boolean allowMultipleMatches, + List enterData, + List normalReturnData, + List exceptionData, boolean logApplications + ) { + this.debugName = debugName; + this.classPattern = classPattern; + this.namePattern = namePattern; + this.descPattern = descPattern; + this.allowMultipleMatches = allowMultipleMatches; + this.enterData = enterData; + this.normalReturnData = normalReturnData; + this.exceptionData = exceptionData; + this.logApplications = logApplications; + } - List getExceptionData(); + public boolean allowsMultipleMatches() { + return allowMultipleMatches; + } - List getEnterData(); + public void reportApplication(String className, String methodName, String methodDesc) { + if (logApplications) { + System.out.println(toString() + " applied to " + className + ":" + methodName + methodDesc); + } + } - boolean allowsMultipleMatches(); + public boolean isApplicable(String name, String desc) { + return namePattern.matcher(name).matches() && descPattern.matcher(desc).matches(); + } - void reportApplication(String className, String methodName, String methodDesc); + public List getEnterData() { + return enterData; + } + + public List getNormalReturnData() { + return normalReturnData; + } + + public List getExceptionData() { + return exceptionData; + } + + @Override + public String toString() { + return debugName + "[" + classPattern + ":" + namePattern + " " + descPattern + (allowMultipleMatches ? " multiple" : "") + "]"; + } } diff --git a/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/MethodInstrumenterImpl.java b/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/MethodInstrumenterImpl.java deleted file mode 100644 index 8f666fc4412..00000000000 --- a/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/MethodInstrumenterImpl.java +++ /dev/null @@ -1,89 +0,0 @@ -/* - * Copyright 2010-2013 JetBrains s.r.o. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.jetbrains.jet.preloading.instrumentation; - -import java.util.List; -import java.util.regex.Pattern; - -class MethodInstrumenterImpl implements MethodInstrumenter { - private final String debugName; - private final Pattern classPattern; - private final Pattern namePattern; - private final Pattern descPattern; - private final boolean allowMultipleMatches; - private final List enterData; - private final List normalReturnData; - private final List exceptionData; - private final boolean logApplications; - - public MethodInstrumenterImpl( - String debugName, - Pattern classPattern, Pattern namePattern, - Pattern descPattern, - boolean allowMultipleMatches, - List enterData, - List normalReturnData, - List exceptionData, boolean logApplications - ) { - this.debugName = debugName; - this.classPattern = classPattern; - this.namePattern = namePattern; - this.descPattern = descPattern; - this.allowMultipleMatches = allowMultipleMatches; - this.enterData = enterData; - this.normalReturnData = normalReturnData; - this.exceptionData = exceptionData; - this.logApplications = logApplications; - } - - @Override - public boolean allowsMultipleMatches() { - return allowMultipleMatches; - } - - @Override - public void reportApplication(String className, String methodName, String methodDesc) { - if (logApplications) { - System.out.println(toString() + " applied to " + className + ":" + methodName + methodDesc); - } - } - - @Override - public boolean isApplicable(String name, String desc) { - return namePattern.matcher(name).matches() && descPattern.matcher(desc).matches(); - } - - @Override - public List getEnterData() { - return enterData; - } - - @Override - public List getNormalReturnData() { - return normalReturnData; - } - - @Override - public List getExceptionData() { - return exceptionData; - } - - @Override - public String toString() { - return debugName + "[" + classPattern + ":" + namePattern + " " + descPattern + (allowMultipleMatches ? " multiple" : "") + "]"; - } -} From 2ed217bb4ae3795f3156386066aaaf28c46a9d5c Mon Sep 17 00:00:00 2001 From: Andrey Breslav Date: Mon, 13 May 2013 17:07:46 +0400 Subject: [PATCH 035/249] Some docs and example --- compiler/preloader/instrumentation/ReadMe.md | 52 ++++++++++ ...et.preloading.instrumentation.Instrumenter | 1 + .../ProfilingInstrumenterExample.java | 96 +++++++++++++++++++ 3 files changed, 149 insertions(+) create mode 100644 compiler/preloader/instrumentation/ReadMe.md create mode 100644 compiler/preloader/instrumentation/src/META-INF/services/org.jetbrains.jet.preloading.instrumentation.Instrumenter create mode 100644 compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/ProfilingInstrumenterExample.java diff --git a/compiler/preloader/instrumentation/ReadMe.md b/compiler/preloader/instrumentation/ReadMe.md new file mode 100644 index 00000000000..632eb225b77 --- /dev/null +++ b/compiler/preloader/instrumentation/ReadMe.md @@ -0,0 +1,52 @@ +# Instrumentation in Kotlin Preloader + +The main purpose of Preloader is to speed up class loading at compiler's startup. +But as a side effect, we got a chance to support instrumenting the compiler's code, which is mainly useful for profiling. + +## How to quickly set up instrumentation + +To run Preloader with instrumentation, pass ```instrument=...``` on the command line: + +``` +org.jetbrains.jet.preloading.Preloader \ + dist/kotlinc/lib/kotlin-compiler.jar \ + org.jetbrains.jet.cli.jvm.K2JVMCompiler \ + 5000 \ + instrument=out/artifacts/instrumentation_jar/instrumentation.jar \ + +``` + +This example uses an artifact already configured in our project. +In this artifact, what to instrument is configured in the ```org.jetbrains.jet.preloading.ProfilingInstrumenterExample``` class. +This is determined by the ```src/META-INF/services/org.jetbrains.jet.preloading.instrumentation.Instrumenter``` file (see JavaDoc for ```java.util.ServiceLoader```). + +## More structured description + +**Instrumenter** is any implementation of ```org.jetbrains.jet.preloading.instrumentation.Instrumenter``` interface. + +Preloader loads the **first** instrumenter service found on the class path. +Services are provided through the [standard JDK mechanism](http://docs.oracle.com/javase/6/docs/api/java/util/ServiceLoader.html). + +Every preloaded class is run through the instrumenter. Before exiting the program instrumenter's dupm() method is called. +**Note** JDK classes and everything in the Preloader's own class path are not preloaded, thus not instrumented. + +The ```instrumentation``` module provides a convenient way to define useful instrumenters: + +* Derive your class from ```org.jetbrains.jet.preloading.instrumentation.InterceptionInstrumenterAdaptor``` +* In this class define public static fields with ```@MethodInterceptor``` annotation + +Whatever the type of the field, if it has methods named by the convention defined below, they will be called as follows: +* ```enter.*``` - upon entering the instrumented method +* ```normalReturn.*``` - upon returning normally from the instrumented method (not throwing an exception) +* ```exception.*``` - upon explicitly throwing an exception from the instrumented method +* ```exit.*``` - upon exiting the instrumented method (either return or throw) +* ```dump.*``` - upon program termination, useful to display the results + +If any of the methods above, except for ```dump.*```, have parameters, they are treated as follows: +* *no annotation* - this parameter receives the respective parameter of the instrumented method +* ```@This``` - this parameter receives the ```this``` of the instrumented method, or ```null``` if there's no ```this``` +* ```@MethodName``` - this parameter receives the name of the instrumented method, must be a ```String``` +* ```@MethodDesc``` - this parameter receives the JVM descriptor of the instrumented method, like ```(ILjava/lang/Object;)V```, must be a ```String``` +* ```@AllArgs``` - this parameter receives an array of all arguments of the instrumented method, must be of type ```Object[]``` + +See ```org.jetbrains.jet.preloading.ProfilingInstrumenterExample```. diff --git a/compiler/preloader/instrumentation/src/META-INF/services/org.jetbrains.jet.preloading.instrumentation.Instrumenter b/compiler/preloader/instrumentation/src/META-INF/services/org.jetbrains.jet.preloading.instrumentation.Instrumenter new file mode 100644 index 00000000000..4778763239c --- /dev/null +++ b/compiler/preloader/instrumentation/src/META-INF/services/org.jetbrains.jet.preloading.instrumentation.Instrumenter @@ -0,0 +1 @@ +org.jetbrains.jet.preloading.ProfilingInstrumenterExample \ No newline at end of file diff --git a/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/ProfilingInstrumenterExample.java b/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/ProfilingInstrumenterExample.java new file mode 100644 index 00000000000..8695d63f058 --- /dev/null +++ b/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/ProfilingInstrumenterExample.java @@ -0,0 +1,96 @@ +/* + * Copyright 2010-2013 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.jetbrains.jet.preloading; + +import org.jetbrains.jet.preloading.instrumentation.InterceptionInstrumenterAdaptor; +import org.jetbrains.jet.preloading.instrumentation.annotations.MethodInterceptor; + +import java.io.PrintStream; +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; + +@SuppressWarnings("UnusedDeclaration") +public class ProfilingInstrumenterExample extends InterceptionInstrumenterAdaptor { + + // How many times are visit* methods of visitors called? + @MethodInterceptor(className = ".*Visitor.*", methodName = "visit.*", methodDesc = ".*", allowMultipleMatches = true) + public static final Object a = new InvocationCount(); + + public static class InvocationCount { + private int count = 0; + + public void enter() { + // This method is called upon entering a visit* method + count++; + } + + public void dump(PrintStream out) { + // This method is called upon program termination + out.println("Invocation count: " + count); + } + } + + // How much time do we spend in equals() methods of all classes inside package org + // NOTE: this works only on methods actually DECLARED in these classes + // This also logs names of actually instrumented methods to console + @MethodInterceptor(className = "org/.*", methodName = "equals", methodDesc = "\\(Ljava/lang/Object;\\)Z", logInterceptions = true) + public static final Object b = new TotalTime(); + + public static class TotalTime { + private long time = 0; + private long start = 0; + private boolean started = false; + + public void enter() { + if (!started) { + start = System.nanoTime(); + started = true; + } + } + + public void exit() { + if (started) { + time += System.nanoTime() - start; + started = false; + } + } + + public void dump(PrintStream out) { + out.printf("Total time: %.3fs\n", (time / 1e9)); + } + } + + // Collect all strings that were capitalized using StringUtil + @MethodInterceptor(className = "com/intellij/openapi/util/text/StringUtil", + methodName = "capitalize", + methodDesc = "\\(Ljava/lang/String;\\).*") + public static Object c = new CollectFirstArguments(); + + public static class CollectFirstArguments { + + private final List arguments = new ArrayList(30000); + + public void enter(Object arg) { + arguments.add(arg); + } + + public void dump(PrintStream out) { + System.out.println("Different values: " + new HashSet(arguments).size()); + } + } +} From cdc375ba06f12bffc6c3fad6fd14595dd347bb8e Mon Sep 17 00:00:00 2001 From: Andrey Breslav Date: Mon, 13 May 2013 17:23:45 +0400 Subject: [PATCH 036/249] Preloader's output beautified --- .../src/org/jetbrains/jet/preloading/Preloader.java | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/compiler/preloader/src/org/jetbrains/jet/preloading/Preloader.java b/compiler/preloader/src/org/jetbrains/jet/preloading/Preloader.java index f632ba4fce3..4987a8c0651 100644 --- a/compiler/preloader/src/org/jetbrains/jet/preloading/Preloader.java +++ b/compiler/preloader/src/org/jetbrains/jet/preloading/Preloader.java @@ -54,6 +54,8 @@ public class Preloader { } finally { if (mode != Mode.NO_TIME) { + System.out.println(); + System.out.println("=== Preloader's measurements: "); long dt = System.nanoTime() - startTime; System.out.format("Total time: %.3fs\n", dt / 1e9); } @@ -99,7 +101,7 @@ public class Preloader { private static Handler getHandler(Mode mode, ClassLoader withInstrumenter) { if (mode == Mode.NO_TIME) return new Handler(); - final Instrumenter instrumenter = mode == Mode.INSTRUMENT ? loadInstrumenter(withInstrumenter) : null; + final Instrumenter instrumenter = mode == Mode.INSTRUMENT ? loadInstrumenter(withInstrumenter) : Instrumenter.DO_NOTHING; final int[] counter = new int[1]; final int[] size = new int[1]; @@ -112,8 +114,10 @@ public class Preloader { @Override public void done() { + System.out.println(); System.out.println("Loaded classes: " + counter[0]); System.out.println("Loaded classes size: " + size[0]); + System.out.println(); instrumenter.dump(System.out); } @@ -132,7 +136,7 @@ public class Preloader { return instrumenters.next(); } else { - System.err.println("No instrumenters found"); + System.err.println("PRELOADER WARNING: No instrumenters found"); return Instrumenter.DO_NOTHING; } } From f2bf2317f8c9e2f7176ce06b91d2376f838e0b74 Mon Sep 17 00:00:00 2001 From: Andrey Breslav Date: Mon, 13 May 2013 17:24:10 +0400 Subject: [PATCH 037/249] Better visible separation between individual instrumenters' outputs --- .../jet/preloading/instrumentation/InterceptionInstrumenter.java | 1 + 1 file changed, 1 insertion(+) diff --git a/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/InterceptionInstrumenter.java b/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/InterceptionInstrumenter.java index 5ee478402a3..c514ce0233f 100644 --- a/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/InterceptionInstrumenter.java +++ b/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/InterceptionInstrumenter.java @@ -219,6 +219,7 @@ public class InterceptionInstrumenter { throw new IllegalStateException(e); } out.println(">>>"); + out.println(); } }); } From de7fd88373e94aff9d4146ec1862539f5578f532 Mon Sep 17 00:00:00 2001 From: Andrey Breslav Date: Mon, 13 May 2013 17:42:56 +0400 Subject: [PATCH 038/249] Warn about using only the first instrumenter --- .../src/org/jetbrains/jet/preloading/Preloader.java | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/compiler/preloader/src/org/jetbrains/jet/preloading/Preloader.java b/compiler/preloader/src/org/jetbrains/jet/preloading/Preloader.java index 4987a8c0651..9de51c713f8 100644 --- a/compiler/preloader/src/org/jetbrains/jet/preloading/Preloader.java +++ b/compiler/preloader/src/org/jetbrains/jet/preloading/Preloader.java @@ -133,7 +133,11 @@ public class Preloader { ServiceLoader loader = ServiceLoader.load(Instrumenter.class, withInstrumenter); Iterator instrumenters = loader.iterator(); if (instrumenters.hasNext()) { - return instrumenters.next(); + Instrumenter instrumenter = instrumenters.next(); + if (instrumenters.hasNext()) { + System.err.println("PRELOADER WARNING: Only the first instrumenter is used: " + instrumenter.getClass()); + } + return instrumenter; } else { System.err.println("PRELOADER WARNING: No instrumenters found"); From e5b2519aa2662ad6c705a181909ea5a7ee74ef21 Mon Sep 17 00:00:00 2001 From: Andrey Breslav Date: Mon, 13 May 2013 17:46:20 +0400 Subject: [PATCH 039/249] Warn when no relevant methods are found --- .../instrumentation/InterceptionInstrumenter.java | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/InterceptionInstrumenter.java b/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/InterceptionInstrumenter.java index c514ce0233f..060367bec85 100644 --- a/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/InterceptionInstrumenter.java +++ b/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/InterceptionInstrumenter.java @@ -57,7 +57,7 @@ public class InterceptionInstrumenter { } private void addHandlerClass(Class handlerClass) { - for (Field field : handlerClass.getFields()) { + for (final Field field : handlerClass.getFields()) { MethodInterceptor annotation = field.getAnnotation(MethodInterceptor.class); if (annotation == null) continue; @@ -74,7 +74,7 @@ public class InterceptionInstrumenter { throw new IllegalArgumentException("Interceptor is null: " + field); } - Class interceptorClass = interceptor.getClass(); + final Class interceptorClass = interceptor.getClass(); FieldData fieldData = getFieldData(field, interceptorClass); @@ -109,6 +109,15 @@ public class InterceptionInstrumenter { } } + if (enterData.isEmpty() && normalReturnData.isEmpty() && exceptionData.isEmpty()) { + dumpTasks.add(new DumpAction() { + @Override + public void dump(PrintStream out) { + out.println("WARNING: No relevant methods found in " + field + " of type " + interceptorClass.getCanonicalName()); + } + }); + } + String nameFromAnnotation = annotation.methodName(); String methodName = nameFromAnnotation.isEmpty() ? field.getName() : nameFromAnnotation; MethodInstrumenter instrumenter = new MethodInstrumenter( From 3d40d11c9867bcdaa9620c7433ea8d2505fb48a5 Mon Sep 17 00:00:00 2001 From: Andrey Breslav Date: Mon, 13 May 2013 18:31:49 +0400 Subject: [PATCH 040/249] Example using @MethodName --- .../ProfilingInstrumenterExample.java | 29 ++++++++++++++++--- 1 file changed, 25 insertions(+), 4 deletions(-) diff --git a/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/ProfilingInstrumenterExample.java b/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/ProfilingInstrumenterExample.java index 8695d63f058..20772c75388 100644 --- a/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/ProfilingInstrumenterExample.java +++ b/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/ProfilingInstrumenterExample.java @@ -17,12 +17,12 @@ package org.jetbrains.jet.preloading; import org.jetbrains.jet.preloading.instrumentation.InterceptionInstrumenterAdaptor; +import org.jetbrains.jet.preloading.instrumentation.annotations.MethodDesc; import org.jetbrains.jet.preloading.instrumentation.annotations.MethodInterceptor; +import org.jetbrains.jet.preloading.instrumentation.annotations.MethodName; import java.io.PrintStream; -import java.util.ArrayList; -import java.util.HashSet; -import java.util.List; +import java.util.*; @SuppressWarnings("UnusedDeclaration") public class ProfilingInstrumenterExample extends InterceptionInstrumenterAdaptor { @@ -90,7 +90,28 @@ public class ProfilingInstrumenterExample extends InterceptionInstrumenterAdapto } public void dump(PrintStream out) { - System.out.println("Different values: " + new HashSet(arguments).size()); + out.println("Different values: " + new HashSet(arguments).size()); + } + } + + // What methods that have a long parameter followed by some object parameter are actually called + @MethodInterceptor(className = ".*", + methodName = ".*", + methodDesc = "\\(.*JL.*?\\).*", + allowMultipleMatches = true) + public static Object d = new MethodCollector(); + + public static class MethodCollector { + private final Collection l = new LinkedHashSet(); + + public void enter(@MethodName String name, @MethodDesc String desc) {//long l, Object arg) { + l.add(name + desc); + } + + public void dump(PrintStream out) { + for (String s : l) { + out.println(s); + } } } } From ab48f3411ac1abc580a8f3323f17a9d5e0edade0 Mon Sep 17 00:00:00 2001 From: Andrey Breslav Date: Mon, 13 May 2013 18:41:03 +0400 Subject: [PATCH 041/249] Support @ClassName --- compiler/preloader/instrumentation/ReadMe.md | 1 + .../ProfilingInstrumenterExample.java | 5 ++-- .../InterceptionInstrumenter.java | 18 ++++++++++--- .../instrumentation/MethodData.java | 7 +++++ .../annotations/ClassName.java | 27 +++++++++++++++++++ 5 files changed, 53 insertions(+), 5 deletions(-) create mode 100644 compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/annotations/ClassName.java diff --git a/compiler/preloader/instrumentation/ReadMe.md b/compiler/preloader/instrumentation/ReadMe.md index 632eb225b77..dfdb9eac23c 100644 --- a/compiler/preloader/instrumentation/ReadMe.md +++ b/compiler/preloader/instrumentation/ReadMe.md @@ -45,6 +45,7 @@ Whatever the type of the field, if it has methods named by the convention define If any of the methods above, except for ```dump.*```, have parameters, they are treated as follows: * *no annotation* - this parameter receives the respective parameter of the instrumented method * ```@This``` - this parameter receives the ```this``` of the instrumented method, or ```null``` if there's no ```this``` +* ```@ClassName``` - this parameter receives the name of the class containing the instrumented method, must be a ```String``` * ```@MethodName``` - this parameter receives the name of the instrumented method, must be a ```String``` * ```@MethodDesc``` - this parameter receives the JVM descriptor of the instrumented method, like ```(ILjava/lang/Object;)V```, must be a ```String``` * ```@AllArgs``` - this parameter receives an array of all arguments of the instrumented method, must be of type ```Object[]``` diff --git a/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/ProfilingInstrumenterExample.java b/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/ProfilingInstrumenterExample.java index 20772c75388..9444aa61012 100644 --- a/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/ProfilingInstrumenterExample.java +++ b/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/ProfilingInstrumenterExample.java @@ -17,6 +17,7 @@ package org.jetbrains.jet.preloading; import org.jetbrains.jet.preloading.instrumentation.InterceptionInstrumenterAdaptor; +import org.jetbrains.jet.preloading.instrumentation.annotations.ClassName; import org.jetbrains.jet.preloading.instrumentation.annotations.MethodDesc; import org.jetbrains.jet.preloading.instrumentation.annotations.MethodInterceptor; import org.jetbrains.jet.preloading.instrumentation.annotations.MethodName; @@ -104,8 +105,8 @@ public class ProfilingInstrumenterExample extends InterceptionInstrumenterAdapto public static class MethodCollector { private final Collection l = new LinkedHashSet(); - public void enter(@MethodName String name, @MethodDesc String desc) {//long l, Object arg) { - l.add(name + desc); + public void enter(@ClassName String className, @MethodName String name, @MethodDesc String desc) { + l.add(className + "." + name + desc); } public void dump(PrintStream out) { diff --git a/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/InterceptionInstrumenter.java b/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/InterceptionInstrumenter.java index 060367bec85..436aa6ebaba 100644 --- a/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/InterceptionInstrumenter.java +++ b/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/InterceptionInstrumenter.java @@ -166,6 +166,7 @@ public class InterceptionInstrumenter { private static MethodData getMethodData(FieldData interceptorField, Method method) { Annotation[][] parameterAnnotations = method.getParameterAnnotations(); int thisParameterIndex = -1; + int classNameParameterIndex = -1; int methodNameParameterIndex = -1; int methodDescParameterIndex = -1; int allArgsParameterIndex = -1; @@ -177,6 +178,12 @@ public class InterceptionInstrumenter { } thisParameterIndex = i; } + else if (annotation instanceof ClassName) { + if (classNameParameterIndex > -1) { + throw new IllegalArgumentException("Multiple @ClassName parameters in " + method); + } + classNameParameterIndex = i; + } else if (annotation instanceof MethodName) { if (methodNameParameterIndex > -1) { throw new IllegalArgumentException("Multiple @MethodName parameters in " + method); @@ -203,6 +210,7 @@ public class InterceptionInstrumenter { method.getName(), Type.getMethodDescriptor(method), thisParameterIndex, + classNameParameterIndex, methodNameParameterIndex, methodDescParameterIndex, allArgsParameterIndex); @@ -338,7 +346,7 @@ public class InterceptionInstrumenter { for (MethodData methodData : enterData) { // At the very beginning of a constructor, i.e. before any super() call, 'this' is not available // It's too hard to detect a place right after the super() call, so we just put null instead of 'this' in such cases - invokeMethod(access, name, desc, getInstructionAdapter(), methodData, isConstructor); + invokeMethod(access, cr.getClassName(), name, desc, getInstructionAdapter(), methodData, isConstructor); } super.visitCode(); } @@ -353,13 +361,13 @@ public class InterceptionInstrumenter { case DRETURN: case ARETURN: for (MethodData methodData : normalReturnData) { - invokeMethod(access, name, desc, getInstructionAdapter(), methodData, false); + invokeMethod(access, cr.getClassName(), name, desc, getInstructionAdapter(), methodData, false); } break; case ATHROW: for (MethodData methodData : exceptionData) { // A constructor may throw before calling super(), 'this' is not available in this case - invokeMethod(access, name, desc, getInstructionAdapter(), methodData, isConstructor); + invokeMethod(access, cr.getClassName(), name, desc, getInstructionAdapter(), methodData, isConstructor); } break; } @@ -445,6 +453,7 @@ public class InterceptionInstrumenter { private static void invokeMethod( int instrumentedMethodAccess, + String instrumentedClassName, String instrumentedMethodName, String instrumentedMethodDesc, InstructionAdapter ia, @@ -475,6 +484,9 @@ public class InterceptionInstrumenter { ia.load(0, OBJECT_TYPE); } } + else if (i == methodData.getClassNameParameterIndex()) { + ia.aconst(instrumentedClassName); + } else if (i == methodData.getMethodNameParameterIndex()) { ia.aconst(instrumentedMethodName); } diff --git a/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/MethodData.java b/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/MethodData.java index 31936fea2fa..3a743ecc2a1 100644 --- a/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/MethodData.java +++ b/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/MethodData.java @@ -19,6 +19,7 @@ package org.jetbrains.jet.preloading.instrumentation; public class MethodData extends MemberData { private final FieldData ownerField; private final int thisParameterIndex; + private final int classNameParameterIndex; private final int methodNameParameterIndex; private final int methodDescParameterIndex; private final int allArgsParameterIndex; @@ -29,6 +30,7 @@ public class MethodData extends MemberData { String name, String desc, int thisParameterIndex, + int classNameParameterIndex, int methodNameParameterIndex, int methodDescParameterIndex, int allArgsParameterIndex @@ -36,6 +38,7 @@ public class MethodData extends MemberData { super(declaringClass, name, desc); this.ownerField = ownerField; this.thisParameterIndex = thisParameterIndex; + this.classNameParameterIndex = classNameParameterIndex; this.methodNameParameterIndex = methodNameParameterIndex; this.methodDescParameterIndex = methodDescParameterIndex; this.allArgsParameterIndex = allArgsParameterIndex; @@ -49,6 +52,10 @@ public class MethodData extends MemberData { return thisParameterIndex; } + public int getClassNameParameterIndex() { + return classNameParameterIndex; + } + public int getMethodNameParameterIndex() { return methodNameParameterIndex; } diff --git a/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/annotations/ClassName.java b/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/annotations/ClassName.java new file mode 100644 index 00000000000..f2c70b404cb --- /dev/null +++ b/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/annotations/ClassName.java @@ -0,0 +1,27 @@ +/* + * Copyright 2010-2013 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.jetbrains.jet.preloading.instrumentation.annotations; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Target(ElementType.PARAMETER) +@Retention(RetentionPolicy.RUNTIME) +public @interface ClassName { +} From bdd4296b0dd0abb544e6d2b3b94b8ca534555278 Mon Sep 17 00:00:00 2001 From: Andrey Breslav Date: Mon, 13 May 2013 18:47:21 +0400 Subject: [PATCH 042/249] Fix parameter indexing problem --- .../instrumentation/InterceptionInstrumenter.java | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/InterceptionInstrumenter.java b/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/InterceptionInstrumenter.java index 436aa6ebaba..1d8f287e146 100644 --- a/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/InterceptionInstrumenter.java +++ b/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/InterceptionInstrumenter.java @@ -471,7 +471,8 @@ public class InterceptionInstrumenter { Type[] parameterTypes = Type.getArgumentTypes(instrumentedMethodDesc); boolean isStatic = (instrumentedMethodAccess & ACC_STATIC) != 0; int base = isStatic ? 0 : 1; - int parameterOffset = 0; + int instrumentedMethodParameterIndex = 0; + int instrumentedMethodParameterOffset = 0; for (int i = 0; i < parameterCount; i++) { if (i == methodData.getThisParameterIndex()) { if (isStatic || thisUnavailable) { @@ -511,9 +512,10 @@ public class InterceptionInstrumenter { } } else { - Type type = parameterTypes[parameterOffset]; - ia.load(base + parameterOffset, type); - parameterOffset += type.getSize(); + Type type = parameterTypes[instrumentedMethodParameterIndex]; + ia.load(base + instrumentedMethodParameterOffset, type); + instrumentedMethodParameterIndex++; + instrumentedMethodParameterOffset += type.getSize(); } } From 39c9cbcd9ee997ef1c88e2379a265813a6e6a0ed Mon Sep 17 00:00:00 2001 From: Andrey Breslav Date: Mon, 13 May 2013 19:04:43 +0400 Subject: [PATCH 043/249] Box arguments if needed --- .../ProfilingInstrumenterExample.java | 34 +++++++++++-- .../InterceptionInstrumenter.java | 48 ++++++++++++------- 2 files changed, 62 insertions(+), 20 deletions(-) diff --git a/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/ProfilingInstrumenterExample.java b/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/ProfilingInstrumenterExample.java index 9444aa61012..84cd06441a2 100644 --- a/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/ProfilingInstrumenterExample.java +++ b/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/ProfilingInstrumenterExample.java @@ -103,16 +103,44 @@ public class ProfilingInstrumenterExample extends InterceptionInstrumenterAdapto public static Object d = new MethodCollector(); public static class MethodCollector { - private final Collection l = new LinkedHashSet(); + private final Collection collected = new LinkedHashSet(); public void enter(@ClassName String className, @MethodName String name, @MethodDesc String desc) { - l.add(className + "." + name + desc); + collected.add(className + "." + name + desc); } public void dump(PrintStream out) { - for (String s : l) { + for (String s : collected) { out.println(s); } } } + + // What integers are passed as first arguments to any methods? + @MethodInterceptor(className = ".*", + methodName = ".*", + methodDesc = "\\(.+\\).*", + allowMultipleMatches = true) + public static Object e = new FirstArgumentCollector() { + @Override + protected boolean accept(Object arg) { + return arg instanceof Integer; + } + }; + + public static abstract class FirstArgumentCollector { + private final Collection collected = new HashSet(); + + protected abstract boolean accept(Object arg); + + public void enter(Object arg) { + if (accept(arg)) { + collected.add(arg); + } + } + + public void dump(PrintStream out) { + out.println("Arguments: " + collected.size()); + } + } } diff --git a/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/InterceptionInstrumenter.java b/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/InterceptionInstrumenter.java index 1d8f287e146..a8a868b5b28 100644 --- a/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/InterceptionInstrumenter.java +++ b/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/InterceptionInstrumenter.java @@ -466,9 +466,10 @@ public class InterceptionInstrumenter { org.jetbrains.asm4.commons.Method asmMethod = getAsmMethod(methodData); - int parameterCount = asmMethod.getArgumentTypes().length; + Type[] interceptingMethodParameterTypes = asmMethod.getArgumentTypes(); + int parameterCount = interceptingMethodParameterTypes.length; if (parameterCount > 0) { - Type[] parameterTypes = Type.getArgumentTypes(instrumentedMethodDesc); + Type[] instrumentedMethodParameterTypes = Type.getArgumentTypes(instrumentedMethodDesc); boolean isStatic = (instrumentedMethodAccess & ACC_STATIC) != 0; int base = isStatic ? 0 : 1; int instrumentedMethodParameterIndex = 0; @@ -495,25 +496,27 @@ public class InterceptionInstrumenter { ia.aconst(instrumentedMethodDesc); } else if (i == methodData.getAllArgsParameterIndex()) { - ia.aconst(parameterTypes.length); + ia.aconst(instrumentedMethodParameterTypes.length); ia.newarray(OBJECT_TYPE); int offset = 0; - for (int parameterIndex = 0; parameterIndex < parameterTypes.length; parameterIndex++) { + for (int parameterIndex = 0; parameterIndex < instrumentedMethodParameterTypes.length; parameterIndex++) { ia.dup(); ia.iconst(parameterIndex); - Type type = parameterTypes[parameterIndex]; + Type type = instrumentedMethodParameterTypes[parameterIndex]; ia.load(base + offset, type); offset += type.getSize(); - applyBoxingIfNeeded(ia, type); + boxOrCastIfNeeded(ia, type, OBJECT_TYPE); ia.astore(OBJECT_TYPE); } } else { - Type type = parameterTypes[instrumentedMethodParameterIndex]; + Type type = instrumentedMethodParameterTypes[instrumentedMethodParameterIndex]; ia.load(base + instrumentedMethodParameterOffset, type); + boxOrCastIfNeeded(ia, type, interceptingMethodParameterTypes[i]); + instrumentedMethodParameterIndex++; instrumentedMethodParameterOffset += type.getSize(); } @@ -532,37 +535,48 @@ public class InterceptionInstrumenter { } } - private static void applyBoxingIfNeeded(InstructionAdapter ia, Type type) { - switch (type.getSort()) { + private static void boxOrCastIfNeeded(InstructionAdapter ia, Type from, Type to) { + if (isPrimitive(to)) { + if (!isPrimitive(from)) { + throw new IllegalArgumentException("Cannot cast " + from + " to " + to); + } + ia.cast(from, to); + return; + } + switch (from.getSort()) { case Type.BOOLEAN: - box(ia, type, Boolean.class); + box(ia, from, Boolean.class); break; case Type.CHAR: - box(ia, type, Character.class); + box(ia, from, Character.class); break; case Type.BYTE: - box(ia, type, Byte.class); + box(ia, from, Byte.class); break; case Type.SHORT: - box(ia, type, Short.class); + box(ia, from, Short.class); break; case Type.INT: - box(ia, type, Integer.class); + box(ia, from, Integer.class); break; case Type.FLOAT: - box(ia, type, Float.class); + box(ia, from, Float.class); break; case Type.LONG: - box(ia, type, Long.class); + box(ia, from, Long.class); break; case Type.DOUBLE: - box(ia, type, Double.class); + box(ia, from, Double.class); break; default: // Nothing to do, it's an object already } } + private static boolean isPrimitive(Type to) { + return to.getSort() <= Type.DOUBLE; + } + private static void box(InstructionAdapter ia, Type from, Class boxedClass) { Type boxedType = Type.getType(boxedClass); ia.invokestatic(boxedType.getInternalName(), "valueOf", "(" + from.getDescriptor() + ")" + boxedType.getDescriptor()); From bb12685004b08a56864436ce46f57190a742720a Mon Sep 17 00:00:00 2001 From: Andrey Breslav Date: Mon, 13 May 2013 19:15:07 +0400 Subject: [PATCH 044/249] Allow using anonymous classes as interceptors --- .../preloading/instrumentation/InterceptionInstrumenter.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/InterceptionInstrumenter.java b/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/InterceptionInstrumenter.java index a8a868b5b28..06a14340055 100644 --- a/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/InterceptionInstrumenter.java +++ b/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/InterceptionInstrumenter.java @@ -220,7 +220,7 @@ public class InterceptionInstrumenter { dumpTasks.add(new DumpAction() { @Override public void dump(PrintStream out) { - out.println("<<< " + instrumenter + ": " + interceptor.getClass().getCanonicalName() + " says:"); + out.println("<<< " + instrumenter + ": " + interceptor.getClass().getName() + " says:"); try { if (method.getParameterTypes().length == 0) { method.invoke(interceptor); @@ -462,7 +462,7 @@ public class InterceptionInstrumenter { ) { FieldData field = methodData.getOwnerField(); ia.getstatic(field.getDeclaringClass(), field.getName(), field.getDesc()); - ia.checkcast(field.getRuntimeType()); + ia.checkcast(Type.getObjectType(methodData.getDeclaringClass())); org.jetbrains.asm4.commons.Method asmMethod = getAsmMethod(methodData); From 551c3702425cfcc368e7c40ec8545d6090c4ca8a Mon Sep 17 00:00:00 2001 From: Andrey Breslav Date: Mon, 13 May 2013 19:37:24 +0400 Subject: [PATCH 045/249] dumpByteCode flag --- .../jet/preloading/ProfilingInstrumenterExample.java | 5 +++-- .../instrumentation/InterceptionInstrumenter.java | 11 ++++++----- .../instrumentation/MethodInstrumenter.java | 10 +++++++++- .../annotations/MethodInterceptor.java | 3 +++ 4 files changed, 21 insertions(+), 8 deletions(-) diff --git a/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/ProfilingInstrumenterExample.java b/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/ProfilingInstrumenterExample.java index 84cd06441a2..4ba01b3316f 100644 --- a/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/ProfilingInstrumenterExample.java +++ b/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/ProfilingInstrumenterExample.java @@ -76,10 +76,11 @@ public class ProfilingInstrumenterExample extends InterceptionInstrumenterAdapto } } - // Collect all strings that were capitalized using StringUtil + // Collect all strings that were capitalized using StringUtil, and dump its instrumented byte code @MethodInterceptor(className = "com/intellij/openapi/util/text/StringUtil", methodName = "capitalize", - methodDesc = "\\(Ljava/lang/String;\\).*") + methodDesc = "\\(Ljava/lang/String;\\).*", + dumpByteCode = true) public static Object c = new CollectFirstArguments(); public static class CollectFirstArguments { diff --git a/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/InterceptionInstrumenter.java b/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/InterceptionInstrumenter.java index 06a14340055..48b3b0b466c 100644 --- a/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/InterceptionInstrumenter.java +++ b/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/InterceptionInstrumenter.java @@ -37,9 +37,6 @@ public class InterceptionInstrumenter { private static final Pattern ANYTHING = Pattern.compile(".*"); private static final Type OBJECT_TYPE = Type.getType(Object.class); - //private final boolean dumpInstrumentedMethods = true; - private final boolean dumpInstrumentedMethods = false; - private final Map classPatterns = new LinkedHashMap(); private final Set neverMatchedClassPatterns = new LinkedHashSet(); @@ -129,7 +126,8 @@ public class InterceptionInstrumenter { enterData, normalReturnData, exceptionData, - annotation.logInterceptions()); + annotation.logInterceptions(), + annotation.dumpByteCode()); for (Method dumpMethod : dumpMethods) { addDumpTask(interceptor, dumpMethod, instrumenter); @@ -305,6 +303,7 @@ public class InterceptionInstrumenter { if (applicableInstrumenters.isEmpty()) return mv; + boolean dumpByteCode = false; final List normalReturnData = new ArrayList(); final List enterData = new ArrayList(); final List exceptionData = new ArrayList(); @@ -314,11 +313,13 @@ public class InterceptionInstrumenter { normalReturnData.addAll(instrumenter.getNormalReturnData()); exceptionData.addAll(instrumenter.getExceptionData()); + + dumpByteCode |= instrumenter.shouldDumpByteCode(); } if (enterData.isEmpty() && normalReturnData.isEmpty() && exceptionData.isEmpty()) return mv; - if (dumpInstrumentedMethods) { + if (dumpByteCode) { mv = getDumpingVisitorWrapper(mv, name, desc); } diff --git a/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/MethodInstrumenter.java b/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/MethodInstrumenter.java index d1e4be18737..504c1663262 100644 --- a/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/MethodInstrumenter.java +++ b/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/MethodInstrumenter.java @@ -29,6 +29,7 @@ class MethodInstrumenter { private final List normalReturnData; private final List exceptionData; private final boolean logApplications; + private final boolean dumpByteCode; public MethodInstrumenter( String debugName, @@ -37,7 +38,9 @@ class MethodInstrumenter { boolean allowMultipleMatches, List enterData, List normalReturnData, - List exceptionData, boolean logApplications + List exceptionData, + boolean logApplications, + boolean dumpByteCode ) { this.debugName = debugName; this.classPattern = classPattern; @@ -48,6 +51,7 @@ class MethodInstrumenter { this.normalReturnData = normalReturnData; this.exceptionData = exceptionData; this.logApplications = logApplications; + this.dumpByteCode = dumpByteCode; } public boolean allowsMultipleMatches() { @@ -76,6 +80,10 @@ class MethodInstrumenter { return exceptionData; } + boolean shouldDumpByteCode() { + return dumpByteCode; + } + @Override public String toString() { return debugName + "[" + classPattern + ":" + namePattern + " " + descPattern + (allowMultipleMatches ? " multiple" : "") + "]"; diff --git a/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/annotations/MethodInterceptor.java b/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/annotations/MethodInterceptor.java index 20370f16514..1c3c2dbdb7f 100644 --- a/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/annotations/MethodInterceptor.java +++ b/compiler/preloader/instrumentation/src/org/jetbrains/jet/preloading/instrumentation/annotations/MethodInterceptor.java @@ -38,4 +38,7 @@ public @interface MethodInterceptor { // if true, every method instrumented with this interceptor will be logged to stdout boolean logInterceptions() default false; + + // if true, byte codes of every method instrumented with this interceptor will be logged to stdout + boolean dumpByteCode() default false; } From 9e584ded111da98a17467b44088e867b765be116 Mon Sep 17 00:00:00 2001 From: "Natalia.Ukhorskaya" Date: Wed, 8 May 2013 17:17:39 +0400 Subject: [PATCH 046/249] ClassFormatError because of initializing variable with Any type with primitive value #KT-3524 Fixed --- .../src/org/jetbrains/jet/codegen/PropertyCodegen.java | 6 +++--- compiler/testData/codegen/box/properties/kt3524.kt | 5 +++++ .../jet/codegen/generated/BlackBoxCodegenTestGenerated.java | 5 +++++ 3 files changed, 13 insertions(+), 3 deletions(-) create mode 100644 compiler/testData/codegen/box/properties/kt3524.kt diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/PropertyCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/PropertyCodegen.java index bdfc892065b..7deeef9a3a0 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/PropertyCodegen.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/PropertyCodegen.java @@ -122,9 +122,9 @@ public class PropertyCodegen extends GenerationStateAware { private FieldVisitor generateBackingFieldAccess(PsiElement p, PropertyDescriptor propertyDescriptor) { Object value = null; - JetExpression initializer = p instanceof JetProperty ? ((JetProperty) p).getInitializer() : null; - if (initializer != null) { - if (initializer instanceof JetConstantExpression && !propertyDescriptor.getType().isNullable()) { + if (p instanceof JetProperty && !ImplementationBodyCodegen.shouldInitializeProperty((JetProperty) p, typeMapper)) { + JetExpression initializer = ((JetProperty) p).getInitializer(); + if (initializer != null) { CompileTimeConstant compileTimeValue = bindingContext.get(BindingContext.COMPILE_TIME_VALUE, initializer); value = compileTimeValue != null ? compileTimeValue.getValue() : null; } diff --git a/compiler/testData/codegen/box/properties/kt3524.kt b/compiler/testData/codegen/box/properties/kt3524.kt new file mode 100644 index 00000000000..3fcdaaebcf1 --- /dev/null +++ b/compiler/testData/codegen/box/properties/kt3524.kt @@ -0,0 +1,5 @@ +val i: Any = 12 + +fun box(): String { + return if (i == 12) "OK" else "fail" +} \ No newline at end of file diff --git a/compiler/tests/org/jetbrains/jet/codegen/generated/BlackBoxCodegenTestGenerated.java b/compiler/tests/org/jetbrains/jet/codegen/generated/BlackBoxCodegenTestGenerated.java index d2ddcaef902..2d7d964b432 100644 --- a/compiler/tests/org/jetbrains/jet/codegen/generated/BlackBoxCodegenTestGenerated.java +++ b/compiler/tests/org/jetbrains/jet/codegen/generated/BlackBoxCodegenTestGenerated.java @@ -3534,6 +3534,11 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest { doTest("compiler/testData/codegen/box/properties/kt3118.kt"); } + @TestMetadata("kt3524.kt") + public void testKt3524() throws Exception { + doTest("compiler/testData/codegen/box/properties/kt3524.kt"); + } + @TestMetadata("kt3551.kt") public void testKt3551() throws Exception { doTest("compiler/testData/codegen/box/properties/kt3551.kt"); From af5f2f09deefb096ad79dae82220d2333f59a755 Mon Sep 17 00:00:00 2001 From: "Natalia.Ukhorskaya" Date: Tue, 14 May 2013 12:38:15 +0400 Subject: [PATCH 047/249] Minor refactoring: add annotations --- .../jetbrains/jet/lang/resolve/BodyResolver.java | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/BodyResolver.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/BodyResolver.java index c2f382593bd..cb2c01f5579 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/BodyResolver.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/BodyResolver.java @@ -497,12 +497,21 @@ public class BodyResolver { } } - private void resolvePropertyInitializer(JetProperty property, PropertyDescriptor propertyDescriptor, JetExpression initializer) { + private void resolvePropertyInitializer( + @NotNull JetProperty property, + @NotNull PropertyDescriptor propertyDescriptor, + @NotNull JetExpression initializer + ) { JetScope propertyDeclarationInnerScope = makeScopeForPropertyInitializerOrDelegate(property, propertyDescriptor); resolvePropertyInitializer(property, propertyDescriptor, initializer, propertyDeclarationInnerScope); } - public void resolvePropertyInitializer(JetProperty property, PropertyDescriptor propertyDescriptor, JetExpression initializer, JetScope scope) { + public void resolvePropertyInitializer( + @NotNull JetProperty property, + @NotNull PropertyDescriptor propertyDescriptor, + @NotNull JetExpression initializer, + @NotNull JetScope scope + ) { JetScope propertyDeclarationInnerScope = descriptorResolver.getPropertyDeclarationInnerScopeForInitializer( scope, propertyDescriptor.getTypeParameters(), NO_RECEIVER_PARAMETER, trace); JetType expectedTypeForInitializer = property.getTypeRef() != null ? propertyDescriptor.getType() : NO_EXPECTED_TYPE; From 3795af90d93219561c9274c0aaad29be771e148a Mon Sep 17 00:00:00 2001 From: "Natalia.Ukhorskaya" Date: Tue, 14 May 2013 13:12:34 +0400 Subject: [PATCH 048/249] Remove redundant scope creation for property initializer --- .../jetbrains/jet/lang/resolve/BodyResolver.java | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/BodyResolver.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/BodyResolver.java index cb2c01f5579..69038aff6dd 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/BodyResolver.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/BodyResolver.java @@ -483,8 +483,10 @@ public class BodyResolver { trace.report(ACCESSOR_FOR_DELEGATED_PROPERTY.on(setter)); } - JetScope scope = makeScopeForPropertyInitializerOrDelegate(jetProperty, propertyDescriptor); - JetType delegateType = expressionTypingServices.safeGetType(scope, delegateExpression, NO_EXPECTED_TYPE, + JetScope propertyScope = getScopeForProperty(jetProperty); + JetScope propertyDeclarationInnerScope = descriptorResolver.getPropertyDeclarationInnerScopeForInitializer( + propertyScope, propertyDescriptor.getTypeParameters(), NO_RECEIVER_PARAMETER, trace); + JetType delegateType = expressionTypingServices.safeGetType(propertyDeclarationInnerScope, delegateExpression, NO_EXPECTED_TYPE, DataFlowInfo.EMPTY, trace); JetScope accessorScope = JetScopeUtils.makeScopeForPropertyAccessor(propertyDescriptor, parentScopeForAccessor, descriptorResolver, trace); @@ -502,7 +504,7 @@ public class BodyResolver { @NotNull PropertyDescriptor propertyDescriptor, @NotNull JetExpression initializer ) { - JetScope propertyDeclarationInnerScope = makeScopeForPropertyInitializerOrDelegate(property, propertyDescriptor); + JetScope propertyDeclarationInnerScope = getScopeForProperty(property); resolvePropertyInitializer(property, propertyDescriptor, initializer, propertyDeclarationInnerScope); } @@ -519,11 +521,10 @@ public class BodyResolver { } @NotNull - private JetScope makeScopeForPropertyInitializerOrDelegate(@NotNull JetProperty property, @NotNull PropertyDescriptor descriptor) { + private JetScope getScopeForProperty(@NotNull JetProperty property) { JetScope scope = this.context.getDeclaringScopes().apply(property); assert scope != null : "Scope for property " + property.getText() + " should exists"; - return descriptorResolver.getPropertyDeclarationInnerScopeForInitializer( - scope, descriptor.getTypeParameters(), NO_RECEIVER_PARAMETER, trace); + return scope; } private void resolveFunctionBodies() { From aca6e97cf5eb60e57b4091c27d489a9b3ecd24c8 Mon Sep 17 00:00:00 2001 From: "Natalia.Ukhorskaya" Date: Tue, 14 May 2013 13:19:44 +0400 Subject: [PATCH 049/249] Create method for resolving delegate with scope (for resolve from ResolveSessionUtils) --- .../org/jetbrains/jet/lang/resolve/BodyResolver.java | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/BodyResolver.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/BodyResolver.java index 69038aff6dd..6a8497f0256 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/BodyResolver.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/BodyResolver.java @@ -472,6 +472,17 @@ public class BodyResolver { @NotNull PropertyDescriptor propertyDescriptor, @NotNull JetExpression delegateExpression, @NotNull JetScope parentScopeForAccessor + ) { + JetScope propertyDeclarationInnerScope = getScopeForProperty(jetProperty); + resolvePropertyDelegate(jetProperty, propertyDescriptor, delegateExpression, parentScopeForAccessor, propertyDeclarationInnerScope); + } + + public void resolvePropertyDelegate( + @NotNull JetProperty jetProperty, + @NotNull PropertyDescriptor propertyDescriptor, + @NotNull JetExpression delegateExpression, + @NotNull JetScope parentScopeForAccessor, + @NotNull JetScope propertyScope ) { JetPropertyAccessor getter = jetProperty.getGetter(); if (getter != null) { @@ -483,7 +494,6 @@ public class BodyResolver { trace.report(ACCESSOR_FOR_DELEGATED_PROPERTY.on(setter)); } - JetScope propertyScope = getScopeForProperty(jetProperty); JetScope propertyDeclarationInnerScope = descriptorResolver.getPropertyDeclarationInnerScopeForInitializer( propertyScope, propertyDescriptor.getTypeParameters(), NO_RECEIVER_PARAMETER, trace); JetType delegateType = expressionTypingServices.safeGetType(propertyDeclarationInnerScope, delegateExpression, NO_EXPECTED_TYPE, From 389563dd181508a3aba6be4bac7a55d14945a945 Mon Sep 17 00:00:00 2001 From: "Natalia.Ukhorskaya" Date: Tue, 14 May 2013 13:22:27 +0400 Subject: [PATCH 050/249] Refactoring: inline methods call --- .../jet/lang/resolve/BodyResolver.java | 27 +++---------------- 1 file changed, 4 insertions(+), 23 deletions(-) diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/BodyResolver.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/BodyResolver.java index 6a8497f0256..c959002b284 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/BodyResolver.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/BodyResolver.java @@ -385,14 +385,14 @@ public class BodyResolver { if (initializer != null) { ConstructorDescriptor primaryConstructor = classDescriptor.getUnsubstitutedPrimaryConstructor(); if (primaryConstructor != null) { - resolvePropertyInitializer(property, propertyDescriptor, initializer); + resolvePropertyInitializer(property, propertyDescriptor, initializer, getScopeForProperty(property)); } } JetExpression delegateExpression = property.getDelegateExpression(); if (delegateExpression != null) { assert initializer == null : "Initializer should be null for delegated property : " + property.getText(); - resolvePropertyDelegate(property, propertyDescriptor, delegateExpression, classDescriptor.getScopeForMemberResolution()); + resolvePropertyDelegate(property, propertyDescriptor, delegateExpression, classDescriptor.getScopeForMemberResolution(), getScopeForProperty(property)); } resolvePropertyAccessors(property, propertyDescriptor); @@ -412,14 +412,14 @@ public class BodyResolver { JetExpression initializer = property.getInitializer(); if (initializer != null) { - resolvePropertyInitializer(property, propertyDescriptor, initializer); + resolvePropertyInitializer(property, propertyDescriptor, initializer, getScopeForProperty(property)); } JetExpression delegateExpression = property.getDelegateExpression(); if (delegateExpression != null) { assert initializer == null : "Initializer should be null for delegated property : " + property.getText(); JetScope scope = context.getDeclaringScopes().apply(property); - resolvePropertyDelegate(property, propertyDescriptor, delegateExpression, scope); + resolvePropertyDelegate(property, propertyDescriptor, delegateExpression, scope, getScopeForProperty(property)); } resolvePropertyAccessors(property, propertyDescriptor); @@ -467,16 +467,6 @@ public class BodyResolver { }); } - private void resolvePropertyDelegate( - @NotNull JetProperty jetProperty, - @NotNull PropertyDescriptor propertyDescriptor, - @NotNull JetExpression delegateExpression, - @NotNull JetScope parentScopeForAccessor - ) { - JetScope propertyDeclarationInnerScope = getScopeForProperty(jetProperty); - resolvePropertyDelegate(jetProperty, propertyDescriptor, delegateExpression, parentScopeForAccessor, propertyDeclarationInnerScope); - } - public void resolvePropertyDelegate( @NotNull JetProperty jetProperty, @NotNull PropertyDescriptor propertyDescriptor, @@ -509,15 +499,6 @@ public class BodyResolver { } } - private void resolvePropertyInitializer( - @NotNull JetProperty property, - @NotNull PropertyDescriptor propertyDescriptor, - @NotNull JetExpression initializer - ) { - JetScope propertyDeclarationInnerScope = getScopeForProperty(property); - resolvePropertyInitializer(property, propertyDescriptor, initializer, propertyDeclarationInnerScope); - } - public void resolvePropertyInitializer( @NotNull JetProperty property, @NotNull PropertyDescriptor propertyDescriptor, From de446a83f9265c2342ce1e472a7eaed2de8c55ac Mon Sep 17 00:00:00 2001 From: "Natalia.Ukhorskaya" Date: Tue, 14 May 2013 13:24:15 +0400 Subject: [PATCH 051/249] Refactoring: introduce variables for property scope --- .../org/jetbrains/jet/lang/resolve/BodyResolver.java | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/BodyResolver.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/BodyResolver.java index c959002b284..19c1188212f 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/BodyResolver.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/BodyResolver.java @@ -382,17 +382,18 @@ public class BodyResolver { computeDeferredType(propertyDescriptor.getReturnType()); JetExpression initializer = property.getInitializer(); + JetScope propertyScope = getScopeForProperty(property); if (initializer != null) { ConstructorDescriptor primaryConstructor = classDescriptor.getUnsubstitutedPrimaryConstructor(); if (primaryConstructor != null) { - resolvePropertyInitializer(property, propertyDescriptor, initializer, getScopeForProperty(property)); + resolvePropertyInitializer(property, propertyDescriptor, initializer, propertyScope); } } JetExpression delegateExpression = property.getDelegateExpression(); if (delegateExpression != null) { assert initializer == null : "Initializer should be null for delegated property : " + property.getText(); - resolvePropertyDelegate(property, propertyDescriptor, delegateExpression, classDescriptor.getScopeForMemberResolution(), getScopeForProperty(property)); + resolvePropertyDelegate(property, propertyDescriptor, delegateExpression, classDescriptor.getScopeForMemberResolution(), propertyScope); } resolvePropertyAccessors(property, propertyDescriptor); @@ -411,15 +412,15 @@ public class BodyResolver { computeDeferredType(propertyDescriptor.getReturnType()); JetExpression initializer = property.getInitializer(); + JetScope propertyScope = getScopeForProperty(property); if (initializer != null) { - resolvePropertyInitializer(property, propertyDescriptor, initializer, getScopeForProperty(property)); + resolvePropertyInitializer(property, propertyDescriptor, initializer, propertyScope); } JetExpression delegateExpression = property.getDelegateExpression(); if (delegateExpression != null) { assert initializer == null : "Initializer should be null for delegated property : " + property.getText(); - JetScope scope = context.getDeclaringScopes().apply(property); - resolvePropertyDelegate(property, propertyDescriptor, delegateExpression, scope, getScopeForProperty(property)); + resolvePropertyDelegate(property, propertyDescriptor, delegateExpression, propertyScope, propertyScope); } resolvePropertyAccessors(property, propertyDescriptor); From 04120f432ce3be5e9484a131f76b8b204913d1d1 Mon Sep 17 00:00:00 2001 From: "Natalia.Ukhorskaya" Date: Tue, 14 May 2013 13:06:10 +0400 Subject: [PATCH 052/249] Delegate properties break "Debug..." and "Run..." actions when type is specified #KT-3594 Fixed --- .../jet/lang/resolve/lazy/ResolveSessionUtils.java | 6 +++++- .../jet/lang/types/expressions/DelegatedPropertyUtils.java | 6 ++---- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/lazy/ResolveSessionUtils.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/lazy/ResolveSessionUtils.java index 3ec28b87236..548ec9d408a 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/lazy/ResolveSessionUtils.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/lazy/ResolveSessionUtils.java @@ -189,11 +189,15 @@ public class ResolveSessionUtils { PropertyDescriptor descriptor = (PropertyDescriptor) resolveSession.resolveToDescriptor(jetProperty); JetExpression propertyInitializer = jetProperty.getInitializer(); - if (propertyInitializer != null) { bodyResolver.resolvePropertyInitializer(jetProperty, descriptor, propertyInitializer, propertyResolutionScope); } + JetExpression propertyDelegate = jetProperty.getDelegateExpression(); + if (propertyDelegate != null) { + bodyResolver.resolvePropertyDelegate(jetProperty, descriptor, propertyDelegate, propertyResolutionScope, propertyResolutionScope); + } + bodyResolver.resolvePropertyAccessors(jetProperty, descriptor); } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/DelegatedPropertyUtils.java b/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/DelegatedPropertyUtils.java index 2e38bbfcc0c..a80402c2e53 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/DelegatedPropertyUtils.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/DelegatedPropertyUtils.java @@ -88,11 +88,9 @@ public class DelegatedPropertyUtils { scope, true); JetType returnType = getDelegateGetMethodReturnType(trace.getBindingContext(), propertyDescriptor); JetType propertyType = propertyDescriptor.getType(); - if (propertyType instanceof DeferredType) { - assert ((DeferredType) propertyType).isComputed() : "Property type should be computed when resolving delegate convention method"; - } - if (returnType != null && !JetTypeChecker.INSTANCE.isSubtypeOf(returnType, propertyType)) { + /* Do not check return type of get() method of delegate for properties with DeferredType because property type is taken from it */ + if (!(propertyType instanceof DeferredType) && returnType != null && !JetTypeChecker.INSTANCE.isSubtypeOf(returnType, propertyType)) { Call call = trace.getBindingContext().get(DELEGATED_PROPERTY_CALL, propertyDescriptor.getGetter()); assert call != null : "Call should exists for " + propertyDescriptor.getGetter(); trace.report(DELEGATE_SPECIAL_FUNCTION_RETURN_TYPE_MISMATCH From 32c5f5f59da0597bc6e366cabe8d13f2cfab39fe Mon Sep 17 00:00:00 2001 From: "Natalia.Ukhorskaya" Date: Tue, 14 May 2013 12:21:14 +0400 Subject: [PATCH 053/249] EA-46019 - assert: PropertyCodegen.generatePropertyDelegateAccess: delegate type can be null when delegate expression is unresolved and back-end called from light class generation --- .../src/org/jetbrains/jet/codegen/PropertyCodegen.java | 6 +++++- idea/testData/javaFacade/ea46019.kt | 7 +++++++ .../jetbrains/jet/plugin/javaFacade/JetJavaFacadeTest.java | 4 ++++ 3 files changed, 16 insertions(+), 1 deletion(-) create mode 100644 idea/testData/javaFacade/ea46019.kt diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/PropertyCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/PropertyCodegen.java index 7deeef9a3a0..10a7bee673e 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/PropertyCodegen.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/PropertyCodegen.java @@ -40,6 +40,7 @@ import org.jetbrains.jet.lang.resolve.java.JvmAbi; import org.jetbrains.jet.lang.resolve.java.JvmStdlibNames; import org.jetbrains.jet.lang.resolve.java.kt.DescriptorKindUtils; import org.jetbrains.jet.lang.resolve.name.Name; +import org.jetbrains.jet.lang.types.ErrorUtils; import org.jetbrains.jet.lang.types.JetType; import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns; @@ -114,7 +115,10 @@ public class PropertyCodegen extends GenerationStateAware { modifiers |= ACC_VOLATILE; } JetType delegateType = bindingContext.get(BindingContext.EXPRESSION_TYPE, p.getDelegateExpression()); - assert delegateType != null : "Type of delegate should be recorded: " + p.getText(); + if (delegateType == null) { + // If delegate expression is unresolved reference + delegateType = ErrorUtils.createErrorType("Delegate type"); + } Type type = typeMapper.mapType(delegateType); return v.newField(p, modifiers, JvmAbi.getPropertyDelegateName(propertyDescriptor.getName()), type.getDescriptor(), null, null); diff --git a/idea/testData/javaFacade/ea46019.kt b/idea/testData/javaFacade/ea46019.kt new file mode 100644 index 00000000000..3ad65c81733 --- /dev/null +++ b/idea/testData/javaFacade/ea46019.kt @@ -0,0 +1,7 @@ +class SomeProp() { + fun get(t: Any, metadata: PropertyMetadataImpl) = 42 +} + +class Some() { + val renderer by SomeProp() +} \ No newline at end of file diff --git a/idea/tests/org/jetbrains/jet/plugin/javaFacade/JetJavaFacadeTest.java b/idea/tests/org/jetbrains/jet/plugin/javaFacade/JetJavaFacadeTest.java index 19761039ba6..fbdae321873 100644 --- a/idea/tests/org/jetbrains/jet/plugin/javaFacade/JetJavaFacadeTest.java +++ b/idea/tests/org/jetbrains/jet/plugin/javaFacade/JetJavaFacadeTest.java @@ -87,6 +87,10 @@ public class JetJavaFacadeTest extends LightCodeInsightFixtureTestCase { doTestWrapClass(); } + public void testEa46019() { + doTestWrapClass(); + } + public void testEa38770() { myFixture.configureByFile(getTestName(true) + ".kt"); From 308b1a3f29aa8059fbd4744c3bc967c6c15d4660 Mon Sep 17 00:00:00 2001 From: "Natalia.Ukhorskaya" Date: Mon, 13 May 2013 17:58:21 +0400 Subject: [PATCH 054/249] Change PropertyMetadata in Library.jet --- compiler/frontend/src/jet/Library.jet | 10 ++-------- compiler/testData/builtin-classes.txt | 7 +++---- 2 files changed, 5 insertions(+), 12 deletions(-) diff --git a/compiler/frontend/src/jet/Library.jet b/compiler/frontend/src/jet/Library.jet index d78d036b747..ab4e2c39222 100644 --- a/compiler/frontend/src/jet/Library.jet +++ b/compiler/frontend/src/jet/Library.jet @@ -65,18 +65,12 @@ public open class Throwable(message : String? = null, cause: Throwable? = null) public fun printStackTrace() : Unit } -/* - * Should have an abstract property 'name', overridden in PropertyMetadataImpl - */ public trait PropertyMetadata { - public fun getName(): String + public val name: String } /* * In front-end we need to resolve call PropertyMetadataImpl() in getter of delegated property * to be able generate it in back-end using ExpressionCodegen.invokeFunction */ -public class PropertyMetadataImpl(private val innerName: String): PropertyMetadata { - public override fun getName(): String = innerName -} - +public class PropertyMetadataImpl(public override val name: String): PropertyMetadata diff --git a/compiler/testData/builtin-classes.txt b/compiler/testData/builtin-classes.txt index b9b026549f0..49213867dbf 100644 --- a/compiler/testData/builtin-classes.txt +++ b/compiler/testData/builtin-classes.txt @@ -1357,13 +1357,12 @@ public trait Progression : jet.Iterable { } public trait PropertyMetadata { - public abstract fun getName(): jet.String + public abstract val name: jet.String } public final class PropertyMetadataImpl : jet.PropertyMetadata { - public constructor PropertyMetadataImpl(/*0*/ innerName: jet.String) - private final val innerName: jet.String - public open override /*1*/ fun getName(): jet.String + public constructor PropertyMetadataImpl(/*0*/ name: jet.String) + public open override /*1*/ val name: jet.String } public trait Range> { From c27427434fadd3477d8fb9c236406d4324793d70 Mon Sep 17 00:00:00 2001 From: Svetlana Isakova Date: Tue, 14 May 2013 20:58:16 +0400 Subject: [PATCH 055/249] changes from pull request: Improved flow analysis performance for variable initialization by Spasi --- .../jet/lang/cfg/PseudocodeVariablesData.java | 38 +++++++++---------- 1 file changed, 18 insertions(+), 20 deletions(-) diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/cfg/PseudocodeVariablesData.java b/compiler/frontend/src/org/jetbrains/jet/lang/cfg/PseudocodeVariablesData.java index e8a200f7d81..1896f51b129 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/cfg/PseudocodeVariablesData.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/cfg/PseudocodeVariablesData.java @@ -45,6 +45,8 @@ public class PseudocodeVariablesData { private final Map> declaredVariablesForDeclaration = Maps.newHashMap(); private final Map> usedVariablesForDeclaration = Maps.newHashMap(); + private Map>> variableInitializers; + public PseudocodeVariablesData(@NotNull Pseudocode pseudocode, @NotNull BindingContext bindingContext) { this.pseudocode = pseudocode; this.bindingContext = bindingContext; @@ -121,7 +123,11 @@ public class PseudocodeVariablesData { @NotNull public Map>> getVariableInitializers() { - return getVariableInitializers(pseudocode); + if (variableInitializers == null) { + variableInitializers = getVariableInitializers(pseudocode); + } + + return variableInitializers; } @NotNull @@ -164,7 +170,7 @@ public class PseudocodeVariablesData { } @NotNull - private Map prepareInitializersMapForStartInstruction( + private static Map prepareInitializersMapForStartInstruction( @NotNull Collection usedVariables, @NotNull Collection declaredVariables) { @@ -184,7 +190,7 @@ public class PseudocodeVariablesData { } @NotNull - private Map mergeIncomingEdgesDataForInitializers( + private static Map mergeIncomingEdgesDataForInitializers( @NotNull Collection> incomingEdgesData) { Set variablesInScope = Sets.newHashSet(); @@ -194,14 +200,20 @@ public class PseudocodeVariablesData { Map enterInstructionData = Maps.newHashMap(); for (VariableDescriptor variable : variablesInScope) { - Set edgesDataForVariable = Sets.newHashSet(); + boolean isInitialized = true; + boolean isDeclared = true; for (Map edgeData : incomingEdgesData) { VariableInitState initState = edgeData.get(variable); if (initState != null) { - edgesDataForVariable.add(initState); + if (!initState.isInitialized) { + isInitialized = false; + } + if (!initState.isDeclared) { + isDeclared = false; + } } } - enterInstructionData.put(variable, VariableInitState.create(edgesDataForVariable)); + enterInstructionData.put(variable, VariableInitState.create(isInitialized, isDeclared)); } return enterInstructionData; } @@ -323,20 +335,6 @@ public class PseudocodeVariablesData { private static VariableInitState create(boolean isDeclaredHere, @Nullable VariableInitState mergedEdgesData) { return create(true, isDeclaredHere || (mergedEdgesData != null && mergedEdgesData.isDeclared)); } - - private static VariableInitState create(@NotNull Set edgesData) { - boolean isInitialized = true; - boolean isDeclared = true; - for (VariableInitState edgeData : edgesData) { - if (!edgeData.isInitialized) { - isInitialized = false; - } - if (!edgeData.isDeclared) { - isDeclared = false; - } - } - return create(isInitialized, isDeclared); - } } public static enum VariableUseState { From 0e96e83154fe0116a837ab691a5ef23b1eeedc70 Mon Sep 17 00:00:00 2001 From: Svetlana Isakova Date: Tue, 14 May 2013 20:58:56 +0400 Subject: [PATCH 056/249] removed unnecessary code --- .../org/jetbrains/jet/lang/cfg/JetFlowInformationProvider.java | 3 --- 1 file changed, 3 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 322e7667cf2..3776c66f4c3 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/cfg/JetFlowInformationProvider.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/cfg/JetFlowInformationProvider.java @@ -277,9 +277,6 @@ public class JetFlowInformationProvider { } boolean isInitializedNotHere = ctxt.enterInitState.isInitialized; - if (expression.getParent() instanceof JetProperty && ((JetProperty)expression).getInitializer() != null) { - isInitializedNotHere = false; - } boolean hasBackingField = true; if (variableDescriptor instanceof PropertyDescriptor) { hasBackingField = trace.get(BindingContext.BACKING_FIELD_REQUIRED, (PropertyDescriptor) variableDescriptor); From 68cd832831efef952858a042864fdad14617acc8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Sapalski?= Date: Thu, 2 May 2013 16:26:07 +0200 Subject: [PATCH 057/249] Search in all superclasses in quickfix for NOTHING_TO_OVERRIDE. --- .../resolve/java/JavaToKotlinMethodMap.java | 16 +--------------- .../jet/lang/resolve/DescriptorUtils.java | 13 +++++++++++++ .../ChangeMemberFunctionSignatureFix.java | 9 +++++---- .../afterAddParameterTwoSupertraits.kt | 11 +++++++++++ .../afterAddParameterTwoSupertypes.kt | 11 +++++++++++ .../beforeAddParameterTwoSupertraits.kt | 11 +++++++++++ .../beforeAddParameterTwoSupertypes.kt | 11 +++++++++++ .../plugin/quickfix/QuickFixTestGenerated.java | 17 +++++++++++++++-- 8 files changed, 78 insertions(+), 21 deletions(-) create mode 100644 idea/testData/quickfix/override/nothingToOverride/afterAddParameterTwoSupertraits.kt create mode 100644 idea/testData/quickfix/override/nothingToOverride/afterAddParameterTwoSupertypes.kt create mode 100644 idea/testData/quickfix/override/nothingToOverride/beforeAddParameterTwoSupertraits.kt create mode 100644 idea/testData/quickfix/override/nothingToOverride/beforeAddParameterTwoSupertypes.kt diff --git a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaToKotlinMethodMap.java b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaToKotlinMethodMap.java index b9e35155d5b..c2d3ea3bd10 100644 --- a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaToKotlinMethodMap.java +++ b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaToKotlinMethodMap.java @@ -26,8 +26,6 @@ import org.jetbrains.jet.lang.descriptors.ClassDescriptor; import org.jetbrains.jet.lang.descriptors.FunctionDescriptor; import org.jetbrains.jet.lang.resolve.DescriptorUtils; import org.jetbrains.jet.lang.resolve.name.Name; -import org.jetbrains.jet.lang.types.JetType; -import org.jetbrains.jet.lang.types.TypeUtils; import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns; import org.jetbrains.jet.renderer.DescriptorRenderer; @@ -46,25 +44,13 @@ public class JavaToKotlinMethodMap { private JavaToKotlinMethodMap() { } - @NotNull - private static Set getAllSuperClasses(@NotNull ClassDescriptor klass) { - Set allSupertypes = TypeUtils.getAllSupertypes(klass.getDefaultType()); - Set allSuperclasses = Sets.newHashSet(); - for (JetType supertype : allSupertypes) { - ClassDescriptor superclass = TypeUtils.getClassDescriptor(supertype); - assert superclass != null; - allSuperclasses.add(superclass); - } - return allSuperclasses; - } - @NotNull public List getFunctions(@NotNull PsiMethod psiMethod, @NotNull ClassDescriptor containingClass) { ImmutableCollection classDatas = mapContainer.map.get(psiMethod.getContainingClass().getQualifiedName()); List result = Lists.newArrayList(); - Set allSuperClasses = getAllSuperClasses(containingClass); + Set allSuperClasses = DescriptorUtils.getAllSuperClasses(containingClass); String serializedPsiMethod = serializePsiMethod(psiMethod); for (ClassData classData : classDatas) { diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/DescriptorUtils.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/DescriptorUtils.java index 368cf5ecfe9..73d15c0171f 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/DescriptorUtils.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/DescriptorUtils.java @@ -18,6 +18,7 @@ package org.jetbrains.jet.lang.resolve; import com.google.common.base.Predicate; 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.descriptors.*; @@ -545,4 +546,16 @@ public class DescriptorUtils { return "values".equals(functionDescriptor.getName().getName()) && methodTypeParameters.isEmpty(); } + + @NotNull + public static Set getAllSuperClasses(@NotNull ClassDescriptor klass) { + Set allSupertypes = TypeUtils.getAllSupertypes(klass.getDefaultType()); + Set allSuperclasses = Sets.newHashSet(); + for (JetType supertype : allSupertypes) { + ClassDescriptor superclass = TypeUtils.getClassDescriptor(supertype); + assert superclass != null; + allSuperclasses.add(superclass); + } + return allSuperclasses; + } } diff --git a/idea/src/org/jetbrains/jet/plugin/quickfix/ChangeMemberFunctionSignatureFix.java b/idea/src/org/jetbrains/jet/plugin/quickfix/ChangeMemberFunctionSignatureFix.java index 64b2cc71779..21e14bf9684 100644 --- a/idea/src/org/jetbrains/jet/plugin/quickfix/ChangeMemberFunctionSignatureFix.java +++ b/idea/src/org/jetbrains/jet/plugin/quickfix/ChangeMemberFunctionSignatureFix.java @@ -31,6 +31,7 @@ import org.jetbrains.annotations.Nullable; import org.jetbrains.jet.lang.descriptors.*; import org.jetbrains.jet.lang.descriptors.impl.FunctionDescriptorUtil; import org.jetbrains.jet.lang.diagnostics.Diagnostic; +import org.jetbrains.jet.lang.psi.JetFile; import org.jetbrains.jet.lang.psi.JetNamedFunction; import org.jetbrains.jet.lang.resolve.BindingContext; import org.jetbrains.jet.lang.resolve.DescriptorUtils; @@ -75,7 +76,7 @@ public class ChangeMemberFunctionSignatureFix extends JetHintAction computePossibleSignatures(JetNamedFunction functionElement) { + private static List computePossibleSignatures(JetNamedFunction functionElement) { BindingContext context = KotlinCacheManagerUtil.getDeclarationsFromProject(functionElement).getBindingContext(); FunctionDescriptor functionDescriptor = context.get(BindingContext.FUNCTION, functionElement); if (functionDescriptor == null) return Lists.newArrayList(); @@ -234,7 +235,7 @@ public class ChangeMemberFunctionSignatureFix extends JetHintActionoverride fun f(a: Int) {} +} diff --git a/idea/testData/quickfix/override/nothingToOverride/beforeAddParameterTwoSupertraits.kt b/idea/testData/quickfix/override/nothingToOverride/beforeAddParameterTwoSupertraits.kt new file mode 100644 index 00000000000..37ec0c70c1b --- /dev/null +++ b/idea/testData/quickfix/override/nothingToOverride/beforeAddParameterTwoSupertraits.kt @@ -0,0 +1,11 @@ +// "Change function signature to 'override fun f(a: Int)'" "true" +trait A { + fun f(a: Int) +} + +trait B : A { +} + +class C : B { + override fun f() {} +} diff --git a/idea/testData/quickfix/override/nothingToOverride/beforeAddParameterTwoSupertypes.kt b/idea/testData/quickfix/override/nothingToOverride/beforeAddParameterTwoSupertypes.kt new file mode 100644 index 00000000000..144907eca27 --- /dev/null +++ b/idea/testData/quickfix/override/nothingToOverride/beforeAddParameterTwoSupertypes.kt @@ -0,0 +1,11 @@ +// "Change function signature to 'override fun f(a: Int)'" "true" +open class A { + open fun f(a: Int) {} +} + +open class B : A() { +} + +class C : B() { + override fun f() {} +} diff --git a/idea/tests/org/jetbrains/jet/plugin/quickfix/QuickFixTestGenerated.java b/idea/tests/org/jetbrains/jet/plugin/quickfix/QuickFixTestGenerated.java index 9697cd550b8..9b32c411512 100644 --- a/idea/tests/org/jetbrains/jet/plugin/quickfix/QuickFixTestGenerated.java +++ b/idea/tests/org/jetbrains/jet/plugin/quickfix/QuickFixTestGenerated.java @@ -16,14 +16,17 @@ package org.jetbrains.jet.plugin.quickfix; +import junit.framework.Assert; import junit.framework.Test; import junit.framework.TestSuite; + +import java.io.File; +import java.util.regex.Pattern; import org.jetbrains.jet.JetTestUtils; import org.jetbrains.jet.test.InnerTestClasses; import org.jetbrains.jet.test.TestMetadata; -import java.io.File; -import java.util.regex.Pattern; +import org.jetbrains.jet.plugin.quickfix.AbstractQuickFixTest; /** This class is generated by {@link org.jetbrains.jet.generators.tests.GenerateTests}. DO NOT MODIFY MANUALLY */ @SuppressWarnings("all") @@ -848,6 +851,16 @@ public class QuickFixTestGenerated extends AbstractQuickFixTest { doTest("idea/testData/quickfix/override/nothingToOverride/beforeAddParameterPreserveVisibility.kt"); } + @TestMetadata("beforeAddParameterTwoSupertraits.kt") + public void testAddParameterTwoSupertraits() throws Exception { + doTest("idea/testData/quickfix/override/nothingToOverride/beforeAddParameterTwoSupertraits.kt"); + } + + @TestMetadata("beforeAddParameterTwoSupertypes.kt") + public void testAddParameterTwoSupertypes() throws Exception { + doTest("idea/testData/quickfix/override/nothingToOverride/beforeAddParameterTwoSupertypes.kt"); + } + public void testAllFilesPresentInNothingToOverride() throws Exception { JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.GenerateTests", new File("idea/testData/quickfix/override/nothingToOverride"), Pattern.compile("^before(\\w+)\\.kt$"), true); } From ed0bd5a9083c4a7f4aab67f806fc74add5a4b79e Mon Sep 17 00:00:00 2001 From: Alexey Sedunov Date: Tue, 9 Apr 2013 18:17:39 +0400 Subject: [PATCH 058/249] Simplify "is assignment" check and move it to JetPsiUtil --- .../org/jetbrains/jet/lang/psi/JetPsiUtil.java | 6 ++++++ .../src/org/jetbrains/jet/lexer/JetTokens.java | 1 + ...nmentWithIfExpressionToStatementIntention.java | 5 ++++- .../CodeTransformationUtils.java | 15 +++------------ 4 files changed, 14 insertions(+), 13 deletions(-) diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetPsiUtil.java b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetPsiUtil.java index 92af4a42247..156445850a1 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetPsiUtil.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetPsiUtil.java @@ -37,6 +37,7 @@ import org.jetbrains.jet.lang.types.expressions.OperatorConventions; import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns; import org.jetbrains.jet.lexer.JetToken; import org.jetbrains.jet.lexer.JetTokens; +import org.jetbrains.jet.util.QualifiedNamesUtil; import java.util.Collection; import java.util.HashSet; @@ -621,4 +622,9 @@ public class JetPsiUtil { int parentPrecedence = getPrecedenceOfOperation(parentExpression, parentOperation); return innerPrecedence < parentPrecedence; } + + public static boolean isAssignment(@NotNull JetElement element) { + return element instanceof JetBinaryExpression && + JetTokens.ALL_ASSIGNMENTS.contains(((JetBinaryExpression) element).getOperationToken()); + } } diff --git a/compiler/frontend/src/org/jetbrains/jet/lexer/JetTokens.java b/compiler/frontend/src/org/jetbrains/jet/lexer/JetTokens.java index c7aeb44da88..8bd4eb4594d 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lexer/JetTokens.java +++ b/compiler/frontend/src/org/jetbrains/jet/lexer/JetTokens.java @@ -195,4 +195,5 @@ public interface JetTokens { IDENTIFIER, LABEL_IDENTIFIER, ATAT, AT); TokenSet AUGMENTED_ASSIGNMENTS = TokenSet.create(PLUSEQ, MINUSEQ, MULTEQ, PERCEQ, DIVEQ); + TokenSet ALL_ASSIGNMENTS = TokenSet.create(EQ, PLUSEQ, MINUSEQ, MULTEQ, PERCEQ, DIVEQ); } diff --git a/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/AssignmentWithIfExpressionToStatementIntention.java b/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/AssignmentWithIfExpressionToStatementIntention.java index 1192e20b1cb..fc5722b207c 100644 --- a/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/AssignmentWithIfExpressionToStatementIntention.java +++ b/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/AssignmentWithIfExpressionToStatementIntention.java @@ -26,6 +26,7 @@ import com.intellij.util.IncorrectOperationException; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.jet.lang.psi.JetBinaryExpression; +import org.jetbrains.jet.lang.psi.JetElement; import org.jetbrains.jet.plugin.JetBundle; public class AssignmentWithIfExpressionToStatementIntention extends BaseIntentionAction { @@ -45,7 +46,9 @@ public class AssignmentWithIfExpressionToStatementIntention extends BaseIntentio PsiElement element = file.findElementAt(offset); while (element != null) { - if (CodeTransformationUtils.checkAssignmentWithIfExpression(element)) return (JetBinaryExpression)element; + if (!(element instanceof JetElement)) return null; + + if (CodeTransformationUtils.checkAssignmentWithIfExpression((JetElement) element)) return (JetBinaryExpression)element; PsiElement parent = PsiTreeUtil.getParentOfType(element, JetBinaryExpression.class, false); element = (element != parent) ? parent : null; } diff --git a/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/CodeTransformationUtils.java b/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/CodeTransformationUtils.java index d49198f2480..d20b67c5c5a 100644 --- a/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/CodeTransformationUtils.java +++ b/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/CodeTransformationUtils.java @@ -17,10 +17,8 @@ package org.jetbrains.jet.plugin.codeInsight.codeTransformations; import com.intellij.openapi.project.Project; -import com.intellij.psi.PsiElement; import org.jetbrains.annotations.NotNull; import org.jetbrains.jet.lang.psi.*; -import org.jetbrains.jet.lexer.JetTokens; import java.util.ArrayList; import java.util.List; @@ -94,17 +92,10 @@ public class CodeTransformationUtils { ); } - public static boolean isAssignment(@NotNull PsiElement element) { - if (!(element instanceof JetBinaryExpression)) return false; - JetBinaryExpression binaryExpression = (JetBinaryExpression)element; - if (binaryExpression.getOperationReference().getReferencedNameElementType() != JetTokens.EQ) return false; - return true; - } - private static boolean checkAllOutcomesAreCompatibleAssignments(@NotNull List outcomes) { JetExpression lastLhs = null; for (JetExpression outcome : outcomes) { - if (!isAssignment(outcome)) return false; + if (!JetPsiUtil.isAssignment(outcome)) return false; JetExpression currLhs = ((JetBinaryExpression)outcome).getLeft(); if (!(currLhs instanceof JetSimpleNameExpression)) return false; @@ -124,8 +115,8 @@ public class CodeTransformationUtils { return !outcomes.isEmpty() && checkAllIfExpressionsAreComplete(ifExpression) && checkAllOutcomesAreCompatibleAssignments(outcomes); } - static boolean checkAssignmentWithIfExpression(@NotNull PsiElement element) { - if (!isAssignment(element)) return false; + static boolean checkAssignmentWithIfExpression(@NotNull JetElement element) { + if (!JetPsiUtil.isAssignment(element)) return false; JetBinaryExpression assignment = (JetBinaryExpression)element; return (assignment.getLeft() instanceof JetSimpleNameExpression) && (assignment.getRight() instanceof JetIfExpression); From e4de51468ff4aacf73d8e29b63b012188fe1a227 Mon Sep 17 00:00:00 2001 From: Alexey Sedunov Date: Wed, 10 Apr 2013 15:48:48 +0400 Subject: [PATCH 059/249] Add construction of "return" and "if" expressions to JetPsiFactory --- .../jetbrains/jet/lang/psi/JetPsiFactory.java | 36 +++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetPsiFactory.java b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetPsiFactory.java index 6ce487786b3..2fa61b6daff 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetPsiFactory.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetPsiFactory.java @@ -272,4 +272,40 @@ public class JetPsiFactory { public static JetExpressionCodeFragment createExpressionCodeFragment(Project project, String text, PsiElement context) { return new JetExpressionCodeFragmentImpl(project, "fragment.kt", text, context); } + + public static JetReturnExpression createReturn(Project project, @NotNull String text) { + return (JetReturnExpression) createExpression(project, "return " + text); + } + + @SuppressWarnings("ConstantConditions") + public static JetReturnExpression createReturn(Project project, @NotNull JetExpression expression) { + JetReturnExpression returnExpr = createReturn(project, "_"); + + assert returnExpr.getReturnedExpression() != null; + + return (JetReturnExpression)returnExpr.getReturnedExpression().replace(expression).getParent(); + } + + public static JetIfExpression createIf(Project project, @NotNull String condText, @NotNull String thenText, @Nullable String elseText) { + return (JetIfExpression) createExpression(project, "if (" + condText + ") " + thenText + (elseText != null ? " else " + elseText : "")); + } + + @SuppressWarnings("ConstantConditions") + public static JetIfExpression createIf(Project project, @NotNull JetExpression condition, @NotNull JetExpression thenExpr, @Nullable JetExpression elseExpr) { + JetIfExpression ifExpr = createIf(project, "_", "_", elseExpr != null ? "_" : null); + + assert ifExpr.getCondition() != null; + assert ifExpr.getThen() != null; + if (elseExpr != null) { + assert ifExpr.getElse() != null; + } + + ifExpr = (JetIfExpression)ifExpr.getCondition().replace(condition).getParent().getParent(); + ifExpr = (JetIfExpression)ifExpr.getThen().replace(thenExpr).getParent().getParent(); + if (elseExpr != null) { + ifExpr = (JetIfExpression)ifExpr.getElse().replace(elseExpr).getParent().getParent(); + } + + return ifExpr; + } } From 51658c65de09714dea9feb6ec327dbbca6c2e69f Mon Sep 17 00:00:00 2001 From: Alexey Sedunov Date: Fri, 12 Apr 2013 17:46:48 +0400 Subject: [PATCH 060/249] Add folding/unfolding operations for branched control structures --- .../jetbrains/jet/lang/psi/JetPsiFactory.java | 8 +- .../jetbrains/jet/lang/psi/JetPsiUtil.java | 57 ++- .../BranchedFoldingUtils.java | 345 ++++++++++++++++++ .../BranchedUnfoldingUtils.java | 150 ++++++++ 4 files changed, 555 insertions(+), 5 deletions(-) create mode 100644 idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/BranchedFoldingUtils.java create mode 100644 idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/BranchedUnfoldingUtils.java diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetPsiFactory.java b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetPsiFactory.java index 2fa61b6daff..46e1c2dd818 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetPsiFactory.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetPsiFactory.java @@ -249,13 +249,13 @@ public class JetPsiFactory { return createExpression(project, "$" + fieldName); } - public static JetBinaryExpression createAssignment(Project project, @NotNull String lhs, @NotNull String rhs) { - return (JetBinaryExpression) createExpression(project, lhs + " = " + rhs); + public static JetBinaryExpression createBinaryExpression(Project project, @NotNull String lhs, @NotNull String op, @NotNull String rhs) { + return (JetBinaryExpression) createExpression(project, lhs + " " + op + " " + rhs); } @SuppressWarnings("ConstantConditions") - public static JetBinaryExpression createAssignment(Project project, @NotNull JetExpression lhs, @NotNull JetExpression rhs) { - JetBinaryExpression assignment = createAssignment(project, "_", "_"); + public static JetBinaryExpression createBinaryExpression(Project project, @NotNull JetExpression lhs, @NotNull String op, @NotNull JetExpression rhs) { + JetBinaryExpression assignment = createBinaryExpression(project, "_", op, "_"); assert assignment.getRight() != null; diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetPsiUtil.java b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetPsiUtil.java index 156445850a1..95bf2b0b285 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetPsiUtil.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetPsiUtil.java @@ -17,6 +17,7 @@ package org.jetbrains.jet.lang.psi; import com.google.common.base.Function; +import com.google.common.base.Predicate; import com.google.common.collect.Lists; import com.intellij.lang.ASTNode; import com.intellij.psi.PsiElement; @@ -623,8 +624,62 @@ public class JetPsiUtil { return innerPrecedence < parentPrecedence; } - public static boolean isAssignment(@NotNull JetElement element) { + public static boolean isAssignment(@NotNull PsiElement element) { return element instanceof JetBinaryExpression && JetTokens.ALL_ASSIGNMENTS.contains(((JetBinaryExpression) element).getOperationToken()); } + + public static boolean isBranchedExpression(@Nullable PsiElement element) { + return element instanceof JetIfExpression || element instanceof JetWhenExpression; + } + + @Nullable + public static JetElement getOutermostLastBlockElement( + @Nullable JetElement element, + @Nullable Predicate checkElement) { + if (element == null) return null; + + if (!(element instanceof JetBlockExpression)) return checkElement == null || checkElement.apply(element) ? element : null; + + JetBlockExpression block = (JetBlockExpression)element; + int n = block.getStatements().size(); + + if (n == 0) return null; + + JetElement lastElement = block.getStatements().get(n - 1); + return checkElement == null || checkElement.apply(lastElement) ? lastElement : null; + } + + @Nullable + public static PsiElement getParentByTypeAndPredicate( + @Nullable PsiElement element, @NotNull Class aClass, @NotNull Predicate predicate, boolean strict) { + if (element == null) return null; + if (strict) { + element = element.getParent(); + } + + while (element != null) { + //noinspection unchecked + if (aClass.isInstance(element) && predicate.apply(element)) { + //noinspection unchecked + return element; + } + if (element instanceof PsiFile) return null; + element = element.getParent(); + } + + return null; + } + + public static boolean checkVariableDeclarationInBlock(@NotNull JetBlockExpression block, @NotNull String varName) { + for (JetElement element : block.getStatements()) { + if (element instanceof JetVariableDeclaration) { + if (((JetVariableDeclaration) element).getNameAsSafeName().getName().equals(varName)) { + return true; + } + } + } + + return false; + } } diff --git a/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/BranchedFoldingUtils.java b/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/BranchedFoldingUtils.java new file mode 100644 index 00000000000..ae5dc0548fb --- /dev/null +++ b/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/BranchedFoldingUtils.java @@ -0,0 +1,345 @@ +/* + * Copyright 2010-2013 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.jetbrains.jet.plugin.codeInsight.codeTransformations.branchedTransformations; + +import com.google.common.base.Predicate; +import com.intellij.openapi.project.Project; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiWhiteSpace; +import com.intellij.psi.tree.IElementType; +import com.intellij.psi.util.PsiTreeUtil; +import org.jetbrains.annotations.Nullable; +import org.jetbrains.jet.lang.psi.*; + +import java.util.ArrayList; +import java.util.List; + +public class BranchedFoldingUtils { + private BranchedFoldingUtils() { + } + + private static boolean checkEquivalence(JetExpression e1, JetExpression e2) { + return e1.getText().equals(e2.getText()); + } + + private static final Predicate CHECK_ASSIGNMENT = new Predicate() { + @Override + public boolean apply(@Nullable JetElement input) { + if (input == null || !JetPsiUtil.isAssignment(input)) { + return false; + } + + JetBinaryExpression assignment = (JetBinaryExpression)input; + + if (assignment.getRight() == null || !(assignment.getLeft() instanceof JetSimpleNameExpression)) { + return false; + } + + if (assignment.getParent() instanceof JetBlockExpression) { + return !JetPsiUtil.checkVariableDeclarationInBlock((JetBlockExpression) assignment.getParent(), assignment.getLeft().getText()); + } + + return true; + } + }; + + private static final Predicate CHECK_RETURN = new Predicate() { + @Override + public boolean apply(@Nullable JetElement input) { + return (input instanceof JetReturnExpression) && ((JetReturnExpression)input).getReturnedExpression() != null; + } + }; + + private static JetBinaryExpression checkAndGetFoldableBranchedAssignment(JetExpression branch) { + return (JetBinaryExpression)JetPsiUtil.getOutermostLastBlockElement(branch, CHECK_ASSIGNMENT); + } + + private static JetReturnExpression checkAndGetFoldableBranchedReturn(JetExpression branch) { + return (JetReturnExpression)JetPsiUtil.getOutermostLastBlockElement(branch, CHECK_RETURN); + } + + private static boolean checkFoldableIfExpressionWithAssignments(JetIfExpression ifExpression) { + JetExpression thenBranch = ifExpression.getThen(); + JetExpression elseBranch = ifExpression.getElse(); + + JetBinaryExpression thenAssignment = checkAndGetFoldableBranchedAssignment(thenBranch); + JetBinaryExpression elseAssignment = checkAndGetFoldableBranchedAssignment(elseBranch); + + if (thenAssignment == null || elseAssignment == null) return false; + + return checkEquivalence(thenAssignment.getLeft(), elseAssignment.getLeft()) && + thenAssignment.getOperationToken().equals(elseAssignment.getOperationToken()); + } + + private static boolean checkFoldableWhenExpressionWithAssignments(JetWhenExpression whenExpression) { + List entries = whenExpression.getEntries(); + + if (entries.isEmpty()) return false; + + boolean hasElse = false; + List assignments = new ArrayList(); + for (JetWhenEntry entry : entries) { + if (entry.isElse()) { + hasElse = true; + } + JetBinaryExpression assignment = checkAndGetFoldableBranchedAssignment(entry.getExpression()); + if (assignment == null) return false; + assignments.add(assignment); + } + + if (!hasElse) return false; + + assert !assignments.isEmpty(); + + JetExpression lhs = assignments.get(0).getLeft(); + IElementType opToken = assignments.get(0).getOperationToken(); + for (int i = 1; i < assignments.size(); i++) { + if (!checkEquivalence(lhs, assignments.get(i).getLeft())) return false; + if (!opToken.equals(assignments.get(i).getOperationToken())) return false; + } + + return true; + } + + private static boolean checkFoldableIfExpressionWithReturns(JetIfExpression ifExpression) { + return checkAndGetFoldableBranchedReturn(ifExpression.getThen()) != null && + checkAndGetFoldableBranchedReturn(ifExpression.getElse()) != null; + } + + private static boolean checkFoldableWhenExpressionWithReturns(JetWhenExpression whenExpression) { + List entries = whenExpression.getEntries(); + + if (entries.isEmpty()) return false; + + boolean hasElse = false; + for (JetWhenEntry entry : entries) { + if (entry.isElse()) { + hasElse = true; + } + if (checkAndGetFoldableBranchedReturn(entry.getExpression()) == null) return false; + } + + return hasElse; + } + + private static boolean checkFoldableIfExpressionWithAsymmetricReturns(JetIfExpression ifExpression) { + if (checkAndGetFoldableBranchedReturn(ifExpression.getThen()) == null || + checkAndGetFoldableBranchedReturn(ifExpression.getElse()) != null) { + return false; + } + + PsiElement nextElement = PsiTreeUtil.skipSiblingsForward(ifExpression, PsiWhiteSpace.class); + return (nextElement instanceof JetExpression) && checkAndGetFoldableBranchedReturn((JetExpression)nextElement) != null; + } + + public static boolean checkFoldableExpression(@Nullable JetExpression root) { + if (root instanceof JetIfExpression) { + JetIfExpression ifExpression = (JetIfExpression)root; + return checkFoldableIfExpressionWithAssignments(ifExpression) || + checkFoldableIfExpressionWithReturns(ifExpression) || + checkFoldableIfExpressionWithAsymmetricReturns(ifExpression) ; + } + + if (root instanceof JetWhenExpression) { + JetWhenExpression whenExpression = (JetWhenExpression)root; + return checkFoldableWhenExpressionWithAssignments(whenExpression) || + checkFoldableWhenExpressionWithReturns(whenExpression); + } + + return false; + } + + private static void foldIfExpressionWithAssignments(JetIfExpression ifExpression) { + Project project = ifExpression.getProject(); + + JetBinaryExpression thenAssignment = checkAndGetFoldableBranchedAssignment(ifExpression.getThen()); + + assert thenAssignment != null; + + String op = thenAssignment.getOperationReference().getText(); + JetSimpleNameExpression lhs = (JetSimpleNameExpression) thenAssignment.getLeft(); + + JetBinaryExpression assignment = + (JetBinaryExpression)ifExpression.replace(JetPsiFactory.createBinaryExpression(project, lhs, op, ifExpression)); + ifExpression = (JetIfExpression)assignment.getRight(); + + assert ifExpression != null; + + thenAssignment = checkAndGetFoldableBranchedAssignment(ifExpression.getThen()); + JetBinaryExpression elseAssignment = checkAndGetFoldableBranchedAssignment(ifExpression.getElse()); + + assert thenAssignment != null; + assert elseAssignment != null; + + JetExpression thenRhs = thenAssignment.getRight(); + JetExpression elseRhs = elseAssignment.getRight(); + + assert thenRhs != null; + assert elseRhs != null; + + thenAssignment.replace(thenRhs); + elseAssignment.replace(elseRhs); + } + + private static void foldIfExpressionWithReturns(JetIfExpression ifExpression) { + Project project = ifExpression.getProject(); + + JetReturnExpression returnExpr = (JetReturnExpression)ifExpression.replace(JetPsiFactory.createReturn(project, ifExpression)); + ifExpression = (JetIfExpression)returnExpr.getReturnedExpression(); + + assert ifExpression != null; + + JetReturnExpression thenReturn = checkAndGetFoldableBranchedReturn(ifExpression.getThen()); + JetReturnExpression elseReturn = checkAndGetFoldableBranchedReturn(ifExpression.getElse()); + + assert thenReturn != null; + assert elseReturn != null; + + JetExpression thenExpr = thenReturn.getReturnedExpression(); + JetExpression elseExpr = elseReturn.getReturnedExpression(); + + assert thenExpr != null; + assert elseExpr != null; + + thenReturn.replace(thenExpr); + elseReturn.replace(elseExpr); + } + + private static void foldIfExpressionWithAsymmetricReturns(JetIfExpression ifExpression) { + Project project = ifExpression.getProject(); + + JetExpression condition = ifExpression.getCondition(); + JetExpression thenRoot = ifExpression.getThen(); + JetExpression elseRoot = (JetExpression)PsiTreeUtil.skipSiblingsForward(ifExpression, PsiWhiteSpace.class); + + assert condition != null; + assert thenRoot != null; + assert elseRoot != null; + + JetIfExpression newIfExpr = JetPsiFactory.createIf(project, condition, thenRoot, elseRoot); + JetReturnExpression newReturnExpr = JetPsiFactory.createReturn(project, newIfExpr); + newReturnExpr = (JetReturnExpression) ifExpression.replace(newReturnExpr); + + JetReturnExpression oldReturn = (JetReturnExpression)PsiTreeUtil.skipSiblingsForward(newReturnExpr, PsiWhiteSpace.class); + + assert oldReturn != null; + + oldReturn.delete(); + + newIfExpr = (JetIfExpression)newReturnExpr.getReturnedExpression(); + + assert newIfExpr != null; + + JetReturnExpression thenReturn = checkAndGetFoldableBranchedReturn(newIfExpr.getThen()); + JetReturnExpression elseReturn = checkAndGetFoldableBranchedReturn(newIfExpr.getElse()); + + assert thenReturn != null; + assert elseReturn != null; + + JetExpression thenExpr = thenReturn.getReturnedExpression(); + JetExpression elseExpr = elseReturn.getReturnedExpression(); + + assert thenExpr != null; + assert elseExpr != null; + + thenReturn.replace(thenExpr); + elseReturn.replace(elseExpr); + } + + private static void foldWhenExpressionWithAssignments(JetWhenExpression whenExpression) { + Project project = whenExpression.getProject(); + + assert !whenExpression.getEntries().isEmpty(); + + JetBinaryExpression firstAssignment = checkAndGetFoldableBranchedAssignment(whenExpression.getEntries().get(0).getExpression()); + + assert firstAssignment != null; + + String op = firstAssignment.getOperationReference().getText(); + JetSimpleNameExpression lhs = (JetSimpleNameExpression) firstAssignment.getLeft(); + + JetBinaryExpression assignment = + (JetBinaryExpression)whenExpression.replace(JetPsiFactory.createBinaryExpression(project, lhs, op, whenExpression)); + whenExpression = (JetWhenExpression)assignment.getRight(); + + assert whenExpression != null; + + for (JetWhenEntry entry : whenExpression.getEntries()) { + JetBinaryExpression currAssignment = checkAndGetFoldableBranchedAssignment(entry.getExpression()); + + assert currAssignment != null; + + JetExpression currRhs = currAssignment.getRight(); + + assert currRhs != null; + + currAssignment.replace(currRhs); + } + } + + private static void foldWhenExpressionWithReturns(JetWhenExpression whenExpression) { + Project project = whenExpression.getProject(); + + assert !whenExpression.getEntries().isEmpty(); + + JetReturnExpression returnExpr = (JetReturnExpression)whenExpression.replace(JetPsiFactory.createReturn(project, whenExpression)); + whenExpression = (JetWhenExpression)returnExpr.getReturnedExpression(); + + assert whenExpression != null; + + for (JetWhenEntry entry : whenExpression.getEntries()) { + JetReturnExpression currReturn = checkAndGetFoldableBranchedReturn(entry.getExpression()); + + assert currReturn != null; + + JetExpression currExpr = currReturn.getReturnedExpression(); + + assert currExpr != null; + + currReturn.replace(currExpr); + } + } + + public static void foldExpression(@Nullable JetExpression root) { + if (root instanceof JetIfExpression) { + JetIfExpression ifExpression = (JetIfExpression)root; + if (checkFoldableIfExpressionWithAssignments(ifExpression)) { + foldIfExpressionWithAssignments(ifExpression); + } else if (checkFoldableIfExpressionWithReturns(ifExpression)) { + foldIfExpressionWithReturns(ifExpression); + } else if (checkFoldableIfExpressionWithAsymmetricReturns(ifExpression)) { + foldIfExpressionWithAsymmetricReturns(ifExpression); + } + } + + if (root instanceof JetWhenExpression) { + JetWhenExpression whenExpression = (JetWhenExpression)root; + if (checkFoldableWhenExpressionWithAssignments(whenExpression)) { + foldWhenExpressionWithAssignments(whenExpression); + } else if (checkFoldableWhenExpressionWithReturns(whenExpression)) { + foldWhenExpressionWithReturns(whenExpression); + } + } + } + + public static final Predicate FOLDABLE_EXPRESSION = new Predicate() { + @Override + public boolean apply(@Nullable PsiElement input) { + return (input instanceof JetExpression) && checkFoldableExpression((JetExpression)input); + } + }; +} diff --git a/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/BranchedUnfoldingUtils.java b/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/BranchedUnfoldingUtils.java new file mode 100644 index 00000000000..5d0ddab68b8 --- /dev/null +++ b/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/BranchedUnfoldingUtils.java @@ -0,0 +1,150 @@ +/* + * Copyright 2010-2013 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.jetbrains.jet.plugin.codeInsight.codeTransformations.branchedTransformations; + +import com.google.common.base.Predicate; +import com.intellij.openapi.project.Project; +import com.intellij.psi.PsiElement; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import org.jetbrains.jet.lang.psi.*; + +public class BranchedUnfoldingUtils { + private BranchedUnfoldingUtils() { + } + + private static boolean checkUnfoldableAssignment(@NotNull JetExpression expression) { + if (!JetPsiUtil.isAssignment(expression)) return false; + + JetBinaryExpression assignment = (JetBinaryExpression)expression; + return assignment.getLeft() instanceof JetSimpleNameExpression && JetPsiUtil.isBranchedExpression(assignment.getRight()); + } + + private static boolean checkUnfoldableReturn(@NotNull JetExpression expression) { + if (!(expression instanceof JetReturnExpression)) return false; + + JetReturnExpression returnExpression = (JetReturnExpression)expression; + return JetPsiUtil.isBranchedExpression(returnExpression.getReturnedExpression()); + } + + public static boolean checkUnfoldableExpression(@NotNull JetExpression root) { + return checkUnfoldableAssignment(root) || checkUnfoldableReturn(root); + } + + private static JetExpression unwrapBranch(@Nullable JetExpression expression) { + return (JetExpression) JetPsiUtil.getOutermostLastBlockElement(expression, null); + } + + private static void unfoldAssignmentToIf(@NotNull JetBinaryExpression assignment) { + Project project = assignment.getProject(); + String op = assignment.getOperationReference().getText(); + String lhsText = assignment.getLeft().getText(); + JetIfExpression ifExpression = (JetIfExpression)assignment.getRight(); + + assert ifExpression != null; + + ifExpression = (JetIfExpression)assignment.replace(ifExpression); + + JetExpression thenExpr = unwrapBranch(ifExpression.getThen()); + JetExpression elseExpr = unwrapBranch(ifExpression.getElse()); + + assert thenExpr != null; + assert elseExpr != null; + + thenExpr.replace(JetPsiFactory.createBinaryExpression(project, JetPsiFactory.createExpression(project, lhsText), op, thenExpr)); + elseExpr.replace(JetPsiFactory.createBinaryExpression(project, JetPsiFactory.createExpression(project, lhsText), op, elseExpr)); + } + + private static void unfoldAssignmentToWhen(@NotNull JetBinaryExpression assignment) { + Project project = assignment.getProject(); + String op = assignment.getOperationReference().getText(); + JetExpression lhs = (JetExpression)assignment.getLeft().copy(); + JetWhenExpression whenExpression = (JetWhenExpression)assignment.getRight(); + + assert whenExpression != null; + + whenExpression = (JetWhenExpression)assignment.replace(whenExpression); + + for (JetWhenEntry entry : whenExpression.getEntries()) { + JetExpression currExpr = unwrapBranch(entry.getExpression()); + + assert currExpr != null; + + currExpr.replace(JetPsiFactory.createBinaryExpression(project, lhs, op, currExpr)); + } + } + + private static void unfoldReturnToIf(@NotNull JetReturnExpression returnExpression) { + Project project = returnExpression.getProject(); + JetIfExpression ifExpression = (JetIfExpression)returnExpression.getReturnedExpression(); + + assert ifExpression != null; + + ifExpression = (JetIfExpression)returnExpression.replace(ifExpression); + + JetExpression thenExpr = unwrapBranch(ifExpression.getThen()); + JetExpression elseExpr = unwrapBranch(ifExpression.getElse()); + + assert thenExpr != null; + assert elseExpr != null; + + thenExpr.replace(JetPsiFactory.createReturn(project, thenExpr)); + elseExpr.replace(JetPsiFactory.createReturn(project, elseExpr)); + } + + private static void unfoldReturnToWhen(@NotNull JetReturnExpression returnExpression) { + Project project = returnExpression.getProject(); + JetWhenExpression whenExpression = (JetWhenExpression)returnExpression.getReturnedExpression(); + + assert whenExpression != null; + + whenExpression = (JetWhenExpression)returnExpression.replace(whenExpression); + + for (JetWhenEntry entry : whenExpression.getEntries()) { + JetExpression currExpr = unwrapBranch(entry.getExpression()); + + assert currExpr != null; + + currExpr.replace(JetPsiFactory.createReturn(project, currExpr)); + } + } + + public static void unfoldExpression(@NotNull JetExpression root) { + if (checkUnfoldableAssignment(root)) { + JetBinaryExpression assignment = (JetBinaryExpression)root; + if (assignment.getRight() instanceof JetIfExpression) { + unfoldAssignmentToIf(assignment); + } else if (assignment.getRight() instanceof JetWhenExpression) { + unfoldAssignmentToWhen(assignment); + } + } else if (checkUnfoldableReturn(root)) { + JetReturnExpression returnExpression = (JetReturnExpression)root; + if (returnExpression.getReturnedExpression() instanceof JetIfExpression) { + unfoldReturnToIf(returnExpression); + } else if (returnExpression.getReturnedExpression() instanceof JetWhenExpression) { + unfoldReturnToWhen(returnExpression); + } + } + } + + public static final Predicate UNFOLDABLE_EXPRESSION = new Predicate() { + @Override + public boolean apply(@Nullable PsiElement input) { + return (input instanceof JetExpression) && checkUnfoldableExpression((JetExpression)input); + } + }; +} From 02e9f174f09da023c180299e3a4aa53a03845ccc Mon Sep 17 00:00:00 2001 From: Alexey Sedunov Date: Fri, 12 Apr 2013 15:50:37 +0400 Subject: [PATCH 061/249] Replace intentions for folding/unfolding operations --- .../after.kt.template | 0 .../before.kt.template | 0 .../description.html | 0 .../after.kt.template | 0 .../before.kt.template | 0 .../description.html | 0 idea/src/META-INF/plugin.xml | 4 +- ...tWithIfExpressionToStatementIntention.java | 72 -------- .../CodeTransformationUtils.java | 157 ------------------ .../FoldBranchedExpressionIntention.java} | 38 ++--- .../UnfoldBranchedExpressionIntention.java | 62 +++++++ .../AbstractCodeTransformationTest.java | 10 +- 12 files changed, 89 insertions(+), 254 deletions(-) rename idea/resources/intentionDescriptions/{IfStatementWithAssignmentsToExpressionIntention => FoldBranchedExpressionIntention}/after.kt.template (100%) rename idea/resources/intentionDescriptions/{IfStatementWithAssignmentsToExpressionIntention => FoldBranchedExpressionIntention}/before.kt.template (100%) rename idea/resources/intentionDescriptions/{IfStatementWithAssignmentsToExpressionIntention => FoldBranchedExpressionIntention}/description.html (100%) rename idea/resources/intentionDescriptions/{AssignmentWithIfExpressionToStatementIntention => UnfoldBranchedExpressionIntention}/after.kt.template (100%) rename idea/resources/intentionDescriptions/{AssignmentWithIfExpressionToStatementIntention => UnfoldBranchedExpressionIntention}/before.kt.template (100%) rename idea/resources/intentionDescriptions/{AssignmentWithIfExpressionToStatementIntention => UnfoldBranchedExpressionIntention}/description.html (100%) delete mode 100644 idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/AssignmentWithIfExpressionToStatementIntention.java delete mode 100644 idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/CodeTransformationUtils.java rename idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/{IfStatementWithAssignmentsToExpressionIntention.java => branchedTransformations/FoldBranchedExpressionIntention.java} (51%) create mode 100644 idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/UnfoldBranchedExpressionIntention.java diff --git a/idea/resources/intentionDescriptions/IfStatementWithAssignmentsToExpressionIntention/after.kt.template b/idea/resources/intentionDescriptions/FoldBranchedExpressionIntention/after.kt.template similarity index 100% rename from idea/resources/intentionDescriptions/IfStatementWithAssignmentsToExpressionIntention/after.kt.template rename to idea/resources/intentionDescriptions/FoldBranchedExpressionIntention/after.kt.template diff --git a/idea/resources/intentionDescriptions/IfStatementWithAssignmentsToExpressionIntention/before.kt.template b/idea/resources/intentionDescriptions/FoldBranchedExpressionIntention/before.kt.template similarity index 100% rename from idea/resources/intentionDescriptions/IfStatementWithAssignmentsToExpressionIntention/before.kt.template rename to idea/resources/intentionDescriptions/FoldBranchedExpressionIntention/before.kt.template diff --git a/idea/resources/intentionDescriptions/IfStatementWithAssignmentsToExpressionIntention/description.html b/idea/resources/intentionDescriptions/FoldBranchedExpressionIntention/description.html similarity index 100% rename from idea/resources/intentionDescriptions/IfStatementWithAssignmentsToExpressionIntention/description.html rename to idea/resources/intentionDescriptions/FoldBranchedExpressionIntention/description.html diff --git a/idea/resources/intentionDescriptions/AssignmentWithIfExpressionToStatementIntention/after.kt.template b/idea/resources/intentionDescriptions/UnfoldBranchedExpressionIntention/after.kt.template similarity index 100% rename from idea/resources/intentionDescriptions/AssignmentWithIfExpressionToStatementIntention/after.kt.template rename to idea/resources/intentionDescriptions/UnfoldBranchedExpressionIntention/after.kt.template diff --git a/idea/resources/intentionDescriptions/AssignmentWithIfExpressionToStatementIntention/before.kt.template b/idea/resources/intentionDescriptions/UnfoldBranchedExpressionIntention/before.kt.template similarity index 100% rename from idea/resources/intentionDescriptions/AssignmentWithIfExpressionToStatementIntention/before.kt.template rename to idea/resources/intentionDescriptions/UnfoldBranchedExpressionIntention/before.kt.template diff --git a/idea/resources/intentionDescriptions/AssignmentWithIfExpressionToStatementIntention/description.html b/idea/resources/intentionDescriptions/UnfoldBranchedExpressionIntention/description.html similarity index 100% rename from idea/resources/intentionDescriptions/AssignmentWithIfExpressionToStatementIntention/description.html rename to idea/resources/intentionDescriptions/UnfoldBranchedExpressionIntention/description.html diff --git a/idea/src/META-INF/plugin.xml b/idea/src/META-INF/plugin.xml index 190e0d0f799..abc42486aad 100644 --- a/idea/src/META-INF/plugin.xml +++ b/idea/src/META-INF/plugin.xml @@ -292,12 +292,12 @@ - org.jetbrains.jet.plugin.codeInsight.codeTransformations.IfStatementWithAssignmentsToExpressionIntention + org.jetbrains.jet.plugin.codeInsight.codeTransformations.branchedTransformations.FoldBranchedExpressionIntention Kotlin - org.jetbrains.jet.plugin.codeInsight.codeTransformations.AssignmentWithIfExpressionToStatementIntention + org.jetbrains.jet.plugin.codeInsight.codeTransformations.branchedTransformations.UnfoldBranchedExpressionIntention Kotlin diff --git a/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/AssignmentWithIfExpressionToStatementIntention.java b/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/AssignmentWithIfExpressionToStatementIntention.java deleted file mode 100644 index fc5722b207c..00000000000 --- a/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/AssignmentWithIfExpressionToStatementIntention.java +++ /dev/null @@ -1,72 +0,0 @@ -/* - * Copyright 2010-2013 JetBrains s.r.o. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.jetbrains.jet.plugin.codeInsight.codeTransformations; - -import com.intellij.codeInsight.intention.impl.BaseIntentionAction; -import com.intellij.openapi.editor.Editor; -import com.intellij.openapi.project.Project; -import com.intellij.psi.PsiElement; -import com.intellij.psi.PsiFile; -import com.intellij.psi.util.PsiTreeUtil; -import com.intellij.util.IncorrectOperationException; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; -import org.jetbrains.jet.lang.psi.JetBinaryExpression; -import org.jetbrains.jet.lang.psi.JetElement; -import org.jetbrains.jet.plugin.JetBundle; - -public class AssignmentWithIfExpressionToStatementIntention extends BaseIntentionAction { - public AssignmentWithIfExpressionToStatementIntention() { - setText(JetBundle.message("transform.assignment.with.if.expression.to.statement")); - } - - @NotNull - @Override - public String getFamilyName() { - return JetBundle.message("transform.assignment.with.if.expression.to.statement.family"); - } - - @Nullable - private static JetBinaryExpression getAssignment(@NotNull Editor editor, @NotNull PsiFile file) { - int offset = editor.getCaretModel().getOffset(); - PsiElement element = file.findElementAt(offset); - - while (element != null) { - if (!(element instanceof JetElement)) return null; - - if (CodeTransformationUtils.checkAssignmentWithIfExpression((JetElement) element)) return (JetBinaryExpression)element; - PsiElement parent = PsiTreeUtil.getParentOfType(element, JetBinaryExpression.class, false); - element = (element != parent) ? parent : null; - } - - return null; - } - - @Override - public boolean isAvailable(@NotNull Project project, @NotNull Editor editor, @NotNull PsiFile file) { - return getAssignment(editor, file) != null; - } - - @Override - public void invoke( - @NotNull Project project, @NotNull Editor editor, @NotNull PsiFile file - ) throws IncorrectOperationException { - JetBinaryExpression assignment = getAssignment(editor, file); - assert assignment != null; - CodeTransformationUtils.transformAssignmentWithIfExpressionToStatement(assignment); - } -} diff --git a/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/CodeTransformationUtils.java b/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/CodeTransformationUtils.java deleted file mode 100644 index d20b67c5c5a..00000000000 --- a/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/CodeTransformationUtils.java +++ /dev/null @@ -1,157 +0,0 @@ -/* - * Copyright 2010-2013 JetBrains s.r.o. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.jetbrains.jet.plugin.codeInsight.codeTransformations; - -import com.intellij.openapi.project.Project; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.jet.lang.psi.*; - -import java.util.ArrayList; -import java.util.List; - -public class CodeTransformationUtils { - private static List getIfExpressionOutcomes(@NotNull JetElement root) { - return root.accept( - new JetVisitor, List>() { - @Override - public List visitExpression(JetExpression expression, List data) { - data.add(expression); - return data; - } - - @Override - public List visitBlockExpression( - JetBlockExpression expression, List data) { - int n = expression.getStatements().size(); - if (n > 0) { - expression.getStatements().get(n - 1).accept(this, data); - } else { - data.add(expression); - } - - return data; - } - - @SuppressWarnings("ConstantConditions") - @Override - public List visitIfExpression( - JetIfExpression expression, List data) { - if (expression.getThen() != null) { - expression.getThen().accept(this, data); - } - if (expression.getElse() != null) { - expression.getElse().accept(this, data); - } - return data; - } - }, - new ArrayList() - ); - } - - private static Boolean checkAllIfExpressionsAreComplete(@NotNull JetElement root) { - return root.accept( - new JetVisitor() { - @Override - public Boolean visitJetElement(JetElement element, Boolean data) { - return data; - } - - @SuppressWarnings("ConstantConditions") - @Override - public Boolean visitIfExpression(JetIfExpression expression, Boolean data) { - if (data && expression.getThen() != null) { - data = expression.getThen().accept(this, data); - } else { - data = false; - } - if (data && expression.getElse() != null) { - data = expression.getElse().accept(this, data); - } else { - data = false; - } - - return data; - } - }, - true - ); - } - - private static boolean checkAllOutcomesAreCompatibleAssignments(@NotNull List outcomes) { - JetExpression lastLhs = null; - for (JetExpression outcome : outcomes) { - if (!JetPsiUtil.isAssignment(outcome)) return false; - - JetExpression currLhs = ((JetBinaryExpression)outcome).getLeft(); - if (!(currLhs instanceof JetSimpleNameExpression)) return false; - - if (lastLhs == null) { - lastLhs = currLhs; - } else if (!lastLhs.getText().equals(currLhs.getText())) return false; - } - - return true; - } - - static boolean checkIfStatementWithAssignments(@NotNull JetIfExpression ifExpression) { - if (ifExpression.getParent() == null) return false; - List outcomes = getIfExpressionOutcomes(ifExpression); - - return !outcomes.isEmpty() && checkAllIfExpressionsAreComplete(ifExpression) && checkAllOutcomesAreCompatibleAssignments(outcomes); - } - - static boolean checkAssignmentWithIfExpression(@NotNull JetElement element) { - if (!JetPsiUtil.isAssignment(element)) return false; - JetBinaryExpression assignment = (JetBinaryExpression)element; - return (assignment.getLeft() instanceof JetSimpleNameExpression) && - (assignment.getRight() instanceof JetIfExpression); - } - - @SuppressWarnings("ConstantConditions") - static void transformIfStatementWithAssignmentsToExpression(@NotNull JetIfExpression ifExpression) { - Project project = ifExpression.getProject(); - List outcomes = getIfExpressionOutcomes(ifExpression); - JetExpression lhs = ((JetBinaryExpression)outcomes.get(0)).getLeft(); - - JetBinaryExpression assignment = JetPsiFactory.createAssignment(project, lhs, ifExpression); - - assignment = (JetBinaryExpression)ifExpression.replace(assignment); - ifExpression = (JetIfExpression)assignment.getRight(); - - for (JetExpression outcome : getIfExpressionOutcomes(ifExpression)) { - outcome.replace(((JetBinaryExpression)outcome).getRight()); - } - } - - @SuppressWarnings("ConstantConditions") - static void transformAssignmentWithIfExpressionToStatement(@NotNull JetBinaryExpression assignment) { - Project project = assignment.getProject(); - String varName = assignment.getLeft().getText(); - JetIfExpression ifExpression = (JetIfExpression)assignment.getRight(); - - ifExpression = (JetIfExpression)assignment.replace(ifExpression); - - for (JetExpression outcome : getIfExpressionOutcomes(ifExpression)) { - JetBinaryExpression localAssignment = JetPsiFactory.createAssignment(project, JetPsiFactory.createExpression(project, varName), outcome); - outcome.replace(localAssignment); - } - } - - private CodeTransformationUtils() { - } -} diff --git a/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/IfStatementWithAssignmentsToExpressionIntention.java b/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/FoldBranchedExpressionIntention.java similarity index 51% rename from idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/IfStatementWithAssignmentsToExpressionIntention.java rename to idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/FoldBranchedExpressionIntention.java index a240d779fdd..8f25d6f40cd 100644 --- a/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/IfStatementWithAssignmentsToExpressionIntention.java +++ b/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/FoldBranchedExpressionIntention.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.jetbrains.jet.plugin.codeInsight.codeTransformations; +package org.jetbrains.jet.plugin.codeInsight.codeTransformations.branchedTransformations; import com.intellij.codeInsight.intention.impl.BaseIntentionAction; import com.intellij.openapi.editor.Editor; @@ -25,40 +25,40 @@ import com.intellij.psi.util.PsiTreeUtil; import com.intellij.util.IncorrectOperationException; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import org.jetbrains.jet.lang.psi.JetElement; +import org.jetbrains.jet.lang.psi.JetExpression; import org.jetbrains.jet.lang.psi.JetIfExpression; +import org.jetbrains.jet.lang.psi.JetPsiUtil; import org.jetbrains.jet.plugin.JetBundle; -public class IfStatementWithAssignmentsToExpressionIntention extends BaseIntentionAction { - public IfStatementWithAssignmentsToExpressionIntention() { - setText(JetBundle.message("transform.if.statement.with.assignments.to.expression")); +public class FoldBranchedExpressionIntention extends BaseIntentionAction { + public FoldBranchedExpressionIntention() { + setText(JetBundle.message("fold.branched.expression")); } @NotNull @Override public String getFamilyName() { - return JetBundle.message("transform.if.statement.with.assignments.to.expression.family"); + return JetBundle.message("fold.branched.expression.family"); } @Nullable - private static JetIfExpression getOriginalExpression(@NotNull Editor editor, @NotNull PsiFile file) { - int offset = editor.getCaretModel().getOffset(); - PsiElement element = file.findElementAt(offset); - return PsiTreeUtil.getParentOfType(element, JetIfExpression.class, false); + private static JetExpression getTarget(@NotNull Editor editor, @NotNull PsiFile file) { + PsiElement element = file.findElementAt(editor.getCaretModel().getOffset()); + return (JetExpression)JetPsiUtil.getParentByTypeAndPredicate(element, JetElement.class, BranchedFoldingUtils.FOLDABLE_EXPRESSION, false); } @Override - public boolean isAvailable( - @NotNull Project project, @NotNull Editor editor, @NotNull PsiFile file) { - JetIfExpression ifExpression = getOriginalExpression(editor, file); - return (ifExpression != null) && CodeTransformationUtils.checkIfStatementWithAssignments(ifExpression); + public boolean isAvailable(@NotNull Project project, @NotNull Editor editor, @NotNull PsiFile file) { + return getTarget(editor, file) != null; } @Override - public void invoke( - @NotNull Project project, @NotNull Editor editor, @NotNull PsiFile file - ) throws IncorrectOperationException { - JetIfExpression ifExpression = getOriginalExpression(editor, file); - assert ifExpression != null; - CodeTransformationUtils.transformIfStatementWithAssignmentsToExpression(ifExpression); + public void invoke(@NotNull Project project, @NotNull Editor editor, @NotNull PsiFile file) throws IncorrectOperationException { + JetExpression target = getTarget(editor, file); + + assert target != null; + + BranchedFoldingUtils.foldExpression(target); } } diff --git a/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/UnfoldBranchedExpressionIntention.java b/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/UnfoldBranchedExpressionIntention.java new file mode 100644 index 00000000000..61cd20886e5 --- /dev/null +++ b/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/UnfoldBranchedExpressionIntention.java @@ -0,0 +1,62 @@ +/* + * Copyright 2010-2013 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.jetbrains.jet.plugin.codeInsight.codeTransformations.branchedTransformations; + +import com.intellij.codeInsight.intention.impl.BaseIntentionAction; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.project.Project; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiFile; +import com.intellij.util.IncorrectOperationException; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import org.jetbrains.jet.lang.psi.JetElement; +import org.jetbrains.jet.lang.psi.JetExpression; +import org.jetbrains.jet.lang.psi.JetPsiUtil; +import org.jetbrains.jet.plugin.JetBundle; + +public class UnfoldBranchedExpressionIntention extends BaseIntentionAction { + public UnfoldBranchedExpressionIntention() { + setText(JetBundle.message("unfold.branched.expression")); + } + + @NotNull + @Override + public String getFamilyName() { + return JetBundle.message("unfold.branched.expression.family"); + } + + @Nullable + private static JetExpression getTarget(@NotNull Editor editor, @NotNull PsiFile file) { + PsiElement element = file.findElementAt(editor.getCaretModel().getOffset()); + return (JetExpression)JetPsiUtil.getParentByTypeAndPredicate(element, JetElement.class, BranchedUnfoldingUtils.UNFOLDABLE_EXPRESSION, false); + } + + @Override + public boolean isAvailable(@NotNull Project project, @NotNull Editor editor, @NotNull PsiFile file) { + return getTarget(editor, file) != null; + } + + @Override + public void invoke(@NotNull Project project, @NotNull Editor editor, @NotNull PsiFile file) throws IncorrectOperationException { + JetExpression target = getTarget(editor, file); + + assert target != null; + + BranchedUnfoldingUtils.unfoldExpression(target); + } +} diff --git a/idea/tests/org/jetbrains/jet/plugin/codeInsight/codeTransformations/AbstractCodeTransformationTest.java b/idea/tests/org/jetbrains/jet/plugin/codeInsight/codeTransformations/AbstractCodeTransformationTest.java index 56e71ad86a9..4c904907a81 100644 --- a/idea/tests/org/jetbrains/jet/plugin/codeInsight/codeTransformations/AbstractCodeTransformationTest.java +++ b/idea/tests/org/jetbrains/jet/plugin/codeInsight/codeTransformations/AbstractCodeTransformationTest.java @@ -21,16 +21,18 @@ import com.intellij.openapi.util.io.FileUtil; import com.intellij.testFramework.LightCodeInsightTestCase; import org.jetbrains.annotations.NotNull; import org.jetbrains.jet.InTextDirectivesUtils; +import org.jetbrains.jet.plugin.codeInsight.codeTransformations.branchedTransformations.FoldBranchedExpressionIntention; +import org.jetbrains.jet.plugin.codeInsight.codeTransformations.branchedTransformations.UnfoldBranchedExpressionIntention; import java.io.File; public abstract class AbstractCodeTransformationTest extends LightCodeInsightTestCase { - public void doTestIfStatementWithAssignmentsToExpression(@NotNull String path) throws Exception { - doTest(path, new IfStatementWithAssignmentsToExpressionIntention()); + public void doTestBranchedFolding(@NotNull String path) throws Exception { + doTest(path, new FoldBranchedExpressionIntention()); } - public void doTestAssignmentWithIfExpressionToStatement(@NotNull String path) throws Exception { - doTest(path, new AssignmentWithIfExpressionToStatementIntention()); + public void doTestBranchedUnfolding(@NotNull String path) throws Exception { + doTest(path, new UnfoldBranchedExpressionIntention()); } public void doTestRemoveUnnecessaryParentheses(@NotNull String path) throws Exception { From f473224e8448bdcc79ac52780456c54be358fa5a Mon Sep 17 00:00:00 2001 From: Alexey Sedunov Date: Fri, 12 Apr 2013 17:09:59 +0400 Subject: [PATCH 062/249] Add tests for folding/unfolding operations --- .../jet/generators/tests/GenerateTests.java | 3 +-- .../folding/assignment}/innerIfTransformed.kt | 0 .../assignment}/innerIfTransformed.kt.after | 0 .../assignment/innerWhenTransformed.kt | 21 +++++++++++++++++++ .../assignment/innerWhenTransformed.kt.after | 21 +++++++++++++++++++ .../branched/folding/assignment/simpleIf.kt | 7 +++++++ .../folding/assignment/simpleIf.kt.after | 7 +++++++ .../simpleIfWithAugmentedAssignment.kt | 7 +++++++ .../simpleIfWithAugmentedAssignment.kt.after | 7 +++++++ .../folding/assignment/simpleIfWithBlocks.kt} | 0 .../assignment/simpleIfWithBlocks.kt.after} | 0 .../assignment/simpleIfWithShadowedVar.kt | 16 ++++++++++++++ .../simpleIfWithUnmatchedAssignmentOps.kt | 12 +++++++++++ .../simpleIfWithUnmatchedAssignments.kt | 13 ++++++++++++ .../assignment}/simpleIfWithoutElse.kt | 0 .../simpleIfWithoutTerminatingAssignment.kt | 0 .../branched/folding/assignment/simpleWhen.kt | 10 +++++++++ .../folding/assignment/simpleWhen.kt.after | 10 +++++++++ .../assignment/simpleWhenWithBlocks.kt | 16 ++++++++++++++ .../assignment/simpleWhenWithBlocks.kt.after | 16 ++++++++++++++ .../assignment/simpleWhenWithShadowedVar.kt | 19 +++++++++++++++++ .../simpleWhenWithUnmatchedAssignments.kt | 18 ++++++++++++++++ .../simpleWhenWithoutTerminatingAssignment.kt | 17 +++++++++++++++ .../folding/asymmetricReturn/simpleIf.kt | 4 ++++ .../asymmetricReturn/simpleIf.kt.after | 3 +++ .../asymmetricReturn/simpleIfWithBlocks.kt | 7 +++++++ .../simpleIfWithBlocks.kt.after | 6 ++++++ .../folding/return/innerIfTransformed.kt} | 16 ++++++-------- .../return/innerIfTransformed.kt.after} | 16 ++++++-------- .../folding/return/innerWhenTransformed.kt | 11 ++++++++++ .../return/innerWhenTransformed.kt.after | 11 ++++++++++ .../branched/folding/return/simpleIf.kt | 6 ++++++ .../branched/folding/return/simpleIf.kt.after | 6 ++++++ .../folding/return/simpleIfWithBlocks.kt | 9 ++++++++ .../return/simpleIfWithBlocks.kt.after | 9 ++++++++ .../branched/folding/return/simpleWhen.kt | 6 ++++++ .../folding/return/simpleWhen.kt.after | 6 ++++++ .../folding/return/simpleWhenWithBlocks.kt | 11 ++++++++++ .../return/simpleWhenWithBlocks.kt.after | 11 ++++++++++ .../assignment}/innerIfTransformed.kt | 0 .../assignment}/innerIfTransformed.kt.after | 0 .../unfolding/assignment}/nestedIfs.kt | 0 .../unfolding/assignment}/nestedIfs.kt.after | 6 +++--- .../branched/unfolding/assignment/simpleIf.kt | 7 +++++++ .../unfolding/assignment/simpleIf.kt.after | 7 +++++++ .../simpleIfWithAugmentedAssignment.kt | 7 +++++++ .../simpleIfWithAugmentedAssignment.kt.after | 7 +++++++ .../assignment/simpleIfWithBlocks.kt} | 0 .../assignment/simpleIfWithBlocks.kt.after} | 0 .../assignment}/simpleIfWithoutAssignment.kt | 0 .../unfolding/asymmetricReturn/simpleIf.kt | 3 +++ .../asymmetricReturn/simpleIf.kt.after | 3 +++ .../asymmetricReturn/simpleIfWithBlocks.kt | 6 ++++++ .../simpleIfWithBlocks.kt.after | 6 ++++++ .../unfolding/return/innerIfTransformed.kt | 17 +++++++++++++++ .../return/innerIfTransformed.kt.after | 17 +++++++++++++++ .../branched/unfolding/return/simpleIf.kt | 6 ++++++ .../unfolding/return/simpleIf.kt.after | 6 ++++++ .../unfolding/return/simpleIfWithBlocks.kt | 9 ++++++++ .../return/simpleIfWithBlocks.kt.after | 9 ++++++++ .../CodeTransformationsTestGenerated.java | 2 +- 61 files changed, 450 insertions(+), 26 deletions(-) rename idea/testData/codeInsight/codeTransformations/{ifStatementWithAssignmentsToExpression => branched/folding/assignment}/innerIfTransformed.kt (100%) rename idea/testData/codeInsight/codeTransformations/{ifStatementWithAssignmentsToExpression => branched/folding/assignment}/innerIfTransformed.kt.after (100%) create mode 100644 idea/testData/codeInsight/codeTransformations/branched/folding/assignment/innerWhenTransformed.kt create mode 100644 idea/testData/codeInsight/codeTransformations/branched/folding/assignment/innerWhenTransformed.kt.after create mode 100644 idea/testData/codeInsight/codeTransformations/branched/folding/assignment/simpleIf.kt create mode 100644 idea/testData/codeInsight/codeTransformations/branched/folding/assignment/simpleIf.kt.after create mode 100644 idea/testData/codeInsight/codeTransformations/branched/folding/assignment/simpleIfWithAugmentedAssignment.kt create mode 100644 idea/testData/codeInsight/codeTransformations/branched/folding/assignment/simpleIfWithAugmentedAssignment.kt.after rename idea/testData/codeInsight/codeTransformations/{assignmentWithIfExpressionToStatement/simpleIf.kt.after => branched/folding/assignment/simpleIfWithBlocks.kt} (100%) rename idea/testData/codeInsight/codeTransformations/{assignmentWithIfExpressionToStatement/simpleIf.kt => branched/folding/assignment/simpleIfWithBlocks.kt.after} (100%) create mode 100644 idea/testData/codeInsight/codeTransformations/branched/folding/assignment/simpleIfWithShadowedVar.kt create mode 100644 idea/testData/codeInsight/codeTransformations/branched/folding/assignment/simpleIfWithUnmatchedAssignmentOps.kt create mode 100644 idea/testData/codeInsight/codeTransformations/branched/folding/assignment/simpleIfWithUnmatchedAssignments.kt rename idea/testData/codeInsight/codeTransformations/{ifStatementWithAssignmentsToExpression => branched/folding/assignment}/simpleIfWithoutElse.kt (100%) rename idea/testData/codeInsight/codeTransformations/{ifStatementWithAssignmentsToExpression => branched/folding/assignment}/simpleIfWithoutTerminatingAssignment.kt (100%) create mode 100644 idea/testData/codeInsight/codeTransformations/branched/folding/assignment/simpleWhen.kt create mode 100644 idea/testData/codeInsight/codeTransformations/branched/folding/assignment/simpleWhen.kt.after create mode 100644 idea/testData/codeInsight/codeTransformations/branched/folding/assignment/simpleWhenWithBlocks.kt create mode 100644 idea/testData/codeInsight/codeTransformations/branched/folding/assignment/simpleWhenWithBlocks.kt.after create mode 100644 idea/testData/codeInsight/codeTransformations/branched/folding/assignment/simpleWhenWithShadowedVar.kt create mode 100644 idea/testData/codeInsight/codeTransformations/branched/folding/assignment/simpleWhenWithUnmatchedAssignments.kt create mode 100644 idea/testData/codeInsight/codeTransformations/branched/folding/assignment/simpleWhenWithoutTerminatingAssignment.kt create mode 100644 idea/testData/codeInsight/codeTransformations/branched/folding/asymmetricReturn/simpleIf.kt create mode 100644 idea/testData/codeInsight/codeTransformations/branched/folding/asymmetricReturn/simpleIf.kt.after create mode 100644 idea/testData/codeInsight/codeTransformations/branched/folding/asymmetricReturn/simpleIfWithBlocks.kt create mode 100644 idea/testData/codeInsight/codeTransformations/branched/folding/asymmetricReturn/simpleIfWithBlocks.kt.after rename idea/testData/codeInsight/codeTransformations/{assignmentWithIfExpressionToStatement/nestedIfs.kt.after => branched/folding/return/innerIfTransformed.kt} (53%) rename idea/testData/codeInsight/codeTransformations/{ifStatementWithAssignmentsToExpression/nestedIfs.kt => branched/folding/return/innerIfTransformed.kt.after} (53%) create mode 100644 idea/testData/codeInsight/codeTransformations/branched/folding/return/innerWhenTransformed.kt create mode 100644 idea/testData/codeInsight/codeTransformations/branched/folding/return/innerWhenTransformed.kt.after create mode 100644 idea/testData/codeInsight/codeTransformations/branched/folding/return/simpleIf.kt create mode 100644 idea/testData/codeInsight/codeTransformations/branched/folding/return/simpleIf.kt.after create mode 100644 idea/testData/codeInsight/codeTransformations/branched/folding/return/simpleIfWithBlocks.kt create mode 100644 idea/testData/codeInsight/codeTransformations/branched/folding/return/simpleIfWithBlocks.kt.after create mode 100644 idea/testData/codeInsight/codeTransformations/branched/folding/return/simpleWhen.kt create mode 100644 idea/testData/codeInsight/codeTransformations/branched/folding/return/simpleWhen.kt.after create mode 100644 idea/testData/codeInsight/codeTransformations/branched/folding/return/simpleWhenWithBlocks.kt create mode 100644 idea/testData/codeInsight/codeTransformations/branched/folding/return/simpleWhenWithBlocks.kt.after rename idea/testData/codeInsight/codeTransformations/{assignmentWithIfExpressionToStatement => branched/unfolding/assignment}/innerIfTransformed.kt (100%) rename idea/testData/codeInsight/codeTransformations/{assignmentWithIfExpressionToStatement => branched/unfolding/assignment}/innerIfTransformed.kt.after (100%) rename idea/testData/codeInsight/codeTransformations/{assignmentWithIfExpressionToStatement => branched/unfolding/assignment}/nestedIfs.kt (100%) rename idea/testData/codeInsight/codeTransformations/{ifStatementWithAssignmentsToExpression => branched/unfolding/assignment}/nestedIfs.kt.after (77%) create mode 100644 idea/testData/codeInsight/codeTransformations/branched/unfolding/assignment/simpleIf.kt create mode 100644 idea/testData/codeInsight/codeTransformations/branched/unfolding/assignment/simpleIf.kt.after create mode 100644 idea/testData/codeInsight/codeTransformations/branched/unfolding/assignment/simpleIfWithAugmentedAssignment.kt create mode 100644 idea/testData/codeInsight/codeTransformations/branched/unfolding/assignment/simpleIfWithAugmentedAssignment.kt.after rename idea/testData/codeInsight/codeTransformations/{ifStatementWithAssignmentsToExpression/simpleIf.kt.after => branched/unfolding/assignment/simpleIfWithBlocks.kt} (100%) rename idea/testData/codeInsight/codeTransformations/{ifStatementWithAssignmentsToExpression/simpleIf.kt => branched/unfolding/assignment/simpleIfWithBlocks.kt.after} (100%) rename idea/testData/codeInsight/codeTransformations/{assignmentWithIfExpressionToStatement => branched/unfolding/assignment}/simpleIfWithoutAssignment.kt (100%) create mode 100644 idea/testData/codeInsight/codeTransformations/branched/unfolding/asymmetricReturn/simpleIf.kt create mode 100644 idea/testData/codeInsight/codeTransformations/branched/unfolding/asymmetricReturn/simpleIf.kt.after create mode 100644 idea/testData/codeInsight/codeTransformations/branched/unfolding/asymmetricReturn/simpleIfWithBlocks.kt create mode 100644 idea/testData/codeInsight/codeTransformations/branched/unfolding/asymmetricReturn/simpleIfWithBlocks.kt.after create mode 100644 idea/testData/codeInsight/codeTransformations/branched/unfolding/return/innerIfTransformed.kt create mode 100644 idea/testData/codeInsight/codeTransformations/branched/unfolding/return/innerIfTransformed.kt.after create mode 100644 idea/testData/codeInsight/codeTransformations/branched/unfolding/return/simpleIf.kt create mode 100644 idea/testData/codeInsight/codeTransformations/branched/unfolding/return/simpleIf.kt.after create mode 100644 idea/testData/codeInsight/codeTransformations/branched/unfolding/return/simpleIfWithBlocks.kt create mode 100644 idea/testData/codeInsight/codeTransformations/branched/unfolding/return/simpleIfWithBlocks.kt.after diff --git a/generators/org/jetbrains/jet/generators/tests/GenerateTests.java b/generators/org/jetbrains/jet/generators/tests/GenerateTests.java index ebfd4695151..8049091a2a3 100644 --- a/generators/org/jetbrains/jet/generators/tests/GenerateTests.java +++ b/generators/org/jetbrains/jet/generators/tests/GenerateTests.java @@ -306,8 +306,7 @@ public class GenerateTests { "CodeTransformationsTestGenerated", AbstractCodeTransformationTest.class, testModel("idea/testData/codeInsight/codeTransformations/ifStatementWithAssignmentsToExpression", "doTestIfStatementWithAssignmentsToExpression"), - testModel("idea/testData/codeInsight/codeTransformations/assignmentWithIfExpressionToStatement", "doTestAssignmentWithIfExpressionToStatement"), - testModel("idea/testData/codeInsight/codeTransformations/removeUnnecessaryParentheses", "doTestRemoveUnnecessaryParentheses") + testModel("idea/testData/codeInsight/codeTransformations/assignmentWithIfExpressionToStatement", "doTestAssignmentWithIfExpressionToStatement") ); generateTest( diff --git a/idea/testData/codeInsight/codeTransformations/ifStatementWithAssignmentsToExpression/innerIfTransformed.kt b/idea/testData/codeInsight/codeTransformations/branched/folding/assignment/innerIfTransformed.kt similarity index 100% rename from idea/testData/codeInsight/codeTransformations/ifStatementWithAssignmentsToExpression/innerIfTransformed.kt rename to idea/testData/codeInsight/codeTransformations/branched/folding/assignment/innerIfTransformed.kt diff --git a/idea/testData/codeInsight/codeTransformations/ifStatementWithAssignmentsToExpression/innerIfTransformed.kt.after b/idea/testData/codeInsight/codeTransformations/branched/folding/assignment/innerIfTransformed.kt.after similarity index 100% rename from idea/testData/codeInsight/codeTransformations/ifStatementWithAssignmentsToExpression/innerIfTransformed.kt.after rename to idea/testData/codeInsight/codeTransformations/branched/folding/assignment/innerIfTransformed.kt.after diff --git a/idea/testData/codeInsight/codeTransformations/branched/folding/assignment/innerWhenTransformed.kt b/idea/testData/codeInsight/codeTransformations/branched/folding/assignment/innerWhenTransformed.kt new file mode 100644 index 00000000000..c1784696fd1 --- /dev/null +++ b/idea/testData/codeInsight/codeTransformations/branched/folding/assignment/innerWhenTransformed.kt @@ -0,0 +1,21 @@ +fun test(n: Int): String { + var res: String + + if (3 > 2) { + when(n) { + 1 -> { + println("***") + res = "one" + } + else -> { + println("***") + res = "two" + } + } + } else { + println("***") + res = "???" + } + + return res +} \ No newline at end of file diff --git a/idea/testData/codeInsight/codeTransformations/branched/folding/assignment/innerWhenTransformed.kt.after b/idea/testData/codeInsight/codeTransformations/branched/folding/assignment/innerWhenTransformed.kt.after new file mode 100644 index 00000000000..d3f6b00fa62 --- /dev/null +++ b/idea/testData/codeInsight/codeTransformations/branched/folding/assignment/innerWhenTransformed.kt.after @@ -0,0 +1,21 @@ +fun test(n: Int): String { + var res: String + + if (3 > 2) { + res = when(n) { + 1 -> { + println("***") + "one" + } + else -> { + println("***") + "two" + } + } + } else { + println("***") + res = "???" + } + + return res +} \ No newline at end of file diff --git a/idea/testData/codeInsight/codeTransformations/branched/folding/assignment/simpleIf.kt b/idea/testData/codeInsight/codeTransformations/branched/folding/assignment/simpleIf.kt new file mode 100644 index 00000000000..b35ea7a79dc --- /dev/null +++ b/idea/testData/codeInsight/codeTransformations/branched/folding/assignment/simpleIf.kt @@ -0,0 +1,7 @@ +fun test(n: Int): String { + var res: String + + if (n == 1) res = "one" else res = "two" + + return res +} \ No newline at end of file diff --git a/idea/testData/codeInsight/codeTransformations/branched/folding/assignment/simpleIf.kt.after b/idea/testData/codeInsight/codeTransformations/branched/folding/assignment/simpleIf.kt.after new file mode 100644 index 00000000000..2270e195d3e --- /dev/null +++ b/idea/testData/codeInsight/codeTransformations/branched/folding/assignment/simpleIf.kt.after @@ -0,0 +1,7 @@ +fun test(n: Int): String { + var res: String + + res = if (n == 1) "one" else "two" + + return res +} \ No newline at end of file diff --git a/idea/testData/codeInsight/codeTransformations/branched/folding/assignment/simpleIfWithAugmentedAssignment.kt b/idea/testData/codeInsight/codeTransformations/branched/folding/assignment/simpleIfWithAugmentedAssignment.kt new file mode 100644 index 00000000000..ccd31de0a4b --- /dev/null +++ b/idea/testData/codeInsight/codeTransformations/branched/folding/assignment/simpleIfWithAugmentedAssignment.kt @@ -0,0 +1,7 @@ +fun test(n: Int): String { + var res: String = "!" + + if (n == 1) res += "one" else res += "two" + + return res +} \ No newline at end of file diff --git a/idea/testData/codeInsight/codeTransformations/branched/folding/assignment/simpleIfWithAugmentedAssignment.kt.after b/idea/testData/codeInsight/codeTransformations/branched/folding/assignment/simpleIfWithAugmentedAssignment.kt.after new file mode 100644 index 00000000000..bdd35f4f302 --- /dev/null +++ b/idea/testData/codeInsight/codeTransformations/branched/folding/assignment/simpleIfWithAugmentedAssignment.kt.after @@ -0,0 +1,7 @@ +fun test(n: Int): String { + var res: String = "!" + + res += if (n == 1) "one" else "two" + + return res +} \ No newline at end of file diff --git a/idea/testData/codeInsight/codeTransformations/assignmentWithIfExpressionToStatement/simpleIf.kt.after b/idea/testData/codeInsight/codeTransformations/branched/folding/assignment/simpleIfWithBlocks.kt similarity index 100% rename from idea/testData/codeInsight/codeTransformations/assignmentWithIfExpressionToStatement/simpleIf.kt.after rename to idea/testData/codeInsight/codeTransformations/branched/folding/assignment/simpleIfWithBlocks.kt diff --git a/idea/testData/codeInsight/codeTransformations/assignmentWithIfExpressionToStatement/simpleIf.kt b/idea/testData/codeInsight/codeTransformations/branched/folding/assignment/simpleIfWithBlocks.kt.after similarity index 100% rename from idea/testData/codeInsight/codeTransformations/assignmentWithIfExpressionToStatement/simpleIf.kt rename to idea/testData/codeInsight/codeTransformations/branched/folding/assignment/simpleIfWithBlocks.kt.after diff --git a/idea/testData/codeInsight/codeTransformations/branched/folding/assignment/simpleIfWithShadowedVar.kt b/idea/testData/codeInsight/codeTransformations/branched/folding/assignment/simpleIfWithShadowedVar.kt new file mode 100644 index 00000000000..a234873b8d9 --- /dev/null +++ b/idea/testData/codeInsight/codeTransformations/branched/folding/assignment/simpleIfWithShadowedVar.kt @@ -0,0 +1,16 @@ +// IS_APPLICABLE: false +fun test(n: Int): String { + var res: String = "" + + if (n == 1) { + println("***") + res = "one" + } else { + var res: String + + println("***") + res = "two" + } + + return res +} \ No newline at end of file diff --git a/idea/testData/codeInsight/codeTransformations/branched/folding/assignment/simpleIfWithUnmatchedAssignmentOps.kt b/idea/testData/codeInsight/codeTransformations/branched/folding/assignment/simpleIfWithUnmatchedAssignmentOps.kt new file mode 100644 index 00000000000..e7a6033e708 --- /dev/null +++ b/idea/testData/codeInsight/codeTransformations/branched/folding/assignment/simpleIfWithUnmatchedAssignmentOps.kt @@ -0,0 +1,12 @@ +// IS_APPLICABLE: false +fun test(s: String): Int { + var n: Int = 1; + + if (s.equals("add")) { + n += 1 + } else { + n -= 1 + } + + return n +} \ No newline at end of file diff --git a/idea/testData/codeInsight/codeTransformations/branched/folding/assignment/simpleIfWithUnmatchedAssignments.kt b/idea/testData/codeInsight/codeTransformations/branched/folding/assignment/simpleIfWithUnmatchedAssignments.kt new file mode 100644 index 00000000000..38c0aeabbec --- /dev/null +++ b/idea/testData/codeInsight/codeTransformations/branched/folding/assignment/simpleIfWithUnmatchedAssignments.kt @@ -0,0 +1,13 @@ +// IS_APPLICABLE: false +fun test(n: Int): String { + var res: String = "" + var res2: String = "" + + if (n == 1) { + res = "one" + } else { + res2 = "two" + } + + return res + res2 +} \ No newline at end of file diff --git a/idea/testData/codeInsight/codeTransformations/ifStatementWithAssignmentsToExpression/simpleIfWithoutElse.kt b/idea/testData/codeInsight/codeTransformations/branched/folding/assignment/simpleIfWithoutElse.kt similarity index 100% rename from idea/testData/codeInsight/codeTransformations/ifStatementWithAssignmentsToExpression/simpleIfWithoutElse.kt rename to idea/testData/codeInsight/codeTransformations/branched/folding/assignment/simpleIfWithoutElse.kt diff --git a/idea/testData/codeInsight/codeTransformations/ifStatementWithAssignmentsToExpression/simpleIfWithoutTerminatingAssignment.kt b/idea/testData/codeInsight/codeTransformations/branched/folding/assignment/simpleIfWithoutTerminatingAssignment.kt similarity index 100% rename from idea/testData/codeInsight/codeTransformations/ifStatementWithAssignmentsToExpression/simpleIfWithoutTerminatingAssignment.kt rename to idea/testData/codeInsight/codeTransformations/branched/folding/assignment/simpleIfWithoutTerminatingAssignment.kt diff --git a/idea/testData/codeInsight/codeTransformations/branched/folding/assignment/simpleWhen.kt b/idea/testData/codeInsight/codeTransformations/branched/folding/assignment/simpleWhen.kt new file mode 100644 index 00000000000..bf7f1257945 --- /dev/null +++ b/idea/testData/codeInsight/codeTransformations/branched/folding/assignment/simpleWhen.kt @@ -0,0 +1,10 @@ +fun test(n: Int): String { + var res: String + + when(n) { + 1 -> res = "one" + else -> res = "two" + } + + return res +} \ No newline at end of file diff --git a/idea/testData/codeInsight/codeTransformations/branched/folding/assignment/simpleWhen.kt.after b/idea/testData/codeInsight/codeTransformations/branched/folding/assignment/simpleWhen.kt.after new file mode 100644 index 00000000000..c961e534ccc --- /dev/null +++ b/idea/testData/codeInsight/codeTransformations/branched/folding/assignment/simpleWhen.kt.after @@ -0,0 +1,10 @@ +fun test(n: Int): String { + var res: String + + res = when(n) { + 1 -> "one" + else -> "two" + } + + return res +} \ No newline at end of file diff --git a/idea/testData/codeInsight/codeTransformations/branched/folding/assignment/simpleWhenWithBlocks.kt b/idea/testData/codeInsight/codeTransformations/branched/folding/assignment/simpleWhenWithBlocks.kt new file mode 100644 index 00000000000..d3e4325d5de --- /dev/null +++ b/idea/testData/codeInsight/codeTransformations/branched/folding/assignment/simpleWhenWithBlocks.kt @@ -0,0 +1,16 @@ +fun test(n: Int): String { + var res: String + + when (n) { + 1 -> { + println("***") + res = "one" + } + else -> { + println("***") + res = "two" + } + } + + return res +} \ No newline at end of file diff --git a/idea/testData/codeInsight/codeTransformations/branched/folding/assignment/simpleWhenWithBlocks.kt.after b/idea/testData/codeInsight/codeTransformations/branched/folding/assignment/simpleWhenWithBlocks.kt.after new file mode 100644 index 00000000000..237433b09f3 --- /dev/null +++ b/idea/testData/codeInsight/codeTransformations/branched/folding/assignment/simpleWhenWithBlocks.kt.after @@ -0,0 +1,16 @@ +fun test(n: Int): String { + var res: String + + res = when (n) { + 1 -> { + println("***") + "one" + } + else -> { + println("***") + "two" + } + } + + return res +} \ No newline at end of file diff --git a/idea/testData/codeInsight/codeTransformations/branched/folding/assignment/simpleWhenWithShadowedVar.kt b/idea/testData/codeInsight/codeTransformations/branched/folding/assignment/simpleWhenWithShadowedVar.kt new file mode 100644 index 00000000000..e258e21ffe4 --- /dev/null +++ b/idea/testData/codeInsight/codeTransformations/branched/folding/assignment/simpleWhenWithShadowedVar.kt @@ -0,0 +1,19 @@ +// IS_APPLICABLE: false +fun test(n: Int): String { + var res: String = "" + + when (n) { + 1 -> { + println("***") + res = "one" + } + else -> { + var res: String + + res = "two" + println("***") + } + } + + return res +} \ No newline at end of file diff --git a/idea/testData/codeInsight/codeTransformations/branched/folding/assignment/simpleWhenWithUnmatchedAssignments.kt b/idea/testData/codeInsight/codeTransformations/branched/folding/assignment/simpleWhenWithUnmatchedAssignments.kt new file mode 100644 index 00000000000..dc577d43980 --- /dev/null +++ b/idea/testData/codeInsight/codeTransformations/branched/folding/assignment/simpleWhenWithUnmatchedAssignments.kt @@ -0,0 +1,18 @@ +// IS_APPLICABLE: false +fun test(n: Int): String { + var res: String = "" + var res2: String = "" + + when (n) { + 1 -> { + println("***") + res = "one" + } + else -> { + println("***") + res2 = "two" + } + } + + return res + res2 +} \ No newline at end of file diff --git a/idea/testData/codeInsight/codeTransformations/branched/folding/assignment/simpleWhenWithoutTerminatingAssignment.kt b/idea/testData/codeInsight/codeTransformations/branched/folding/assignment/simpleWhenWithoutTerminatingAssignment.kt new file mode 100644 index 00000000000..6b2f07c7e4a --- /dev/null +++ b/idea/testData/codeInsight/codeTransformations/branched/folding/assignment/simpleWhenWithoutTerminatingAssignment.kt @@ -0,0 +1,17 @@ +// IS_APPLICABLE: false +fun test(n: Int): String { + var res: String + + when (n) { + 1 -> { + println("***") + res = "one" + } + else -> { + res = "two" + println("***") + } + } + + return res +} \ No newline at end of file diff --git a/idea/testData/codeInsight/codeTransformations/branched/folding/asymmetricReturn/simpleIf.kt b/idea/testData/codeInsight/codeTransformations/branched/folding/asymmetricReturn/simpleIf.kt new file mode 100644 index 00000000000..1760f3812e5 --- /dev/null +++ b/idea/testData/codeInsight/codeTransformations/branched/folding/asymmetricReturn/simpleIf.kt @@ -0,0 +1,4 @@ +fun test(n: Int): String { + if (n == 1) return "one" + return "two" +} \ No newline at end of file diff --git a/idea/testData/codeInsight/codeTransformations/branched/folding/asymmetricReturn/simpleIf.kt.after b/idea/testData/codeInsight/codeTransformations/branched/folding/asymmetricReturn/simpleIf.kt.after new file mode 100644 index 00000000000..741973c35c6 --- /dev/null +++ b/idea/testData/codeInsight/codeTransformations/branched/folding/asymmetricReturn/simpleIf.kt.after @@ -0,0 +1,3 @@ +fun test(n: Int): String { + return if (n == 1) "one" else "two" +} \ No newline at end of file diff --git a/idea/testData/codeInsight/codeTransformations/branched/folding/asymmetricReturn/simpleIfWithBlocks.kt b/idea/testData/codeInsight/codeTransformations/branched/folding/asymmetricReturn/simpleIfWithBlocks.kt new file mode 100644 index 00000000000..ccdf2e9f3e6 --- /dev/null +++ b/idea/testData/codeInsight/codeTransformations/branched/folding/asymmetricReturn/simpleIfWithBlocks.kt @@ -0,0 +1,7 @@ +fun test(n: Int): String { + if (n == 1) { + println("***") + return "one" + } + return "two" +} \ No newline at end of file diff --git a/idea/testData/codeInsight/codeTransformations/branched/folding/asymmetricReturn/simpleIfWithBlocks.kt.after b/idea/testData/codeInsight/codeTransformations/branched/folding/asymmetricReturn/simpleIfWithBlocks.kt.after new file mode 100644 index 00000000000..5777e6c7ac1 --- /dev/null +++ b/idea/testData/codeInsight/codeTransformations/branched/folding/asymmetricReturn/simpleIfWithBlocks.kt.after @@ -0,0 +1,6 @@ +fun test(n: Int): String { + return if (n == 1) { + println("***") + "one" + } else "two" +} \ No newline at end of file diff --git a/idea/testData/codeInsight/codeTransformations/assignmentWithIfExpressionToStatement/nestedIfs.kt.after b/idea/testData/codeInsight/codeTransformations/branched/folding/return/innerIfTransformed.kt similarity index 53% rename from idea/testData/codeInsight/codeTransformations/assignmentWithIfExpressionToStatement/nestedIfs.kt.after rename to idea/testData/codeInsight/codeTransformations/branched/folding/return/innerIfTransformed.kt index f7be6ee23aa..b402a1c2f2d 100644 --- a/idea/testData/codeInsight/codeTransformations/assignmentWithIfExpressionToStatement/nestedIfs.kt.after +++ b/idea/testData/codeInsight/codeTransformations/branched/folding/return/innerIfTransformed.kt @@ -1,21 +1,17 @@ fun test(n: Int): String { - var res: String - - if (n == 1) { - if (3 > 2) { + if (n == 1) { + if (3 > 2) { println("***") - res = "one" + return "one" } else { println("***") - res = "???" + return "???" } } else if (n == 2) { println("***") - res = "two" + return "two" } else { println("***") - res = "too many" + return "too many" } - - return res } \ No newline at end of file diff --git a/idea/testData/codeInsight/codeTransformations/ifStatementWithAssignmentsToExpression/nestedIfs.kt b/idea/testData/codeInsight/codeTransformations/branched/folding/return/innerIfTransformed.kt.after similarity index 53% rename from idea/testData/codeInsight/codeTransformations/ifStatementWithAssignmentsToExpression/nestedIfs.kt rename to idea/testData/codeInsight/codeTransformations/branched/folding/return/innerIfTransformed.kt.after index f7be6ee23aa..bf97963e5f0 100644 --- a/idea/testData/codeInsight/codeTransformations/ifStatementWithAssignmentsToExpression/nestedIfs.kt +++ b/idea/testData/codeInsight/codeTransformations/branched/folding/return/innerIfTransformed.kt.after @@ -1,21 +1,17 @@ fun test(n: Int): String { - var res: String - - if (n == 1) { - if (3 > 2) { + if (n == 1) { + return if (3 > 2) { println("***") - res = "one" + "one" } else { println("***") - res = "???" + "???" } } else if (n == 2) { println("***") - res = "two" + return "two" } else { println("***") - res = "too many" + return "too many" } - - return res } \ No newline at end of file diff --git a/idea/testData/codeInsight/codeTransformations/branched/folding/return/innerWhenTransformed.kt b/idea/testData/codeInsight/codeTransformations/branched/folding/return/innerWhenTransformed.kt new file mode 100644 index 00000000000..0a5a8764560 --- /dev/null +++ b/idea/testData/codeInsight/codeTransformations/branched/folding/return/innerWhenTransformed.kt @@ -0,0 +1,11 @@ +fun test(n: Int): String { + if (3 > 2) { + when (n) { + 1 -> return "one" + else -> return "two" + } + } else { + println("***") + return "???" + } +} \ No newline at end of file diff --git a/idea/testData/codeInsight/codeTransformations/branched/folding/return/innerWhenTransformed.kt.after b/idea/testData/codeInsight/codeTransformations/branched/folding/return/innerWhenTransformed.kt.after new file mode 100644 index 00000000000..cec7664dbfa --- /dev/null +++ b/idea/testData/codeInsight/codeTransformations/branched/folding/return/innerWhenTransformed.kt.after @@ -0,0 +1,11 @@ +fun test(n: Int): String { + if (3 > 2) { + return when (n) { + 1 -> "one" + else -> "two" + } + } else { + println("***") + return "???" + } +} \ No newline at end of file diff --git a/idea/testData/codeInsight/codeTransformations/branched/folding/return/simpleIf.kt b/idea/testData/codeInsight/codeTransformations/branched/folding/return/simpleIf.kt new file mode 100644 index 00000000000..a37ae9c22d3 --- /dev/null +++ b/idea/testData/codeInsight/codeTransformations/branched/folding/return/simpleIf.kt @@ -0,0 +1,6 @@ +fun test(n: Int): String { + if (n == 1) + return "one" + else + return "two" +} \ No newline at end of file diff --git a/idea/testData/codeInsight/codeTransformations/branched/folding/return/simpleIf.kt.after b/idea/testData/codeInsight/codeTransformations/branched/folding/return/simpleIf.kt.after new file mode 100644 index 00000000000..d7158b67554 --- /dev/null +++ b/idea/testData/codeInsight/codeTransformations/branched/folding/return/simpleIf.kt.after @@ -0,0 +1,6 @@ +fun test(n: Int): String { + return if (n == 1) + "one" + else + "two" +} \ No newline at end of file diff --git a/idea/testData/codeInsight/codeTransformations/branched/folding/return/simpleIfWithBlocks.kt b/idea/testData/codeInsight/codeTransformations/branched/folding/return/simpleIfWithBlocks.kt new file mode 100644 index 00000000000..4a306f5f17d --- /dev/null +++ b/idea/testData/codeInsight/codeTransformations/branched/folding/return/simpleIfWithBlocks.kt @@ -0,0 +1,9 @@ +fun test(n: Int): String { + if (n == 1) { + println("***") + return "one" + } else { + println("***") + return "two" + } +} \ No newline at end of file diff --git a/idea/testData/codeInsight/codeTransformations/branched/folding/return/simpleIfWithBlocks.kt.after b/idea/testData/codeInsight/codeTransformations/branched/folding/return/simpleIfWithBlocks.kt.after new file mode 100644 index 00000000000..a88492572b5 --- /dev/null +++ b/idea/testData/codeInsight/codeTransformations/branched/folding/return/simpleIfWithBlocks.kt.after @@ -0,0 +1,9 @@ +fun test(n: Int): String { + return if (n == 1) { + println("***") + "one" + } else { + println("***") + "two" + } +} \ No newline at end of file diff --git a/idea/testData/codeInsight/codeTransformations/branched/folding/return/simpleWhen.kt b/idea/testData/codeInsight/codeTransformations/branched/folding/return/simpleWhen.kt new file mode 100644 index 00000000000..09add4b1e81 --- /dev/null +++ b/idea/testData/codeInsight/codeTransformations/branched/folding/return/simpleWhen.kt @@ -0,0 +1,6 @@ +fun test(n: Int): String { + when (n) { + 1 -> return "one" + else -> return "two" + } +} \ No newline at end of file diff --git a/idea/testData/codeInsight/codeTransformations/branched/folding/return/simpleWhen.kt.after b/idea/testData/codeInsight/codeTransformations/branched/folding/return/simpleWhen.kt.after new file mode 100644 index 00000000000..83a1dee18ec --- /dev/null +++ b/idea/testData/codeInsight/codeTransformations/branched/folding/return/simpleWhen.kt.after @@ -0,0 +1,6 @@ +fun test(n: Int): String { + return when (n) { + 1 -> "one" + else -> "two" + } +} \ No newline at end of file diff --git a/idea/testData/codeInsight/codeTransformations/branched/folding/return/simpleWhenWithBlocks.kt b/idea/testData/codeInsight/codeTransformations/branched/folding/return/simpleWhenWithBlocks.kt new file mode 100644 index 00000000000..1c9b980257f --- /dev/null +++ b/idea/testData/codeInsight/codeTransformations/branched/folding/return/simpleWhenWithBlocks.kt @@ -0,0 +1,11 @@ +fun test(n: Int): String { + when(n) { + 1 -> { + println("***") + return "one" + } + else -> { + println("***") + return "two" + } +} \ No newline at end of file diff --git a/idea/testData/codeInsight/codeTransformations/branched/folding/return/simpleWhenWithBlocks.kt.after b/idea/testData/codeInsight/codeTransformations/branched/folding/return/simpleWhenWithBlocks.kt.after new file mode 100644 index 00000000000..5565cdc2ecd --- /dev/null +++ b/idea/testData/codeInsight/codeTransformations/branched/folding/return/simpleWhenWithBlocks.kt.after @@ -0,0 +1,11 @@ +fun test(n: Int): String { + return when(n) { + 1 -> { + println("***") + "one" + } + else -> { + println("***") + "two" + } +} \ No newline at end of file diff --git a/idea/testData/codeInsight/codeTransformations/assignmentWithIfExpressionToStatement/innerIfTransformed.kt b/idea/testData/codeInsight/codeTransformations/branched/unfolding/assignment/innerIfTransformed.kt similarity index 100% rename from idea/testData/codeInsight/codeTransformations/assignmentWithIfExpressionToStatement/innerIfTransformed.kt rename to idea/testData/codeInsight/codeTransformations/branched/unfolding/assignment/innerIfTransformed.kt diff --git a/idea/testData/codeInsight/codeTransformations/assignmentWithIfExpressionToStatement/innerIfTransformed.kt.after b/idea/testData/codeInsight/codeTransformations/branched/unfolding/assignment/innerIfTransformed.kt.after similarity index 100% rename from idea/testData/codeInsight/codeTransformations/assignmentWithIfExpressionToStatement/innerIfTransformed.kt.after rename to idea/testData/codeInsight/codeTransformations/branched/unfolding/assignment/innerIfTransformed.kt.after diff --git a/idea/testData/codeInsight/codeTransformations/assignmentWithIfExpressionToStatement/nestedIfs.kt b/idea/testData/codeInsight/codeTransformations/branched/unfolding/assignment/nestedIfs.kt similarity index 100% rename from idea/testData/codeInsight/codeTransformations/assignmentWithIfExpressionToStatement/nestedIfs.kt rename to idea/testData/codeInsight/codeTransformations/branched/unfolding/assignment/nestedIfs.kt diff --git a/idea/testData/codeInsight/codeTransformations/ifStatementWithAssignmentsToExpression/nestedIfs.kt.after b/idea/testData/codeInsight/codeTransformations/branched/unfolding/assignment/nestedIfs.kt.after similarity index 77% rename from idea/testData/codeInsight/codeTransformations/ifStatementWithAssignmentsToExpression/nestedIfs.kt.after rename to idea/testData/codeInsight/codeTransformations/branched/unfolding/assignment/nestedIfs.kt.after index d5ae1e4a2b0..a4f680c426d 100644 --- a/idea/testData/codeInsight/codeTransformations/ifStatementWithAssignmentsToExpression/nestedIfs.kt.after +++ b/idea/testData/codeInsight/codeTransformations/branched/unfolding/assignment/nestedIfs.kt.after @@ -1,15 +1,15 @@ fun test(n: Int): String { var res: String - res = if (n == 1) { - if (3 > 2) { + if (n == 1) { + res = if (3 > 2) { println("***") "one" } else { println("***") "???" } - } else if (n == 2) { + } else res = if (n == 2) { println("***") "two" } else { diff --git a/idea/testData/codeInsight/codeTransformations/branched/unfolding/assignment/simpleIf.kt b/idea/testData/codeInsight/codeTransformations/branched/unfolding/assignment/simpleIf.kt new file mode 100644 index 00000000000..2270e195d3e --- /dev/null +++ b/idea/testData/codeInsight/codeTransformations/branched/unfolding/assignment/simpleIf.kt @@ -0,0 +1,7 @@ +fun test(n: Int): String { + var res: String + + res = if (n == 1) "one" else "two" + + return res +} \ No newline at end of file diff --git a/idea/testData/codeInsight/codeTransformations/branched/unfolding/assignment/simpleIf.kt.after b/idea/testData/codeInsight/codeTransformations/branched/unfolding/assignment/simpleIf.kt.after new file mode 100644 index 00000000000..b35ea7a79dc --- /dev/null +++ b/idea/testData/codeInsight/codeTransformations/branched/unfolding/assignment/simpleIf.kt.after @@ -0,0 +1,7 @@ +fun test(n: Int): String { + var res: String + + if (n == 1) res = "one" else res = "two" + + return res +} \ No newline at end of file diff --git a/idea/testData/codeInsight/codeTransformations/branched/unfolding/assignment/simpleIfWithAugmentedAssignment.kt b/idea/testData/codeInsight/codeTransformations/branched/unfolding/assignment/simpleIfWithAugmentedAssignment.kt new file mode 100644 index 00000000000..bdd35f4f302 --- /dev/null +++ b/idea/testData/codeInsight/codeTransformations/branched/unfolding/assignment/simpleIfWithAugmentedAssignment.kt @@ -0,0 +1,7 @@ +fun test(n: Int): String { + var res: String = "!" + + res += if (n == 1) "one" else "two" + + return res +} \ No newline at end of file diff --git a/idea/testData/codeInsight/codeTransformations/branched/unfolding/assignment/simpleIfWithAugmentedAssignment.kt.after b/idea/testData/codeInsight/codeTransformations/branched/unfolding/assignment/simpleIfWithAugmentedAssignment.kt.after new file mode 100644 index 00000000000..ccd31de0a4b --- /dev/null +++ b/idea/testData/codeInsight/codeTransformations/branched/unfolding/assignment/simpleIfWithAugmentedAssignment.kt.after @@ -0,0 +1,7 @@ +fun test(n: Int): String { + var res: String = "!" + + if (n == 1) res += "one" else res += "two" + + return res +} \ No newline at end of file diff --git a/idea/testData/codeInsight/codeTransformations/ifStatementWithAssignmentsToExpression/simpleIf.kt.after b/idea/testData/codeInsight/codeTransformations/branched/unfolding/assignment/simpleIfWithBlocks.kt similarity index 100% rename from idea/testData/codeInsight/codeTransformations/ifStatementWithAssignmentsToExpression/simpleIf.kt.after rename to idea/testData/codeInsight/codeTransformations/branched/unfolding/assignment/simpleIfWithBlocks.kt diff --git a/idea/testData/codeInsight/codeTransformations/ifStatementWithAssignmentsToExpression/simpleIf.kt b/idea/testData/codeInsight/codeTransformations/branched/unfolding/assignment/simpleIfWithBlocks.kt.after similarity index 100% rename from idea/testData/codeInsight/codeTransformations/ifStatementWithAssignmentsToExpression/simpleIf.kt rename to idea/testData/codeInsight/codeTransformations/branched/unfolding/assignment/simpleIfWithBlocks.kt.after diff --git a/idea/testData/codeInsight/codeTransformations/assignmentWithIfExpressionToStatement/simpleIfWithoutAssignment.kt b/idea/testData/codeInsight/codeTransformations/branched/unfolding/assignment/simpleIfWithoutAssignment.kt similarity index 100% rename from idea/testData/codeInsight/codeTransformations/assignmentWithIfExpressionToStatement/simpleIfWithoutAssignment.kt rename to idea/testData/codeInsight/codeTransformations/branched/unfolding/assignment/simpleIfWithoutAssignment.kt diff --git a/idea/testData/codeInsight/codeTransformations/branched/unfolding/asymmetricReturn/simpleIf.kt b/idea/testData/codeInsight/codeTransformations/branched/unfolding/asymmetricReturn/simpleIf.kt new file mode 100644 index 00000000000..741973c35c6 --- /dev/null +++ b/idea/testData/codeInsight/codeTransformations/branched/unfolding/asymmetricReturn/simpleIf.kt @@ -0,0 +1,3 @@ +fun test(n: Int): String { + return if (n == 1) "one" else "two" +} \ No newline at end of file diff --git a/idea/testData/codeInsight/codeTransformations/branched/unfolding/asymmetricReturn/simpleIf.kt.after b/idea/testData/codeInsight/codeTransformations/branched/unfolding/asymmetricReturn/simpleIf.kt.after new file mode 100644 index 00000000000..28edafffc4f --- /dev/null +++ b/idea/testData/codeInsight/codeTransformations/branched/unfolding/asymmetricReturn/simpleIf.kt.after @@ -0,0 +1,3 @@ +fun test(n: Int): String { + if (n == 1) return "one" else return "two" +} \ No newline at end of file diff --git a/idea/testData/codeInsight/codeTransformations/branched/unfolding/asymmetricReturn/simpleIfWithBlocks.kt b/idea/testData/codeInsight/codeTransformations/branched/unfolding/asymmetricReturn/simpleIfWithBlocks.kt new file mode 100644 index 00000000000..5777e6c7ac1 --- /dev/null +++ b/idea/testData/codeInsight/codeTransformations/branched/unfolding/asymmetricReturn/simpleIfWithBlocks.kt @@ -0,0 +1,6 @@ +fun test(n: Int): String { + return if (n == 1) { + println("***") + "one" + } else "two" +} \ No newline at end of file diff --git a/idea/testData/codeInsight/codeTransformations/branched/unfolding/asymmetricReturn/simpleIfWithBlocks.kt.after b/idea/testData/codeInsight/codeTransformations/branched/unfolding/asymmetricReturn/simpleIfWithBlocks.kt.after new file mode 100644 index 00000000000..d750043923c --- /dev/null +++ b/idea/testData/codeInsight/codeTransformations/branched/unfolding/asymmetricReturn/simpleIfWithBlocks.kt.after @@ -0,0 +1,6 @@ +fun test(n: Int): String { + if (n == 1) { + println("***") + return "one" + } else return "two" +} \ No newline at end of file diff --git a/idea/testData/codeInsight/codeTransformations/branched/unfolding/return/innerIfTransformed.kt b/idea/testData/codeInsight/codeTransformations/branched/unfolding/return/innerIfTransformed.kt new file mode 100644 index 00000000000..bf97963e5f0 --- /dev/null +++ b/idea/testData/codeInsight/codeTransformations/branched/unfolding/return/innerIfTransformed.kt @@ -0,0 +1,17 @@ +fun test(n: Int): String { + if (n == 1) { + return if (3 > 2) { + println("***") + "one" + } else { + println("***") + "???" + } + } else if (n == 2) { + println("***") + return "two" + } else { + println("***") + return "too many" + } +} \ No newline at end of file diff --git a/idea/testData/codeInsight/codeTransformations/branched/unfolding/return/innerIfTransformed.kt.after b/idea/testData/codeInsight/codeTransformations/branched/unfolding/return/innerIfTransformed.kt.after new file mode 100644 index 00000000000..b402a1c2f2d --- /dev/null +++ b/idea/testData/codeInsight/codeTransformations/branched/unfolding/return/innerIfTransformed.kt.after @@ -0,0 +1,17 @@ +fun test(n: Int): String { + if (n == 1) { + if (3 > 2) { + println("***") + return "one" + } else { + println("***") + return "???" + } + } else if (n == 2) { + println("***") + return "two" + } else { + println("***") + return "too many" + } +} \ No newline at end of file diff --git a/idea/testData/codeInsight/codeTransformations/branched/unfolding/return/simpleIf.kt b/idea/testData/codeInsight/codeTransformations/branched/unfolding/return/simpleIf.kt new file mode 100644 index 00000000000..ab784e48446 --- /dev/null +++ b/idea/testData/codeInsight/codeTransformations/branched/unfolding/return/simpleIf.kt @@ -0,0 +1,6 @@ +fun test(n: Int): String { + return if (n == 1) + "one" + else + "two" +} \ No newline at end of file diff --git a/idea/testData/codeInsight/codeTransformations/branched/unfolding/return/simpleIf.kt.after b/idea/testData/codeInsight/codeTransformations/branched/unfolding/return/simpleIf.kt.after new file mode 100644 index 00000000000..588394bf7fd --- /dev/null +++ b/idea/testData/codeInsight/codeTransformations/branched/unfolding/return/simpleIf.kt.after @@ -0,0 +1,6 @@ +fun test(n: Int): String { + if (n == 1) + return "one" + else + return "two" +} \ No newline at end of file diff --git a/idea/testData/codeInsight/codeTransformations/branched/unfolding/return/simpleIfWithBlocks.kt b/idea/testData/codeInsight/codeTransformations/branched/unfolding/return/simpleIfWithBlocks.kt new file mode 100644 index 00000000000..a88492572b5 --- /dev/null +++ b/idea/testData/codeInsight/codeTransformations/branched/unfolding/return/simpleIfWithBlocks.kt @@ -0,0 +1,9 @@ +fun test(n: Int): String { + return if (n == 1) { + println("***") + "one" + } else { + println("***") + "two" + } +} \ No newline at end of file diff --git a/idea/testData/codeInsight/codeTransformations/branched/unfolding/return/simpleIfWithBlocks.kt.after b/idea/testData/codeInsight/codeTransformations/branched/unfolding/return/simpleIfWithBlocks.kt.after new file mode 100644 index 00000000000..4a306f5f17d --- /dev/null +++ b/idea/testData/codeInsight/codeTransformations/branched/unfolding/return/simpleIfWithBlocks.kt.after @@ -0,0 +1,9 @@ +fun test(n: Int): String { + if (n == 1) { + println("***") + return "one" + } else { + println("***") + return "two" + } +} \ No newline at end of file diff --git a/idea/tests/org/jetbrains/jet/plugin/codeInsight/codeTransformations/CodeTransformationsTestGenerated.java b/idea/tests/org/jetbrains/jet/plugin/codeInsight/codeTransformations/CodeTransformationsTestGenerated.java index 5241ce2fe83..fb13ee13277 100644 --- a/idea/tests/org/jetbrains/jet/plugin/codeInsight/codeTransformations/CodeTransformationsTestGenerated.java +++ b/idea/tests/org/jetbrains/jet/plugin/codeInsight/codeTransformations/CodeTransformationsTestGenerated.java @@ -30,7 +30,7 @@ import org.jetbrains.jet.plugin.codeInsight.codeTransformations.AbstractCodeTran /** This class is generated by {@link org.jetbrains.jet.generators.tests.GenerateTests}. DO NOT MODIFY MANUALLY */ @SuppressWarnings("all") -@InnerTestClasses({CodeTransformationsTestGenerated.IfStatementWithAssignmentsToExpression.class, CodeTransformationsTestGenerated.AssignmentWithIfExpressionToStatement.class, CodeTransformationsTestGenerated.RemoveUnnecessaryParentheses.class}) +@InnerTestClasses({CodeTransformationsTestGenerated.IfStatementWithAssignmentsToExpression.class, CodeTransformationsTestGenerated.AssignmentWithIfExpressionToStatement.class}) public class CodeTransformationsTestGenerated extends AbstractCodeTransformationTest { @TestMetadata("idea/testData/codeInsight/codeTransformations/ifStatementWithAssignmentsToExpression") public static class IfStatementWithAssignmentsToExpression extends AbstractCodeTransformationTest { From edea00f53e4c29242158d70d369128dd24d36edc Mon Sep 17 00:00:00 2001 From: Alexey Sedunov Date: Fri, 12 Apr 2013 18:36:02 +0400 Subject: [PATCH 063/249] Extract method for assignment matching --- .../BranchedFoldingUtils.java | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/BranchedFoldingUtils.java b/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/BranchedFoldingUtils.java index ae5dc0548fb..f5ca4ae1133 100644 --- a/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/BranchedFoldingUtils.java +++ b/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/BranchedFoldingUtils.java @@ -20,7 +20,6 @@ import com.google.common.base.Predicate; import com.intellij.openapi.project.Project; import com.intellij.psi.PsiElement; import com.intellij.psi.PsiWhiteSpace; -import com.intellij.psi.tree.IElementType; import com.intellij.psi.util.PsiTreeUtil; import org.jetbrains.annotations.Nullable; import org.jetbrains.jet.lang.psi.*; @@ -72,6 +71,10 @@ public class BranchedFoldingUtils { return (JetReturnExpression)JetPsiUtil.getOutermostLastBlockElement(branch, CHECK_RETURN); } + private static boolean checkAssignmentsMatch(JetBinaryExpression a1, JetBinaryExpression a2) { + return checkEquivalence(a1.getLeft(), a2.getLeft()) && a1.getOperationToken().equals(a2.getOperationToken()); + } + private static boolean checkFoldableIfExpressionWithAssignments(JetIfExpression ifExpression) { JetExpression thenBranch = ifExpression.getThen(); JetExpression elseBranch = ifExpression.getElse(); @@ -81,8 +84,7 @@ public class BranchedFoldingUtils { if (thenAssignment == null || elseAssignment == null) return false; - return checkEquivalence(thenAssignment.getLeft(), elseAssignment.getLeft()) && - thenAssignment.getOperationToken().equals(elseAssignment.getOperationToken()); + return checkAssignmentsMatch(thenAssignment, elseAssignment); } private static boolean checkFoldableWhenExpressionWithAssignments(JetWhenExpression whenExpression) { @@ -105,11 +107,9 @@ public class BranchedFoldingUtils { assert !assignments.isEmpty(); - JetExpression lhs = assignments.get(0).getLeft(); - IElementType opToken = assignments.get(0).getOperationToken(); - for (int i = 1; i < assignments.size(); i++) { - if (!checkEquivalence(lhs, assignments.get(i).getLeft())) return false; - if (!opToken.equals(assignments.get(i).getOperationToken())) return false; + JetBinaryExpression firstAssignment = assignments.get(0); + for (JetBinaryExpression assignment : assignments) { + if (!checkAssignmentsMatch(assignment, firstAssignment)) return false; } return true; From 033e82666dc10c46034f1f6ebd86ee11dc194620 Mon Sep 17 00:00:00 2001 From: Alexey Sedunov Date: Fri, 12 Apr 2013 18:42:35 +0400 Subject: [PATCH 064/249] Extract method for else branch check in when expression --- .../jet/codegen/ExpressionCodegen.java | 8 +------- .../org/jetbrains/jet/lang/psi/JetPsiUtil.java | 10 ++++++++++ .../BranchedFoldingUtils.java | 18 ++++++------------ .../plugin/quickfix/MoveWhenElseBranchFix.java | 9 ++------- 4 files changed, 19 insertions(+), 26 deletions(-) diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java index 95dddc83deb..19f0dc3f072 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java @@ -3626,13 +3626,7 @@ The "returned" value of try expression with no finally is either the last expres } Label end = new Label(); - boolean hasElse = false; - for (JetWhenEntry whenEntry : expression.getEntries()) { - if (whenEntry.isElse()) { - hasElse = true; - break; - } - } + boolean hasElse = JetPsiUtil.checkWhenExpressionHasSingleElse(expression); Label nextCondition = null; for (JetWhenEntry whenEntry : expression.getEntries()) { diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetPsiUtil.java b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetPsiUtil.java index 95bf2b0b285..f8a50903fcf 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetPsiUtil.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetPsiUtil.java @@ -682,4 +682,14 @@ public class JetPsiUtil { return false; } + + public static boolean checkWhenExpressionHasSingleElse(JetWhenExpression whenExpression) { + int elseCount = 0; + for (JetWhenEntry entry : whenExpression.getEntries()) { + if (entry.isElse()) { + elseCount++; + } + } + return (elseCount == 1); + } } diff --git a/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/BranchedFoldingUtils.java b/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/BranchedFoldingUtils.java index f5ca4ae1133..6dcb9f378cc 100644 --- a/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/BranchedFoldingUtils.java +++ b/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/BranchedFoldingUtils.java @@ -88,23 +88,19 @@ public class BranchedFoldingUtils { } private static boolean checkFoldableWhenExpressionWithAssignments(JetWhenExpression whenExpression) { + if (!JetPsiUtil.checkWhenExpressionHasSingleElse(whenExpression)) return false; + List entries = whenExpression.getEntries(); if (entries.isEmpty()) return false; - boolean hasElse = false; List assignments = new ArrayList(); for (JetWhenEntry entry : entries) { - if (entry.isElse()) { - hasElse = true; - } JetBinaryExpression assignment = checkAndGetFoldableBranchedAssignment(entry.getExpression()); if (assignment == null) return false; assignments.add(assignment); } - if (!hasElse) return false; - assert !assignments.isEmpty(); JetBinaryExpression firstAssignment = assignments.get(0); @@ -121,24 +117,22 @@ public class BranchedFoldingUtils { } private static boolean checkFoldableWhenExpressionWithReturns(JetWhenExpression whenExpression) { + if (!JetPsiUtil.checkWhenExpressionHasSingleElse(whenExpression)) return false; + List entries = whenExpression.getEntries(); if (entries.isEmpty()) return false; - boolean hasElse = false; for (JetWhenEntry entry : entries) { - if (entry.isElse()) { - hasElse = true; - } if (checkAndGetFoldableBranchedReturn(entry.getExpression()) == null) return false; } - return hasElse; + return true; } private static boolean checkFoldableIfExpressionWithAsymmetricReturns(JetIfExpression ifExpression) { if (checkAndGetFoldableBranchedReturn(ifExpression.getThen()) == null || - checkAndGetFoldableBranchedReturn(ifExpression.getElse()) != null) { + ifExpression.getElse() != null) { return false; } diff --git a/idea/src/org/jetbrains/jet/plugin/quickfix/MoveWhenElseBranchFix.java b/idea/src/org/jetbrains/jet/plugin/quickfix/MoveWhenElseBranchFix.java index 9d4dad15056..132d8989c9d 100644 --- a/idea/src/org/jetbrains/jet/plugin/quickfix/MoveWhenElseBranchFix.java +++ b/idea/src/org/jetbrains/jet/plugin/quickfix/MoveWhenElseBranchFix.java @@ -27,6 +27,7 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.jet.lang.diagnostics.Diagnostic; import org.jetbrains.jet.lang.psi.JetPsiFactory; +import org.jetbrains.jet.lang.psi.JetPsiUtil; import org.jetbrains.jet.lang.psi.JetWhenEntry; import org.jetbrains.jet.lang.psi.JetWhenExpression; import org.jetbrains.jet.plugin.JetBundle; @@ -53,13 +54,7 @@ public class MoveWhenElseBranchFix extends JetIntentionAction if (!super.isAvailable(project, editor, file)) { return false; } - int elseCount = 0; - for (JetWhenEntry entry : element.getEntries()) { - if (entry.isElse()) { - elseCount++; - } - } - return (elseCount == 1); + return JetPsiUtil.checkWhenExpressionHasSingleElse(element); } @Override From a778ce24e7ea39ccb3e5800e0f79efc43f246199 Mon Sep 17 00:00:00 2001 From: Alexey Sedunov Date: Fri, 12 Apr 2013 20:40:56 +0400 Subject: [PATCH 065/249] Rename method --- .../BranchedUnfoldingUtils.java | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/BranchedUnfoldingUtils.java b/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/BranchedUnfoldingUtils.java index 5d0ddab68b8..9a6969d4e4f 100644 --- a/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/BranchedUnfoldingUtils.java +++ b/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/BranchedUnfoldingUtils.java @@ -45,7 +45,7 @@ public class BranchedUnfoldingUtils { return checkUnfoldableAssignment(root) || checkUnfoldableReturn(root); } - private static JetExpression unwrapBranch(@Nullable JetExpression expression) { + private static JetExpression getOutermostLastBlockElement(@Nullable JetExpression expression) { return (JetExpression) JetPsiUtil.getOutermostLastBlockElement(expression, null); } @@ -59,8 +59,8 @@ public class BranchedUnfoldingUtils { ifExpression = (JetIfExpression)assignment.replace(ifExpression); - JetExpression thenExpr = unwrapBranch(ifExpression.getThen()); - JetExpression elseExpr = unwrapBranch(ifExpression.getElse()); + JetExpression thenExpr = getOutermostLastBlockElement(ifExpression.getThen()); + JetExpression elseExpr = getOutermostLastBlockElement(ifExpression.getElse()); assert thenExpr != null; assert elseExpr != null; @@ -80,7 +80,7 @@ public class BranchedUnfoldingUtils { whenExpression = (JetWhenExpression)assignment.replace(whenExpression); for (JetWhenEntry entry : whenExpression.getEntries()) { - JetExpression currExpr = unwrapBranch(entry.getExpression()); + JetExpression currExpr = getOutermostLastBlockElement(entry.getExpression()); assert currExpr != null; @@ -96,8 +96,8 @@ public class BranchedUnfoldingUtils { ifExpression = (JetIfExpression)returnExpression.replace(ifExpression); - JetExpression thenExpr = unwrapBranch(ifExpression.getThen()); - JetExpression elseExpr = unwrapBranch(ifExpression.getElse()); + JetExpression thenExpr = getOutermostLastBlockElement(ifExpression.getThen()); + JetExpression elseExpr = getOutermostLastBlockElement(ifExpression.getElse()); assert thenExpr != null; assert elseExpr != null; @@ -115,7 +115,7 @@ public class BranchedUnfoldingUtils { whenExpression = (JetWhenExpression)returnExpression.replace(whenExpression); for (JetWhenEntry entry : whenExpression.getEntries()) { - JetExpression currExpr = unwrapBranch(entry.getExpression()); + JetExpression currExpr = getOutermostLastBlockElement(entry.getExpression()); assert currExpr != null; From 216f86565824961c46ed6e19be34f805f89e0e2a Mon Sep 17 00:00:00 2001 From: Alexey Sedunov Date: Fri, 12 Apr 2013 20:42:29 +0400 Subject: [PATCH 066/249] Move assertion out of if statement --- .../src/org/jetbrains/jet/lang/psi/JetPsiFactory.java | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetPsiFactory.java b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetPsiFactory.java index 46e1c2dd818..dcf879db749 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetPsiFactory.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetPsiFactory.java @@ -296,9 +296,7 @@ public class JetPsiFactory { assert ifExpr.getCondition() != null; assert ifExpr.getThen() != null; - if (elseExpr != null) { - assert ifExpr.getElse() != null; - } + assert elseExpr == null || ifExpr.getElse() != null; ifExpr = (JetIfExpression)ifExpr.getCondition().replace(condition).getParent().getParent(); ifExpr = (JetIfExpression)ifExpr.getThen().replace(thenExpr).getParent().getParent(); From 89030d1ced5a19e075563dd588e6e11c744fda50 Mon Sep 17 00:00:00 2001 From: Alexey Sedunov Date: Fri, 12 Apr 2013 20:46:59 +0400 Subject: [PATCH 067/249] Make predicate non-nullable --- .../org/jetbrains/jet/lang/psi/JetPsiUtil.java | 15 ++++++++++----- .../BranchedUnfoldingUtils.java | 2 +- 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetPsiUtil.java b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetPsiUtil.java index f8a50903fcf..cf562e674ad 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetPsiUtil.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetPsiUtil.java @@ -634,12 +634,10 @@ public class JetPsiUtil { } @Nullable - public static JetElement getOutermostLastBlockElement( - @Nullable JetElement element, - @Nullable Predicate checkElement) { + public static JetElement getOutermostLastBlockElement(@Nullable JetElement element, @NotNull Predicate checkElement) { if (element == null) return null; - if (!(element instanceof JetBlockExpression)) return checkElement == null || checkElement.apply(element) ? element : null; + if (!(element instanceof JetBlockExpression)) return checkElement.apply(element) ? element : null; JetBlockExpression block = (JetBlockExpression)element; int n = block.getStatements().size(); @@ -647,7 +645,7 @@ public class JetPsiUtil { if (n == 0) return null; JetElement lastElement = block.getStatements().get(n - 1); - return checkElement == null || checkElement.apply(lastElement) ? lastElement : null; + return checkElement.apply(lastElement) ? lastElement : null; } @Nullable @@ -692,4 +690,11 @@ public class JetPsiUtil { } return (elseCount == 1); } + + public static final Predicate ANY_JET_ELEMENT = new Predicate() { + @Override + public boolean apply(@Nullable JetElement input) { + return true; + } + }; } diff --git a/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/BranchedUnfoldingUtils.java b/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/BranchedUnfoldingUtils.java index 9a6969d4e4f..707d019ee01 100644 --- a/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/BranchedUnfoldingUtils.java +++ b/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/BranchedUnfoldingUtils.java @@ -46,7 +46,7 @@ public class BranchedUnfoldingUtils { } private static JetExpression getOutermostLastBlockElement(@Nullable JetExpression expression) { - return (JetExpression) JetPsiUtil.getOutermostLastBlockElement(expression, null); + return (JetExpression) JetPsiUtil.getOutermostLastBlockElement(expression, JetPsiUtil.ANY_JET_ELEMENT); } private static void unfoldAssignmentToIf(@NotNull JetBinaryExpression assignment) { From 97b53000ab24b434d5cf196df62347aee69c623d Mon Sep 17 00:00:00 2001 From: Alexey Sedunov Date: Mon, 15 Apr 2013 15:51:29 +0400 Subject: [PATCH 068/249] Add @NotNull annotation to factory methods --- .../src/org/jetbrains/jet/lang/psi/JetPsiFactory.java | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetPsiFactory.java b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetPsiFactory.java index dcf879db749..f925ca13211 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetPsiFactory.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetPsiFactory.java @@ -249,11 +249,13 @@ public class JetPsiFactory { return createExpression(project, "$" + fieldName); } + @NotNull public static JetBinaryExpression createBinaryExpression(Project project, @NotNull String lhs, @NotNull String op, @NotNull String rhs) { return (JetBinaryExpression) createExpression(project, lhs + " " + op + " " + rhs); } @SuppressWarnings("ConstantConditions") + @NotNull public static JetBinaryExpression createBinaryExpression(Project project, @NotNull JetExpression lhs, @NotNull String op, @NotNull JetExpression rhs) { JetBinaryExpression assignment = createBinaryExpression(project, "_", op, "_"); @@ -273,11 +275,13 @@ public class JetPsiFactory { return new JetExpressionCodeFragmentImpl(project, "fragment.kt", text, context); } + @NotNull public static JetReturnExpression createReturn(Project project, @NotNull String text) { return (JetReturnExpression) createExpression(project, "return " + text); } @SuppressWarnings("ConstantConditions") + @NotNull public static JetReturnExpression createReturn(Project project, @NotNull JetExpression expression) { JetReturnExpression returnExpr = createReturn(project, "_"); @@ -286,11 +290,13 @@ public class JetPsiFactory { return (JetReturnExpression)returnExpr.getReturnedExpression().replace(expression).getParent(); } + @NotNull public static JetIfExpression createIf(Project project, @NotNull String condText, @NotNull String thenText, @Nullable String elseText) { return (JetIfExpression) createExpression(project, "if (" + condText + ") " + thenText + (elseText != null ? " else " + elseText : "")); } @SuppressWarnings("ConstantConditions") + @NotNull public static JetIfExpression createIf(Project project, @NotNull JetExpression condition, @NotNull JetExpression thenExpr, @Nullable JetExpression elseExpr) { JetIfExpression ifExpr = createIf(project, "_", "_", elseExpr != null ? "_" : null); From 8757e3763b086621251419b5999b553dc5120bde Mon Sep 17 00:00:00 2001 From: Alexey Sedunov Date: Mon, 15 Apr 2013 15:53:10 +0400 Subject: [PATCH 069/249] Remove redundant tests --- .../branched/unfolding/asymmetricReturn/simpleIf.kt | 3 --- .../branched/unfolding/asymmetricReturn/simpleIf.kt.after | 3 --- .../unfolding/asymmetricReturn/simpleIfWithBlocks.kt | 6 ------ .../unfolding/asymmetricReturn/simpleIfWithBlocks.kt.after | 6 ------ 4 files changed, 18 deletions(-) delete mode 100644 idea/testData/codeInsight/codeTransformations/branched/unfolding/asymmetricReturn/simpleIf.kt delete mode 100644 idea/testData/codeInsight/codeTransformations/branched/unfolding/asymmetricReturn/simpleIf.kt.after delete mode 100644 idea/testData/codeInsight/codeTransformations/branched/unfolding/asymmetricReturn/simpleIfWithBlocks.kt delete mode 100644 idea/testData/codeInsight/codeTransformations/branched/unfolding/asymmetricReturn/simpleIfWithBlocks.kt.after diff --git a/idea/testData/codeInsight/codeTransformations/branched/unfolding/asymmetricReturn/simpleIf.kt b/idea/testData/codeInsight/codeTransformations/branched/unfolding/asymmetricReturn/simpleIf.kt deleted file mode 100644 index 741973c35c6..00000000000 --- a/idea/testData/codeInsight/codeTransformations/branched/unfolding/asymmetricReturn/simpleIf.kt +++ /dev/null @@ -1,3 +0,0 @@ -fun test(n: Int): String { - return if (n == 1) "one" else "two" -} \ No newline at end of file diff --git a/idea/testData/codeInsight/codeTransformations/branched/unfolding/asymmetricReturn/simpleIf.kt.after b/idea/testData/codeInsight/codeTransformations/branched/unfolding/asymmetricReturn/simpleIf.kt.after deleted file mode 100644 index 28edafffc4f..00000000000 --- a/idea/testData/codeInsight/codeTransformations/branched/unfolding/asymmetricReturn/simpleIf.kt.after +++ /dev/null @@ -1,3 +0,0 @@ -fun test(n: Int): String { - if (n == 1) return "one" else return "two" -} \ No newline at end of file diff --git a/idea/testData/codeInsight/codeTransformations/branched/unfolding/asymmetricReturn/simpleIfWithBlocks.kt b/idea/testData/codeInsight/codeTransformations/branched/unfolding/asymmetricReturn/simpleIfWithBlocks.kt deleted file mode 100644 index 5777e6c7ac1..00000000000 --- a/idea/testData/codeInsight/codeTransformations/branched/unfolding/asymmetricReturn/simpleIfWithBlocks.kt +++ /dev/null @@ -1,6 +0,0 @@ -fun test(n: Int): String { - return if (n == 1) { - println("***") - "one" - } else "two" -} \ No newline at end of file diff --git a/idea/testData/codeInsight/codeTransformations/branched/unfolding/asymmetricReturn/simpleIfWithBlocks.kt.after b/idea/testData/codeInsight/codeTransformations/branched/unfolding/asymmetricReturn/simpleIfWithBlocks.kt.after deleted file mode 100644 index d750043923c..00000000000 --- a/idea/testData/codeInsight/codeTransformations/branched/unfolding/asymmetricReturn/simpleIfWithBlocks.kt.after +++ /dev/null @@ -1,6 +0,0 @@ -fun test(n: Int): String { - if (n == 1) { - println("***") - return "one" - } else return "two" -} \ No newline at end of file From d5e78c3bd574bb8b3c5450682b0359ae8021760f Mon Sep 17 00:00:00 2001 From: Alexey Sedunov Date: Mon, 15 Apr 2013 16:01:37 +0400 Subject: [PATCH 070/249] Add support of comments in asymmetric returns --- .../jetbrains/jet/lang/psi/JetPsiUtil.java | 6 + .../BranchedFoldingUtils.java | 8 +- .../asymmetricReturn/simpleIfWithComments.kt | 5 + .../simpleIfWithComments.kt.after | 4 + .../CodeTransformationsTestGenerated.java | 334 ++++++++++++------ 5 files changed, 239 insertions(+), 118 deletions(-) create mode 100644 idea/testData/codeInsight/codeTransformations/branched/folding/asymmetricReturn/simpleIfWithComments.kt create mode 100644 idea/testData/codeInsight/codeTransformations/branched/folding/asymmetricReturn/simpleIfWithComments.kt.after diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetPsiUtil.java b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetPsiUtil.java index cf562e674ad..73364aa0f56 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetPsiUtil.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetPsiUtil.java @@ -20,8 +20,10 @@ import com.google.common.base.Function; import com.google.common.base.Predicate; import com.google.common.collect.Lists; import com.intellij.lang.ASTNode; +import com.intellij.psi.PsiComment; import com.intellij.psi.PsiElement; import com.intellij.psi.PsiFile; +import com.intellij.psi.PsiWhiteSpace; import com.intellij.psi.impl.CheckUtil; import com.intellij.psi.impl.source.codeStyle.CodeEditUtil; import com.intellij.psi.tree.IElementType; @@ -691,6 +693,10 @@ public class JetPsiUtil { return (elseCount == 1); } + public static PsiElement skipTrailingWhitespacesAndComments(PsiElement element) { + return PsiTreeUtil.skipSiblingsForward(element, PsiWhiteSpace.class, PsiComment.class); + } + public static final Predicate ANY_JET_ELEMENT = new Predicate() { @Override public boolean apply(@Nullable JetElement input) { diff --git a/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/BranchedFoldingUtils.java b/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/BranchedFoldingUtils.java index 6dcb9f378cc..d8511964c4f 100644 --- a/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/BranchedFoldingUtils.java +++ b/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/BranchedFoldingUtils.java @@ -19,8 +19,6 @@ package org.jetbrains.jet.plugin.codeInsight.codeTransformations.branchedTransfo import com.google.common.base.Predicate; import com.intellij.openapi.project.Project; import com.intellij.psi.PsiElement; -import com.intellij.psi.PsiWhiteSpace; -import com.intellij.psi.util.PsiTreeUtil; import org.jetbrains.annotations.Nullable; import org.jetbrains.jet.lang.psi.*; @@ -136,7 +134,7 @@ public class BranchedFoldingUtils { return false; } - PsiElement nextElement = PsiTreeUtil.skipSiblingsForward(ifExpression, PsiWhiteSpace.class); + PsiElement nextElement = JetPsiUtil.skipTrailingWhitespacesAndComments(ifExpression); return (nextElement instanceof JetExpression) && checkAndGetFoldableBranchedReturn((JetExpression)nextElement) != null; } @@ -218,7 +216,7 @@ public class BranchedFoldingUtils { JetExpression condition = ifExpression.getCondition(); JetExpression thenRoot = ifExpression.getThen(); - JetExpression elseRoot = (JetExpression)PsiTreeUtil.skipSiblingsForward(ifExpression, PsiWhiteSpace.class); + JetExpression elseRoot = (JetExpression)JetPsiUtil.skipTrailingWhitespacesAndComments(ifExpression); assert condition != null; assert thenRoot != null; @@ -228,7 +226,7 @@ public class BranchedFoldingUtils { JetReturnExpression newReturnExpr = JetPsiFactory.createReturn(project, newIfExpr); newReturnExpr = (JetReturnExpression) ifExpression.replace(newReturnExpr); - JetReturnExpression oldReturn = (JetReturnExpression)PsiTreeUtil.skipSiblingsForward(newReturnExpr, PsiWhiteSpace.class); + JetReturnExpression oldReturn = (JetReturnExpression)JetPsiUtil.skipTrailingWhitespacesAndComments(newReturnExpr); assert oldReturn != null; diff --git a/idea/testData/codeInsight/codeTransformations/branched/folding/asymmetricReturn/simpleIfWithComments.kt b/idea/testData/codeInsight/codeTransformations/branched/folding/asymmetricReturn/simpleIfWithComments.kt new file mode 100644 index 00000000000..7c1e5e55c0c --- /dev/null +++ b/idea/testData/codeInsight/codeTransformations/branched/folding/asymmetricReturn/simpleIfWithComments.kt @@ -0,0 +1,5 @@ +fun test(n: Int): String { + if (n == 1) return "one" + // comment + return "two" +} \ No newline at end of file diff --git a/idea/testData/codeInsight/codeTransformations/branched/folding/asymmetricReturn/simpleIfWithComments.kt.after b/idea/testData/codeInsight/codeTransformations/branched/folding/asymmetricReturn/simpleIfWithComments.kt.after new file mode 100644 index 00000000000..83a9dbff5da --- /dev/null +++ b/idea/testData/codeInsight/codeTransformations/branched/folding/asymmetricReturn/simpleIfWithComments.kt.after @@ -0,0 +1,4 @@ +fun test(n: Int): String { + return if (n == 1) "one" else "two" + // comment +} \ No newline at end of file diff --git a/idea/tests/org/jetbrains/jet/plugin/codeInsight/codeTransformations/CodeTransformationsTestGenerated.java b/idea/tests/org/jetbrains/jet/plugin/codeInsight/codeTransformations/CodeTransformationsTestGenerated.java index fb13ee13277..573c6bdaa89 100644 --- a/idea/tests/org/jetbrains/jet/plugin/codeInsight/codeTransformations/CodeTransformationsTestGenerated.java +++ b/idea/tests/org/jetbrains/jet/plugin/codeInsight/codeTransformations/CodeTransformationsTestGenerated.java @@ -30,142 +30,250 @@ import org.jetbrains.jet.plugin.codeInsight.codeTransformations.AbstractCodeTran /** This class is generated by {@link org.jetbrains.jet.generators.tests.GenerateTests}. DO NOT MODIFY MANUALLY */ @SuppressWarnings("all") -@InnerTestClasses({CodeTransformationsTestGenerated.IfStatementWithAssignmentsToExpression.class, CodeTransformationsTestGenerated.AssignmentWithIfExpressionToStatement.class}) +@InnerTestClasses({CodeTransformationsTestGenerated.Folding.class, CodeTransformationsTestGenerated.Unfolding.class}) public class CodeTransformationsTestGenerated extends AbstractCodeTransformationTest { - @TestMetadata("idea/testData/codeInsight/codeTransformations/ifStatementWithAssignmentsToExpression") - public static class IfStatementWithAssignmentsToExpression extends AbstractCodeTransformationTest { - public void testAllFilesPresentInIfStatementWithAssignmentsToExpression() throws Exception { - JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.GenerateTests", new File("idea/testData/codeInsight/codeTransformations/ifStatementWithAssignmentsToExpression"), Pattern.compile("^(.+)\\.kt$"), true); + @TestMetadata("idea/testData/codeInsight/codeTransformations/branched/folding") + @InnerTestClasses({Folding.Assignment.class, Folding.AsymmetricReturn.class, Folding.Return.class}) + public static class Folding extends AbstractCodeTransformationTest { + public void testAllFilesPresentInFolding() throws Exception { + JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.GenerateTests", new File("idea/testData/codeInsight/codeTransformations/branched/folding"), Pattern.compile("^(.+)\\.kt$"), true); } - @TestMetadata("innerIfTransformed.kt") - public void testInnerIfTransformed() throws Exception { - doTestIfStatementWithAssignmentsToExpression("idea/testData/codeInsight/codeTransformations/ifStatementWithAssignmentsToExpression/innerIfTransformed.kt"); + @TestMetadata("idea/testData/codeInsight/codeTransformations/branched/folding/assignment") + public static class Assignment extends AbstractCodeTransformationTest { + public void testAllFilesPresentInAssignment() throws Exception { + JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.GenerateTests", new File("idea/testData/codeInsight/codeTransformations/branched/folding/assignment"), Pattern.compile("^(.+)\\.kt$"), true); + } + + @TestMetadata("innerIfTransformed.kt") + public void testInnerIfTransformed() throws Exception { + doTestBranchedFolding("idea/testData/codeInsight/codeTransformations/branched/folding/assignment/innerIfTransformed.kt"); + } + + @TestMetadata("innerWhenTransformed.kt") + public void testInnerWhenTransformed() throws Exception { + doTestBranchedFolding("idea/testData/codeInsight/codeTransformations/branched/folding/assignment/innerWhenTransformed.kt"); + } + + @TestMetadata("simpleIf.kt") + public void testSimpleIf() throws Exception { + doTestBranchedFolding("idea/testData/codeInsight/codeTransformations/branched/folding/assignment/simpleIf.kt"); + } + + @TestMetadata("simpleIfWithAugmentedAssignment.kt") + public void testSimpleIfWithAugmentedAssignment() throws Exception { + doTestBranchedFolding("idea/testData/codeInsight/codeTransformations/branched/folding/assignment/simpleIfWithAugmentedAssignment.kt"); + } + + @TestMetadata("simpleIfWithBlocks.kt") + public void testSimpleIfWithBlocks() throws Exception { + doTestBranchedFolding("idea/testData/codeInsight/codeTransformations/branched/folding/assignment/simpleIfWithBlocks.kt"); + } + + @TestMetadata("simpleIfWithShadowedVar.kt") + public void testSimpleIfWithShadowedVar() throws Exception { + doTestBranchedFolding("idea/testData/codeInsight/codeTransformations/branched/folding/assignment/simpleIfWithShadowedVar.kt"); + } + + @TestMetadata("simpleIfWithUnmatchedAssignmentOps.kt") + public void testSimpleIfWithUnmatchedAssignmentOps() throws Exception { + doTestBranchedFolding("idea/testData/codeInsight/codeTransformations/branched/folding/assignment/simpleIfWithUnmatchedAssignmentOps.kt"); + } + + @TestMetadata("simpleIfWithUnmatchedAssignments.kt") + public void testSimpleIfWithUnmatchedAssignments() throws Exception { + doTestBranchedFolding("idea/testData/codeInsight/codeTransformations/branched/folding/assignment/simpleIfWithUnmatchedAssignments.kt"); + } + + @TestMetadata("simpleIfWithoutElse.kt") + public void testSimpleIfWithoutElse() throws Exception { + doTestBranchedFolding("idea/testData/codeInsight/codeTransformations/branched/folding/assignment/simpleIfWithoutElse.kt"); + } + + @TestMetadata("simpleIfWithoutTerminatingAssignment.kt") + public void testSimpleIfWithoutTerminatingAssignment() throws Exception { + doTestBranchedFolding("idea/testData/codeInsight/codeTransformations/branched/folding/assignment/simpleIfWithoutTerminatingAssignment.kt"); + } + + @TestMetadata("simpleWhen.kt") + public void testSimpleWhen() throws Exception { + doTestBranchedFolding("idea/testData/codeInsight/codeTransformations/branched/folding/assignment/simpleWhen.kt"); + } + + @TestMetadata("simpleWhenWithBlocks.kt") + public void testSimpleWhenWithBlocks() throws Exception { + doTestBranchedFolding("idea/testData/codeInsight/codeTransformations/branched/folding/assignment/simpleWhenWithBlocks.kt"); + } + + @TestMetadata("simpleWhenWithShadowedVar.kt") + public void testSimpleWhenWithShadowedVar() throws Exception { + doTestBranchedFolding("idea/testData/codeInsight/codeTransformations/branched/folding/assignment/simpleWhenWithShadowedVar.kt"); + } + + @TestMetadata("simpleWhenWithUnmatchedAssignments.kt") + public void testSimpleWhenWithUnmatchedAssignments() throws Exception { + doTestBranchedFolding("idea/testData/codeInsight/codeTransformations/branched/folding/assignment/simpleWhenWithUnmatchedAssignments.kt"); + } + + @TestMetadata("simpleWhenWithoutTerminatingAssignment.kt") + public void testSimpleWhenWithoutTerminatingAssignment() throws Exception { + doTestBranchedFolding("idea/testData/codeInsight/codeTransformations/branched/folding/assignment/simpleWhenWithoutTerminatingAssignment.kt"); + } + } - @TestMetadata("nestedIfs.kt") - public void testNestedIfs() throws Exception { - doTestIfStatementWithAssignmentsToExpression("idea/testData/codeInsight/codeTransformations/ifStatementWithAssignmentsToExpression/nestedIfs.kt"); + @TestMetadata("idea/testData/codeInsight/codeTransformations/branched/folding/asymmetricReturn") + public static class AsymmetricReturn extends AbstractCodeTransformationTest { + public void testAllFilesPresentInAsymmetricReturn() throws Exception { + JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.GenerateTests", new File("idea/testData/codeInsight/codeTransformations/branched/folding/asymmetricReturn"), Pattern.compile("^(.+)\\.kt$"), true); + } + + @TestMetadata("simpleIf.kt") + public void testSimpleIf() throws Exception { + doTestBranchedFolding("idea/testData/codeInsight/codeTransformations/branched/folding/asymmetricReturn/simpleIf.kt"); + } + + @TestMetadata("simpleIfWithBlocks.kt") + public void testSimpleIfWithBlocks() throws Exception { + doTestBranchedFolding("idea/testData/codeInsight/codeTransformations/branched/folding/asymmetricReturn/simpleIfWithBlocks.kt"); + } + + @TestMetadata("simpleIfWithComments.kt") + public void testSimpleIfWithComments() throws Exception { + doTestBranchedFolding("idea/testData/codeInsight/codeTransformations/branched/folding/asymmetricReturn/simpleIfWithComments.kt"); + } + } - @TestMetadata("simpleIf.kt") - public void testSimpleIf() throws Exception { - doTestIfStatementWithAssignmentsToExpression("idea/testData/codeInsight/codeTransformations/ifStatementWithAssignmentsToExpression/simpleIf.kt"); + @TestMetadata("idea/testData/codeInsight/codeTransformations/branched/folding/return") + public static class Return extends AbstractCodeTransformationTest { + public void testAllFilesPresentInReturn() throws Exception { + JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.GenerateTests", new File("idea/testData/codeInsight/codeTransformations/branched/folding/return"), Pattern.compile("^(.+)\\.kt$"), true); + } + + @TestMetadata("innerIfTransformed.kt") + public void testInnerIfTransformed() throws Exception { + doTestBranchedFolding("idea/testData/codeInsight/codeTransformations/branched/folding/return/innerIfTransformed.kt"); + } + + @TestMetadata("innerWhenTransformed.kt") + public void testInnerWhenTransformed() throws Exception { + doTestBranchedFolding("idea/testData/codeInsight/codeTransformations/branched/folding/return/innerWhenTransformed.kt"); + } + + @TestMetadata("simpleIf.kt") + public void testSimpleIf() throws Exception { + doTestBranchedFolding("idea/testData/codeInsight/codeTransformations/branched/folding/return/simpleIf.kt"); + } + + @TestMetadata("simpleIfWithBlocks.kt") + public void testSimpleIfWithBlocks() throws Exception { + doTestBranchedFolding("idea/testData/codeInsight/codeTransformations/branched/folding/return/simpleIfWithBlocks.kt"); + } + + @TestMetadata("simpleWhen.kt") + public void testSimpleWhen() throws Exception { + doTestBranchedFolding("idea/testData/codeInsight/codeTransformations/branched/folding/return/simpleWhen.kt"); + } + + @TestMetadata("simpleWhenWithBlocks.kt") + public void testSimpleWhenWithBlocks() throws Exception { + doTestBranchedFolding("idea/testData/codeInsight/codeTransformations/branched/folding/return/simpleWhenWithBlocks.kt"); + } + } - @TestMetadata("simpleIfWithoutElse.kt") - public void testSimpleIfWithoutElse() throws Exception { - doTestIfStatementWithAssignmentsToExpression("idea/testData/codeInsight/codeTransformations/ifStatementWithAssignmentsToExpression/simpleIfWithoutElse.kt"); + public static Test innerSuite() { + TestSuite suite = new TestSuite("Folding"); + suite.addTestSuite(Folding.class); + suite.addTestSuite(Assignment.class); + suite.addTestSuite(AsymmetricReturn.class); + suite.addTestSuite(Return.class); + return suite; } - - @TestMetadata("simpleIfWithoutTerminatingAssignment.kt") - public void testSimpleIfWithoutTerminatingAssignment() throws Exception { - doTestIfStatementWithAssignmentsToExpression("idea/testData/codeInsight/codeTransformations/ifStatementWithAssignmentsToExpression/simpleIfWithoutTerminatingAssignment.kt"); - } - } - @TestMetadata("idea/testData/codeInsight/codeTransformations/assignmentWithIfExpressionToStatement") - public static class AssignmentWithIfExpressionToStatement extends AbstractCodeTransformationTest { - public void testAllFilesPresentInAssignmentWithIfExpressionToStatement() throws Exception { - JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.GenerateTests", new File("idea/testData/codeInsight/codeTransformations/assignmentWithIfExpressionToStatement"), Pattern.compile("^(.+)\\.kt$"), true); + @TestMetadata("idea/testData/codeInsight/codeTransformations/branched/unfolding") + @InnerTestClasses({Unfolding.Assignment.class, Unfolding.Return.class}) + public static class Unfolding extends AbstractCodeTransformationTest { + public void testAllFilesPresentInUnfolding() throws Exception { + JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.GenerateTests", new File("idea/testData/codeInsight/codeTransformations/branched/unfolding"), Pattern.compile("^(.+)\\.kt$"), true); } - @TestMetadata("innerIfTransformed.kt") - public void testInnerIfTransformed() throws Exception { - doTestAssignmentWithIfExpressionToStatement("idea/testData/codeInsight/codeTransformations/assignmentWithIfExpressionToStatement/innerIfTransformed.kt"); + @TestMetadata("idea/testData/codeInsight/codeTransformations/branched/unfolding/assignment") + public static class Assignment extends AbstractCodeTransformationTest { + public void testAllFilesPresentInAssignment() throws Exception { + JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.GenerateTests", new File("idea/testData/codeInsight/codeTransformations/branched/unfolding/assignment"), Pattern.compile("^(.+)\\.kt$"), true); + } + + @TestMetadata("innerIfTransformed.kt") + public void testInnerIfTransformed() throws Exception { + doTestBranchedUnfolding("idea/testData/codeInsight/codeTransformations/branched/unfolding/assignment/innerIfTransformed.kt"); + } + + @TestMetadata("nestedIfs.kt") + public void testNestedIfs() throws Exception { + doTestBranchedUnfolding("idea/testData/codeInsight/codeTransformations/branched/unfolding/assignment/nestedIfs.kt"); + } + + @TestMetadata("simpleIf.kt") + public void testSimpleIf() throws Exception { + doTestBranchedUnfolding("idea/testData/codeInsight/codeTransformations/branched/unfolding/assignment/simpleIf.kt"); + } + + @TestMetadata("simpleIfWithAugmentedAssignment.kt") + public void testSimpleIfWithAugmentedAssignment() throws Exception { + doTestBranchedUnfolding("idea/testData/codeInsight/codeTransformations/branched/unfolding/assignment/simpleIfWithAugmentedAssignment.kt"); + } + + @TestMetadata("simpleIfWithBlocks.kt") + public void testSimpleIfWithBlocks() throws Exception { + doTestBranchedUnfolding("idea/testData/codeInsight/codeTransformations/branched/unfolding/assignment/simpleIfWithBlocks.kt"); + } + + @TestMetadata("simpleIfWithoutAssignment.kt") + public void testSimpleIfWithoutAssignment() throws Exception { + doTestBranchedUnfolding("idea/testData/codeInsight/codeTransformations/branched/unfolding/assignment/simpleIfWithoutAssignment.kt"); + } + } - @TestMetadata("nestedIfs.kt") - public void testNestedIfs() throws Exception { - doTestAssignmentWithIfExpressionToStatement("idea/testData/codeInsight/codeTransformations/assignmentWithIfExpressionToStatement/nestedIfs.kt"); + @TestMetadata("idea/testData/codeInsight/codeTransformations/branched/unfolding/return") + public static class Return extends AbstractCodeTransformationTest { + public void testAllFilesPresentInReturn() throws Exception { + JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.GenerateTests", new File("idea/testData/codeInsight/codeTransformations/branched/unfolding/return"), Pattern.compile("^(.+)\\.kt$"), true); + } + + @TestMetadata("innerIfTransformed.kt") + public void testInnerIfTransformed() throws Exception { + doTestBranchedUnfolding("idea/testData/codeInsight/codeTransformations/branched/unfolding/return/innerIfTransformed.kt"); + } + + @TestMetadata("simpleIf.kt") + public void testSimpleIf() throws Exception { + doTestBranchedUnfolding("idea/testData/codeInsight/codeTransformations/branched/unfolding/return/simpleIf.kt"); + } + + @TestMetadata("simpleIfWithBlocks.kt") + public void testSimpleIfWithBlocks() throws Exception { + doTestBranchedUnfolding("idea/testData/codeInsight/codeTransformations/branched/unfolding/return/simpleIfWithBlocks.kt"); + } + } - @TestMetadata("simpleIf.kt") - public void testSimpleIf() throws Exception { - doTestAssignmentWithIfExpressionToStatement("idea/testData/codeInsight/codeTransformations/assignmentWithIfExpressionToStatement/simpleIf.kt"); + public static Test innerSuite() { + TestSuite suite = new TestSuite("Unfolding"); + suite.addTestSuite(Unfolding.class); + suite.addTestSuite(Assignment.class); + suite.addTestSuite(Return.class); + return suite; } - - @TestMetadata("simpleIfWithoutAssignment.kt") - public void testSimpleIfWithoutAssignment() throws Exception { - doTestAssignmentWithIfExpressionToStatement("idea/testData/codeInsight/codeTransformations/assignmentWithIfExpressionToStatement/simpleIfWithoutAssignment.kt"); - } - - } - - @TestMetadata("idea/testData/codeInsight/codeTransformations/removeUnnecessaryParentheses") - public static class RemoveUnnecessaryParentheses extends AbstractCodeTransformationTest { - public void testAllFilesPresentInRemoveUnnecessaryParentheses() throws Exception { - JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.GenerateTests", new File("idea/testData/codeInsight/codeTransformations/removeUnnecessaryParentheses"), Pattern.compile("^(.+)\\.kt$"), true); - } - - @TestMetadata("necessaryParentheses1.kt") - public void testNecessaryParentheses1() throws Exception { - doTestRemoveUnnecessaryParentheses("idea/testData/codeInsight/codeTransformations/removeUnnecessaryParentheses/necessaryParentheses1.kt"); - } - - @TestMetadata("necessaryParentheses2.kt") - public void testNecessaryParentheses2() throws Exception { - doTestRemoveUnnecessaryParentheses("idea/testData/codeInsight/codeTransformations/removeUnnecessaryParentheses/necessaryParentheses2.kt"); - } - - @TestMetadata("necessaryParentheses3.kt") - public void testNecessaryParentheses3() throws Exception { - doTestRemoveUnnecessaryParentheses("idea/testData/codeInsight/codeTransformations/removeUnnecessaryParentheses/necessaryParentheses3.kt"); - } - - @TestMetadata("necessaryParentheses4.kt") - public void testNecessaryParentheses4() throws Exception { - doTestRemoveUnnecessaryParentheses("idea/testData/codeInsight/codeTransformations/removeUnnecessaryParentheses/necessaryParentheses4.kt"); - } - - @TestMetadata("necessaryParentheses5.kt") - public void testNecessaryParentheses5() throws Exception { - doTestRemoveUnnecessaryParentheses("idea/testData/codeInsight/codeTransformations/removeUnnecessaryParentheses/necessaryParentheses5.kt"); - } - - @TestMetadata("unnecessaryParentheses1.kt") - public void testUnnecessaryParentheses1() throws Exception { - doTestRemoveUnnecessaryParentheses("idea/testData/codeInsight/codeTransformations/removeUnnecessaryParentheses/unnecessaryParentheses1.kt"); - } - - @TestMetadata("unnecessaryParentheses2.kt") - public void testUnnecessaryParentheses2() throws Exception { - doTestRemoveUnnecessaryParentheses("idea/testData/codeInsight/codeTransformations/removeUnnecessaryParentheses/unnecessaryParentheses2.kt"); - } - - @TestMetadata("unnecessaryParentheses3.kt") - public void testUnnecessaryParentheses3() throws Exception { - doTestRemoveUnnecessaryParentheses("idea/testData/codeInsight/codeTransformations/removeUnnecessaryParentheses/unnecessaryParentheses3.kt"); - } - - @TestMetadata("unnecessaryParentheses4.kt") - public void testUnnecessaryParentheses4() throws Exception { - doTestRemoveUnnecessaryParentheses("idea/testData/codeInsight/codeTransformations/removeUnnecessaryParentheses/unnecessaryParentheses4.kt"); - } - - @TestMetadata("unnecessaryParentheses5.kt") - public void testUnnecessaryParentheses5() throws Exception { - doTestRemoveUnnecessaryParentheses("idea/testData/codeInsight/codeTransformations/removeUnnecessaryParentheses/unnecessaryParentheses5.kt"); - } - - @TestMetadata("unnecessaryParentheses6.kt") - public void testUnnecessaryParentheses6() throws Exception { - doTestRemoveUnnecessaryParentheses("idea/testData/codeInsight/codeTransformations/removeUnnecessaryParentheses/unnecessaryParentheses6.kt"); - } - - @TestMetadata("unnecessaryParentheses7.kt") - public void testUnnecessaryParentheses7() throws Exception { - doTestRemoveUnnecessaryParentheses("idea/testData/codeInsight/codeTransformations/removeUnnecessaryParentheses/unnecessaryParentheses7.kt"); - } - } public static Test suite() { TestSuite suite = new TestSuite("CodeTransformationsTestGenerated"); - suite.addTestSuite(IfStatementWithAssignmentsToExpression.class); - suite.addTestSuite(AssignmentWithIfExpressionToStatement.class); - suite.addTestSuite(RemoveUnnecessaryParentheses.class); + suite.addTest(Folding.innerSuite()); + suite.addTest(Unfolding.innerSuite()); return suite; } } From 2f00097b2a4b1b3a4ace88c6ab91e9715715c2ee Mon Sep 17 00:00:00 2001 From: Alexey Sedunov Date: Mon, 15 Apr 2013 16:08:58 +0400 Subject: [PATCH 071/249] Add assertion messages --- .../BranchedFoldingUtils.java | 60 ++++++++++--------- .../BranchedUnfoldingUtils.java | 22 +++---- 2 files changed, 43 insertions(+), 39 deletions(-) diff --git a/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/BranchedFoldingUtils.java b/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/BranchedFoldingUtils.java index d8511964c4f..0ffb6a9188d 100644 --- a/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/BranchedFoldingUtils.java +++ b/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/BranchedFoldingUtils.java @@ -155,12 +155,14 @@ public class BranchedFoldingUtils { return false; } + public static final String FOLD_WITHOUT_CHECK = "Expression must be checked before folding"; + private static void foldIfExpressionWithAssignments(JetIfExpression ifExpression) { Project project = ifExpression.getProject(); JetBinaryExpression thenAssignment = checkAndGetFoldableBranchedAssignment(ifExpression.getThen()); - assert thenAssignment != null; + assert thenAssignment != null : FOLD_WITHOUT_CHECK; String op = thenAssignment.getOperationReference().getText(); JetSimpleNameExpression lhs = (JetSimpleNameExpression) thenAssignment.getLeft(); @@ -169,19 +171,19 @@ public class BranchedFoldingUtils { (JetBinaryExpression)ifExpression.replace(JetPsiFactory.createBinaryExpression(project, lhs, op, ifExpression)); ifExpression = (JetIfExpression)assignment.getRight(); - assert ifExpression != null; + assert ifExpression != null : FOLD_WITHOUT_CHECK; thenAssignment = checkAndGetFoldableBranchedAssignment(ifExpression.getThen()); JetBinaryExpression elseAssignment = checkAndGetFoldableBranchedAssignment(ifExpression.getElse()); - assert thenAssignment != null; - assert elseAssignment != null; + assert thenAssignment != null : FOLD_WITHOUT_CHECK; + assert elseAssignment != null : FOLD_WITHOUT_CHECK; JetExpression thenRhs = thenAssignment.getRight(); JetExpression elseRhs = elseAssignment.getRight(); - assert thenRhs != null; - assert elseRhs != null; + assert thenRhs != null : FOLD_WITHOUT_CHECK; + assert elseRhs != null : FOLD_WITHOUT_CHECK; thenAssignment.replace(thenRhs); elseAssignment.replace(elseRhs); @@ -193,19 +195,19 @@ public class BranchedFoldingUtils { JetReturnExpression returnExpr = (JetReturnExpression)ifExpression.replace(JetPsiFactory.createReturn(project, ifExpression)); ifExpression = (JetIfExpression)returnExpr.getReturnedExpression(); - assert ifExpression != null; + assert ifExpression != null : FOLD_WITHOUT_CHECK; JetReturnExpression thenReturn = checkAndGetFoldableBranchedReturn(ifExpression.getThen()); JetReturnExpression elseReturn = checkAndGetFoldableBranchedReturn(ifExpression.getElse()); - assert thenReturn != null; - assert elseReturn != null; + assert thenReturn != null : FOLD_WITHOUT_CHECK; + assert elseReturn != null : FOLD_WITHOUT_CHECK; JetExpression thenExpr = thenReturn.getReturnedExpression(); JetExpression elseExpr = elseReturn.getReturnedExpression(); - assert thenExpr != null; - assert elseExpr != null; + assert thenExpr != null : FOLD_WITHOUT_CHECK; + assert elseExpr != null : FOLD_WITHOUT_CHECK; thenReturn.replace(thenExpr); elseReturn.replace(elseExpr); @@ -218,9 +220,9 @@ public class BranchedFoldingUtils { JetExpression thenRoot = ifExpression.getThen(); JetExpression elseRoot = (JetExpression)JetPsiUtil.skipTrailingWhitespacesAndComments(ifExpression); - assert condition != null; - assert thenRoot != null; - assert elseRoot != null; + assert condition != null : FOLD_WITHOUT_CHECK; + assert thenRoot != null : FOLD_WITHOUT_CHECK; + assert elseRoot != null : FOLD_WITHOUT_CHECK; JetIfExpression newIfExpr = JetPsiFactory.createIf(project, condition, thenRoot, elseRoot); JetReturnExpression newReturnExpr = JetPsiFactory.createReturn(project, newIfExpr); @@ -228,25 +230,25 @@ public class BranchedFoldingUtils { JetReturnExpression oldReturn = (JetReturnExpression)JetPsiUtil.skipTrailingWhitespacesAndComments(newReturnExpr); - assert oldReturn != null; + assert oldReturn != null : FOLD_WITHOUT_CHECK; oldReturn.delete(); newIfExpr = (JetIfExpression)newReturnExpr.getReturnedExpression(); - assert newIfExpr != null; + assert newIfExpr != null : FOLD_WITHOUT_CHECK; JetReturnExpression thenReturn = checkAndGetFoldableBranchedReturn(newIfExpr.getThen()); JetReturnExpression elseReturn = checkAndGetFoldableBranchedReturn(newIfExpr.getElse()); - assert thenReturn != null; - assert elseReturn != null; + assert thenReturn != null : FOLD_WITHOUT_CHECK; + assert elseReturn != null : FOLD_WITHOUT_CHECK; JetExpression thenExpr = thenReturn.getReturnedExpression(); JetExpression elseExpr = elseReturn.getReturnedExpression(); - assert thenExpr != null; - assert elseExpr != null; + assert thenExpr != null : FOLD_WITHOUT_CHECK; + assert elseExpr != null : FOLD_WITHOUT_CHECK; thenReturn.replace(thenExpr); elseReturn.replace(elseExpr); @@ -255,11 +257,11 @@ public class BranchedFoldingUtils { private static void foldWhenExpressionWithAssignments(JetWhenExpression whenExpression) { Project project = whenExpression.getProject(); - assert !whenExpression.getEntries().isEmpty(); + assert !whenExpression.getEntries().isEmpty() : FOLD_WITHOUT_CHECK; JetBinaryExpression firstAssignment = checkAndGetFoldableBranchedAssignment(whenExpression.getEntries().get(0).getExpression()); - assert firstAssignment != null; + assert firstAssignment != null : FOLD_WITHOUT_CHECK; String op = firstAssignment.getOperationReference().getText(); JetSimpleNameExpression lhs = (JetSimpleNameExpression) firstAssignment.getLeft(); @@ -268,16 +270,16 @@ public class BranchedFoldingUtils { (JetBinaryExpression)whenExpression.replace(JetPsiFactory.createBinaryExpression(project, lhs, op, whenExpression)); whenExpression = (JetWhenExpression)assignment.getRight(); - assert whenExpression != null; + assert whenExpression != null : FOLD_WITHOUT_CHECK; for (JetWhenEntry entry : whenExpression.getEntries()) { JetBinaryExpression currAssignment = checkAndGetFoldableBranchedAssignment(entry.getExpression()); - assert currAssignment != null; + assert currAssignment != null : FOLD_WITHOUT_CHECK; JetExpression currRhs = currAssignment.getRight(); - assert currRhs != null; + assert currRhs != null : FOLD_WITHOUT_CHECK; currAssignment.replace(currRhs); } @@ -286,21 +288,21 @@ public class BranchedFoldingUtils { private static void foldWhenExpressionWithReturns(JetWhenExpression whenExpression) { Project project = whenExpression.getProject(); - assert !whenExpression.getEntries().isEmpty(); + assert !whenExpression.getEntries().isEmpty() : FOLD_WITHOUT_CHECK; JetReturnExpression returnExpr = (JetReturnExpression)whenExpression.replace(JetPsiFactory.createReturn(project, whenExpression)); whenExpression = (JetWhenExpression)returnExpr.getReturnedExpression(); - assert whenExpression != null; + assert whenExpression != null : FOLD_WITHOUT_CHECK; for (JetWhenEntry entry : whenExpression.getEntries()) { JetReturnExpression currReturn = checkAndGetFoldableBranchedReturn(entry.getExpression()); - assert currReturn != null; + assert currReturn != null : FOLD_WITHOUT_CHECK; JetExpression currExpr = currReturn.getReturnedExpression(); - assert currExpr != null; + assert currExpr != null : FOLD_WITHOUT_CHECK; currReturn.replace(currExpr); } diff --git a/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/BranchedUnfoldingUtils.java b/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/BranchedUnfoldingUtils.java index 707d019ee01..da88e10dc1b 100644 --- a/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/BranchedUnfoldingUtils.java +++ b/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/BranchedUnfoldingUtils.java @@ -49,21 +49,23 @@ public class BranchedUnfoldingUtils { return (JetExpression) JetPsiUtil.getOutermostLastBlockElement(expression, JetPsiUtil.ANY_JET_ELEMENT); } + public static final String UNFOLD_WITHOUT_CHECK = "Expression must be checked before unfolding"; + private static void unfoldAssignmentToIf(@NotNull JetBinaryExpression assignment) { Project project = assignment.getProject(); String op = assignment.getOperationReference().getText(); String lhsText = assignment.getLeft().getText(); JetIfExpression ifExpression = (JetIfExpression)assignment.getRight(); - assert ifExpression != null; + assert ifExpression != null : UNFOLD_WITHOUT_CHECK; ifExpression = (JetIfExpression)assignment.replace(ifExpression); JetExpression thenExpr = getOutermostLastBlockElement(ifExpression.getThen()); JetExpression elseExpr = getOutermostLastBlockElement(ifExpression.getElse()); - assert thenExpr != null; - assert elseExpr != null; + assert thenExpr != null : UNFOLD_WITHOUT_CHECK; + assert elseExpr != null : UNFOLD_WITHOUT_CHECK; thenExpr.replace(JetPsiFactory.createBinaryExpression(project, JetPsiFactory.createExpression(project, lhsText), op, thenExpr)); elseExpr.replace(JetPsiFactory.createBinaryExpression(project, JetPsiFactory.createExpression(project, lhsText), op, elseExpr)); @@ -75,14 +77,14 @@ public class BranchedUnfoldingUtils { JetExpression lhs = (JetExpression)assignment.getLeft().copy(); JetWhenExpression whenExpression = (JetWhenExpression)assignment.getRight(); - assert whenExpression != null; + assert whenExpression != null : UNFOLD_WITHOUT_CHECK; whenExpression = (JetWhenExpression)assignment.replace(whenExpression); for (JetWhenEntry entry : whenExpression.getEntries()) { JetExpression currExpr = getOutermostLastBlockElement(entry.getExpression()); - assert currExpr != null; + assert currExpr != null : UNFOLD_WITHOUT_CHECK; currExpr.replace(JetPsiFactory.createBinaryExpression(project, lhs, op, currExpr)); } @@ -92,15 +94,15 @@ public class BranchedUnfoldingUtils { Project project = returnExpression.getProject(); JetIfExpression ifExpression = (JetIfExpression)returnExpression.getReturnedExpression(); - assert ifExpression != null; + assert ifExpression != null : UNFOLD_WITHOUT_CHECK; ifExpression = (JetIfExpression)returnExpression.replace(ifExpression); JetExpression thenExpr = getOutermostLastBlockElement(ifExpression.getThen()); JetExpression elseExpr = getOutermostLastBlockElement(ifExpression.getElse()); - assert thenExpr != null; - assert elseExpr != null; + assert thenExpr != null : UNFOLD_WITHOUT_CHECK; + assert elseExpr != null : UNFOLD_WITHOUT_CHECK; thenExpr.replace(JetPsiFactory.createReturn(project, thenExpr)); elseExpr.replace(JetPsiFactory.createReturn(project, elseExpr)); @@ -110,14 +112,14 @@ public class BranchedUnfoldingUtils { Project project = returnExpression.getProject(); JetWhenExpression whenExpression = (JetWhenExpression)returnExpression.getReturnedExpression(); - assert whenExpression != null; + assert whenExpression != null : UNFOLD_WITHOUT_CHECK; whenExpression = (JetWhenExpression)returnExpression.replace(whenExpression); for (JetWhenEntry entry : whenExpression.getEntries()) { JetExpression currExpr = getOutermostLastBlockElement(entry.getExpression()); - assert currExpr != null; + assert currExpr != null : UNFOLD_WITHOUT_CHECK; currExpr.replace(JetPsiFactory.createReturn(project, currExpr)); } From 9e441b0525734e7aaa70cd1eb405880105bec224 Mon Sep 17 00:00:00 2001 From: Alexey Sedunov Date: Mon, 15 Apr 2013 16:24:39 +0400 Subject: [PATCH 072/249] Fix intention descriptions and templates --- .../after.kt.template | 16 ++++++---------- .../before.kt.template | 16 ++++++---------- .../description.html | 4 ++-- .../after.kt.template | 16 ++++++---------- .../before.kt.template | 16 ++++++---------- .../description.html | 4 ++-- .../FoldBranchedExpressionIntention.java | 2 -- 7 files changed, 28 insertions(+), 46 deletions(-) diff --git a/idea/resources/intentionDescriptions/FoldBranchedExpressionIntention/after.kt.template b/idea/resources/intentionDescriptions/FoldBranchedExpressionIntention/after.kt.template index 79454db998b..2a07dd895ee 100644 --- a/idea/resources/intentionDescriptions/FoldBranchedExpressionIntention/after.kt.template +++ b/idea/resources/intentionDescriptions/FoldBranchedExpressionIntention/after.kt.template @@ -1,11 +1,7 @@ -public class MyClass { - public fun f(a: Int): String { - var res: String - - res = if (a == 1) "one"; - else if (a == 2) "two"; - else "too many"; - - return res; - } +res = if (n == 1) { + println("***") + "one" +} else { + println("***") + "two" } \ No newline at end of file diff --git a/idea/resources/intentionDescriptions/FoldBranchedExpressionIntention/before.kt.template b/idea/resources/intentionDescriptions/FoldBranchedExpressionIntention/before.kt.template index f77b5f803e3..e61b2e5599b 100644 --- a/idea/resources/intentionDescriptions/FoldBranchedExpressionIntention/before.kt.template +++ b/idea/resources/intentionDescriptions/FoldBranchedExpressionIntention/before.kt.template @@ -1,11 +1,7 @@ -public class MyClass { - public fun f(a: Int): String { - var res: String - - if (a == 1) res = "one"; - else if (a == 2) res = "two"; - else res = "too many"; - - return res; - } +if (n == 1) { + println("***") + res = "one" +} else { + println("***") + res = "two" } \ No newline at end of file diff --git a/idea/resources/intentionDescriptions/FoldBranchedExpressionIntention/description.html b/idea/resources/intentionDescriptions/FoldBranchedExpressionIntention/description.html index bdb8e184981..256249f1e15 100644 --- a/idea/resources/intentionDescriptions/FoldBranchedExpressionIntention/description.html +++ b/idea/resources/intentionDescriptions/FoldBranchedExpressionIntention/description.html @@ -1,6 +1,6 @@ -This intention converts 'if' statement where each branch is terminated with assignment to the same variable -into single assignment with 'if' expression +This intention converts branched (if/when) expression where each branch is terminated with assignment/return/method call into single +assignment/return/method call with branched expression as argument \ No newline at end of file diff --git a/idea/resources/intentionDescriptions/UnfoldBranchedExpressionIntention/after.kt.template b/idea/resources/intentionDescriptions/UnfoldBranchedExpressionIntention/after.kt.template index f77b5f803e3..e61b2e5599b 100644 --- a/idea/resources/intentionDescriptions/UnfoldBranchedExpressionIntention/after.kt.template +++ b/idea/resources/intentionDescriptions/UnfoldBranchedExpressionIntention/after.kt.template @@ -1,11 +1,7 @@ -public class MyClass { - public fun f(a: Int): String { - var res: String - - if (a == 1) res = "one"; - else if (a == 2) res = "two"; - else res = "too many"; - - return res; - } +if (n == 1) { + println("***") + res = "one" +} else { + println("***") + res = "two" } \ No newline at end of file diff --git a/idea/resources/intentionDescriptions/UnfoldBranchedExpressionIntention/before.kt.template b/idea/resources/intentionDescriptions/UnfoldBranchedExpressionIntention/before.kt.template index 79454db998b..2a07dd895ee 100644 --- a/idea/resources/intentionDescriptions/UnfoldBranchedExpressionIntention/before.kt.template +++ b/idea/resources/intentionDescriptions/UnfoldBranchedExpressionIntention/before.kt.template @@ -1,11 +1,7 @@ -public class MyClass { - public fun f(a: Int): String { - var res: String - - res = if (a == 1) "one"; - else if (a == 2) "two"; - else "too many"; - - return res; - } +res = if (n == 1) { + println("***") + "one" +} else { + println("***") + "two" } \ No newline at end of file diff --git a/idea/resources/intentionDescriptions/UnfoldBranchedExpressionIntention/description.html b/idea/resources/intentionDescriptions/UnfoldBranchedExpressionIntention/description.html index bac916bbe3e..e130de78a1b 100644 --- a/idea/resources/intentionDescriptions/UnfoldBranchedExpressionIntention/description.html +++ b/idea/resources/intentionDescriptions/UnfoldBranchedExpressionIntention/description.html @@ -1,6 +1,6 @@ -This intention converts assignment with 'if' expression as right-hand side -into 'if' statement where each branch is terminated with assignment to the original variable +This intention converts assignment/return/method call with branched (if/when) expression as argument +to branched expression where each branch is terminated with assignment/return/method call \ No newline at end of file diff --git a/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/FoldBranchedExpressionIntention.java b/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/FoldBranchedExpressionIntention.java index 8f25d6f40cd..89e67823803 100644 --- a/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/FoldBranchedExpressionIntention.java +++ b/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/FoldBranchedExpressionIntention.java @@ -21,13 +21,11 @@ import com.intellij.openapi.editor.Editor; import com.intellij.openapi.project.Project; import com.intellij.psi.PsiElement; import com.intellij.psi.PsiFile; -import com.intellij.psi.util.PsiTreeUtil; import com.intellij.util.IncorrectOperationException; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.jet.lang.psi.JetElement; import org.jetbrains.jet.lang.psi.JetExpression; -import org.jetbrains.jet.lang.psi.JetIfExpression; import org.jetbrains.jet.lang.psi.JetPsiUtil; import org.jetbrains.jet.plugin.JetBundle; From 64e578297c432111dda2a67d99d85ecf5578a038 Mon Sep 17 00:00:00 2001 From: Alexey Sedunov Date: Tue, 16 Apr 2013 14:33:58 +0400 Subject: [PATCH 073/249] Replace fold/unfold intentions with a set of specialized ones --- .../jet/generators/tests/GenerateTests.java | 11 +- .../after.kt.template | 7 - .../before.kt.template | 7 - .../description.html | 6 - .../after.kt.template | 5 + .../before.kt.template | 5 + .../description.html | 5 + .../after.kt.template | 3 + .../before.kt.template | 4 + .../description.html | 5 + .../FoldIfToReturnIntention/after.kt.template | 5 + .../before.kt.template | 5 + .../FoldIfToReturnIntention/description.html | 5 + .../after.kt.template | 5 + .../before.kt.template | 5 + .../description.html | 5 + .../after.kt.template | 5 + .../before.kt.template | 5 + .../description.html | 5 + .../after.kt.template | 5 + .../before.kt.template | 5 + .../description.html | 5 + .../after.kt.template | 5 + .../before.kt.template | 5 + .../description.html | 5 + .../after.kt.template | 7 - .../before.kt.template | 7 - .../description.html | 6 - .../after.kt.template | 5 + .../before.kt.template | 5 + .../description.html | 5 + .../after.kt.template | 5 + .../before.kt.template | 5 + .../description.html | 5 + idea/src/META-INF/plugin.xml | 39 +- .../jetbrains/jet/plugin/JetBundle.properties | 24 + ... AbstractCodeTransformationIntention.java} | 42 +- .../BranchedFoldingUtils.java | 58 +-- .../BranchedUnfoldingUtils.java | 74 ++- .../branchedTransformations/FoldableKind.java | 68 +++ .../UnfoldBranchedExpressionIntention.java | 62 --- .../UnfoldableKind.java | 62 +++ .../core/Transformer.java | 25 + .../FoldBranchedExpressionIntention.java | 40 ++ .../FoldIfToAssignmentIntention.java | 25 + ...FoldIfToReturnAsymmetricallyIntention.java | 25 + .../intentions/FoldIfToReturnIntention.java | 25 + .../FoldWhenToAssignmentIntention.java | 25 + .../intentions/FoldWhenToReturnIntention.java | 25 + .../UnfoldAssignmentToIfIntention.java | 25 + .../UnfoldAssignmentToWhenIntention.java | 25 + .../UnfoldBranchedExpressionIntention.java | 38 ++ .../intentions/UnfoldReturnToIfIntention.java | 25 + .../UnfoldReturnToWhenIntention.java | 25 + .../innerIfTransformed.kt | 0 .../innerIfTransformed.kt.after | 0 .../simpleIf.kt | 0 .../simpleIf.kt.after | 0 .../simpleIfWithAugmentedAssignment.kt | 0 .../simpleIfWithAugmentedAssignment.kt.after | 0 .../simpleIfWithBlocks.kt | 0 .../simpleIfWithBlocks.kt.after | 0 .../simpleIfWithShadowedVar.kt | 0 .../simpleIfWithUnmatchedAssignmentOps.kt | 0 .../simpleIfWithUnmatchedAssignments.kt | 0 .../simpleIfWithoutElse.kt | 0 .../simpleIfWithoutTerminatingAssignment.kt | 0 .../innerIfTransformed.kt | 0 .../innerIfTransformed.kt.after | 0 .../{return => ifToReturn}/simpleIf.kt | 0 .../{return => ifToReturn}/simpleIf.kt.after | 0 .../simpleIfWithBlocks.kt | 0 .../simpleIfWithBlocks.kt.after | 0 .../simpleIf.kt | 0 .../simpleIf.kt.after | 0 .../simpleIfWithBlocks.kt | 0 .../simpleIfWithBlocks.kt.after | 0 .../simpleIfWithComments.kt | 0 .../simpleIfWithComments.kt.after | 0 .../innerWhenTransformed.kt | 0 .../innerWhenTransformed.kt.after | 0 .../simpleWhen.kt | 0 .../simpleWhen.kt.after | 0 .../simpleWhenWithBlocks.kt | 0 .../simpleWhenWithBlocks.kt.after | 0 .../simpleWhenWithShadowedVar.kt | 0 .../simpleWhenWithUnmatchedAssignments.kt | 0 .../simpleWhenWithoutTerminatingAssignment.kt | 0 .../innerWhenTransformed.kt | 0 .../innerWhenTransformed.kt.after | 0 .../{return => whenToReturn}/simpleWhen.kt | 0 .../simpleWhen.kt.after | 0 .../simpleWhenWithBlocks.kt | 0 .../simpleWhenWithBlocks.kt.after | 0 .../innerIfTransformed.kt | 0 .../innerIfTransformed.kt.after | 0 .../nestedIfs.kt | 0 .../nestedIfs.kt.after | 0 .../simpleIf.kt | 0 .../simpleIf.kt.after | 0 .../simpleIfWithAugmentedAssignment.kt | 0 .../simpleIfWithAugmentedAssignment.kt.after | 0 .../simpleIfWithBlocks.kt | 0 .../simpleIfWithBlocks.kt.after | 0 .../simpleIfWithoutAssignment.kt | 0 .../innerIfTransformed.kt | 0 .../innerIfTransformed.kt.after | 0 .../{return => returnToIf}/simpleIf.kt | 0 .../{return => returnToIf}/simpleIf.kt.after | 0 .../simpleIfWithBlocks.kt | 0 .../simpleIfWithBlocks.kt.after | 0 .../AbstractCodeTransformationTest.java | 39 +- .../CodeTransformationsTestGenerated.java | 430 +++++++++--------- 113 files changed, 972 insertions(+), 437 deletions(-) delete mode 100644 idea/resources/intentionDescriptions/FoldBranchedExpressionIntention/after.kt.template delete mode 100644 idea/resources/intentionDescriptions/FoldBranchedExpressionIntention/before.kt.template delete mode 100644 idea/resources/intentionDescriptions/FoldBranchedExpressionIntention/description.html create mode 100644 idea/resources/intentionDescriptions/FoldIfToAssignmentIntention/after.kt.template create mode 100644 idea/resources/intentionDescriptions/FoldIfToAssignmentIntention/before.kt.template create mode 100644 idea/resources/intentionDescriptions/FoldIfToAssignmentIntention/description.html create mode 100644 idea/resources/intentionDescriptions/FoldIfToReturnAsymmetricallyIntention/after.kt.template create mode 100644 idea/resources/intentionDescriptions/FoldIfToReturnAsymmetricallyIntention/before.kt.template create mode 100644 idea/resources/intentionDescriptions/FoldIfToReturnAsymmetricallyIntention/description.html create mode 100644 idea/resources/intentionDescriptions/FoldIfToReturnIntention/after.kt.template create mode 100644 idea/resources/intentionDescriptions/FoldIfToReturnIntention/before.kt.template create mode 100644 idea/resources/intentionDescriptions/FoldIfToReturnIntention/description.html create mode 100644 idea/resources/intentionDescriptions/FoldWhenToAssignmentIntention/after.kt.template create mode 100644 idea/resources/intentionDescriptions/FoldWhenToAssignmentIntention/before.kt.template create mode 100644 idea/resources/intentionDescriptions/FoldWhenToAssignmentIntention/description.html create mode 100644 idea/resources/intentionDescriptions/FoldWhenToReturnIntention/after.kt.template create mode 100644 idea/resources/intentionDescriptions/FoldWhenToReturnIntention/before.kt.template create mode 100644 idea/resources/intentionDescriptions/FoldWhenToReturnIntention/description.html create mode 100644 idea/resources/intentionDescriptions/UnfoldAssignmentToIfIntention/after.kt.template create mode 100644 idea/resources/intentionDescriptions/UnfoldAssignmentToIfIntention/before.kt.template create mode 100644 idea/resources/intentionDescriptions/UnfoldAssignmentToIfIntention/description.html create mode 100644 idea/resources/intentionDescriptions/UnfoldAssignmentToWhenIntention/after.kt.template create mode 100644 idea/resources/intentionDescriptions/UnfoldAssignmentToWhenIntention/before.kt.template create mode 100644 idea/resources/intentionDescriptions/UnfoldAssignmentToWhenIntention/description.html delete mode 100644 idea/resources/intentionDescriptions/UnfoldBranchedExpressionIntention/after.kt.template delete mode 100644 idea/resources/intentionDescriptions/UnfoldBranchedExpressionIntention/before.kt.template delete mode 100644 idea/resources/intentionDescriptions/UnfoldBranchedExpressionIntention/description.html create mode 100644 idea/resources/intentionDescriptions/UnfoldReturnToIfIntention/after.kt.template create mode 100644 idea/resources/intentionDescriptions/UnfoldReturnToIfIntention/before.kt.template create mode 100644 idea/resources/intentionDescriptions/UnfoldReturnToIfIntention/description.html create mode 100644 idea/resources/intentionDescriptions/UnfoldReturnToWhenIntention/after.kt.template create mode 100644 idea/resources/intentionDescriptions/UnfoldReturnToWhenIntention/before.kt.template create mode 100644 idea/resources/intentionDescriptions/UnfoldReturnToWhenIntention/description.html rename idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/{FoldBranchedExpressionIntention.java => AbstractCodeTransformationIntention.java} (59%) create mode 100644 idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/FoldableKind.java delete mode 100644 idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/UnfoldBranchedExpressionIntention.java create mode 100644 idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/UnfoldableKind.java create mode 100644 idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/core/Transformer.java create mode 100644 idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/intentions/FoldBranchedExpressionIntention.java create mode 100644 idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/intentions/FoldIfToAssignmentIntention.java create mode 100644 idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/intentions/FoldIfToReturnAsymmetricallyIntention.java create mode 100644 idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/intentions/FoldIfToReturnIntention.java create mode 100644 idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/intentions/FoldWhenToAssignmentIntention.java create mode 100644 idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/intentions/FoldWhenToReturnIntention.java create mode 100644 idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/intentions/UnfoldAssignmentToIfIntention.java create mode 100644 idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/intentions/UnfoldAssignmentToWhenIntention.java create mode 100644 idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/intentions/UnfoldBranchedExpressionIntention.java create mode 100644 idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/intentions/UnfoldReturnToIfIntention.java create mode 100644 idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/intentions/UnfoldReturnToWhenIntention.java rename idea/testData/codeInsight/codeTransformations/branched/folding/{assignment => ifToAssignment}/innerIfTransformed.kt (100%) rename idea/testData/codeInsight/codeTransformations/branched/folding/{assignment => ifToAssignment}/innerIfTransformed.kt.after (100%) rename idea/testData/codeInsight/codeTransformations/branched/folding/{assignment => ifToAssignment}/simpleIf.kt (100%) rename idea/testData/codeInsight/codeTransformations/branched/folding/{assignment => ifToAssignment}/simpleIf.kt.after (100%) rename idea/testData/codeInsight/codeTransformations/branched/folding/{assignment => ifToAssignment}/simpleIfWithAugmentedAssignment.kt (100%) rename idea/testData/codeInsight/codeTransformations/branched/folding/{assignment => ifToAssignment}/simpleIfWithAugmentedAssignment.kt.after (100%) rename idea/testData/codeInsight/codeTransformations/branched/folding/{assignment => ifToAssignment}/simpleIfWithBlocks.kt (100%) rename idea/testData/codeInsight/codeTransformations/branched/folding/{assignment => ifToAssignment}/simpleIfWithBlocks.kt.after (100%) rename idea/testData/codeInsight/codeTransformations/branched/folding/{assignment => ifToAssignment}/simpleIfWithShadowedVar.kt (100%) rename idea/testData/codeInsight/codeTransformations/branched/folding/{assignment => ifToAssignment}/simpleIfWithUnmatchedAssignmentOps.kt (100%) rename idea/testData/codeInsight/codeTransformations/branched/folding/{assignment => ifToAssignment}/simpleIfWithUnmatchedAssignments.kt (100%) rename idea/testData/codeInsight/codeTransformations/branched/folding/{assignment => ifToAssignment}/simpleIfWithoutElse.kt (100%) rename idea/testData/codeInsight/codeTransformations/branched/folding/{assignment => ifToAssignment}/simpleIfWithoutTerminatingAssignment.kt (100%) rename idea/testData/codeInsight/codeTransformations/branched/folding/{return => ifToReturn}/innerIfTransformed.kt (100%) rename idea/testData/codeInsight/codeTransformations/branched/folding/{return => ifToReturn}/innerIfTransformed.kt.after (100%) rename idea/testData/codeInsight/codeTransformations/branched/folding/{return => ifToReturn}/simpleIf.kt (100%) rename idea/testData/codeInsight/codeTransformations/branched/folding/{return => ifToReturn}/simpleIf.kt.after (100%) rename idea/testData/codeInsight/codeTransformations/branched/folding/{return => ifToReturn}/simpleIfWithBlocks.kt (100%) rename idea/testData/codeInsight/codeTransformations/branched/folding/{return => ifToReturn}/simpleIfWithBlocks.kt.after (100%) rename idea/testData/codeInsight/codeTransformations/branched/folding/{asymmetricReturn => ifToReturnAsymmetrically}/simpleIf.kt (100%) rename idea/testData/codeInsight/codeTransformations/branched/folding/{asymmetricReturn => ifToReturnAsymmetrically}/simpleIf.kt.after (100%) rename idea/testData/codeInsight/codeTransformations/branched/folding/{asymmetricReturn => ifToReturnAsymmetrically}/simpleIfWithBlocks.kt (100%) rename idea/testData/codeInsight/codeTransformations/branched/folding/{asymmetricReturn => ifToReturnAsymmetrically}/simpleIfWithBlocks.kt.after (100%) rename idea/testData/codeInsight/codeTransformations/branched/folding/{asymmetricReturn => ifToReturnAsymmetrically}/simpleIfWithComments.kt (100%) rename idea/testData/codeInsight/codeTransformations/branched/folding/{asymmetricReturn => ifToReturnAsymmetrically}/simpleIfWithComments.kt.after (100%) rename idea/testData/codeInsight/codeTransformations/branched/folding/{assignment => whenToAssignment}/innerWhenTransformed.kt (100%) rename idea/testData/codeInsight/codeTransformations/branched/folding/{assignment => whenToAssignment}/innerWhenTransformed.kt.after (100%) rename idea/testData/codeInsight/codeTransformations/branched/folding/{assignment => whenToAssignment}/simpleWhen.kt (100%) rename idea/testData/codeInsight/codeTransformations/branched/folding/{assignment => whenToAssignment}/simpleWhen.kt.after (100%) rename idea/testData/codeInsight/codeTransformations/branched/folding/{assignment => whenToAssignment}/simpleWhenWithBlocks.kt (100%) rename idea/testData/codeInsight/codeTransformations/branched/folding/{assignment => whenToAssignment}/simpleWhenWithBlocks.kt.after (100%) rename idea/testData/codeInsight/codeTransformations/branched/folding/{assignment => whenToAssignment}/simpleWhenWithShadowedVar.kt (100%) rename idea/testData/codeInsight/codeTransformations/branched/folding/{assignment => whenToAssignment}/simpleWhenWithUnmatchedAssignments.kt (100%) rename idea/testData/codeInsight/codeTransformations/branched/folding/{assignment => whenToAssignment}/simpleWhenWithoutTerminatingAssignment.kt (100%) rename idea/testData/codeInsight/codeTransformations/branched/folding/{return => whenToReturn}/innerWhenTransformed.kt (100%) rename idea/testData/codeInsight/codeTransformations/branched/folding/{return => whenToReturn}/innerWhenTransformed.kt.after (100%) rename idea/testData/codeInsight/codeTransformations/branched/folding/{return => whenToReturn}/simpleWhen.kt (100%) rename idea/testData/codeInsight/codeTransformations/branched/folding/{return => whenToReturn}/simpleWhen.kt.after (100%) rename idea/testData/codeInsight/codeTransformations/branched/folding/{return => whenToReturn}/simpleWhenWithBlocks.kt (100%) rename idea/testData/codeInsight/codeTransformations/branched/folding/{return => whenToReturn}/simpleWhenWithBlocks.kt.after (100%) rename idea/testData/codeInsight/codeTransformations/branched/unfolding/{assignment => assignmentToIf}/innerIfTransformed.kt (100%) rename idea/testData/codeInsight/codeTransformations/branched/unfolding/{assignment => assignmentToIf}/innerIfTransformed.kt.after (100%) rename idea/testData/codeInsight/codeTransformations/branched/unfolding/{assignment => assignmentToIf}/nestedIfs.kt (100%) rename idea/testData/codeInsight/codeTransformations/branched/unfolding/{assignment => assignmentToIf}/nestedIfs.kt.after (100%) rename idea/testData/codeInsight/codeTransformations/branched/unfolding/{assignment => assignmentToIf}/simpleIf.kt (100%) rename idea/testData/codeInsight/codeTransformations/branched/unfolding/{assignment => assignmentToIf}/simpleIf.kt.after (100%) rename idea/testData/codeInsight/codeTransformations/branched/unfolding/{assignment => assignmentToIf}/simpleIfWithAugmentedAssignment.kt (100%) rename idea/testData/codeInsight/codeTransformations/branched/unfolding/{assignment => assignmentToIf}/simpleIfWithAugmentedAssignment.kt.after (100%) rename idea/testData/codeInsight/codeTransformations/branched/unfolding/{assignment => assignmentToIf}/simpleIfWithBlocks.kt (100%) rename idea/testData/codeInsight/codeTransformations/branched/unfolding/{assignment => assignmentToIf}/simpleIfWithBlocks.kt.after (100%) rename idea/testData/codeInsight/codeTransformations/branched/unfolding/{assignment => assignmentToIf}/simpleIfWithoutAssignment.kt (100%) rename idea/testData/codeInsight/codeTransformations/branched/unfolding/{return => returnToIf}/innerIfTransformed.kt (100%) rename idea/testData/codeInsight/codeTransformations/branched/unfolding/{return => returnToIf}/innerIfTransformed.kt.after (100%) rename idea/testData/codeInsight/codeTransformations/branched/unfolding/{return => returnToIf}/simpleIf.kt (100%) rename idea/testData/codeInsight/codeTransformations/branched/unfolding/{return => returnToIf}/simpleIf.kt.after (100%) rename idea/testData/codeInsight/codeTransformations/branched/unfolding/{return => returnToIf}/simpleIfWithBlocks.kt (100%) rename idea/testData/codeInsight/codeTransformations/branched/unfolding/{return => returnToIf}/simpleIfWithBlocks.kt.after (100%) diff --git a/generators/org/jetbrains/jet/generators/tests/GenerateTests.java b/generators/org/jetbrains/jet/generators/tests/GenerateTests.java index 8049091a2a3..25e534362f2 100644 --- a/generators/org/jetbrains/jet/generators/tests/GenerateTests.java +++ b/generators/org/jetbrains/jet/generators/tests/GenerateTests.java @@ -305,8 +305,15 @@ public class GenerateTests { "idea/tests/", "CodeTransformationsTestGenerated", AbstractCodeTransformationTest.class, - testModel("idea/testData/codeInsight/codeTransformations/ifStatementWithAssignmentsToExpression", "doTestIfStatementWithAssignmentsToExpression"), - testModel("idea/testData/codeInsight/codeTransformations/assignmentWithIfExpressionToStatement", "doTestAssignmentWithIfExpressionToStatement") + testModel("idea/testData/codeInsight/codeTransformations/branched/folding/ifToAssignment", "doTestFoldIfToAssignment"), + testModel("idea/testData/codeInsight/codeTransformations/branched/folding/ifToReturn", "doTestFoldIfToReturn"), + testModel("idea/testData/codeInsight/codeTransformations/branched/folding/ifToReturnAsymmetrically", "doTestFoldIfToReturnAsymmetrically"), + testModel("idea/testData/codeInsight/codeTransformations/branched/folding/whenToAssignment", "doTestFoldWhenToAssignment"), + testModel("idea/testData/codeInsight/codeTransformations/branched/folding/whenToReturn", "doTestFoldWhenToReturn"), + testModel("idea/testData/codeInsight/codeTransformations/branched/unfolding/assignmentToIf", "doTestUnfoldAssignmentToIf"), + testModel("idea/testData/codeInsight/codeTransformations/branched/unfolding/assignmentToWhen", "doTestUnfoldAssignmentToWhen"), + testModel("idea/testData/codeInsight/codeTransformations/branched/unfolding/returnToIf", "doTestUnfoldReturnToIf"), + testModel("idea/testData/codeInsight/codeTransformations/branched/unfolding/returnToWhen", "doTestUnfoldReturnToWhen") ); generateTest( diff --git a/idea/resources/intentionDescriptions/FoldBranchedExpressionIntention/after.kt.template b/idea/resources/intentionDescriptions/FoldBranchedExpressionIntention/after.kt.template deleted file mode 100644 index 2a07dd895ee..00000000000 --- a/idea/resources/intentionDescriptions/FoldBranchedExpressionIntention/after.kt.template +++ /dev/null @@ -1,7 +0,0 @@ -res = if (n == 1) { - println("***") - "one" -} else { - println("***") - "two" -} \ No newline at end of file diff --git a/idea/resources/intentionDescriptions/FoldBranchedExpressionIntention/before.kt.template b/idea/resources/intentionDescriptions/FoldBranchedExpressionIntention/before.kt.template deleted file mode 100644 index e61b2e5599b..00000000000 --- a/idea/resources/intentionDescriptions/FoldBranchedExpressionIntention/before.kt.template +++ /dev/null @@ -1,7 +0,0 @@ -if (n == 1) { - println("***") - res = "one" -} else { - println("***") - res = "two" -} \ No newline at end of file diff --git a/idea/resources/intentionDescriptions/FoldBranchedExpressionIntention/description.html b/idea/resources/intentionDescriptions/FoldBranchedExpressionIntention/description.html deleted file mode 100644 index 256249f1e15..00000000000 --- a/idea/resources/intentionDescriptions/FoldBranchedExpressionIntention/description.html +++ /dev/null @@ -1,6 +0,0 @@ - - -This intention converts branched (if/when) expression where each branch is terminated with assignment/return/method call into single -assignment/return/method call with branched expression as argument - - \ No newline at end of file diff --git a/idea/resources/intentionDescriptions/FoldIfToAssignmentIntention/after.kt.template b/idea/resources/intentionDescriptions/FoldIfToAssignmentIntention/after.kt.template new file mode 100644 index 00000000000..81e1d86690b --- /dev/null +++ b/idea/resources/intentionDescriptions/FoldIfToAssignmentIntention/after.kt.template @@ -0,0 +1,5 @@ +res = if (ok) { + "ok" +} else { + "failed" +} \ No newline at end of file diff --git a/idea/resources/intentionDescriptions/FoldIfToAssignmentIntention/before.kt.template b/idea/resources/intentionDescriptions/FoldIfToAssignmentIntention/before.kt.template new file mode 100644 index 00000000000..03c87bc1010 --- /dev/null +++ b/idea/resources/intentionDescriptions/FoldIfToAssignmentIntention/before.kt.template @@ -0,0 +1,5 @@ +if (ok) { + res = "ok" +} else { + res = "failed" +} \ No newline at end of file diff --git a/idea/resources/intentionDescriptions/FoldIfToAssignmentIntention/description.html b/idea/resources/intentionDescriptions/FoldIfToAssignmentIntention/description.html new file mode 100644 index 00000000000..9a581e4ade0 --- /dev/null +++ b/idea/resources/intentionDescriptions/FoldIfToAssignmentIntention/description.html @@ -0,0 +1,5 @@ + + +This intention converts 'if' expression where each branch is terminated with assignment into a single assignment with 'if' expression as a right-hand side + + \ No newline at end of file diff --git a/idea/resources/intentionDescriptions/FoldIfToReturnAsymmetricallyIntention/after.kt.template b/idea/resources/intentionDescriptions/FoldIfToReturnAsymmetricallyIntention/after.kt.template new file mode 100644 index 00000000000..20fcc992c5d --- /dev/null +++ b/idea/resources/intentionDescriptions/FoldIfToReturnAsymmetricallyIntention/after.kt.template @@ -0,0 +1,3 @@ +return if (ok) { + "ok" +} else "failed" \ No newline at end of file diff --git a/idea/resources/intentionDescriptions/FoldIfToReturnAsymmetricallyIntention/before.kt.template b/idea/resources/intentionDescriptions/FoldIfToReturnAsymmetricallyIntention/before.kt.template new file mode 100644 index 00000000000..ef72374d66c --- /dev/null +++ b/idea/resources/intentionDescriptions/FoldIfToReturnAsymmetricallyIntention/before.kt.template @@ -0,0 +1,4 @@ +if (ok) { + return "ok" +} +return "failed" \ No newline at end of file diff --git a/idea/resources/intentionDescriptions/FoldIfToReturnAsymmetricallyIntention/description.html b/idea/resources/intentionDescriptions/FoldIfToReturnAsymmetricallyIntention/description.html new file mode 100644 index 00000000000..d1df2972fb1 --- /dev/null +++ b/idea/resources/intentionDescriptions/FoldIfToReturnAsymmetricallyIntention/description.html @@ -0,0 +1,5 @@ + + +This intention converts single-branch 'if' expression immediately followed by 'return' into a single 'return' with 'if' expression as an argument + + \ No newline at end of file diff --git a/idea/resources/intentionDescriptions/FoldIfToReturnIntention/after.kt.template b/idea/resources/intentionDescriptions/FoldIfToReturnIntention/after.kt.template new file mode 100644 index 00000000000..0394cfc84c6 --- /dev/null +++ b/idea/resources/intentionDescriptions/FoldIfToReturnIntention/after.kt.template @@ -0,0 +1,5 @@ +return if (ok) { + "ok" +} else { + "failed" +} \ No newline at end of file diff --git a/idea/resources/intentionDescriptions/FoldIfToReturnIntention/before.kt.template b/idea/resources/intentionDescriptions/FoldIfToReturnIntention/before.kt.template new file mode 100644 index 00000000000..2cdc1aaaa9f --- /dev/null +++ b/idea/resources/intentionDescriptions/FoldIfToReturnIntention/before.kt.template @@ -0,0 +1,5 @@ +if (ok) { + return "ok" +} else { + return "failed" +} \ No newline at end of file diff --git a/idea/resources/intentionDescriptions/FoldIfToReturnIntention/description.html b/idea/resources/intentionDescriptions/FoldIfToReturnIntention/description.html new file mode 100644 index 00000000000..e700394d8ff --- /dev/null +++ b/idea/resources/intentionDescriptions/FoldIfToReturnIntention/description.html @@ -0,0 +1,5 @@ + + +This intention converts 'if' expression where each branch is terminated with 'return' into a single 'return' with 'if' expression as a right-hand side + + \ No newline at end of file diff --git a/idea/resources/intentionDescriptions/FoldWhenToAssignmentIntention/after.kt.template b/idea/resources/intentionDescriptions/FoldWhenToAssignmentIntention/after.kt.template new file mode 100644 index 00000000000..12ecbd93619 --- /dev/null +++ b/idea/resources/intentionDescriptions/FoldWhenToAssignmentIntention/after.kt.template @@ -0,0 +1,5 @@ +res = when (n) { + 1 -> "one" + 2 -> "two" + else -> "many" +} \ No newline at end of file diff --git a/idea/resources/intentionDescriptions/FoldWhenToAssignmentIntention/before.kt.template b/idea/resources/intentionDescriptions/FoldWhenToAssignmentIntention/before.kt.template new file mode 100644 index 00000000000..a059e3024f7 --- /dev/null +++ b/idea/resources/intentionDescriptions/FoldWhenToAssignmentIntention/before.kt.template @@ -0,0 +1,5 @@ +when (n) { + 1 -> res = "one" + 2 -> res = "two" + else -> res = "many" +} \ No newline at end of file diff --git a/idea/resources/intentionDescriptions/FoldWhenToAssignmentIntention/description.html b/idea/resources/intentionDescriptions/FoldWhenToAssignmentIntention/description.html new file mode 100644 index 00000000000..d90211f6b50 --- /dev/null +++ b/idea/resources/intentionDescriptions/FoldWhenToAssignmentIntention/description.html @@ -0,0 +1,5 @@ + + +This intention converts 'when' expression where each branch is terminated with assignment into a single assignment with 'when' expression as right-hand side + + \ No newline at end of file diff --git a/idea/resources/intentionDescriptions/FoldWhenToReturnIntention/after.kt.template b/idea/resources/intentionDescriptions/FoldWhenToReturnIntention/after.kt.template new file mode 100644 index 00000000000..ec9b48b8a9b --- /dev/null +++ b/idea/resources/intentionDescriptions/FoldWhenToReturnIntention/after.kt.template @@ -0,0 +1,5 @@ +return when (n) { + 1 -> "one" + 2 -> "two" + else -> "many" +} \ No newline at end of file diff --git a/idea/resources/intentionDescriptions/FoldWhenToReturnIntention/before.kt.template b/idea/resources/intentionDescriptions/FoldWhenToReturnIntention/before.kt.template new file mode 100644 index 00000000000..9ea6721ea13 --- /dev/null +++ b/idea/resources/intentionDescriptions/FoldWhenToReturnIntention/before.kt.template @@ -0,0 +1,5 @@ +when (n) { + 1 -> return "one" + 2 -> return "two" + else -> return "many" +} \ No newline at end of file diff --git a/idea/resources/intentionDescriptions/FoldWhenToReturnIntention/description.html b/idea/resources/intentionDescriptions/FoldWhenToReturnIntention/description.html new file mode 100644 index 00000000000..1101f0ea527 --- /dev/null +++ b/idea/resources/intentionDescriptions/FoldWhenToReturnIntention/description.html @@ -0,0 +1,5 @@ + + +This intention converts 'when' expression where each branch is terminated with 'return' into a single 'return' with 'when' expression as a right-hand side + + \ No newline at end of file diff --git a/idea/resources/intentionDescriptions/UnfoldAssignmentToIfIntention/after.kt.template b/idea/resources/intentionDescriptions/UnfoldAssignmentToIfIntention/after.kt.template new file mode 100644 index 00000000000..03c87bc1010 --- /dev/null +++ b/idea/resources/intentionDescriptions/UnfoldAssignmentToIfIntention/after.kt.template @@ -0,0 +1,5 @@ +if (ok) { + res = "ok" +} else { + res = "failed" +} \ No newline at end of file diff --git a/idea/resources/intentionDescriptions/UnfoldAssignmentToIfIntention/before.kt.template b/idea/resources/intentionDescriptions/UnfoldAssignmentToIfIntention/before.kt.template new file mode 100644 index 00000000000..81e1d86690b --- /dev/null +++ b/idea/resources/intentionDescriptions/UnfoldAssignmentToIfIntention/before.kt.template @@ -0,0 +1,5 @@ +res = if (ok) { + "ok" +} else { + "failed" +} \ No newline at end of file diff --git a/idea/resources/intentionDescriptions/UnfoldAssignmentToIfIntention/description.html b/idea/resources/intentionDescriptions/UnfoldAssignmentToIfIntention/description.html new file mode 100644 index 00000000000..0491b178023 --- /dev/null +++ b/idea/resources/intentionDescriptions/UnfoldAssignmentToIfIntention/description.html @@ -0,0 +1,5 @@ + + +This intention converts assignment with 'if' right-hand side to 'if' expression where each branch is terminated with assignment + + \ No newline at end of file diff --git a/idea/resources/intentionDescriptions/UnfoldAssignmentToWhenIntention/after.kt.template b/idea/resources/intentionDescriptions/UnfoldAssignmentToWhenIntention/after.kt.template new file mode 100644 index 00000000000..a059e3024f7 --- /dev/null +++ b/idea/resources/intentionDescriptions/UnfoldAssignmentToWhenIntention/after.kt.template @@ -0,0 +1,5 @@ +when (n) { + 1 -> res = "one" + 2 -> res = "two" + else -> res = "many" +} \ No newline at end of file diff --git a/idea/resources/intentionDescriptions/UnfoldAssignmentToWhenIntention/before.kt.template b/idea/resources/intentionDescriptions/UnfoldAssignmentToWhenIntention/before.kt.template new file mode 100644 index 00000000000..12ecbd93619 --- /dev/null +++ b/idea/resources/intentionDescriptions/UnfoldAssignmentToWhenIntention/before.kt.template @@ -0,0 +1,5 @@ +res = when (n) { + 1 -> "one" + 2 -> "two" + else -> "many" +} \ No newline at end of file diff --git a/idea/resources/intentionDescriptions/UnfoldAssignmentToWhenIntention/description.html b/idea/resources/intentionDescriptions/UnfoldAssignmentToWhenIntention/description.html new file mode 100644 index 00000000000..5c034ae4b11 --- /dev/null +++ b/idea/resources/intentionDescriptions/UnfoldAssignmentToWhenIntention/description.html @@ -0,0 +1,5 @@ + + +This intention converts assignment with 'when' right-hand side to 'when' expression where each branch is terminated with assignment + + \ No newline at end of file diff --git a/idea/resources/intentionDescriptions/UnfoldBranchedExpressionIntention/after.kt.template b/idea/resources/intentionDescriptions/UnfoldBranchedExpressionIntention/after.kt.template deleted file mode 100644 index e61b2e5599b..00000000000 --- a/idea/resources/intentionDescriptions/UnfoldBranchedExpressionIntention/after.kt.template +++ /dev/null @@ -1,7 +0,0 @@ -if (n == 1) { - println("***") - res = "one" -} else { - println("***") - res = "two" -} \ No newline at end of file diff --git a/idea/resources/intentionDescriptions/UnfoldBranchedExpressionIntention/before.kt.template b/idea/resources/intentionDescriptions/UnfoldBranchedExpressionIntention/before.kt.template deleted file mode 100644 index 2a07dd895ee..00000000000 --- a/idea/resources/intentionDescriptions/UnfoldBranchedExpressionIntention/before.kt.template +++ /dev/null @@ -1,7 +0,0 @@ -res = if (n == 1) { - println("***") - "one" -} else { - println("***") - "two" -} \ No newline at end of file diff --git a/idea/resources/intentionDescriptions/UnfoldBranchedExpressionIntention/description.html b/idea/resources/intentionDescriptions/UnfoldBranchedExpressionIntention/description.html deleted file mode 100644 index e130de78a1b..00000000000 --- a/idea/resources/intentionDescriptions/UnfoldBranchedExpressionIntention/description.html +++ /dev/null @@ -1,6 +0,0 @@ - - -This intention converts assignment/return/method call with branched (if/when) expression as argument -to branched expression where each branch is terminated with assignment/return/method call - - \ No newline at end of file diff --git a/idea/resources/intentionDescriptions/UnfoldReturnToIfIntention/after.kt.template b/idea/resources/intentionDescriptions/UnfoldReturnToIfIntention/after.kt.template new file mode 100644 index 00000000000..2cdc1aaaa9f --- /dev/null +++ b/idea/resources/intentionDescriptions/UnfoldReturnToIfIntention/after.kt.template @@ -0,0 +1,5 @@ +if (ok) { + return "ok" +} else { + return "failed" +} \ No newline at end of file diff --git a/idea/resources/intentionDescriptions/UnfoldReturnToIfIntention/before.kt.template b/idea/resources/intentionDescriptions/UnfoldReturnToIfIntention/before.kt.template new file mode 100644 index 00000000000..0394cfc84c6 --- /dev/null +++ b/idea/resources/intentionDescriptions/UnfoldReturnToIfIntention/before.kt.template @@ -0,0 +1,5 @@ +return if (ok) { + "ok" +} else { + "failed" +} \ No newline at end of file diff --git a/idea/resources/intentionDescriptions/UnfoldReturnToIfIntention/description.html b/idea/resources/intentionDescriptions/UnfoldReturnToIfIntention/description.html new file mode 100644 index 00000000000..b6ed03a21f3 --- /dev/null +++ b/idea/resources/intentionDescriptions/UnfoldReturnToIfIntention/description.html @@ -0,0 +1,5 @@ + + +This intention converts 'return' with 'if' expression as a result to 'if' expression where each branch is terminated with 'return' + + \ No newline at end of file diff --git a/idea/resources/intentionDescriptions/UnfoldReturnToWhenIntention/after.kt.template b/idea/resources/intentionDescriptions/UnfoldReturnToWhenIntention/after.kt.template new file mode 100644 index 00000000000..9ea6721ea13 --- /dev/null +++ b/idea/resources/intentionDescriptions/UnfoldReturnToWhenIntention/after.kt.template @@ -0,0 +1,5 @@ +when (n) { + 1 -> return "one" + 2 -> return "two" + else -> return "many" +} \ No newline at end of file diff --git a/idea/resources/intentionDescriptions/UnfoldReturnToWhenIntention/before.kt.template b/idea/resources/intentionDescriptions/UnfoldReturnToWhenIntention/before.kt.template new file mode 100644 index 00000000000..ec9b48b8a9b --- /dev/null +++ b/idea/resources/intentionDescriptions/UnfoldReturnToWhenIntention/before.kt.template @@ -0,0 +1,5 @@ +return when (n) { + 1 -> "one" + 2 -> "two" + else -> "many" +} \ No newline at end of file diff --git a/idea/resources/intentionDescriptions/UnfoldReturnToWhenIntention/description.html b/idea/resources/intentionDescriptions/UnfoldReturnToWhenIntention/description.html new file mode 100644 index 00000000000..d28fc706aa2 --- /dev/null +++ b/idea/resources/intentionDescriptions/UnfoldReturnToWhenIntention/description.html @@ -0,0 +1,5 @@ + + +This intention converts 'return' with 'when' expression as a result to 'when' expression where each branch is terminated with 'return' + + \ No newline at end of file diff --git a/idea/src/META-INF/plugin.xml b/idea/src/META-INF/plugin.xml index abc42486aad..56dd14cd602 100644 --- a/idea/src/META-INF/plugin.xml +++ b/idea/src/META-INF/plugin.xml @@ -292,12 +292,47 @@ - org.jetbrains.jet.plugin.codeInsight.codeTransformations.branchedTransformations.FoldBranchedExpressionIntention + org.jetbrains.jet.plugin.codeInsight.codeTransformations.branchedTransformations.intentions.FoldIfToAssignmentIntention Kotlin - org.jetbrains.jet.plugin.codeInsight.codeTransformations.branchedTransformations.UnfoldBranchedExpressionIntention + org.jetbrains.jet.plugin.codeInsight.codeTransformations.branchedTransformations.intentions.FoldIfToReturnAsymmetricallyIntention + Kotlin + + + + org.jetbrains.jet.plugin.codeInsight.codeTransformations.branchedTransformations.intentions.FoldIfToReturnIntention + Kotlin + + + + org.jetbrains.jet.plugin.codeInsight.codeTransformations.branchedTransformations.intentions.FoldWhenToAssignmentIntention + Kotlin + + + + org.jetbrains.jet.plugin.codeInsight.codeTransformations.branchedTransformations.intentions.FoldWhenToReturnIntention + Kotlin + + + + org.jetbrains.jet.plugin.codeInsight.codeTransformations.branchedTransformations.intentions.UnfoldAssignmentToIfIntention + Kotlin + + + + org.jetbrains.jet.plugin.codeInsight.codeTransformations.branchedTransformations.intentions.UnfoldAssignmentToWhenIntention + Kotlin + + + + org.jetbrains.jet.plugin.codeInsight.codeTransformations.branchedTransformations.intentions.UnfoldReturnToIfIntention + Kotlin + + + + org.jetbrains.jet.plugin.codeInsight.codeTransformations.branchedTransformations.intentions.UnfoldReturnToWhenIntention Kotlin diff --git a/idea/src/org/jetbrains/jet/plugin/JetBundle.properties b/idea/src/org/jetbrains/jet/plugin/JetBundle.properties index 4447e0f40c9..39c51b4092c 100644 --- a/idea/src/org/jetbrains/jet/plugin/JetBundle.properties +++ b/idea/src/org/jetbrains/jet/plugin/JetBundle.properties @@ -152,6 +152,30 @@ surround.with.cannot.perform.action=Cannot perform Surround With action to the c remove.variable.family.name=Remove variable remove.variable.action=Remove variable ''{0}'' kotlin.code.transformations=Kotlin Code Transformations +fold.if.to.assignment=Replace 'if' expression with assignment +fold.if.to.assignment.family=Replace 'if' Expression with Assignment +fold.if.to.return=Replace 'if' expression with return +fold.if.to.return.family=Replace 'if' Expression with Return +fold.if.to.call=Replace 'if' expression with method call +fold.if.to.call.family=Replace 'if' Expression with Method Call +fold.when.to.assignment=Replace 'when' expression with assignment +fold.when.to.assignment.family=Replace 'when' Expression with Assignment +fold.when.to.return=Replace 'when' expression with return +fold.when.to.return.family=Replace 'when' Expression with Return +fold.when.to.call=Replace 'when' expression with method call +fold.when.to.call.family=Replace 'when' Expression with Method Call +unfold.assignment.to.if=Replace assignment with 'if' expression +unfold.assignment.to.if.family=Replace Assignment with 'if' Expression +unfold.return.to.if=Replace return with 'if' expression +unfold.return.to.if.family=Replace Return with 'if' Expression +unfold.call.to.if=Replace method call with 'if' expression +unfold.call.to.if.family=Replace Method Call with 'if' Expression +unfold.assignment.to.when=Replace assignment with 'when' expression +unfold.assignment.to.when.family=Replace Assignment with 'when' Expression +unfold.return.to.when=Replace return with 'when' expression +unfold.return.to.when.family=Replace Return with 'when' Expression +unfold.call.to.when=Replace method call with 'when' expression +unfold.call.to.when.family=Replace Method Call with 'when' Expressiontransform.if.statement.with.assignments.to.expression=Transform 'if' statement with assignments to expression transform.if.statement.with.assignments.to.expression=Transform 'if' statement with assignments to expression transform.assignment.with.if.expression.to.statement=Transform assignment with 'if' expression to statement transform.if.statement.with.assignments.to.expression.family=Transform 'if' Statement with Assignments to Expression diff --git a/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/FoldBranchedExpressionIntention.java b/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/AbstractCodeTransformationIntention.java similarity index 59% rename from idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/FoldBranchedExpressionIntention.java rename to idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/AbstractCodeTransformationIntention.java index 89e67823803..72aace46d98 100644 --- a/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/FoldBranchedExpressionIntention.java +++ b/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/AbstractCodeTransformationIntention.java @@ -16,6 +16,7 @@ package org.jetbrains.jet.plugin.codeInsight.codeTransformations.branchedTransformations; +import com.google.common.base.Predicate; import com.intellij.codeInsight.intention.impl.BaseIntentionAction; import com.intellij.openapi.editor.Editor; import com.intellij.openapi.project.Project; @@ -25,25 +26,38 @@ import com.intellij.util.IncorrectOperationException; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.jet.lang.psi.JetElement; -import org.jetbrains.jet.lang.psi.JetExpression; import org.jetbrains.jet.lang.psi.JetPsiUtil; import org.jetbrains.jet.plugin.JetBundle; +import org.jetbrains.jet.plugin.codeInsight.codeTransformations.branchedTransformations.core.Transformer; -public class FoldBranchedExpressionIntention extends BaseIntentionAction { - public FoldBranchedExpressionIntention() { - setText(JetBundle.message("fold.branched.expression")); +public abstract class AbstractCodeTransformationIntention extends BaseIntentionAction { + private final T transformer; + private final Predicate filter; + + protected AbstractCodeTransformationIntention(@NotNull T transformer, @NotNull Predicate filter) { + this.transformer = transformer; + this.filter = filter; + setText(JetBundle.message(transformer.getKey())); + } + + @Nullable + private PsiElement getTarget(@NotNull Editor editor, @NotNull PsiFile file) { + PsiElement element = file.findElementAt(editor.getCaretModel().getOffset()); + return JetPsiUtil.getParentByTypeAndPredicate(element, JetElement.class, filter, false); + } + + protected final T getTransformer() { + return transformer; + } + + protected final Predicate getFilter() { + return filter; } @NotNull @Override public String getFamilyName() { - return JetBundle.message("fold.branched.expression.family"); - } - - @Nullable - private static JetExpression getTarget(@NotNull Editor editor, @NotNull PsiFile file) { - PsiElement element = file.findElementAt(editor.getCaretModel().getOffset()); - return (JetExpression)JetPsiUtil.getParentByTypeAndPredicate(element, JetElement.class, BranchedFoldingUtils.FOLDABLE_EXPRESSION, false); + return JetBundle.message(transformer.getKey() + ".family"); } @Override @@ -53,10 +67,10 @@ public class FoldBranchedExpressionIntention extends BaseIntentionAction { @Override public void invoke(@NotNull Project project, @NotNull Editor editor, @NotNull PsiFile file) throws IncorrectOperationException { - JetExpression target = getTarget(editor, file); + PsiElement target = getTarget(editor, file); - assert target != null; + assert target != null : "Intention is not applicable"; - BranchedFoldingUtils.foldExpression(target); + transformer.transform(target); } } diff --git a/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/BranchedFoldingUtils.java b/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/BranchedFoldingUtils.java index 0ffb6a9188d..98b9c363e6c 100644 --- a/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/BranchedFoldingUtils.java +++ b/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/BranchedFoldingUtils.java @@ -138,26 +138,27 @@ public class BranchedFoldingUtils { return (nextElement instanceof JetExpression) && checkAndGetFoldableBranchedReturn((JetExpression)nextElement) != null; } - public static boolean checkFoldableExpression(@Nullable JetExpression root) { + @Nullable + public static FoldableKind getFoldableExpressionKind(@Nullable JetExpression root) { if (root instanceof JetIfExpression) { JetIfExpression ifExpression = (JetIfExpression)root; - return checkFoldableIfExpressionWithAssignments(ifExpression) || - checkFoldableIfExpressionWithReturns(ifExpression) || - checkFoldableIfExpressionWithAsymmetricReturns(ifExpression) ; - } - if (root instanceof JetWhenExpression) { + if (checkFoldableIfExpressionWithAssignments(ifExpression)) return FoldableKind.IF_TO_ASSIGNMENT; + if (checkFoldableIfExpressionWithReturns(ifExpression)) return FoldableKind.IF_TO_RETURN; + if (checkFoldableIfExpressionWithAsymmetricReturns(ifExpression)) return FoldableKind.IF_TO_RETURN_ASYMMETRICALLY; + } else if (root instanceof JetWhenExpression) { JetWhenExpression whenExpression = (JetWhenExpression)root; - return checkFoldableWhenExpressionWithAssignments(whenExpression) || - checkFoldableWhenExpressionWithReturns(whenExpression); + + if (checkFoldableWhenExpressionWithAssignments(whenExpression)) return FoldableKind.WHEN_TO_ASSIGNMENT; + if (checkFoldableWhenExpressionWithReturns(whenExpression)) return FoldableKind.WHEN_TO_RETURN; } - return false; + return null; } public static final String FOLD_WITHOUT_CHECK = "Expression must be checked before folding"; - private static void foldIfExpressionWithAssignments(JetIfExpression ifExpression) { + public static void foldIfExpressionWithAssignments(JetIfExpression ifExpression) { Project project = ifExpression.getProject(); JetBinaryExpression thenAssignment = checkAndGetFoldableBranchedAssignment(ifExpression.getThen()); @@ -189,7 +190,7 @@ public class BranchedFoldingUtils { elseAssignment.replace(elseRhs); } - private static void foldIfExpressionWithReturns(JetIfExpression ifExpression) { + public static void foldIfExpressionWithReturns(JetIfExpression ifExpression) { Project project = ifExpression.getProject(); JetReturnExpression returnExpr = (JetReturnExpression)ifExpression.replace(JetPsiFactory.createReturn(project, ifExpression)); @@ -213,7 +214,7 @@ public class BranchedFoldingUtils { elseReturn.replace(elseExpr); } - private static void foldIfExpressionWithAsymmetricReturns(JetIfExpression ifExpression) { + public static void foldIfExpressionWithAsymmetricReturns(JetIfExpression ifExpression) { Project project = ifExpression.getProject(); JetExpression condition = ifExpression.getCondition(); @@ -254,7 +255,7 @@ public class BranchedFoldingUtils { elseReturn.replace(elseExpr); } - private static void foldWhenExpressionWithAssignments(JetWhenExpression whenExpression) { + public static void foldWhenExpressionWithAssignments(JetWhenExpression whenExpression) { Project project = whenExpression.getProject(); assert !whenExpression.getEntries().isEmpty() : FOLD_WITHOUT_CHECK; @@ -285,7 +286,7 @@ public class BranchedFoldingUtils { } } - private static void foldWhenExpressionWithReturns(JetWhenExpression whenExpression) { + public static void foldWhenExpressionWithReturns(JetWhenExpression whenExpression) { Project project = whenExpression.getProject(); assert !whenExpression.getEntries().isEmpty() : FOLD_WITHOUT_CHECK; @@ -307,33 +308,4 @@ public class BranchedFoldingUtils { currReturn.replace(currExpr); } } - - public static void foldExpression(@Nullable JetExpression root) { - if (root instanceof JetIfExpression) { - JetIfExpression ifExpression = (JetIfExpression)root; - if (checkFoldableIfExpressionWithAssignments(ifExpression)) { - foldIfExpressionWithAssignments(ifExpression); - } else if (checkFoldableIfExpressionWithReturns(ifExpression)) { - foldIfExpressionWithReturns(ifExpression); - } else if (checkFoldableIfExpressionWithAsymmetricReturns(ifExpression)) { - foldIfExpressionWithAsymmetricReturns(ifExpression); - } - } - - if (root instanceof JetWhenExpression) { - JetWhenExpression whenExpression = (JetWhenExpression)root; - if (checkFoldableWhenExpressionWithAssignments(whenExpression)) { - foldWhenExpressionWithAssignments(whenExpression); - } else if (checkFoldableWhenExpressionWithReturns(whenExpression)) { - foldWhenExpressionWithReturns(whenExpression); - } - } - } - - public static final Predicate FOLDABLE_EXPRESSION = new Predicate() { - @Override - public boolean apply(@Nullable PsiElement input) { - return (input instanceof JetExpression) && checkFoldableExpression((JetExpression)input); - } - }; } diff --git a/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/BranchedUnfoldingUtils.java b/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/BranchedUnfoldingUtils.java index da88e10dc1b..074f383d385 100644 --- a/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/BranchedUnfoldingUtils.java +++ b/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/BranchedUnfoldingUtils.java @@ -27,31 +27,36 @@ public class BranchedUnfoldingUtils { private BranchedUnfoldingUtils() { } - private static boolean checkUnfoldableAssignment(@NotNull JetExpression expression) { - if (!JetPsiUtil.isAssignment(expression)) return false; - - JetBinaryExpression assignment = (JetBinaryExpression)expression; - return assignment.getLeft() instanceof JetSimpleNameExpression && JetPsiUtil.isBranchedExpression(assignment.getRight()); - } - - private static boolean checkUnfoldableReturn(@NotNull JetExpression expression) { - if (!(expression instanceof JetReturnExpression)) return false; - - JetReturnExpression returnExpression = (JetReturnExpression)expression; - return JetPsiUtil.isBranchedExpression(returnExpression.getReturnedExpression()); - } - - public static boolean checkUnfoldableExpression(@NotNull JetExpression root) { - return checkUnfoldableAssignment(root) || checkUnfoldableReturn(root); - } - private static JetExpression getOutermostLastBlockElement(@Nullable JetExpression expression) { return (JetExpression) JetPsiUtil.getOutermostLastBlockElement(expression, JetPsiUtil.ANY_JET_ELEMENT); } + @Nullable + public static UnfoldableKind getUnfoldableExpressionKind(@Nullable JetExpression root) { + if (root == null) return null; + + if (JetPsiUtil.isAssignment(root)) { + JetBinaryExpression assignment = (JetBinaryExpression)root; + JetExpression lhs = assignment.getLeft(); + JetExpression rhs = assignment.getRight(); + + if (!(lhs instanceof JetSimpleNameExpression)) return null; + + if (rhs instanceof JetIfExpression) return UnfoldableKind.ASSIGNMENT_TO_IF; + if (rhs instanceof JetWhenExpression) return UnfoldableKind.ASSIGNMENT_TO_WHEN; + } else if (root instanceof JetReturnExpression) { + JetExpression resultExpr = ((JetReturnExpression)root).getReturnedExpression(); + + if (resultExpr instanceof JetIfExpression) return UnfoldableKind.RETURN_TO_IF; + if (resultExpr instanceof JetWhenExpression) return UnfoldableKind.RETURN_TO_WHEN; + } + + return null; + } + public static final String UNFOLD_WITHOUT_CHECK = "Expression must be checked before unfolding"; - private static void unfoldAssignmentToIf(@NotNull JetBinaryExpression assignment) { + public static void unfoldAssignmentToIf(@NotNull JetBinaryExpression assignment) { Project project = assignment.getProject(); String op = assignment.getOperationReference().getText(); String lhsText = assignment.getLeft().getText(); @@ -71,7 +76,7 @@ public class BranchedUnfoldingUtils { elseExpr.replace(JetPsiFactory.createBinaryExpression(project, JetPsiFactory.createExpression(project, lhsText), op, elseExpr)); } - private static void unfoldAssignmentToWhen(@NotNull JetBinaryExpression assignment) { + public static void unfoldAssignmentToWhen(@NotNull JetBinaryExpression assignment) { Project project = assignment.getProject(); String op = assignment.getOperationReference().getText(); JetExpression lhs = (JetExpression)assignment.getLeft().copy(); @@ -90,7 +95,7 @@ public class BranchedUnfoldingUtils { } } - private static void unfoldReturnToIf(@NotNull JetReturnExpression returnExpression) { + public static void unfoldReturnToIf(@NotNull JetReturnExpression returnExpression) { Project project = returnExpression.getProject(); JetIfExpression ifExpression = (JetIfExpression)returnExpression.getReturnedExpression(); @@ -108,7 +113,7 @@ public class BranchedUnfoldingUtils { elseExpr.replace(JetPsiFactory.createReturn(project, elseExpr)); } - private static void unfoldReturnToWhen(@NotNull JetReturnExpression returnExpression) { + public static void unfoldReturnToWhen(@NotNull JetReturnExpression returnExpression) { Project project = returnExpression.getProject(); JetWhenExpression whenExpression = (JetWhenExpression)returnExpression.getReturnedExpression(); @@ -124,29 +129,4 @@ public class BranchedUnfoldingUtils { currExpr.replace(JetPsiFactory.createReturn(project, currExpr)); } } - - public static void unfoldExpression(@NotNull JetExpression root) { - if (checkUnfoldableAssignment(root)) { - JetBinaryExpression assignment = (JetBinaryExpression)root; - if (assignment.getRight() instanceof JetIfExpression) { - unfoldAssignmentToIf(assignment); - } else if (assignment.getRight() instanceof JetWhenExpression) { - unfoldAssignmentToWhen(assignment); - } - } else if (checkUnfoldableReturn(root)) { - JetReturnExpression returnExpression = (JetReturnExpression)root; - if (returnExpression.getReturnedExpression() instanceof JetIfExpression) { - unfoldReturnToIf(returnExpression); - } else if (returnExpression.getReturnedExpression() instanceof JetWhenExpression) { - unfoldReturnToWhen(returnExpression); - } - } - } - - public static final Predicate UNFOLDABLE_EXPRESSION = new Predicate() { - @Override - public boolean apply(@Nullable PsiElement input) { - return (input instanceof JetExpression) && checkUnfoldableExpression((JetExpression)input); - } - }; } diff --git a/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/FoldableKind.java b/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/FoldableKind.java new file mode 100644 index 00000000000..0bc3b8e9ac1 --- /dev/null +++ b/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/FoldableKind.java @@ -0,0 +1,68 @@ +/* + * Copyright 2010-2013 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance TO the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * TOOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.jetbrains.jet.plugin.codeInsight.codeTransformations.branchedTransformations; + +import com.intellij.psi.PsiElement; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.jet.lang.psi.JetIfExpression; +import org.jetbrains.jet.lang.psi.JetWhenExpression; +import org.jetbrains.jet.plugin.codeInsight.codeTransformations.branchedTransformations.core.Transformer; + +public enum FoldableKind implements Transformer { + IF_TO_ASSIGNMENT("fold.if.to.assignment") { + @Override + public void transform(@NotNull PsiElement element) { + BranchedFoldingUtils.foldIfExpressionWithAssignments((JetIfExpression) element); + } + }, + IF_TO_RETURN("fold.if.to.return") { + @Override + public void transform(@NotNull PsiElement element) { + BranchedFoldingUtils.foldIfExpressionWithReturns((JetIfExpression) element); + } + }, + IF_TO_RETURN_ASYMMETRICALLY("fold.if.to.return") { + @Override + public void transform(@NotNull PsiElement element) { + BranchedFoldingUtils.foldIfExpressionWithAsymmetricReturns((JetIfExpression) element); + } + }, + WHEN_TO_ASSIGNMENT("fold.when.to.assignment") { + @Override + public void transform(@NotNull PsiElement element) { + BranchedFoldingUtils.foldWhenExpressionWithAssignments((JetWhenExpression) element); + } + }, + WHEN_TO_RETURN("fold.when.to.return") { + @Override + public void transform(@NotNull PsiElement element) { + BranchedFoldingUtils.foldWhenExpressionWithReturns((JetWhenExpression) element); + } + }; + + private final String key; + + private FoldableKind(String key) { + this.key = key; + } + + @NotNull + @Override + public String getKey() { + return key; + } +} diff --git a/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/UnfoldBranchedExpressionIntention.java b/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/UnfoldBranchedExpressionIntention.java deleted file mode 100644 index 61cd20886e5..00000000000 --- a/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/UnfoldBranchedExpressionIntention.java +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Copyright 2010-2013 JetBrains s.r.o. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.jetbrains.jet.plugin.codeInsight.codeTransformations.branchedTransformations; - -import com.intellij.codeInsight.intention.impl.BaseIntentionAction; -import com.intellij.openapi.editor.Editor; -import com.intellij.openapi.project.Project; -import com.intellij.psi.PsiElement; -import com.intellij.psi.PsiFile; -import com.intellij.util.IncorrectOperationException; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; -import org.jetbrains.jet.lang.psi.JetElement; -import org.jetbrains.jet.lang.psi.JetExpression; -import org.jetbrains.jet.lang.psi.JetPsiUtil; -import org.jetbrains.jet.plugin.JetBundle; - -public class UnfoldBranchedExpressionIntention extends BaseIntentionAction { - public UnfoldBranchedExpressionIntention() { - setText(JetBundle.message("unfold.branched.expression")); - } - - @NotNull - @Override - public String getFamilyName() { - return JetBundle.message("unfold.branched.expression.family"); - } - - @Nullable - private static JetExpression getTarget(@NotNull Editor editor, @NotNull PsiFile file) { - PsiElement element = file.findElementAt(editor.getCaretModel().getOffset()); - return (JetExpression)JetPsiUtil.getParentByTypeAndPredicate(element, JetElement.class, BranchedUnfoldingUtils.UNFOLDABLE_EXPRESSION, false); - } - - @Override - public boolean isAvailable(@NotNull Project project, @NotNull Editor editor, @NotNull PsiFile file) { - return getTarget(editor, file) != null; - } - - @Override - public void invoke(@NotNull Project project, @NotNull Editor editor, @NotNull PsiFile file) throws IncorrectOperationException { - JetExpression target = getTarget(editor, file); - - assert target != null; - - BranchedUnfoldingUtils.unfoldExpression(target); - } -} diff --git a/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/UnfoldableKind.java b/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/UnfoldableKind.java new file mode 100644 index 00000000000..c27b330118f --- /dev/null +++ b/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/UnfoldableKind.java @@ -0,0 +1,62 @@ +/* + * Copyright 2010-2013 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.jetbrains.jet.plugin.codeInsight.codeTransformations.branchedTransformations; + +import com.intellij.psi.PsiElement; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.jet.lang.psi.JetBinaryExpression; +import org.jetbrains.jet.lang.psi.JetReturnExpression; +import org.jetbrains.jet.plugin.codeInsight.codeTransformations.branchedTransformations.core.Transformer; + +public enum UnfoldableKind implements Transformer { + ASSIGNMENT_TO_IF("unfold.assignment.to.if") { + @Override + public void transform(@NotNull PsiElement element) { + BranchedUnfoldingUtils.unfoldAssignmentToIf((JetBinaryExpression) element); + } + }, + RETURN_TO_IF("unfold.return.to.if") { + @Override + public void transform(@NotNull PsiElement element) { + BranchedUnfoldingUtils.unfoldReturnToIf((JetReturnExpression) element); + } + }, + ASSIGNMENT_TO_WHEN("unfold.assignment.to.when") { + @Override + public void transform(@NotNull PsiElement element) { + BranchedUnfoldingUtils.unfoldAssignmentToWhen((JetBinaryExpression) element); + } + }, + RETURN_TO_WHEN("unfold.return.to.when") { + @Override + public void transform(@NotNull PsiElement element) { + BranchedUnfoldingUtils.unfoldReturnToWhen((JetReturnExpression) element); + } + }; + + private final String key; + + private UnfoldableKind(String key) { + this.key = key; + } + + @NotNull + @Override + public String getKey() { + return key; + } +} diff --git a/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/core/Transformer.java b/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/core/Transformer.java new file mode 100644 index 00000000000..a2ce45fed31 --- /dev/null +++ b/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/core/Transformer.java @@ -0,0 +1,25 @@ +/* + * Copyright 2010-2013 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.jetbrains.jet.plugin.codeInsight.codeTransformations.branchedTransformations.core; + +import com.intellij.psi.PsiElement; +import org.jetbrains.annotations.NotNull; + +public interface Transformer { + public @NotNull String getKey(); + public void transform(@NotNull PsiElement element); +} diff --git a/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/intentions/FoldBranchedExpressionIntention.java b/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/intentions/FoldBranchedExpressionIntention.java new file mode 100644 index 00000000000..e61bcce509f --- /dev/null +++ b/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/intentions/FoldBranchedExpressionIntention.java @@ -0,0 +1,40 @@ +/* + * Copyright 2010-2013 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.jetbrains.jet.plugin.codeInsight.codeTransformations.branchedTransformations.intentions; + +import com.google.common.base.Predicate; +import com.intellij.psi.PsiElement; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import org.jetbrains.jet.lang.psi.JetExpression; +import org.jetbrains.jet.plugin.codeInsight.codeTransformations.branchedTransformations.AbstractCodeTransformationIntention; +import org.jetbrains.jet.plugin.codeInsight.codeTransformations.branchedTransformations.BranchedFoldingUtils; +import org.jetbrains.jet.plugin.codeInsight.codeTransformations.branchedTransformations.FoldableKind; + +public abstract class FoldBranchedExpressionIntention extends AbstractCodeTransformationIntention { + protected FoldBranchedExpressionIntention(@NotNull final FoldableKind foldableKind) { + super( + foldableKind, + new Predicate() { + @Override + public boolean apply(@Nullable PsiElement input) { + return (input instanceof JetExpression) && BranchedFoldingUtils.getFoldableExpressionKind((JetExpression) input) == foldableKind; + } + } + ); + } +} diff --git a/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/intentions/FoldIfToAssignmentIntention.java b/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/intentions/FoldIfToAssignmentIntention.java new file mode 100644 index 00000000000..30b2466f232 --- /dev/null +++ b/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/intentions/FoldIfToAssignmentIntention.java @@ -0,0 +1,25 @@ +/* + * Copyright 2010-2013 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.jetbrains.jet.plugin.codeInsight.codeTransformations.branchedTransformations.intentions; + +import org.jetbrains.jet.plugin.codeInsight.codeTransformations.branchedTransformations.FoldableKind; + +public class FoldIfToAssignmentIntention extends FoldBranchedExpressionIntention { + public FoldIfToAssignmentIntention() { + super(FoldableKind.IF_TO_ASSIGNMENT); + } +} diff --git a/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/intentions/FoldIfToReturnAsymmetricallyIntention.java b/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/intentions/FoldIfToReturnAsymmetricallyIntention.java new file mode 100644 index 00000000000..128ecf8a25a --- /dev/null +++ b/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/intentions/FoldIfToReturnAsymmetricallyIntention.java @@ -0,0 +1,25 @@ +/* + * Copyright 2010-2013 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.jetbrains.jet.plugin.codeInsight.codeTransformations.branchedTransformations.intentions; + +import org.jetbrains.jet.plugin.codeInsight.codeTransformations.branchedTransformations.FoldableKind; + +public class FoldIfToReturnAsymmetricallyIntention extends FoldBranchedExpressionIntention { + public FoldIfToReturnAsymmetricallyIntention() { + super(FoldableKind.IF_TO_RETURN_ASYMMETRICALLY); + } +} diff --git a/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/intentions/FoldIfToReturnIntention.java b/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/intentions/FoldIfToReturnIntention.java new file mode 100644 index 00000000000..a63fd84b868 --- /dev/null +++ b/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/intentions/FoldIfToReturnIntention.java @@ -0,0 +1,25 @@ +/* + * Copyright 2010-2013 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.jetbrains.jet.plugin.codeInsight.codeTransformations.branchedTransformations.intentions; + +import org.jetbrains.jet.plugin.codeInsight.codeTransformations.branchedTransformations.FoldableKind; + +public class FoldIfToReturnIntention extends FoldBranchedExpressionIntention { + public FoldIfToReturnIntention() { + super(FoldableKind.IF_TO_RETURN); + } +} diff --git a/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/intentions/FoldWhenToAssignmentIntention.java b/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/intentions/FoldWhenToAssignmentIntention.java new file mode 100644 index 00000000000..3c307dc3b3d --- /dev/null +++ b/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/intentions/FoldWhenToAssignmentIntention.java @@ -0,0 +1,25 @@ +/* + * Copyright 2010-2013 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.jetbrains.jet.plugin.codeInsight.codeTransformations.branchedTransformations.intentions; + +import org.jetbrains.jet.plugin.codeInsight.codeTransformations.branchedTransformations.FoldableKind; + +public class FoldWhenToAssignmentIntention extends FoldBranchedExpressionIntention { + public FoldWhenToAssignmentIntention() { + super(FoldableKind.WHEN_TO_ASSIGNMENT); + } +} diff --git a/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/intentions/FoldWhenToReturnIntention.java b/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/intentions/FoldWhenToReturnIntention.java new file mode 100644 index 00000000000..fd1bc61726c --- /dev/null +++ b/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/intentions/FoldWhenToReturnIntention.java @@ -0,0 +1,25 @@ +/* + * Copyright 2010-2013 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.jetbrains.jet.plugin.codeInsight.codeTransformations.branchedTransformations.intentions; + +import org.jetbrains.jet.plugin.codeInsight.codeTransformations.branchedTransformations.FoldableKind; + +public class FoldWhenToReturnIntention extends FoldBranchedExpressionIntention { + public FoldWhenToReturnIntention() { + super(FoldableKind.WHEN_TO_RETURN); + } +} diff --git a/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/intentions/UnfoldAssignmentToIfIntention.java b/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/intentions/UnfoldAssignmentToIfIntention.java new file mode 100644 index 00000000000..a0db1a07526 --- /dev/null +++ b/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/intentions/UnfoldAssignmentToIfIntention.java @@ -0,0 +1,25 @@ +/* + * Copyright 2010-2013 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.jetbrains.jet.plugin.codeInsight.codeTransformations.branchedTransformations.intentions; + +import org.jetbrains.jet.plugin.codeInsight.codeTransformations.branchedTransformations.UnfoldableKind; + +public class UnfoldAssignmentToIfIntention extends UnfoldBranchedExpressionIntention { + public UnfoldAssignmentToIfIntention() { + super(UnfoldableKind.ASSIGNMENT_TO_IF); + } +} diff --git a/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/intentions/UnfoldAssignmentToWhenIntention.java b/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/intentions/UnfoldAssignmentToWhenIntention.java new file mode 100644 index 00000000000..102c65ddd1f --- /dev/null +++ b/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/intentions/UnfoldAssignmentToWhenIntention.java @@ -0,0 +1,25 @@ +/* + * Copyright 2010-2013 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.jetbrains.jet.plugin.codeInsight.codeTransformations.branchedTransformations.intentions; + +import org.jetbrains.jet.plugin.codeInsight.codeTransformations.branchedTransformations.UnfoldableKind; + +public class UnfoldAssignmentToWhenIntention extends UnfoldBranchedExpressionIntention { + public UnfoldAssignmentToWhenIntention() { + super(UnfoldableKind.ASSIGNMENT_TO_WHEN); + } +} diff --git a/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/intentions/UnfoldBranchedExpressionIntention.java b/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/intentions/UnfoldBranchedExpressionIntention.java new file mode 100644 index 00000000000..6d21ec4afa9 --- /dev/null +++ b/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/intentions/UnfoldBranchedExpressionIntention.java @@ -0,0 +1,38 @@ +/* + * Copyright 2010-2013 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.jetbrains.jet.plugin.codeInsight.codeTransformations.branchedTransformations.intentions; + +import com.google.common.base.Predicate; +import com.intellij.psi.PsiElement; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import org.jetbrains.jet.lang.psi.JetExpression; +import org.jetbrains.jet.plugin.codeInsight.codeTransformations.branchedTransformations.*; + +public abstract class UnfoldBranchedExpressionIntention extends AbstractCodeTransformationIntention { + protected UnfoldBranchedExpressionIntention(@NotNull final UnfoldableKind unfoldableKind) { + super( + unfoldableKind, + new Predicate() { + @Override + public boolean apply(@Nullable PsiElement input) { + return (input instanceof JetExpression) && BranchedUnfoldingUtils.getUnfoldableExpressionKind((JetExpression) input) == unfoldableKind; + } + } + ); + } +} diff --git a/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/intentions/UnfoldReturnToIfIntention.java b/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/intentions/UnfoldReturnToIfIntention.java new file mode 100644 index 00000000000..4018d2dcfc2 --- /dev/null +++ b/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/intentions/UnfoldReturnToIfIntention.java @@ -0,0 +1,25 @@ +/* + * Copyright 2010-2013 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.jetbrains.jet.plugin.codeInsight.codeTransformations.branchedTransformations.intentions; + +import org.jetbrains.jet.plugin.codeInsight.codeTransformations.branchedTransformations.UnfoldableKind; + +public class UnfoldReturnToIfIntention extends UnfoldBranchedExpressionIntention { + public UnfoldReturnToIfIntention() { + super(UnfoldableKind.RETURN_TO_IF); + } +} diff --git a/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/intentions/UnfoldReturnToWhenIntention.java b/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/intentions/UnfoldReturnToWhenIntention.java new file mode 100644 index 00000000000..156954aada1 --- /dev/null +++ b/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/intentions/UnfoldReturnToWhenIntention.java @@ -0,0 +1,25 @@ +/* + * Copyright 2010-2013 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.jetbrains.jet.plugin.codeInsight.codeTransformations.branchedTransformations.intentions; + +import org.jetbrains.jet.plugin.codeInsight.codeTransformations.branchedTransformations.UnfoldableKind; + +public class UnfoldReturnToWhenIntention extends UnfoldBranchedExpressionIntention { + public UnfoldReturnToWhenIntention() { + super(UnfoldableKind.RETURN_TO_WHEN); + } +} diff --git a/idea/testData/codeInsight/codeTransformations/branched/folding/assignment/innerIfTransformed.kt b/idea/testData/codeInsight/codeTransformations/branched/folding/ifToAssignment/innerIfTransformed.kt similarity index 100% rename from idea/testData/codeInsight/codeTransformations/branched/folding/assignment/innerIfTransformed.kt rename to idea/testData/codeInsight/codeTransformations/branched/folding/ifToAssignment/innerIfTransformed.kt diff --git a/idea/testData/codeInsight/codeTransformations/branched/folding/assignment/innerIfTransformed.kt.after b/idea/testData/codeInsight/codeTransformations/branched/folding/ifToAssignment/innerIfTransformed.kt.after similarity index 100% rename from idea/testData/codeInsight/codeTransformations/branched/folding/assignment/innerIfTransformed.kt.after rename to idea/testData/codeInsight/codeTransformations/branched/folding/ifToAssignment/innerIfTransformed.kt.after diff --git a/idea/testData/codeInsight/codeTransformations/branched/folding/assignment/simpleIf.kt b/idea/testData/codeInsight/codeTransformations/branched/folding/ifToAssignment/simpleIf.kt similarity index 100% rename from idea/testData/codeInsight/codeTransformations/branched/folding/assignment/simpleIf.kt rename to idea/testData/codeInsight/codeTransformations/branched/folding/ifToAssignment/simpleIf.kt diff --git a/idea/testData/codeInsight/codeTransformations/branched/folding/assignment/simpleIf.kt.after b/idea/testData/codeInsight/codeTransformations/branched/folding/ifToAssignment/simpleIf.kt.after similarity index 100% rename from idea/testData/codeInsight/codeTransformations/branched/folding/assignment/simpleIf.kt.after rename to idea/testData/codeInsight/codeTransformations/branched/folding/ifToAssignment/simpleIf.kt.after diff --git a/idea/testData/codeInsight/codeTransformations/branched/folding/assignment/simpleIfWithAugmentedAssignment.kt b/idea/testData/codeInsight/codeTransformations/branched/folding/ifToAssignment/simpleIfWithAugmentedAssignment.kt similarity index 100% rename from idea/testData/codeInsight/codeTransformations/branched/folding/assignment/simpleIfWithAugmentedAssignment.kt rename to idea/testData/codeInsight/codeTransformations/branched/folding/ifToAssignment/simpleIfWithAugmentedAssignment.kt diff --git a/idea/testData/codeInsight/codeTransformations/branched/folding/assignment/simpleIfWithAugmentedAssignment.kt.after b/idea/testData/codeInsight/codeTransformations/branched/folding/ifToAssignment/simpleIfWithAugmentedAssignment.kt.after similarity index 100% rename from idea/testData/codeInsight/codeTransformations/branched/folding/assignment/simpleIfWithAugmentedAssignment.kt.after rename to idea/testData/codeInsight/codeTransformations/branched/folding/ifToAssignment/simpleIfWithAugmentedAssignment.kt.after diff --git a/idea/testData/codeInsight/codeTransformations/branched/folding/assignment/simpleIfWithBlocks.kt b/idea/testData/codeInsight/codeTransformations/branched/folding/ifToAssignment/simpleIfWithBlocks.kt similarity index 100% rename from idea/testData/codeInsight/codeTransformations/branched/folding/assignment/simpleIfWithBlocks.kt rename to idea/testData/codeInsight/codeTransformations/branched/folding/ifToAssignment/simpleIfWithBlocks.kt diff --git a/idea/testData/codeInsight/codeTransformations/branched/folding/assignment/simpleIfWithBlocks.kt.after b/idea/testData/codeInsight/codeTransformations/branched/folding/ifToAssignment/simpleIfWithBlocks.kt.after similarity index 100% rename from idea/testData/codeInsight/codeTransformations/branched/folding/assignment/simpleIfWithBlocks.kt.after rename to idea/testData/codeInsight/codeTransformations/branched/folding/ifToAssignment/simpleIfWithBlocks.kt.after diff --git a/idea/testData/codeInsight/codeTransformations/branched/folding/assignment/simpleIfWithShadowedVar.kt b/idea/testData/codeInsight/codeTransformations/branched/folding/ifToAssignment/simpleIfWithShadowedVar.kt similarity index 100% rename from idea/testData/codeInsight/codeTransformations/branched/folding/assignment/simpleIfWithShadowedVar.kt rename to idea/testData/codeInsight/codeTransformations/branched/folding/ifToAssignment/simpleIfWithShadowedVar.kt diff --git a/idea/testData/codeInsight/codeTransformations/branched/folding/assignment/simpleIfWithUnmatchedAssignmentOps.kt b/idea/testData/codeInsight/codeTransformations/branched/folding/ifToAssignment/simpleIfWithUnmatchedAssignmentOps.kt similarity index 100% rename from idea/testData/codeInsight/codeTransformations/branched/folding/assignment/simpleIfWithUnmatchedAssignmentOps.kt rename to idea/testData/codeInsight/codeTransformations/branched/folding/ifToAssignment/simpleIfWithUnmatchedAssignmentOps.kt diff --git a/idea/testData/codeInsight/codeTransformations/branched/folding/assignment/simpleIfWithUnmatchedAssignments.kt b/idea/testData/codeInsight/codeTransformations/branched/folding/ifToAssignment/simpleIfWithUnmatchedAssignments.kt similarity index 100% rename from idea/testData/codeInsight/codeTransformations/branched/folding/assignment/simpleIfWithUnmatchedAssignments.kt rename to idea/testData/codeInsight/codeTransformations/branched/folding/ifToAssignment/simpleIfWithUnmatchedAssignments.kt diff --git a/idea/testData/codeInsight/codeTransformations/branched/folding/assignment/simpleIfWithoutElse.kt b/idea/testData/codeInsight/codeTransformations/branched/folding/ifToAssignment/simpleIfWithoutElse.kt similarity index 100% rename from idea/testData/codeInsight/codeTransformations/branched/folding/assignment/simpleIfWithoutElse.kt rename to idea/testData/codeInsight/codeTransformations/branched/folding/ifToAssignment/simpleIfWithoutElse.kt diff --git a/idea/testData/codeInsight/codeTransformations/branched/folding/assignment/simpleIfWithoutTerminatingAssignment.kt b/idea/testData/codeInsight/codeTransformations/branched/folding/ifToAssignment/simpleIfWithoutTerminatingAssignment.kt similarity index 100% rename from idea/testData/codeInsight/codeTransformations/branched/folding/assignment/simpleIfWithoutTerminatingAssignment.kt rename to idea/testData/codeInsight/codeTransformations/branched/folding/ifToAssignment/simpleIfWithoutTerminatingAssignment.kt diff --git a/idea/testData/codeInsight/codeTransformations/branched/folding/return/innerIfTransformed.kt b/idea/testData/codeInsight/codeTransformations/branched/folding/ifToReturn/innerIfTransformed.kt similarity index 100% rename from idea/testData/codeInsight/codeTransformations/branched/folding/return/innerIfTransformed.kt rename to idea/testData/codeInsight/codeTransformations/branched/folding/ifToReturn/innerIfTransformed.kt diff --git a/idea/testData/codeInsight/codeTransformations/branched/folding/return/innerIfTransformed.kt.after b/idea/testData/codeInsight/codeTransformations/branched/folding/ifToReturn/innerIfTransformed.kt.after similarity index 100% rename from idea/testData/codeInsight/codeTransformations/branched/folding/return/innerIfTransformed.kt.after rename to idea/testData/codeInsight/codeTransformations/branched/folding/ifToReturn/innerIfTransformed.kt.after diff --git a/idea/testData/codeInsight/codeTransformations/branched/folding/return/simpleIf.kt b/idea/testData/codeInsight/codeTransformations/branched/folding/ifToReturn/simpleIf.kt similarity index 100% rename from idea/testData/codeInsight/codeTransformations/branched/folding/return/simpleIf.kt rename to idea/testData/codeInsight/codeTransformations/branched/folding/ifToReturn/simpleIf.kt diff --git a/idea/testData/codeInsight/codeTransformations/branched/folding/return/simpleIf.kt.after b/idea/testData/codeInsight/codeTransformations/branched/folding/ifToReturn/simpleIf.kt.after similarity index 100% rename from idea/testData/codeInsight/codeTransformations/branched/folding/return/simpleIf.kt.after rename to idea/testData/codeInsight/codeTransformations/branched/folding/ifToReturn/simpleIf.kt.after diff --git a/idea/testData/codeInsight/codeTransformations/branched/folding/return/simpleIfWithBlocks.kt b/idea/testData/codeInsight/codeTransformations/branched/folding/ifToReturn/simpleIfWithBlocks.kt similarity index 100% rename from idea/testData/codeInsight/codeTransformations/branched/folding/return/simpleIfWithBlocks.kt rename to idea/testData/codeInsight/codeTransformations/branched/folding/ifToReturn/simpleIfWithBlocks.kt diff --git a/idea/testData/codeInsight/codeTransformations/branched/folding/return/simpleIfWithBlocks.kt.after b/idea/testData/codeInsight/codeTransformations/branched/folding/ifToReturn/simpleIfWithBlocks.kt.after similarity index 100% rename from idea/testData/codeInsight/codeTransformations/branched/folding/return/simpleIfWithBlocks.kt.after rename to idea/testData/codeInsight/codeTransformations/branched/folding/ifToReturn/simpleIfWithBlocks.kt.after diff --git a/idea/testData/codeInsight/codeTransformations/branched/folding/asymmetricReturn/simpleIf.kt b/idea/testData/codeInsight/codeTransformations/branched/folding/ifToReturnAsymmetrically/simpleIf.kt similarity index 100% rename from idea/testData/codeInsight/codeTransformations/branched/folding/asymmetricReturn/simpleIf.kt rename to idea/testData/codeInsight/codeTransformations/branched/folding/ifToReturnAsymmetrically/simpleIf.kt diff --git a/idea/testData/codeInsight/codeTransformations/branched/folding/asymmetricReturn/simpleIf.kt.after b/idea/testData/codeInsight/codeTransformations/branched/folding/ifToReturnAsymmetrically/simpleIf.kt.after similarity index 100% rename from idea/testData/codeInsight/codeTransformations/branched/folding/asymmetricReturn/simpleIf.kt.after rename to idea/testData/codeInsight/codeTransformations/branched/folding/ifToReturnAsymmetrically/simpleIf.kt.after diff --git a/idea/testData/codeInsight/codeTransformations/branched/folding/asymmetricReturn/simpleIfWithBlocks.kt b/idea/testData/codeInsight/codeTransformations/branched/folding/ifToReturnAsymmetrically/simpleIfWithBlocks.kt similarity index 100% rename from idea/testData/codeInsight/codeTransformations/branched/folding/asymmetricReturn/simpleIfWithBlocks.kt rename to idea/testData/codeInsight/codeTransformations/branched/folding/ifToReturnAsymmetrically/simpleIfWithBlocks.kt diff --git a/idea/testData/codeInsight/codeTransformations/branched/folding/asymmetricReturn/simpleIfWithBlocks.kt.after b/idea/testData/codeInsight/codeTransformations/branched/folding/ifToReturnAsymmetrically/simpleIfWithBlocks.kt.after similarity index 100% rename from idea/testData/codeInsight/codeTransformations/branched/folding/asymmetricReturn/simpleIfWithBlocks.kt.after rename to idea/testData/codeInsight/codeTransformations/branched/folding/ifToReturnAsymmetrically/simpleIfWithBlocks.kt.after diff --git a/idea/testData/codeInsight/codeTransformations/branched/folding/asymmetricReturn/simpleIfWithComments.kt b/idea/testData/codeInsight/codeTransformations/branched/folding/ifToReturnAsymmetrically/simpleIfWithComments.kt similarity index 100% rename from idea/testData/codeInsight/codeTransformations/branched/folding/asymmetricReturn/simpleIfWithComments.kt rename to idea/testData/codeInsight/codeTransformations/branched/folding/ifToReturnAsymmetrically/simpleIfWithComments.kt diff --git a/idea/testData/codeInsight/codeTransformations/branched/folding/asymmetricReturn/simpleIfWithComments.kt.after b/idea/testData/codeInsight/codeTransformations/branched/folding/ifToReturnAsymmetrically/simpleIfWithComments.kt.after similarity index 100% rename from idea/testData/codeInsight/codeTransformations/branched/folding/asymmetricReturn/simpleIfWithComments.kt.after rename to idea/testData/codeInsight/codeTransformations/branched/folding/ifToReturnAsymmetrically/simpleIfWithComments.kt.after diff --git a/idea/testData/codeInsight/codeTransformations/branched/folding/assignment/innerWhenTransformed.kt b/idea/testData/codeInsight/codeTransformations/branched/folding/whenToAssignment/innerWhenTransformed.kt similarity index 100% rename from idea/testData/codeInsight/codeTransformations/branched/folding/assignment/innerWhenTransformed.kt rename to idea/testData/codeInsight/codeTransformations/branched/folding/whenToAssignment/innerWhenTransformed.kt diff --git a/idea/testData/codeInsight/codeTransformations/branched/folding/assignment/innerWhenTransformed.kt.after b/idea/testData/codeInsight/codeTransformations/branched/folding/whenToAssignment/innerWhenTransformed.kt.after similarity index 100% rename from idea/testData/codeInsight/codeTransformations/branched/folding/assignment/innerWhenTransformed.kt.after rename to idea/testData/codeInsight/codeTransformations/branched/folding/whenToAssignment/innerWhenTransformed.kt.after diff --git a/idea/testData/codeInsight/codeTransformations/branched/folding/assignment/simpleWhen.kt b/idea/testData/codeInsight/codeTransformations/branched/folding/whenToAssignment/simpleWhen.kt similarity index 100% rename from idea/testData/codeInsight/codeTransformations/branched/folding/assignment/simpleWhen.kt rename to idea/testData/codeInsight/codeTransformations/branched/folding/whenToAssignment/simpleWhen.kt diff --git a/idea/testData/codeInsight/codeTransformations/branched/folding/assignment/simpleWhen.kt.after b/idea/testData/codeInsight/codeTransformations/branched/folding/whenToAssignment/simpleWhen.kt.after similarity index 100% rename from idea/testData/codeInsight/codeTransformations/branched/folding/assignment/simpleWhen.kt.after rename to idea/testData/codeInsight/codeTransformations/branched/folding/whenToAssignment/simpleWhen.kt.after diff --git a/idea/testData/codeInsight/codeTransformations/branched/folding/assignment/simpleWhenWithBlocks.kt b/idea/testData/codeInsight/codeTransformations/branched/folding/whenToAssignment/simpleWhenWithBlocks.kt similarity index 100% rename from idea/testData/codeInsight/codeTransformations/branched/folding/assignment/simpleWhenWithBlocks.kt rename to idea/testData/codeInsight/codeTransformations/branched/folding/whenToAssignment/simpleWhenWithBlocks.kt diff --git a/idea/testData/codeInsight/codeTransformations/branched/folding/assignment/simpleWhenWithBlocks.kt.after b/idea/testData/codeInsight/codeTransformations/branched/folding/whenToAssignment/simpleWhenWithBlocks.kt.after similarity index 100% rename from idea/testData/codeInsight/codeTransformations/branched/folding/assignment/simpleWhenWithBlocks.kt.after rename to idea/testData/codeInsight/codeTransformations/branched/folding/whenToAssignment/simpleWhenWithBlocks.kt.after diff --git a/idea/testData/codeInsight/codeTransformations/branched/folding/assignment/simpleWhenWithShadowedVar.kt b/idea/testData/codeInsight/codeTransformations/branched/folding/whenToAssignment/simpleWhenWithShadowedVar.kt similarity index 100% rename from idea/testData/codeInsight/codeTransformations/branched/folding/assignment/simpleWhenWithShadowedVar.kt rename to idea/testData/codeInsight/codeTransformations/branched/folding/whenToAssignment/simpleWhenWithShadowedVar.kt diff --git a/idea/testData/codeInsight/codeTransformations/branched/folding/assignment/simpleWhenWithUnmatchedAssignments.kt b/idea/testData/codeInsight/codeTransformations/branched/folding/whenToAssignment/simpleWhenWithUnmatchedAssignments.kt similarity index 100% rename from idea/testData/codeInsight/codeTransformations/branched/folding/assignment/simpleWhenWithUnmatchedAssignments.kt rename to idea/testData/codeInsight/codeTransformations/branched/folding/whenToAssignment/simpleWhenWithUnmatchedAssignments.kt diff --git a/idea/testData/codeInsight/codeTransformations/branched/folding/assignment/simpleWhenWithoutTerminatingAssignment.kt b/idea/testData/codeInsight/codeTransformations/branched/folding/whenToAssignment/simpleWhenWithoutTerminatingAssignment.kt similarity index 100% rename from idea/testData/codeInsight/codeTransformations/branched/folding/assignment/simpleWhenWithoutTerminatingAssignment.kt rename to idea/testData/codeInsight/codeTransformations/branched/folding/whenToAssignment/simpleWhenWithoutTerminatingAssignment.kt diff --git a/idea/testData/codeInsight/codeTransformations/branched/folding/return/innerWhenTransformed.kt b/idea/testData/codeInsight/codeTransformations/branched/folding/whenToReturn/innerWhenTransformed.kt similarity index 100% rename from idea/testData/codeInsight/codeTransformations/branched/folding/return/innerWhenTransformed.kt rename to idea/testData/codeInsight/codeTransformations/branched/folding/whenToReturn/innerWhenTransformed.kt diff --git a/idea/testData/codeInsight/codeTransformations/branched/folding/return/innerWhenTransformed.kt.after b/idea/testData/codeInsight/codeTransformations/branched/folding/whenToReturn/innerWhenTransformed.kt.after similarity index 100% rename from idea/testData/codeInsight/codeTransformations/branched/folding/return/innerWhenTransformed.kt.after rename to idea/testData/codeInsight/codeTransformations/branched/folding/whenToReturn/innerWhenTransformed.kt.after diff --git a/idea/testData/codeInsight/codeTransformations/branched/folding/return/simpleWhen.kt b/idea/testData/codeInsight/codeTransformations/branched/folding/whenToReturn/simpleWhen.kt similarity index 100% rename from idea/testData/codeInsight/codeTransformations/branched/folding/return/simpleWhen.kt rename to idea/testData/codeInsight/codeTransformations/branched/folding/whenToReturn/simpleWhen.kt diff --git a/idea/testData/codeInsight/codeTransformations/branched/folding/return/simpleWhen.kt.after b/idea/testData/codeInsight/codeTransformations/branched/folding/whenToReturn/simpleWhen.kt.after similarity index 100% rename from idea/testData/codeInsight/codeTransformations/branched/folding/return/simpleWhen.kt.after rename to idea/testData/codeInsight/codeTransformations/branched/folding/whenToReturn/simpleWhen.kt.after diff --git a/idea/testData/codeInsight/codeTransformations/branched/folding/return/simpleWhenWithBlocks.kt b/idea/testData/codeInsight/codeTransformations/branched/folding/whenToReturn/simpleWhenWithBlocks.kt similarity index 100% rename from idea/testData/codeInsight/codeTransformations/branched/folding/return/simpleWhenWithBlocks.kt rename to idea/testData/codeInsight/codeTransformations/branched/folding/whenToReturn/simpleWhenWithBlocks.kt diff --git a/idea/testData/codeInsight/codeTransformations/branched/folding/return/simpleWhenWithBlocks.kt.after b/idea/testData/codeInsight/codeTransformations/branched/folding/whenToReturn/simpleWhenWithBlocks.kt.after similarity index 100% rename from idea/testData/codeInsight/codeTransformations/branched/folding/return/simpleWhenWithBlocks.kt.after rename to idea/testData/codeInsight/codeTransformations/branched/folding/whenToReturn/simpleWhenWithBlocks.kt.after diff --git a/idea/testData/codeInsight/codeTransformations/branched/unfolding/assignment/innerIfTransformed.kt b/idea/testData/codeInsight/codeTransformations/branched/unfolding/assignmentToIf/innerIfTransformed.kt similarity index 100% rename from idea/testData/codeInsight/codeTransformations/branched/unfolding/assignment/innerIfTransformed.kt rename to idea/testData/codeInsight/codeTransformations/branched/unfolding/assignmentToIf/innerIfTransformed.kt diff --git a/idea/testData/codeInsight/codeTransformations/branched/unfolding/assignment/innerIfTransformed.kt.after b/idea/testData/codeInsight/codeTransformations/branched/unfolding/assignmentToIf/innerIfTransformed.kt.after similarity index 100% rename from idea/testData/codeInsight/codeTransformations/branched/unfolding/assignment/innerIfTransformed.kt.after rename to idea/testData/codeInsight/codeTransformations/branched/unfolding/assignmentToIf/innerIfTransformed.kt.after diff --git a/idea/testData/codeInsight/codeTransformations/branched/unfolding/assignment/nestedIfs.kt b/idea/testData/codeInsight/codeTransformations/branched/unfolding/assignmentToIf/nestedIfs.kt similarity index 100% rename from idea/testData/codeInsight/codeTransformations/branched/unfolding/assignment/nestedIfs.kt rename to idea/testData/codeInsight/codeTransformations/branched/unfolding/assignmentToIf/nestedIfs.kt diff --git a/idea/testData/codeInsight/codeTransformations/branched/unfolding/assignment/nestedIfs.kt.after b/idea/testData/codeInsight/codeTransformations/branched/unfolding/assignmentToIf/nestedIfs.kt.after similarity index 100% rename from idea/testData/codeInsight/codeTransformations/branched/unfolding/assignment/nestedIfs.kt.after rename to idea/testData/codeInsight/codeTransformations/branched/unfolding/assignmentToIf/nestedIfs.kt.after diff --git a/idea/testData/codeInsight/codeTransformations/branched/unfolding/assignment/simpleIf.kt b/idea/testData/codeInsight/codeTransformations/branched/unfolding/assignmentToIf/simpleIf.kt similarity index 100% rename from idea/testData/codeInsight/codeTransformations/branched/unfolding/assignment/simpleIf.kt rename to idea/testData/codeInsight/codeTransformations/branched/unfolding/assignmentToIf/simpleIf.kt diff --git a/idea/testData/codeInsight/codeTransformations/branched/unfolding/assignment/simpleIf.kt.after b/idea/testData/codeInsight/codeTransformations/branched/unfolding/assignmentToIf/simpleIf.kt.after similarity index 100% rename from idea/testData/codeInsight/codeTransformations/branched/unfolding/assignment/simpleIf.kt.after rename to idea/testData/codeInsight/codeTransformations/branched/unfolding/assignmentToIf/simpleIf.kt.after diff --git a/idea/testData/codeInsight/codeTransformations/branched/unfolding/assignment/simpleIfWithAugmentedAssignment.kt b/idea/testData/codeInsight/codeTransformations/branched/unfolding/assignmentToIf/simpleIfWithAugmentedAssignment.kt similarity index 100% rename from idea/testData/codeInsight/codeTransformations/branched/unfolding/assignment/simpleIfWithAugmentedAssignment.kt rename to idea/testData/codeInsight/codeTransformations/branched/unfolding/assignmentToIf/simpleIfWithAugmentedAssignment.kt diff --git a/idea/testData/codeInsight/codeTransformations/branched/unfolding/assignment/simpleIfWithAugmentedAssignment.kt.after b/idea/testData/codeInsight/codeTransformations/branched/unfolding/assignmentToIf/simpleIfWithAugmentedAssignment.kt.after similarity index 100% rename from idea/testData/codeInsight/codeTransformations/branched/unfolding/assignment/simpleIfWithAugmentedAssignment.kt.after rename to idea/testData/codeInsight/codeTransformations/branched/unfolding/assignmentToIf/simpleIfWithAugmentedAssignment.kt.after diff --git a/idea/testData/codeInsight/codeTransformations/branched/unfolding/assignment/simpleIfWithBlocks.kt b/idea/testData/codeInsight/codeTransformations/branched/unfolding/assignmentToIf/simpleIfWithBlocks.kt similarity index 100% rename from idea/testData/codeInsight/codeTransformations/branched/unfolding/assignment/simpleIfWithBlocks.kt rename to idea/testData/codeInsight/codeTransformations/branched/unfolding/assignmentToIf/simpleIfWithBlocks.kt diff --git a/idea/testData/codeInsight/codeTransformations/branched/unfolding/assignment/simpleIfWithBlocks.kt.after b/idea/testData/codeInsight/codeTransformations/branched/unfolding/assignmentToIf/simpleIfWithBlocks.kt.after similarity index 100% rename from idea/testData/codeInsight/codeTransformations/branched/unfolding/assignment/simpleIfWithBlocks.kt.after rename to idea/testData/codeInsight/codeTransformations/branched/unfolding/assignmentToIf/simpleIfWithBlocks.kt.after diff --git a/idea/testData/codeInsight/codeTransformations/branched/unfolding/assignment/simpleIfWithoutAssignment.kt b/idea/testData/codeInsight/codeTransformations/branched/unfolding/assignmentToIf/simpleIfWithoutAssignment.kt similarity index 100% rename from idea/testData/codeInsight/codeTransformations/branched/unfolding/assignment/simpleIfWithoutAssignment.kt rename to idea/testData/codeInsight/codeTransformations/branched/unfolding/assignmentToIf/simpleIfWithoutAssignment.kt diff --git a/idea/testData/codeInsight/codeTransformations/branched/unfolding/return/innerIfTransformed.kt b/idea/testData/codeInsight/codeTransformations/branched/unfolding/returnToIf/innerIfTransformed.kt similarity index 100% rename from idea/testData/codeInsight/codeTransformations/branched/unfolding/return/innerIfTransformed.kt rename to idea/testData/codeInsight/codeTransformations/branched/unfolding/returnToIf/innerIfTransformed.kt diff --git a/idea/testData/codeInsight/codeTransformations/branched/unfolding/return/innerIfTransformed.kt.after b/idea/testData/codeInsight/codeTransformations/branched/unfolding/returnToIf/innerIfTransformed.kt.after similarity index 100% rename from idea/testData/codeInsight/codeTransformations/branched/unfolding/return/innerIfTransformed.kt.after rename to idea/testData/codeInsight/codeTransformations/branched/unfolding/returnToIf/innerIfTransformed.kt.after diff --git a/idea/testData/codeInsight/codeTransformations/branched/unfolding/return/simpleIf.kt b/idea/testData/codeInsight/codeTransformations/branched/unfolding/returnToIf/simpleIf.kt similarity index 100% rename from idea/testData/codeInsight/codeTransformations/branched/unfolding/return/simpleIf.kt rename to idea/testData/codeInsight/codeTransformations/branched/unfolding/returnToIf/simpleIf.kt diff --git a/idea/testData/codeInsight/codeTransformations/branched/unfolding/return/simpleIf.kt.after b/idea/testData/codeInsight/codeTransformations/branched/unfolding/returnToIf/simpleIf.kt.after similarity index 100% rename from idea/testData/codeInsight/codeTransformations/branched/unfolding/return/simpleIf.kt.after rename to idea/testData/codeInsight/codeTransformations/branched/unfolding/returnToIf/simpleIf.kt.after diff --git a/idea/testData/codeInsight/codeTransformations/branched/unfolding/return/simpleIfWithBlocks.kt b/idea/testData/codeInsight/codeTransformations/branched/unfolding/returnToIf/simpleIfWithBlocks.kt similarity index 100% rename from idea/testData/codeInsight/codeTransformations/branched/unfolding/return/simpleIfWithBlocks.kt rename to idea/testData/codeInsight/codeTransformations/branched/unfolding/returnToIf/simpleIfWithBlocks.kt diff --git a/idea/testData/codeInsight/codeTransformations/branched/unfolding/return/simpleIfWithBlocks.kt.after b/idea/testData/codeInsight/codeTransformations/branched/unfolding/returnToIf/simpleIfWithBlocks.kt.after similarity index 100% rename from idea/testData/codeInsight/codeTransformations/branched/unfolding/return/simpleIfWithBlocks.kt.after rename to idea/testData/codeInsight/codeTransformations/branched/unfolding/returnToIf/simpleIfWithBlocks.kt.after diff --git a/idea/tests/org/jetbrains/jet/plugin/codeInsight/codeTransformations/AbstractCodeTransformationTest.java b/idea/tests/org/jetbrains/jet/plugin/codeInsight/codeTransformations/AbstractCodeTransformationTest.java index 4c904907a81..4d7e40e9de1 100644 --- a/idea/tests/org/jetbrains/jet/plugin/codeInsight/codeTransformations/AbstractCodeTransformationTest.java +++ b/idea/tests/org/jetbrains/jet/plugin/codeInsight/codeTransformations/AbstractCodeTransformationTest.java @@ -21,18 +21,45 @@ import com.intellij.openapi.util.io.FileUtil; import com.intellij.testFramework.LightCodeInsightTestCase; import org.jetbrains.annotations.NotNull; import org.jetbrains.jet.InTextDirectivesUtils; -import org.jetbrains.jet.plugin.codeInsight.codeTransformations.branchedTransformations.FoldBranchedExpressionIntention; -import org.jetbrains.jet.plugin.codeInsight.codeTransformations.branchedTransformations.UnfoldBranchedExpressionIntention; +import org.jetbrains.jet.plugin.codeInsight.codeTransformations.branchedTransformations.intentions.*; import java.io.File; public abstract class AbstractCodeTransformationTest extends LightCodeInsightTestCase { - public void doTestBranchedFolding(@NotNull String path) throws Exception { - doTest(path, new FoldBranchedExpressionIntention()); + public void doTestFoldIfToAssignment(@NotNull String path) throws Exception { + doTest(path, new FoldIfToAssignmentIntention()); } - public void doTestBranchedUnfolding(@NotNull String path) throws Exception { - doTest(path, new UnfoldBranchedExpressionIntention()); + public void doTestFoldIfToReturn(@NotNull String path) throws Exception { + doTest(path, new FoldIfToReturnIntention()); + } + + public void doTestFoldIfToReturnAsymmetrically(@NotNull String path) throws Exception { + doTest(path, new FoldIfToReturnAsymmetricallyIntention()); + } + + public void doTestFoldWhenToAssignment(@NotNull String path) throws Exception { + doTest(path, new FoldWhenToAssignmentIntention()); + } + + public void doTestFoldWhenToReturn(@NotNull String path) throws Exception { + doTest(path, new FoldWhenToReturnIntention()); + } + + public void doTestUnfoldAssignmentToIf(@NotNull String path) throws Exception { + doTest(path, new UnfoldAssignmentToIfIntention()); + } + + public void doTestUnfoldAssignmentToWhen(@NotNull String path) throws Exception { + doTest(path, new UnfoldAssignmentToWhenIntention()); + } + + public void doTestUnfoldReturnToIf(@NotNull String path) throws Exception { + doTest(path, new UnfoldReturnToIfIntention()); + } + + public void doTestUnfoldReturnToWhen(@NotNull String path) throws Exception { + doTest(path, new UnfoldAssignmentToIfIntention()); } public void doTestRemoveUnnecessaryParentheses(@NotNull String path) throws Exception { diff --git a/idea/tests/org/jetbrains/jet/plugin/codeInsight/codeTransformations/CodeTransformationsTestGenerated.java b/idea/tests/org/jetbrains/jet/plugin/codeInsight/codeTransformations/CodeTransformationsTestGenerated.java index 573c6bdaa89..7313beab78e 100644 --- a/idea/tests/org/jetbrains/jet/plugin/codeInsight/codeTransformations/CodeTransformationsTestGenerated.java +++ b/idea/tests/org/jetbrains/jet/plugin/codeInsight/codeTransformations/CodeTransformationsTestGenerated.java @@ -30,250 +30,238 @@ import org.jetbrains.jet.plugin.codeInsight.codeTransformations.AbstractCodeTran /** This class is generated by {@link org.jetbrains.jet.generators.tests.GenerateTests}. DO NOT MODIFY MANUALLY */ @SuppressWarnings("all") -@InnerTestClasses({CodeTransformationsTestGenerated.Folding.class, CodeTransformationsTestGenerated.Unfolding.class}) +@InnerTestClasses({CodeTransformationsTestGenerated.IfToAssignment.class, CodeTransformationsTestGenerated.IfToReturn.class, CodeTransformationsTestGenerated.IfToReturnAsymmetrically.class, CodeTransformationsTestGenerated.WhenToAssignment.class, CodeTransformationsTestGenerated.WhenToReturn.class, CodeTransformationsTestGenerated.AssignmentToIf.class, CodeTransformationsTestGenerated.ReturnToIf.class}) public class CodeTransformationsTestGenerated extends AbstractCodeTransformationTest { - @TestMetadata("idea/testData/codeInsight/codeTransformations/branched/folding") - @InnerTestClasses({Folding.Assignment.class, Folding.AsymmetricReturn.class, Folding.Return.class}) - public static class Folding extends AbstractCodeTransformationTest { - public void testAllFilesPresentInFolding() throws Exception { - JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.GenerateTests", new File("idea/testData/codeInsight/codeTransformations/branched/folding"), Pattern.compile("^(.+)\\.kt$"), true); + @TestMetadata("idea/testData/codeInsight/codeTransformations/branched/folding/ifToAssignment") + public static class IfToAssignment extends AbstractCodeTransformationTest { + public void testAllFilesPresentInIfToAssignment() throws Exception { + JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.GenerateTests", new File("idea/testData/codeInsight/codeTransformations/branched/folding/ifToAssignment"), Pattern.compile("^(.+)\\.kt$"), true); } - @TestMetadata("idea/testData/codeInsight/codeTransformations/branched/folding/assignment") - public static class Assignment extends AbstractCodeTransformationTest { - public void testAllFilesPresentInAssignment() throws Exception { - JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.GenerateTests", new File("idea/testData/codeInsight/codeTransformations/branched/folding/assignment"), Pattern.compile("^(.+)\\.kt$"), true); - } - - @TestMetadata("innerIfTransformed.kt") - public void testInnerIfTransformed() throws Exception { - doTestBranchedFolding("idea/testData/codeInsight/codeTransformations/branched/folding/assignment/innerIfTransformed.kt"); - } - - @TestMetadata("innerWhenTransformed.kt") - public void testInnerWhenTransformed() throws Exception { - doTestBranchedFolding("idea/testData/codeInsight/codeTransformations/branched/folding/assignment/innerWhenTransformed.kt"); - } - - @TestMetadata("simpleIf.kt") - public void testSimpleIf() throws Exception { - doTestBranchedFolding("idea/testData/codeInsight/codeTransformations/branched/folding/assignment/simpleIf.kt"); - } - - @TestMetadata("simpleIfWithAugmentedAssignment.kt") - public void testSimpleIfWithAugmentedAssignment() throws Exception { - doTestBranchedFolding("idea/testData/codeInsight/codeTransformations/branched/folding/assignment/simpleIfWithAugmentedAssignment.kt"); - } - - @TestMetadata("simpleIfWithBlocks.kt") - public void testSimpleIfWithBlocks() throws Exception { - doTestBranchedFolding("idea/testData/codeInsight/codeTransformations/branched/folding/assignment/simpleIfWithBlocks.kt"); - } - - @TestMetadata("simpleIfWithShadowedVar.kt") - public void testSimpleIfWithShadowedVar() throws Exception { - doTestBranchedFolding("idea/testData/codeInsight/codeTransformations/branched/folding/assignment/simpleIfWithShadowedVar.kt"); - } - - @TestMetadata("simpleIfWithUnmatchedAssignmentOps.kt") - public void testSimpleIfWithUnmatchedAssignmentOps() throws Exception { - doTestBranchedFolding("idea/testData/codeInsight/codeTransformations/branched/folding/assignment/simpleIfWithUnmatchedAssignmentOps.kt"); - } - - @TestMetadata("simpleIfWithUnmatchedAssignments.kt") - public void testSimpleIfWithUnmatchedAssignments() throws Exception { - doTestBranchedFolding("idea/testData/codeInsight/codeTransformations/branched/folding/assignment/simpleIfWithUnmatchedAssignments.kt"); - } - - @TestMetadata("simpleIfWithoutElse.kt") - public void testSimpleIfWithoutElse() throws Exception { - doTestBranchedFolding("idea/testData/codeInsight/codeTransformations/branched/folding/assignment/simpleIfWithoutElse.kt"); - } - - @TestMetadata("simpleIfWithoutTerminatingAssignment.kt") - public void testSimpleIfWithoutTerminatingAssignment() throws Exception { - doTestBranchedFolding("idea/testData/codeInsight/codeTransformations/branched/folding/assignment/simpleIfWithoutTerminatingAssignment.kt"); - } - - @TestMetadata("simpleWhen.kt") - public void testSimpleWhen() throws Exception { - doTestBranchedFolding("idea/testData/codeInsight/codeTransformations/branched/folding/assignment/simpleWhen.kt"); - } - - @TestMetadata("simpleWhenWithBlocks.kt") - public void testSimpleWhenWithBlocks() throws Exception { - doTestBranchedFolding("idea/testData/codeInsight/codeTransformations/branched/folding/assignment/simpleWhenWithBlocks.kt"); - } - - @TestMetadata("simpleWhenWithShadowedVar.kt") - public void testSimpleWhenWithShadowedVar() throws Exception { - doTestBranchedFolding("idea/testData/codeInsight/codeTransformations/branched/folding/assignment/simpleWhenWithShadowedVar.kt"); - } - - @TestMetadata("simpleWhenWithUnmatchedAssignments.kt") - public void testSimpleWhenWithUnmatchedAssignments() throws Exception { - doTestBranchedFolding("idea/testData/codeInsight/codeTransformations/branched/folding/assignment/simpleWhenWithUnmatchedAssignments.kt"); - } - - @TestMetadata("simpleWhenWithoutTerminatingAssignment.kt") - public void testSimpleWhenWithoutTerminatingAssignment() throws Exception { - doTestBranchedFolding("idea/testData/codeInsight/codeTransformations/branched/folding/assignment/simpleWhenWithoutTerminatingAssignment.kt"); - } - + @TestMetadata("innerIfTransformed.kt") + public void testInnerIfTransformed() throws Exception { + doTestFoldIfToAssignment("idea/testData/codeInsight/codeTransformations/branched/folding/ifToAssignment/innerIfTransformed.kt"); } - @TestMetadata("idea/testData/codeInsight/codeTransformations/branched/folding/asymmetricReturn") - public static class AsymmetricReturn extends AbstractCodeTransformationTest { - public void testAllFilesPresentInAsymmetricReturn() throws Exception { - JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.GenerateTests", new File("idea/testData/codeInsight/codeTransformations/branched/folding/asymmetricReturn"), Pattern.compile("^(.+)\\.kt$"), true); - } - - @TestMetadata("simpleIf.kt") - public void testSimpleIf() throws Exception { - doTestBranchedFolding("idea/testData/codeInsight/codeTransformations/branched/folding/asymmetricReturn/simpleIf.kt"); - } - - @TestMetadata("simpleIfWithBlocks.kt") - public void testSimpleIfWithBlocks() throws Exception { - doTestBranchedFolding("idea/testData/codeInsight/codeTransformations/branched/folding/asymmetricReturn/simpleIfWithBlocks.kt"); - } - - @TestMetadata("simpleIfWithComments.kt") - public void testSimpleIfWithComments() throws Exception { - doTestBranchedFolding("idea/testData/codeInsight/codeTransformations/branched/folding/asymmetricReturn/simpleIfWithComments.kt"); - } - + @TestMetadata("simpleIf.kt") + public void testSimpleIf() throws Exception { + doTestFoldIfToAssignment("idea/testData/codeInsight/codeTransformations/branched/folding/ifToAssignment/simpleIf.kt"); } - @TestMetadata("idea/testData/codeInsight/codeTransformations/branched/folding/return") - public static class Return extends AbstractCodeTransformationTest { - public void testAllFilesPresentInReturn() throws Exception { - JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.GenerateTests", new File("idea/testData/codeInsight/codeTransformations/branched/folding/return"), Pattern.compile("^(.+)\\.kt$"), true); - } - - @TestMetadata("innerIfTransformed.kt") - public void testInnerIfTransformed() throws Exception { - doTestBranchedFolding("idea/testData/codeInsight/codeTransformations/branched/folding/return/innerIfTransformed.kt"); - } - - @TestMetadata("innerWhenTransformed.kt") - public void testInnerWhenTransformed() throws Exception { - doTestBranchedFolding("idea/testData/codeInsight/codeTransformations/branched/folding/return/innerWhenTransformed.kt"); - } - - @TestMetadata("simpleIf.kt") - public void testSimpleIf() throws Exception { - doTestBranchedFolding("idea/testData/codeInsight/codeTransformations/branched/folding/return/simpleIf.kt"); - } - - @TestMetadata("simpleIfWithBlocks.kt") - public void testSimpleIfWithBlocks() throws Exception { - doTestBranchedFolding("idea/testData/codeInsight/codeTransformations/branched/folding/return/simpleIfWithBlocks.kt"); - } - - @TestMetadata("simpleWhen.kt") - public void testSimpleWhen() throws Exception { - doTestBranchedFolding("idea/testData/codeInsight/codeTransformations/branched/folding/return/simpleWhen.kt"); - } - - @TestMetadata("simpleWhenWithBlocks.kt") - public void testSimpleWhenWithBlocks() throws Exception { - doTestBranchedFolding("idea/testData/codeInsight/codeTransformations/branched/folding/return/simpleWhenWithBlocks.kt"); - } - + @TestMetadata("simpleIfWithAugmentedAssignment.kt") + public void testSimpleIfWithAugmentedAssignment() throws Exception { + doTestFoldIfToAssignment("idea/testData/codeInsight/codeTransformations/branched/folding/ifToAssignment/simpleIfWithAugmentedAssignment.kt"); } - public static Test innerSuite() { - TestSuite suite = new TestSuite("Folding"); - suite.addTestSuite(Folding.class); - suite.addTestSuite(Assignment.class); - suite.addTestSuite(AsymmetricReturn.class); - suite.addTestSuite(Return.class); - return suite; + @TestMetadata("simpleIfWithBlocks.kt") + public void testSimpleIfWithBlocks() throws Exception { + doTestFoldIfToAssignment("idea/testData/codeInsight/codeTransformations/branched/folding/ifToAssignment/simpleIfWithBlocks.kt"); } + + @TestMetadata("simpleIfWithShadowedVar.kt") + public void testSimpleIfWithShadowedVar() throws Exception { + doTestFoldIfToAssignment("idea/testData/codeInsight/codeTransformations/branched/folding/ifToAssignment/simpleIfWithShadowedVar.kt"); + } + + @TestMetadata("simpleIfWithUnmatchedAssignmentOps.kt") + public void testSimpleIfWithUnmatchedAssignmentOps() throws Exception { + doTestFoldIfToAssignment("idea/testData/codeInsight/codeTransformations/branched/folding/ifToAssignment/simpleIfWithUnmatchedAssignmentOps.kt"); + } + + @TestMetadata("simpleIfWithUnmatchedAssignments.kt") + public void testSimpleIfWithUnmatchedAssignments() throws Exception { + doTestFoldIfToAssignment("idea/testData/codeInsight/codeTransformations/branched/folding/ifToAssignment/simpleIfWithUnmatchedAssignments.kt"); + } + + @TestMetadata("simpleIfWithoutElse.kt") + public void testSimpleIfWithoutElse() throws Exception { + doTestFoldIfToAssignment("idea/testData/codeInsight/codeTransformations/branched/folding/ifToAssignment/simpleIfWithoutElse.kt"); + } + + @TestMetadata("simpleIfWithoutTerminatingAssignment.kt") + public void testSimpleIfWithoutTerminatingAssignment() throws Exception { + doTestFoldIfToAssignment("idea/testData/codeInsight/codeTransformations/branched/folding/ifToAssignment/simpleIfWithoutTerminatingAssignment.kt"); + } + } - @TestMetadata("idea/testData/codeInsight/codeTransformations/branched/unfolding") - @InnerTestClasses({Unfolding.Assignment.class, Unfolding.Return.class}) - public static class Unfolding extends AbstractCodeTransformationTest { - public void testAllFilesPresentInUnfolding() throws Exception { - JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.GenerateTests", new File("idea/testData/codeInsight/codeTransformations/branched/unfolding"), Pattern.compile("^(.+)\\.kt$"), true); + @TestMetadata("idea/testData/codeInsight/codeTransformations/branched/folding/ifToReturn") + public static class IfToReturn extends AbstractCodeTransformationTest { + public void testAllFilesPresentInIfToReturn() throws Exception { + JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.GenerateTests", new File("idea/testData/codeInsight/codeTransformations/branched/folding/ifToReturn"), Pattern.compile("^(.+)\\.kt$"), true); } - @TestMetadata("idea/testData/codeInsight/codeTransformations/branched/unfolding/assignment") - public static class Assignment extends AbstractCodeTransformationTest { - public void testAllFilesPresentInAssignment() throws Exception { - JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.GenerateTests", new File("idea/testData/codeInsight/codeTransformations/branched/unfolding/assignment"), Pattern.compile("^(.+)\\.kt$"), true); - } - - @TestMetadata("innerIfTransformed.kt") - public void testInnerIfTransformed() throws Exception { - doTestBranchedUnfolding("idea/testData/codeInsight/codeTransformations/branched/unfolding/assignment/innerIfTransformed.kt"); - } - - @TestMetadata("nestedIfs.kt") - public void testNestedIfs() throws Exception { - doTestBranchedUnfolding("idea/testData/codeInsight/codeTransformations/branched/unfolding/assignment/nestedIfs.kt"); - } - - @TestMetadata("simpleIf.kt") - public void testSimpleIf() throws Exception { - doTestBranchedUnfolding("idea/testData/codeInsight/codeTransformations/branched/unfolding/assignment/simpleIf.kt"); - } - - @TestMetadata("simpleIfWithAugmentedAssignment.kt") - public void testSimpleIfWithAugmentedAssignment() throws Exception { - doTestBranchedUnfolding("idea/testData/codeInsight/codeTransformations/branched/unfolding/assignment/simpleIfWithAugmentedAssignment.kt"); - } - - @TestMetadata("simpleIfWithBlocks.kt") - public void testSimpleIfWithBlocks() throws Exception { - doTestBranchedUnfolding("idea/testData/codeInsight/codeTransformations/branched/unfolding/assignment/simpleIfWithBlocks.kt"); - } - - @TestMetadata("simpleIfWithoutAssignment.kt") - public void testSimpleIfWithoutAssignment() throws Exception { - doTestBranchedUnfolding("idea/testData/codeInsight/codeTransformations/branched/unfolding/assignment/simpleIfWithoutAssignment.kt"); - } - + @TestMetadata("innerIfTransformed.kt") + public void testInnerIfTransformed() throws Exception { + doTestFoldIfToReturn("idea/testData/codeInsight/codeTransformations/branched/folding/ifToReturn/innerIfTransformed.kt"); } - @TestMetadata("idea/testData/codeInsight/codeTransformations/branched/unfolding/return") - public static class Return extends AbstractCodeTransformationTest { - public void testAllFilesPresentInReturn() throws Exception { - JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.GenerateTests", new File("idea/testData/codeInsight/codeTransformations/branched/unfolding/return"), Pattern.compile("^(.+)\\.kt$"), true); - } - - @TestMetadata("innerIfTransformed.kt") - public void testInnerIfTransformed() throws Exception { - doTestBranchedUnfolding("idea/testData/codeInsight/codeTransformations/branched/unfolding/return/innerIfTransformed.kt"); - } - - @TestMetadata("simpleIf.kt") - public void testSimpleIf() throws Exception { - doTestBranchedUnfolding("idea/testData/codeInsight/codeTransformations/branched/unfolding/return/simpleIf.kt"); - } - - @TestMetadata("simpleIfWithBlocks.kt") - public void testSimpleIfWithBlocks() throws Exception { - doTestBranchedUnfolding("idea/testData/codeInsight/codeTransformations/branched/unfolding/return/simpleIfWithBlocks.kt"); - } - + @TestMetadata("simpleIf.kt") + public void testSimpleIf() throws Exception { + doTestFoldIfToReturn("idea/testData/codeInsight/codeTransformations/branched/folding/ifToReturn/simpleIf.kt"); } - public static Test innerSuite() { - TestSuite suite = new TestSuite("Unfolding"); - suite.addTestSuite(Unfolding.class); - suite.addTestSuite(Assignment.class); - suite.addTestSuite(Return.class); - return suite; + @TestMetadata("simpleIfWithBlocks.kt") + public void testSimpleIfWithBlocks() throws Exception { + doTestFoldIfToReturn("idea/testData/codeInsight/codeTransformations/branched/folding/ifToReturn/simpleIfWithBlocks.kt"); } + + } + + @TestMetadata("idea/testData/codeInsight/codeTransformations/branched/folding/ifToReturnAsymmetrically") + public static class IfToReturnAsymmetrically extends AbstractCodeTransformationTest { + public void testAllFilesPresentInIfToReturnAsymmetrically() throws Exception { + JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.GenerateTests", new File("idea/testData/codeInsight/codeTransformations/branched/folding/ifToReturnAsymmetrically"), Pattern.compile("^(.+)\\.kt$"), true); + } + + @TestMetadata("simpleIf.kt") + public void testSimpleIf() throws Exception { + doTestFoldIfToReturnAsymmetrically("idea/testData/codeInsight/codeTransformations/branched/folding/ifToReturnAsymmetrically/simpleIf.kt"); + } + + @TestMetadata("simpleIfWithBlocks.kt") + public void testSimpleIfWithBlocks() throws Exception { + doTestFoldIfToReturnAsymmetrically("idea/testData/codeInsight/codeTransformations/branched/folding/ifToReturnAsymmetrically/simpleIfWithBlocks.kt"); + } + + @TestMetadata("simpleIfWithComments.kt") + public void testSimpleIfWithComments() throws Exception { + doTestFoldIfToReturnAsymmetrically("idea/testData/codeInsight/codeTransformations/branched/folding/ifToReturnAsymmetrically/simpleIfWithComments.kt"); + } + + } + + @TestMetadata("idea/testData/codeInsight/codeTransformations/branched/folding/whenToAssignment") + public static class WhenToAssignment extends AbstractCodeTransformationTest { + public void testAllFilesPresentInWhenToAssignment() throws Exception { + JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.GenerateTests", new File("idea/testData/codeInsight/codeTransformations/branched/folding/whenToAssignment"), Pattern.compile("^(.+)\\.kt$"), true); + } + + @TestMetadata("innerWhenTransformed.kt") + public void testInnerWhenTransformed() throws Exception { + doTestFoldWhenToAssignment("idea/testData/codeInsight/codeTransformations/branched/folding/whenToAssignment/innerWhenTransformed.kt"); + } + + @TestMetadata("simpleWhen.kt") + public void testSimpleWhen() throws Exception { + doTestFoldWhenToAssignment("idea/testData/codeInsight/codeTransformations/branched/folding/whenToAssignment/simpleWhen.kt"); + } + + @TestMetadata("simpleWhenWithBlocks.kt") + public void testSimpleWhenWithBlocks() throws Exception { + doTestFoldWhenToAssignment("idea/testData/codeInsight/codeTransformations/branched/folding/whenToAssignment/simpleWhenWithBlocks.kt"); + } + + @TestMetadata("simpleWhenWithShadowedVar.kt") + public void testSimpleWhenWithShadowedVar() throws Exception { + doTestFoldWhenToAssignment("idea/testData/codeInsight/codeTransformations/branched/folding/whenToAssignment/simpleWhenWithShadowedVar.kt"); + } + + @TestMetadata("simpleWhenWithUnmatchedAssignments.kt") + public void testSimpleWhenWithUnmatchedAssignments() throws Exception { + doTestFoldWhenToAssignment("idea/testData/codeInsight/codeTransformations/branched/folding/whenToAssignment/simpleWhenWithUnmatchedAssignments.kt"); + } + + @TestMetadata("simpleWhenWithoutTerminatingAssignment.kt") + public void testSimpleWhenWithoutTerminatingAssignment() throws Exception { + doTestFoldWhenToAssignment("idea/testData/codeInsight/codeTransformations/branched/folding/whenToAssignment/simpleWhenWithoutTerminatingAssignment.kt"); + } + + } + + @TestMetadata("idea/testData/codeInsight/codeTransformations/branched/folding/whenToReturn") + public static class WhenToReturn extends AbstractCodeTransformationTest { + public void testAllFilesPresentInWhenToReturn() throws Exception { + JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.GenerateTests", new File("idea/testData/codeInsight/codeTransformations/branched/folding/whenToReturn"), Pattern.compile("^(.+)\\.kt$"), true); + } + + @TestMetadata("innerWhenTransformed.kt") + public void testInnerWhenTransformed() throws Exception { + doTestFoldWhenToReturn("idea/testData/codeInsight/codeTransformations/branched/folding/whenToReturn/innerWhenTransformed.kt"); + } + + @TestMetadata("simpleWhen.kt") + public void testSimpleWhen() throws Exception { + doTestFoldWhenToReturn("idea/testData/codeInsight/codeTransformations/branched/folding/whenToReturn/simpleWhen.kt"); + } + + @TestMetadata("simpleWhenWithBlocks.kt") + public void testSimpleWhenWithBlocks() throws Exception { + doTestFoldWhenToReturn("idea/testData/codeInsight/codeTransformations/branched/folding/whenToReturn/simpleWhenWithBlocks.kt"); + } + + } + + @TestMetadata("idea/testData/codeInsight/codeTransformations/branched/unfolding/assignmentToIf") + public static class AssignmentToIf extends AbstractCodeTransformationTest { + public void testAllFilesPresentInAssignmentToIf() throws Exception { + JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.GenerateTests", new File("idea/testData/codeInsight/codeTransformations/branched/unfolding/assignmentToIf"), Pattern.compile("^(.+)\\.kt$"), true); + } + + @TestMetadata("innerIfTransformed.kt") + public void testInnerIfTransformed() throws Exception { + doTestUnfoldAssignmentToIf("idea/testData/codeInsight/codeTransformations/branched/unfolding/assignmentToIf/innerIfTransformed.kt"); + } + + @TestMetadata("nestedIfs.kt") + public void testNestedIfs() throws Exception { + doTestUnfoldAssignmentToIf("idea/testData/codeInsight/codeTransformations/branched/unfolding/assignmentToIf/nestedIfs.kt"); + } + + @TestMetadata("simpleIf.kt") + public void testSimpleIf() throws Exception { + doTestUnfoldAssignmentToIf("idea/testData/codeInsight/codeTransformations/branched/unfolding/assignmentToIf/simpleIf.kt"); + } + + @TestMetadata("simpleIfWithAugmentedAssignment.kt") + public void testSimpleIfWithAugmentedAssignment() throws Exception { + doTestUnfoldAssignmentToIf("idea/testData/codeInsight/codeTransformations/branched/unfolding/assignmentToIf/simpleIfWithAugmentedAssignment.kt"); + } + + @TestMetadata("simpleIfWithBlocks.kt") + public void testSimpleIfWithBlocks() throws Exception { + doTestUnfoldAssignmentToIf("idea/testData/codeInsight/codeTransformations/branched/unfolding/assignmentToIf/simpleIfWithBlocks.kt"); + } + + @TestMetadata("simpleIfWithoutAssignment.kt") + public void testSimpleIfWithoutAssignment() throws Exception { + doTestUnfoldAssignmentToIf("idea/testData/codeInsight/codeTransformations/branched/unfolding/assignmentToIf/simpleIfWithoutAssignment.kt"); + } + + } + + @TestMetadata("idea/testData/codeInsight/codeTransformations/branched/unfolding/returnToIf") + public static class ReturnToIf extends AbstractCodeTransformationTest { + public void testAllFilesPresentInReturnToIf() throws Exception { + JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.GenerateTests", new File("idea/testData/codeInsight/codeTransformations/branched/unfolding/returnToIf"), Pattern.compile("^(.+)\\.kt$"), true); + } + + @TestMetadata("innerIfTransformed.kt") + public void testInnerIfTransformed() throws Exception { + doTestUnfoldReturnToIf("idea/testData/codeInsight/codeTransformations/branched/unfolding/returnToIf/innerIfTransformed.kt"); + } + + @TestMetadata("simpleIf.kt") + public void testSimpleIf() throws Exception { + doTestUnfoldReturnToIf("idea/testData/codeInsight/codeTransformations/branched/unfolding/returnToIf/simpleIf.kt"); + } + + @TestMetadata("simpleIfWithBlocks.kt") + public void testSimpleIfWithBlocks() throws Exception { + doTestUnfoldReturnToIf("idea/testData/codeInsight/codeTransformations/branched/unfolding/returnToIf/simpleIfWithBlocks.kt"); + } + } public static Test suite() { TestSuite suite = new TestSuite("CodeTransformationsTestGenerated"); - suite.addTest(Folding.innerSuite()); - suite.addTest(Unfolding.innerSuite()); + suite.addTestSuite(IfToAssignment.class); + suite.addTestSuite(IfToReturn.class); + suite.addTestSuite(IfToReturnAsymmetrically.class); + suite.addTestSuite(WhenToAssignment.class); + suite.addTestSuite(WhenToReturn.class); + suite.addTestSuite(AssignmentToIf.class); + suite.addTestSuite(ReturnToIf.class); return suite; } } From 09b4a5afa31c4ba70c270bf4c14c7646c20d461a Mon Sep 17 00:00:00 2001 From: Alexey Sedunov Date: Tue, 16 Apr 2013 15:18:00 +0400 Subject: [PATCH 074/249] Add tests for unfolding to 'when' --- .../assignmentToWhen/innerWhenTransformed.kt | 21 ++++++++ .../innerWhenTransformed.kt.after | 21 ++++++++ .../unfolding/assignmentToWhen/simpleWhen.kt | 10 ++++ .../assignmentToWhen/simpleWhen.kt.after | 10 ++++ .../assignmentToWhen/simpleWhenWithBlocks.kt | 16 ++++++ .../simpleWhenWithBlocks.kt.after | 16 ++++++ .../returnToWhen/innerWhenTransformed.kt | 11 ++++ .../innerWhenTransformed.kt.after | 11 ++++ .../unfolding/returnToWhen/simpleWhen.kt | 6 +++ .../returnToWhen/simpleWhen.kt.after | 6 +++ .../returnToWhen/simpleWhenWithBlocks.kt | 11 ++++ .../simpleWhenWithBlocks.kt.after | 11 ++++ .../AbstractCodeTransformationTest.java | 2 +- .../CodeTransformationsTestGenerated.java | 50 ++++++++++++++++++- 14 files changed, 200 insertions(+), 2 deletions(-) create mode 100644 idea/testData/codeInsight/codeTransformations/branched/unfolding/assignmentToWhen/innerWhenTransformed.kt create mode 100644 idea/testData/codeInsight/codeTransformations/branched/unfolding/assignmentToWhen/innerWhenTransformed.kt.after create mode 100644 idea/testData/codeInsight/codeTransformations/branched/unfolding/assignmentToWhen/simpleWhen.kt create mode 100644 idea/testData/codeInsight/codeTransformations/branched/unfolding/assignmentToWhen/simpleWhen.kt.after create mode 100644 idea/testData/codeInsight/codeTransformations/branched/unfolding/assignmentToWhen/simpleWhenWithBlocks.kt create mode 100644 idea/testData/codeInsight/codeTransformations/branched/unfolding/assignmentToWhen/simpleWhenWithBlocks.kt.after create mode 100644 idea/testData/codeInsight/codeTransformations/branched/unfolding/returnToWhen/innerWhenTransformed.kt create mode 100644 idea/testData/codeInsight/codeTransformations/branched/unfolding/returnToWhen/innerWhenTransformed.kt.after create mode 100644 idea/testData/codeInsight/codeTransformations/branched/unfolding/returnToWhen/simpleWhen.kt create mode 100644 idea/testData/codeInsight/codeTransformations/branched/unfolding/returnToWhen/simpleWhen.kt.after create mode 100644 idea/testData/codeInsight/codeTransformations/branched/unfolding/returnToWhen/simpleWhenWithBlocks.kt create mode 100644 idea/testData/codeInsight/codeTransformations/branched/unfolding/returnToWhen/simpleWhenWithBlocks.kt.after diff --git a/idea/testData/codeInsight/codeTransformations/branched/unfolding/assignmentToWhen/innerWhenTransformed.kt b/idea/testData/codeInsight/codeTransformations/branched/unfolding/assignmentToWhen/innerWhenTransformed.kt new file mode 100644 index 00000000000..d3f6b00fa62 --- /dev/null +++ b/idea/testData/codeInsight/codeTransformations/branched/unfolding/assignmentToWhen/innerWhenTransformed.kt @@ -0,0 +1,21 @@ +fun test(n: Int): String { + var res: String + + if (3 > 2) { + res = when(n) { + 1 -> { + println("***") + "one" + } + else -> { + println("***") + "two" + } + } + } else { + println("***") + res = "???" + } + + return res +} \ No newline at end of file diff --git a/idea/testData/codeInsight/codeTransformations/branched/unfolding/assignmentToWhen/innerWhenTransformed.kt.after b/idea/testData/codeInsight/codeTransformations/branched/unfolding/assignmentToWhen/innerWhenTransformed.kt.after new file mode 100644 index 00000000000..c1784696fd1 --- /dev/null +++ b/idea/testData/codeInsight/codeTransformations/branched/unfolding/assignmentToWhen/innerWhenTransformed.kt.after @@ -0,0 +1,21 @@ +fun test(n: Int): String { + var res: String + + if (3 > 2) { + when(n) { + 1 -> { + println("***") + res = "one" + } + else -> { + println("***") + res = "two" + } + } + } else { + println("***") + res = "???" + } + + return res +} \ No newline at end of file diff --git a/idea/testData/codeInsight/codeTransformations/branched/unfolding/assignmentToWhen/simpleWhen.kt b/idea/testData/codeInsight/codeTransformations/branched/unfolding/assignmentToWhen/simpleWhen.kt new file mode 100644 index 00000000000..c961e534ccc --- /dev/null +++ b/idea/testData/codeInsight/codeTransformations/branched/unfolding/assignmentToWhen/simpleWhen.kt @@ -0,0 +1,10 @@ +fun test(n: Int): String { + var res: String + + res = when(n) { + 1 -> "one" + else -> "two" + } + + return res +} \ No newline at end of file diff --git a/idea/testData/codeInsight/codeTransformations/branched/unfolding/assignmentToWhen/simpleWhen.kt.after b/idea/testData/codeInsight/codeTransformations/branched/unfolding/assignmentToWhen/simpleWhen.kt.after new file mode 100644 index 00000000000..bf7f1257945 --- /dev/null +++ b/idea/testData/codeInsight/codeTransformations/branched/unfolding/assignmentToWhen/simpleWhen.kt.after @@ -0,0 +1,10 @@ +fun test(n: Int): String { + var res: String + + when(n) { + 1 -> res = "one" + else -> res = "two" + } + + return res +} \ No newline at end of file diff --git a/idea/testData/codeInsight/codeTransformations/branched/unfolding/assignmentToWhen/simpleWhenWithBlocks.kt b/idea/testData/codeInsight/codeTransformations/branched/unfolding/assignmentToWhen/simpleWhenWithBlocks.kt new file mode 100644 index 00000000000..237433b09f3 --- /dev/null +++ b/idea/testData/codeInsight/codeTransformations/branched/unfolding/assignmentToWhen/simpleWhenWithBlocks.kt @@ -0,0 +1,16 @@ +fun test(n: Int): String { + var res: String + + res = when (n) { + 1 -> { + println("***") + "one" + } + else -> { + println("***") + "two" + } + } + + return res +} \ No newline at end of file diff --git a/idea/testData/codeInsight/codeTransformations/branched/unfolding/assignmentToWhen/simpleWhenWithBlocks.kt.after b/idea/testData/codeInsight/codeTransformations/branched/unfolding/assignmentToWhen/simpleWhenWithBlocks.kt.after new file mode 100644 index 00000000000..d3e4325d5de --- /dev/null +++ b/idea/testData/codeInsight/codeTransformations/branched/unfolding/assignmentToWhen/simpleWhenWithBlocks.kt.after @@ -0,0 +1,16 @@ +fun test(n: Int): String { + var res: String + + when (n) { + 1 -> { + println("***") + res = "one" + } + else -> { + println("***") + res = "two" + } + } + + return res +} \ No newline at end of file diff --git a/idea/testData/codeInsight/codeTransformations/branched/unfolding/returnToWhen/innerWhenTransformed.kt b/idea/testData/codeInsight/codeTransformations/branched/unfolding/returnToWhen/innerWhenTransformed.kt new file mode 100644 index 00000000000..cec7664dbfa --- /dev/null +++ b/idea/testData/codeInsight/codeTransformations/branched/unfolding/returnToWhen/innerWhenTransformed.kt @@ -0,0 +1,11 @@ +fun test(n: Int): String { + if (3 > 2) { + return when (n) { + 1 -> "one" + else -> "two" + } + } else { + println("***") + return "???" + } +} \ No newline at end of file diff --git a/idea/testData/codeInsight/codeTransformations/branched/unfolding/returnToWhen/innerWhenTransformed.kt.after b/idea/testData/codeInsight/codeTransformations/branched/unfolding/returnToWhen/innerWhenTransformed.kt.after new file mode 100644 index 00000000000..0a5a8764560 --- /dev/null +++ b/idea/testData/codeInsight/codeTransformations/branched/unfolding/returnToWhen/innerWhenTransformed.kt.after @@ -0,0 +1,11 @@ +fun test(n: Int): String { + if (3 > 2) { + when (n) { + 1 -> return "one" + else -> return "two" + } + } else { + println("***") + return "???" + } +} \ No newline at end of file diff --git a/idea/testData/codeInsight/codeTransformations/branched/unfolding/returnToWhen/simpleWhen.kt b/idea/testData/codeInsight/codeTransformations/branched/unfolding/returnToWhen/simpleWhen.kt new file mode 100644 index 00000000000..83a1dee18ec --- /dev/null +++ b/idea/testData/codeInsight/codeTransformations/branched/unfolding/returnToWhen/simpleWhen.kt @@ -0,0 +1,6 @@ +fun test(n: Int): String { + return when (n) { + 1 -> "one" + else -> "two" + } +} \ No newline at end of file diff --git a/idea/testData/codeInsight/codeTransformations/branched/unfolding/returnToWhen/simpleWhen.kt.after b/idea/testData/codeInsight/codeTransformations/branched/unfolding/returnToWhen/simpleWhen.kt.after new file mode 100644 index 00000000000..09add4b1e81 --- /dev/null +++ b/idea/testData/codeInsight/codeTransformations/branched/unfolding/returnToWhen/simpleWhen.kt.after @@ -0,0 +1,6 @@ +fun test(n: Int): String { + when (n) { + 1 -> return "one" + else -> return "two" + } +} \ No newline at end of file diff --git a/idea/testData/codeInsight/codeTransformations/branched/unfolding/returnToWhen/simpleWhenWithBlocks.kt b/idea/testData/codeInsight/codeTransformations/branched/unfolding/returnToWhen/simpleWhenWithBlocks.kt new file mode 100644 index 00000000000..5565cdc2ecd --- /dev/null +++ b/idea/testData/codeInsight/codeTransformations/branched/unfolding/returnToWhen/simpleWhenWithBlocks.kt @@ -0,0 +1,11 @@ +fun test(n: Int): String { + return when(n) { + 1 -> { + println("***") + "one" + } + else -> { + println("***") + "two" + } +} \ No newline at end of file diff --git a/idea/testData/codeInsight/codeTransformations/branched/unfolding/returnToWhen/simpleWhenWithBlocks.kt.after b/idea/testData/codeInsight/codeTransformations/branched/unfolding/returnToWhen/simpleWhenWithBlocks.kt.after new file mode 100644 index 00000000000..1c9b980257f --- /dev/null +++ b/idea/testData/codeInsight/codeTransformations/branched/unfolding/returnToWhen/simpleWhenWithBlocks.kt.after @@ -0,0 +1,11 @@ +fun test(n: Int): String { + when(n) { + 1 -> { + println("***") + return "one" + } + else -> { + println("***") + return "two" + } +} \ No newline at end of file diff --git a/idea/tests/org/jetbrains/jet/plugin/codeInsight/codeTransformations/AbstractCodeTransformationTest.java b/idea/tests/org/jetbrains/jet/plugin/codeInsight/codeTransformations/AbstractCodeTransformationTest.java index 4d7e40e9de1..690abe64d19 100644 --- a/idea/tests/org/jetbrains/jet/plugin/codeInsight/codeTransformations/AbstractCodeTransformationTest.java +++ b/idea/tests/org/jetbrains/jet/plugin/codeInsight/codeTransformations/AbstractCodeTransformationTest.java @@ -59,7 +59,7 @@ public abstract class AbstractCodeTransformationTest extends LightCodeInsightTes } public void doTestUnfoldReturnToWhen(@NotNull String path) throws Exception { - doTest(path, new UnfoldAssignmentToIfIntention()); + doTest(path, new UnfoldReturnToWhenIntention()); } public void doTestRemoveUnnecessaryParentheses(@NotNull String path) throws Exception { diff --git a/idea/tests/org/jetbrains/jet/plugin/codeInsight/codeTransformations/CodeTransformationsTestGenerated.java b/idea/tests/org/jetbrains/jet/plugin/codeInsight/codeTransformations/CodeTransformationsTestGenerated.java index 7313beab78e..4ec4671eee3 100644 --- a/idea/tests/org/jetbrains/jet/plugin/codeInsight/codeTransformations/CodeTransformationsTestGenerated.java +++ b/idea/tests/org/jetbrains/jet/plugin/codeInsight/codeTransformations/CodeTransformationsTestGenerated.java @@ -30,7 +30,7 @@ import org.jetbrains.jet.plugin.codeInsight.codeTransformations.AbstractCodeTran /** This class is generated by {@link org.jetbrains.jet.generators.tests.GenerateTests}. DO NOT MODIFY MANUALLY */ @SuppressWarnings("all") -@InnerTestClasses({CodeTransformationsTestGenerated.IfToAssignment.class, CodeTransformationsTestGenerated.IfToReturn.class, CodeTransformationsTestGenerated.IfToReturnAsymmetrically.class, CodeTransformationsTestGenerated.WhenToAssignment.class, CodeTransformationsTestGenerated.WhenToReturn.class, CodeTransformationsTestGenerated.AssignmentToIf.class, CodeTransformationsTestGenerated.ReturnToIf.class}) +@InnerTestClasses({CodeTransformationsTestGenerated.IfToAssignment.class, CodeTransformationsTestGenerated.IfToReturn.class, CodeTransformationsTestGenerated.IfToReturnAsymmetrically.class, CodeTransformationsTestGenerated.WhenToAssignment.class, CodeTransformationsTestGenerated.WhenToReturn.class, CodeTransformationsTestGenerated.AssignmentToIf.class, CodeTransformationsTestGenerated.AssignmentToWhen.class, CodeTransformationsTestGenerated.ReturnToIf.class, CodeTransformationsTestGenerated.ReturnToWhen.class}) public class CodeTransformationsTestGenerated extends AbstractCodeTransformationTest { @TestMetadata("idea/testData/codeInsight/codeTransformations/branched/folding/ifToAssignment") public static class IfToAssignment extends AbstractCodeTransformationTest { @@ -230,6 +230,29 @@ public class CodeTransformationsTestGenerated extends AbstractCodeTransformation } + @TestMetadata("idea/testData/codeInsight/codeTransformations/branched/unfolding/assignmentToWhen") + public static class AssignmentToWhen extends AbstractCodeTransformationTest { + public void testAllFilesPresentInAssignmentToWhen() throws Exception { + JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.GenerateTests", new File("idea/testData/codeInsight/codeTransformations/branched/unfolding/assignmentToWhen"), Pattern.compile("^(.+)\\.kt$"), true); + } + + @TestMetadata("innerWhenTransformed.kt") + public void testInnerWhenTransformed() throws Exception { + doTestUnfoldAssignmentToWhen("idea/testData/codeInsight/codeTransformations/branched/unfolding/assignmentToWhen/innerWhenTransformed.kt"); + } + + @TestMetadata("simpleWhen.kt") + public void testSimpleWhen() throws Exception { + doTestUnfoldAssignmentToWhen("idea/testData/codeInsight/codeTransformations/branched/unfolding/assignmentToWhen/simpleWhen.kt"); + } + + @TestMetadata("simpleWhenWithBlocks.kt") + public void testSimpleWhenWithBlocks() throws Exception { + doTestUnfoldAssignmentToWhen("idea/testData/codeInsight/codeTransformations/branched/unfolding/assignmentToWhen/simpleWhenWithBlocks.kt"); + } + + } + @TestMetadata("idea/testData/codeInsight/codeTransformations/branched/unfolding/returnToIf") public static class ReturnToIf extends AbstractCodeTransformationTest { public void testAllFilesPresentInReturnToIf() throws Exception { @@ -253,6 +276,29 @@ public class CodeTransformationsTestGenerated extends AbstractCodeTransformation } + @TestMetadata("idea/testData/codeInsight/codeTransformations/branched/unfolding/returnToWhen") + public static class ReturnToWhen extends AbstractCodeTransformationTest { + public void testAllFilesPresentInReturnToWhen() throws Exception { + JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.GenerateTests", new File("idea/testData/codeInsight/codeTransformations/branched/unfolding/returnToWhen"), Pattern.compile("^(.+)\\.kt$"), true); + } + + @TestMetadata("innerWhenTransformed.kt") + public void testInnerWhenTransformed() throws Exception { + doTestUnfoldReturnToWhen("idea/testData/codeInsight/codeTransformations/branched/unfolding/returnToWhen/innerWhenTransformed.kt"); + } + + @TestMetadata("simpleWhen.kt") + public void testSimpleWhen() throws Exception { + doTestUnfoldReturnToWhen("idea/testData/codeInsight/codeTransformations/branched/unfolding/returnToWhen/simpleWhen.kt"); + } + + @TestMetadata("simpleWhenWithBlocks.kt") + public void testSimpleWhenWithBlocks() throws Exception { + doTestUnfoldReturnToWhen("idea/testData/codeInsight/codeTransformations/branched/unfolding/returnToWhen/simpleWhenWithBlocks.kt"); + } + + } + public static Test suite() { TestSuite suite = new TestSuite("CodeTransformationsTestGenerated"); suite.addTestSuite(IfToAssignment.class); @@ -261,7 +307,9 @@ public class CodeTransformationsTestGenerated extends AbstractCodeTransformation suite.addTestSuite(WhenToAssignment.class); suite.addTestSuite(WhenToReturn.class); suite.addTestSuite(AssignmentToIf.class); + suite.addTestSuite(AssignmentToWhen.class); suite.addTestSuite(ReturnToIf.class); + suite.addTestSuite(ReturnToWhen.class); return suite; } } From 2ba806bee877e0bfa2412888101891417ffcfd5e Mon Sep 17 00:00:00 2001 From: Alexey Sedunov Date: Tue, 16 Apr 2013 15:18:32 +0400 Subject: [PATCH 075/249] Fix bug in assignment-to-when unfolding --- .../branchedTransformations/BranchedUnfoldingUtils.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/BranchedUnfoldingUtils.java b/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/BranchedUnfoldingUtils.java index 074f383d385..3ded7e15d31 100644 --- a/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/BranchedUnfoldingUtils.java +++ b/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/BranchedUnfoldingUtils.java @@ -79,7 +79,7 @@ public class BranchedUnfoldingUtils { public static void unfoldAssignmentToWhen(@NotNull JetBinaryExpression assignment) { Project project = assignment.getProject(); String op = assignment.getOperationReference().getText(); - JetExpression lhs = (JetExpression)assignment.getLeft().copy(); + String lhsText = assignment.getLeft().getText(); JetWhenExpression whenExpression = (JetWhenExpression)assignment.getRight(); assert whenExpression != null : UNFOLD_WITHOUT_CHECK; @@ -91,7 +91,7 @@ public class BranchedUnfoldingUtils { assert currExpr != null : UNFOLD_WITHOUT_CHECK; - currExpr.replace(JetPsiFactory.createBinaryExpression(project, lhs, op, currExpr)); + currExpr.replace(JetPsiFactory.createBinaryExpression(project, JetPsiFactory.createExpression(project, lhsText), op, currExpr)); } } From fe3d7492574dc7faffab1ab5f7b3926c143bbcd6 Mon Sep 17 00:00:00 2001 From: Alexey Sedunov Date: Wed, 17 Apr 2013 16:35:50 +0400 Subject: [PATCH 076/249] Minimize update operations on active PSI and move them to the last phase --- .../BranchedFoldingUtils.java | 96 ++++++++++--------- .../BranchedUnfoldingUtils.java | 40 ++++---- 2 files changed, 72 insertions(+), 64 deletions(-) diff --git a/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/BranchedFoldingUtils.java b/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/BranchedFoldingUtils.java index 98b9c363e6c..fdcf12eafeb 100644 --- a/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/BranchedFoldingUtils.java +++ b/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/BranchedFoldingUtils.java @@ -61,11 +61,11 @@ public class BranchedFoldingUtils { } }; - private static JetBinaryExpression checkAndGetFoldableBranchedAssignment(JetExpression branch) { + private static JetBinaryExpression getFoldableBranchedAssignment(JetExpression branch) { return (JetBinaryExpression)JetPsiUtil.getOutermostLastBlockElement(branch, CHECK_ASSIGNMENT); } - private static JetReturnExpression checkAndGetFoldableBranchedReturn(JetExpression branch) { + private static JetReturnExpression getFoldableBranchedReturn(JetExpression branch) { return (JetReturnExpression)JetPsiUtil.getOutermostLastBlockElement(branch, CHECK_RETURN); } @@ -77,8 +77,8 @@ public class BranchedFoldingUtils { JetExpression thenBranch = ifExpression.getThen(); JetExpression elseBranch = ifExpression.getElse(); - JetBinaryExpression thenAssignment = checkAndGetFoldableBranchedAssignment(thenBranch); - JetBinaryExpression elseAssignment = checkAndGetFoldableBranchedAssignment(elseBranch); + JetBinaryExpression thenAssignment = getFoldableBranchedAssignment(thenBranch); + JetBinaryExpression elseAssignment = getFoldableBranchedAssignment(elseBranch); if (thenAssignment == null || elseAssignment == null) return false; @@ -94,7 +94,7 @@ public class BranchedFoldingUtils { List assignments = new ArrayList(); for (JetWhenEntry entry : entries) { - JetBinaryExpression assignment = checkAndGetFoldableBranchedAssignment(entry.getExpression()); + JetBinaryExpression assignment = getFoldableBranchedAssignment(entry.getExpression()); if (assignment == null) return false; assignments.add(assignment); } @@ -110,8 +110,8 @@ public class BranchedFoldingUtils { } private static boolean checkFoldableIfExpressionWithReturns(JetIfExpression ifExpression) { - return checkAndGetFoldableBranchedReturn(ifExpression.getThen()) != null && - checkAndGetFoldableBranchedReturn(ifExpression.getElse()) != null; + return getFoldableBranchedReturn(ifExpression.getThen()) != null && + getFoldableBranchedReturn(ifExpression.getElse()) != null; } private static boolean checkFoldableWhenExpressionWithReturns(JetWhenExpression whenExpression) { @@ -122,20 +122,20 @@ public class BranchedFoldingUtils { if (entries.isEmpty()) return false; for (JetWhenEntry entry : entries) { - if (checkAndGetFoldableBranchedReturn(entry.getExpression()) == null) return false; + if (getFoldableBranchedReturn(entry.getExpression()) == null) return false; } return true; } private static boolean checkFoldableIfExpressionWithAsymmetricReturns(JetIfExpression ifExpression) { - if (checkAndGetFoldableBranchedReturn(ifExpression.getThen()) == null || + if (getFoldableBranchedReturn(ifExpression.getThen()) == null || ifExpression.getElse() != null) { return false; } PsiElement nextElement = JetPsiUtil.skipTrailingWhitespacesAndComments(ifExpression); - return (nextElement instanceof JetExpression) && checkAndGetFoldableBranchedReturn((JetExpression)nextElement) != null; + return (nextElement instanceof JetExpression) && getFoldableBranchedReturn((JetExpression) nextElement) != null; } @Nullable @@ -161,21 +161,20 @@ public class BranchedFoldingUtils { public static void foldIfExpressionWithAssignments(JetIfExpression ifExpression) { Project project = ifExpression.getProject(); - JetBinaryExpression thenAssignment = checkAndGetFoldableBranchedAssignment(ifExpression.getThen()); + JetBinaryExpression thenAssignment = getFoldableBranchedAssignment(ifExpression.getThen()); assert thenAssignment != null : FOLD_WITHOUT_CHECK; String op = thenAssignment.getOperationReference().getText(); JetSimpleNameExpression lhs = (JetSimpleNameExpression) thenAssignment.getLeft(); - JetBinaryExpression assignment = - (JetBinaryExpression)ifExpression.replace(JetPsiFactory.createBinaryExpression(project, lhs, op, ifExpression)); - ifExpression = (JetIfExpression)assignment.getRight(); + JetBinaryExpression assignment = JetPsiFactory.createBinaryExpression(project, lhs, op, ifExpression); + JetIfExpression newIfExpression = (JetIfExpression)assignment.getRight(); - assert ifExpression != null : FOLD_WITHOUT_CHECK; + assert newIfExpression != null : FOLD_WITHOUT_CHECK; - thenAssignment = checkAndGetFoldableBranchedAssignment(ifExpression.getThen()); - JetBinaryExpression elseAssignment = checkAndGetFoldableBranchedAssignment(ifExpression.getElse()); + thenAssignment = getFoldableBranchedAssignment(newIfExpression.getThen()); + JetBinaryExpression elseAssignment = getFoldableBranchedAssignment(newIfExpression.getElse()); assert thenAssignment != null : FOLD_WITHOUT_CHECK; assert elseAssignment != null : FOLD_WITHOUT_CHECK; @@ -188,18 +187,20 @@ public class BranchedFoldingUtils { thenAssignment.replace(thenRhs); elseAssignment.replace(elseRhs); + + ifExpression.replace(assignment); } public static void foldIfExpressionWithReturns(JetIfExpression ifExpression) { Project project = ifExpression.getProject(); - JetReturnExpression returnExpr = (JetReturnExpression)ifExpression.replace(JetPsiFactory.createReturn(project, ifExpression)); - ifExpression = (JetIfExpression)returnExpr.getReturnedExpression(); + JetReturnExpression newReturnExpression = JetPsiFactory.createReturn(project, ifExpression); + JetIfExpression newIfExpression = (JetIfExpression)newReturnExpression.getReturnedExpression(); - assert ifExpression != null : FOLD_WITHOUT_CHECK; + assert newIfExpression != null; - JetReturnExpression thenReturn = checkAndGetFoldableBranchedReturn(ifExpression.getThen()); - JetReturnExpression elseReturn = checkAndGetFoldableBranchedReturn(ifExpression.getElse()); + JetReturnExpression thenReturn = getFoldableBranchedReturn(newIfExpression.getThen()); + JetReturnExpression elseReturn = getFoldableBranchedReturn(newIfExpression.getElse()); assert thenReturn != null : FOLD_WITHOUT_CHECK; assert elseReturn != null : FOLD_WITHOUT_CHECK; @@ -212,6 +213,8 @@ public class BranchedFoldingUtils { thenReturn.replace(thenExpr); elseReturn.replace(elseExpr); + + ifExpression.replace(newReturnExpression); } public static void foldIfExpressionWithAsymmetricReturns(JetIfExpression ifExpression) { @@ -225,22 +228,15 @@ public class BranchedFoldingUtils { assert thenRoot != null : FOLD_WITHOUT_CHECK; assert elseRoot != null : FOLD_WITHOUT_CHECK; - JetIfExpression newIfExpr = JetPsiFactory.createIf(project, condition, thenRoot, elseRoot); - JetReturnExpression newReturnExpr = JetPsiFactory.createReturn(project, newIfExpr); - newReturnExpr = (JetReturnExpression) ifExpression.replace(newReturnExpr); + JetIfExpression newIfExpression = JetPsiFactory.createIf(project, condition, thenRoot, elseRoot); + JetReturnExpression newReturnExpression = JetPsiFactory.createReturn(project, newIfExpression); - JetReturnExpression oldReturn = (JetReturnExpression)JetPsiUtil.skipTrailingWhitespacesAndComments(newReturnExpr); + newIfExpression = (JetIfExpression)newReturnExpression.getReturnedExpression(); - assert oldReturn != null : FOLD_WITHOUT_CHECK; + assert newIfExpression != null : FOLD_WITHOUT_CHECK; - oldReturn.delete(); - - newIfExpr = (JetIfExpression)newReturnExpr.getReturnedExpression(); - - assert newIfExpr != null : FOLD_WITHOUT_CHECK; - - JetReturnExpression thenReturn = checkAndGetFoldableBranchedReturn(newIfExpr.getThen()); - JetReturnExpression elseReturn = checkAndGetFoldableBranchedReturn(newIfExpr.getElse()); + JetReturnExpression thenReturn = getFoldableBranchedReturn(newIfExpression.getThen()); + JetReturnExpression elseReturn = getFoldableBranchedReturn(newIfExpression.getElse()); assert thenReturn != null : FOLD_WITHOUT_CHECK; assert elseReturn != null : FOLD_WITHOUT_CHECK; @@ -253,6 +249,9 @@ public class BranchedFoldingUtils { thenReturn.replace(thenExpr); elseReturn.replace(elseExpr); + + elseRoot.delete(); + ifExpression.replace(newReturnExpression); } public static void foldWhenExpressionWithAssignments(JetWhenExpression whenExpression) { @@ -260,21 +259,20 @@ public class BranchedFoldingUtils { assert !whenExpression.getEntries().isEmpty() : FOLD_WITHOUT_CHECK; - JetBinaryExpression firstAssignment = checkAndGetFoldableBranchedAssignment(whenExpression.getEntries().get(0).getExpression()); + JetBinaryExpression firstAssignment = getFoldableBranchedAssignment(whenExpression.getEntries().get(0).getExpression()); assert firstAssignment != null : FOLD_WITHOUT_CHECK; String op = firstAssignment.getOperationReference().getText(); JetSimpleNameExpression lhs = (JetSimpleNameExpression) firstAssignment.getLeft(); - JetBinaryExpression assignment = - (JetBinaryExpression)whenExpression.replace(JetPsiFactory.createBinaryExpression(project, lhs, op, whenExpression)); - whenExpression = (JetWhenExpression)assignment.getRight(); + JetBinaryExpression assignment = JetPsiFactory.createBinaryExpression(project, lhs, op, whenExpression); + JetWhenExpression newWhenExpression = (JetWhenExpression)assignment.getRight(); - assert whenExpression != null : FOLD_WITHOUT_CHECK; + assert newWhenExpression != null : FOLD_WITHOUT_CHECK; - for (JetWhenEntry entry : whenExpression.getEntries()) { - JetBinaryExpression currAssignment = checkAndGetFoldableBranchedAssignment(entry.getExpression()); + for (JetWhenEntry entry : newWhenExpression.getEntries()) { + JetBinaryExpression currAssignment = getFoldableBranchedAssignment(entry.getExpression()); assert currAssignment != null : FOLD_WITHOUT_CHECK; @@ -284,6 +282,8 @@ public class BranchedFoldingUtils { currAssignment.replace(currRhs); } + + whenExpression.replace(assignment); } public static void foldWhenExpressionWithReturns(JetWhenExpression whenExpression) { @@ -291,13 +291,13 @@ public class BranchedFoldingUtils { assert !whenExpression.getEntries().isEmpty() : FOLD_WITHOUT_CHECK; - JetReturnExpression returnExpr = (JetReturnExpression)whenExpression.replace(JetPsiFactory.createReturn(project, whenExpression)); - whenExpression = (JetWhenExpression)returnExpr.getReturnedExpression(); + JetReturnExpression newReturnExpression = JetPsiFactory.createReturn(project, whenExpression); + JetWhenExpression newWhenExpression = (JetWhenExpression)newReturnExpression.getReturnedExpression(); - assert whenExpression != null : FOLD_WITHOUT_CHECK; + assert newWhenExpression != null : FOLD_WITHOUT_CHECK; - for (JetWhenEntry entry : whenExpression.getEntries()) { - JetReturnExpression currReturn = checkAndGetFoldableBranchedReturn(entry.getExpression()); + for (JetWhenEntry entry : newWhenExpression.getEntries()) { + JetReturnExpression currReturn = getFoldableBranchedReturn(entry.getExpression()); assert currReturn != null : FOLD_WITHOUT_CHECK; @@ -307,5 +307,7 @@ public class BranchedFoldingUtils { currReturn.replace(currExpr); } + + whenExpression.replace(newReturnExpression); } } diff --git a/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/BranchedUnfoldingUtils.java b/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/BranchedUnfoldingUtils.java index 3ded7e15d31..d9b1c9c4e2d 100644 --- a/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/BranchedUnfoldingUtils.java +++ b/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/BranchedUnfoldingUtils.java @@ -16,9 +16,7 @@ package org.jetbrains.jet.plugin.codeInsight.codeTransformations.branchedTransformations; -import com.google.common.base.Predicate; import com.intellij.openapi.project.Project; -import com.intellij.psi.PsiElement; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.jet.lang.psi.*; @@ -59,40 +57,44 @@ public class BranchedUnfoldingUtils { public static void unfoldAssignmentToIf(@NotNull JetBinaryExpression assignment) { Project project = assignment.getProject(); String op = assignment.getOperationReference().getText(); - String lhsText = assignment.getLeft().getText(); + JetExpression lhs = assignment.getLeft(); JetIfExpression ifExpression = (JetIfExpression)assignment.getRight(); assert ifExpression != null : UNFOLD_WITHOUT_CHECK; - ifExpression = (JetIfExpression)assignment.replace(ifExpression); + JetIfExpression newIfExpression = (JetIfExpression) ifExpression.copy(); - JetExpression thenExpr = getOutermostLastBlockElement(ifExpression.getThen()); - JetExpression elseExpr = getOutermostLastBlockElement(ifExpression.getElse()); + JetExpression thenExpr = getOutermostLastBlockElement(newIfExpression.getThen()); + JetExpression elseExpr = getOutermostLastBlockElement(newIfExpression.getElse()); assert thenExpr != null : UNFOLD_WITHOUT_CHECK; assert elseExpr != null : UNFOLD_WITHOUT_CHECK; - thenExpr.replace(JetPsiFactory.createBinaryExpression(project, JetPsiFactory.createExpression(project, lhsText), op, thenExpr)); - elseExpr.replace(JetPsiFactory.createBinaryExpression(project, JetPsiFactory.createExpression(project, lhsText), op, elseExpr)); + thenExpr.replace(JetPsiFactory.createBinaryExpression(project, lhs, op, thenExpr)); + elseExpr.replace(JetPsiFactory.createBinaryExpression(project, lhs, op, elseExpr)); + + assignment.replace(newIfExpression); } public static void unfoldAssignmentToWhen(@NotNull JetBinaryExpression assignment) { Project project = assignment.getProject(); String op = assignment.getOperationReference().getText(); - String lhsText = assignment.getLeft().getText(); + JetExpression lhs = assignment.getLeft(); JetWhenExpression whenExpression = (JetWhenExpression)assignment.getRight(); assert whenExpression != null : UNFOLD_WITHOUT_CHECK; - whenExpression = (JetWhenExpression)assignment.replace(whenExpression); + JetWhenExpression newWhenExpression = (JetWhenExpression) whenExpression.copy(); - for (JetWhenEntry entry : whenExpression.getEntries()) { + for (JetWhenEntry entry : newWhenExpression.getEntries()) { JetExpression currExpr = getOutermostLastBlockElement(entry.getExpression()); assert currExpr != null : UNFOLD_WITHOUT_CHECK; - currExpr.replace(JetPsiFactory.createBinaryExpression(project, JetPsiFactory.createExpression(project, lhsText), op, currExpr)); + currExpr.replace(JetPsiFactory.createBinaryExpression(project, lhs, op, currExpr)); } + + assignment.replace(newWhenExpression); } public static void unfoldReturnToIf(@NotNull JetReturnExpression returnExpression) { @@ -101,16 +103,18 @@ public class BranchedUnfoldingUtils { assert ifExpression != null : UNFOLD_WITHOUT_CHECK; - ifExpression = (JetIfExpression)returnExpression.replace(ifExpression); + JetIfExpression newIfExpression = (JetIfExpression) ifExpression.copy(); - JetExpression thenExpr = getOutermostLastBlockElement(ifExpression.getThen()); - JetExpression elseExpr = getOutermostLastBlockElement(ifExpression.getElse()); + JetExpression thenExpr = getOutermostLastBlockElement(newIfExpression.getThen()); + JetExpression elseExpr = getOutermostLastBlockElement(newIfExpression.getElse()); assert thenExpr != null : UNFOLD_WITHOUT_CHECK; assert elseExpr != null : UNFOLD_WITHOUT_CHECK; thenExpr.replace(JetPsiFactory.createReturn(project, thenExpr)); elseExpr.replace(JetPsiFactory.createReturn(project, elseExpr)); + + returnExpression.replace(newIfExpression); } public static void unfoldReturnToWhen(@NotNull JetReturnExpression returnExpression) { @@ -119,14 +123,16 @@ public class BranchedUnfoldingUtils { assert whenExpression != null : UNFOLD_WITHOUT_CHECK; - whenExpression = (JetWhenExpression)returnExpression.replace(whenExpression); + JetWhenExpression newWhenExpression = (JetWhenExpression) whenExpression.copy(); - for (JetWhenEntry entry : whenExpression.getEntries()) { + for (JetWhenEntry entry : newWhenExpression.getEntries()) { JetExpression currExpr = getOutermostLastBlockElement(entry.getExpression()); assert currExpr != null : UNFOLD_WITHOUT_CHECK; currExpr.replace(JetPsiFactory.createReturn(project, currExpr)); } + + returnExpression.replace(newWhenExpression); } } From 9ae17cfe856eac403cd296d26d1049a2b435f5a0 Mon Sep 17 00:00:00 2001 From: Alexey Sedunov Date: Wed, 17 Apr 2013 18:07:43 +0400 Subject: [PATCH 077/249] Make intentions inner classes --- .../after.kt.template | 0 .../before.kt.template | 0 .../description.html | 0 .../after.kt.template | 0 .../before.kt.template | 0 .../description.html | 0 .../after.kt.template | 0 .../before.kt.template | 0 .../description.html | 0 .../after.kt.template | 0 .../before.kt.template | 0 .../description.html | 0 .../after.kt.template | 0 .../before.kt.template | 0 .../description.html | 0 .../after.kt.template | 0 .../before.kt.template | 0 .../description.html | 0 .../after.kt.template | 0 .../before.kt.template | 0 .../description.html | 0 .../after.kt.template | 0 .../before.kt.template | 0 .../description.html | 0 .../after.kt.template | 0 .../before.kt.template | 0 .../description.html | 0 idea/src/META-INF/plugin.xml | 18 +++++------ .../AbstractCodeTransformationIntention.java | 8 ----- .../core/Transformer.java | 3 +- .../FoldBranchedExpressionIntention.java | 30 +++++++++++++++++++ .../FoldIfToAssignmentIntention.java | 25 ---------------- ...FoldIfToReturnAsymmetricallyIntention.java | 25 ---------------- .../intentions/FoldIfToReturnIntention.java | 25 ---------------- .../FoldWhenToAssignmentIntention.java | 25 ---------------- .../intentions/FoldWhenToReturnIntention.java | 25 ---------------- .../UnfoldAssignmentToIfIntention.java | 25 ---------------- .../UnfoldAssignmentToWhenIntention.java | 25 ---------------- .../UnfoldBranchedExpressionIntention.java | 24 +++++++++++++++ .../intentions/UnfoldReturnToIfIntention.java | 25 ---------------- .../UnfoldReturnToWhenIntention.java | 25 ---------------- .../AbstractCodeTransformationTest.java | 18 +++++------ 42 files changed, 74 insertions(+), 252 deletions(-) rename idea/resources/intentionDescriptions/{FoldIfToAssignmentIntention => FoldBranchedExpressionIntentionFoldIfToAssignmentIntention}/after.kt.template (100%) rename idea/resources/intentionDescriptions/{FoldIfToAssignmentIntention => FoldBranchedExpressionIntentionFoldIfToAssignmentIntention}/before.kt.template (100%) rename idea/resources/intentionDescriptions/{FoldIfToAssignmentIntention => FoldBranchedExpressionIntentionFoldIfToAssignmentIntention}/description.html (100%) rename idea/resources/intentionDescriptions/{FoldIfToReturnAsymmetricallyIntention => FoldBranchedExpressionIntentionFoldIfToReturnAsymmetricallyIntention}/after.kt.template (100%) rename idea/resources/intentionDescriptions/{FoldIfToReturnAsymmetricallyIntention => FoldBranchedExpressionIntentionFoldIfToReturnAsymmetricallyIntention}/before.kt.template (100%) rename idea/resources/intentionDescriptions/{FoldIfToReturnAsymmetricallyIntention => FoldBranchedExpressionIntentionFoldIfToReturnAsymmetricallyIntention}/description.html (100%) rename idea/resources/intentionDescriptions/{FoldIfToReturnIntention => FoldBranchedExpressionIntentionFoldIfToReturnIntention}/after.kt.template (100%) rename idea/resources/intentionDescriptions/{FoldIfToReturnIntention => FoldBranchedExpressionIntentionFoldIfToReturnIntention}/before.kt.template (100%) rename idea/resources/intentionDescriptions/{FoldIfToReturnIntention => FoldBranchedExpressionIntentionFoldIfToReturnIntention}/description.html (100%) rename idea/resources/intentionDescriptions/{FoldWhenToAssignmentIntention => FoldBranchedExpressionIntentionFoldWhenToAssignmentIntention}/after.kt.template (100%) rename idea/resources/intentionDescriptions/{FoldWhenToAssignmentIntention => FoldBranchedExpressionIntentionFoldWhenToAssignmentIntention}/before.kt.template (100%) rename idea/resources/intentionDescriptions/{FoldWhenToAssignmentIntention => FoldBranchedExpressionIntentionFoldWhenToAssignmentIntention}/description.html (100%) rename idea/resources/intentionDescriptions/{FoldWhenToReturnIntention => FoldBranchedExpressionIntentionFoldWhenToReturnIntention}/after.kt.template (100%) rename idea/resources/intentionDescriptions/{FoldWhenToReturnIntention => FoldBranchedExpressionIntentionFoldWhenToReturnIntention}/before.kt.template (100%) rename idea/resources/intentionDescriptions/{FoldWhenToReturnIntention => FoldBranchedExpressionIntentionFoldWhenToReturnIntention}/description.html (100%) rename idea/resources/intentionDescriptions/{UnfoldAssignmentToIfIntention => UnfoldBranchedExpressionIntentionUnfoldAssignmentToIfIntention}/after.kt.template (100%) rename idea/resources/intentionDescriptions/{UnfoldAssignmentToIfIntention => UnfoldBranchedExpressionIntentionUnfoldAssignmentToIfIntention}/before.kt.template (100%) rename idea/resources/intentionDescriptions/{UnfoldAssignmentToIfIntention => UnfoldBranchedExpressionIntentionUnfoldAssignmentToIfIntention}/description.html (100%) rename idea/resources/intentionDescriptions/{UnfoldAssignmentToWhenIntention => UnfoldBranchedExpressionIntentionUnfoldAssignmentToWhenIntention}/after.kt.template (100%) rename idea/resources/intentionDescriptions/{UnfoldAssignmentToWhenIntention => UnfoldBranchedExpressionIntentionUnfoldAssignmentToWhenIntention}/before.kt.template (100%) rename idea/resources/intentionDescriptions/{UnfoldAssignmentToWhenIntention => UnfoldBranchedExpressionIntentionUnfoldAssignmentToWhenIntention}/description.html (100%) rename idea/resources/intentionDescriptions/{UnfoldReturnToIfIntention => UnfoldBranchedExpressionIntentionUnfoldReturnToIfIntention}/after.kt.template (100%) rename idea/resources/intentionDescriptions/{UnfoldReturnToIfIntention => UnfoldBranchedExpressionIntentionUnfoldReturnToIfIntention}/before.kt.template (100%) rename idea/resources/intentionDescriptions/{UnfoldReturnToIfIntention => UnfoldBranchedExpressionIntentionUnfoldReturnToIfIntention}/description.html (100%) rename idea/resources/intentionDescriptions/{UnfoldReturnToWhenIntention => UnfoldBranchedExpressionIntentionUnfoldReturnToWhenIntention}/after.kt.template (100%) rename idea/resources/intentionDescriptions/{UnfoldReturnToWhenIntention => UnfoldBranchedExpressionIntentionUnfoldReturnToWhenIntention}/before.kt.template (100%) rename idea/resources/intentionDescriptions/{UnfoldReturnToWhenIntention => UnfoldBranchedExpressionIntentionUnfoldReturnToWhenIntention}/description.html (100%) delete mode 100644 idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/intentions/FoldIfToAssignmentIntention.java delete mode 100644 idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/intentions/FoldIfToReturnAsymmetricallyIntention.java delete mode 100644 idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/intentions/FoldIfToReturnIntention.java delete mode 100644 idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/intentions/FoldWhenToAssignmentIntention.java delete mode 100644 idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/intentions/FoldWhenToReturnIntention.java delete mode 100644 idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/intentions/UnfoldAssignmentToIfIntention.java delete mode 100644 idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/intentions/UnfoldAssignmentToWhenIntention.java delete mode 100644 idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/intentions/UnfoldReturnToIfIntention.java delete mode 100644 idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/intentions/UnfoldReturnToWhenIntention.java diff --git a/idea/resources/intentionDescriptions/FoldIfToAssignmentIntention/after.kt.template b/idea/resources/intentionDescriptions/FoldBranchedExpressionIntentionFoldIfToAssignmentIntention/after.kt.template similarity index 100% rename from idea/resources/intentionDescriptions/FoldIfToAssignmentIntention/after.kt.template rename to idea/resources/intentionDescriptions/FoldBranchedExpressionIntentionFoldIfToAssignmentIntention/after.kt.template diff --git a/idea/resources/intentionDescriptions/FoldIfToAssignmentIntention/before.kt.template b/idea/resources/intentionDescriptions/FoldBranchedExpressionIntentionFoldIfToAssignmentIntention/before.kt.template similarity index 100% rename from idea/resources/intentionDescriptions/FoldIfToAssignmentIntention/before.kt.template rename to idea/resources/intentionDescriptions/FoldBranchedExpressionIntentionFoldIfToAssignmentIntention/before.kt.template diff --git a/idea/resources/intentionDescriptions/FoldIfToAssignmentIntention/description.html b/idea/resources/intentionDescriptions/FoldBranchedExpressionIntentionFoldIfToAssignmentIntention/description.html similarity index 100% rename from idea/resources/intentionDescriptions/FoldIfToAssignmentIntention/description.html rename to idea/resources/intentionDescriptions/FoldBranchedExpressionIntentionFoldIfToAssignmentIntention/description.html diff --git a/idea/resources/intentionDescriptions/FoldIfToReturnAsymmetricallyIntention/after.kt.template b/idea/resources/intentionDescriptions/FoldBranchedExpressionIntentionFoldIfToReturnAsymmetricallyIntention/after.kt.template similarity index 100% rename from idea/resources/intentionDescriptions/FoldIfToReturnAsymmetricallyIntention/after.kt.template rename to idea/resources/intentionDescriptions/FoldBranchedExpressionIntentionFoldIfToReturnAsymmetricallyIntention/after.kt.template diff --git a/idea/resources/intentionDescriptions/FoldIfToReturnAsymmetricallyIntention/before.kt.template b/idea/resources/intentionDescriptions/FoldBranchedExpressionIntentionFoldIfToReturnAsymmetricallyIntention/before.kt.template similarity index 100% rename from idea/resources/intentionDescriptions/FoldIfToReturnAsymmetricallyIntention/before.kt.template rename to idea/resources/intentionDescriptions/FoldBranchedExpressionIntentionFoldIfToReturnAsymmetricallyIntention/before.kt.template diff --git a/idea/resources/intentionDescriptions/FoldIfToReturnAsymmetricallyIntention/description.html b/idea/resources/intentionDescriptions/FoldBranchedExpressionIntentionFoldIfToReturnAsymmetricallyIntention/description.html similarity index 100% rename from idea/resources/intentionDescriptions/FoldIfToReturnAsymmetricallyIntention/description.html rename to idea/resources/intentionDescriptions/FoldBranchedExpressionIntentionFoldIfToReturnAsymmetricallyIntention/description.html diff --git a/idea/resources/intentionDescriptions/FoldIfToReturnIntention/after.kt.template b/idea/resources/intentionDescriptions/FoldBranchedExpressionIntentionFoldIfToReturnIntention/after.kt.template similarity index 100% rename from idea/resources/intentionDescriptions/FoldIfToReturnIntention/after.kt.template rename to idea/resources/intentionDescriptions/FoldBranchedExpressionIntentionFoldIfToReturnIntention/after.kt.template diff --git a/idea/resources/intentionDescriptions/FoldIfToReturnIntention/before.kt.template b/idea/resources/intentionDescriptions/FoldBranchedExpressionIntentionFoldIfToReturnIntention/before.kt.template similarity index 100% rename from idea/resources/intentionDescriptions/FoldIfToReturnIntention/before.kt.template rename to idea/resources/intentionDescriptions/FoldBranchedExpressionIntentionFoldIfToReturnIntention/before.kt.template diff --git a/idea/resources/intentionDescriptions/FoldIfToReturnIntention/description.html b/idea/resources/intentionDescriptions/FoldBranchedExpressionIntentionFoldIfToReturnIntention/description.html similarity index 100% rename from idea/resources/intentionDescriptions/FoldIfToReturnIntention/description.html rename to idea/resources/intentionDescriptions/FoldBranchedExpressionIntentionFoldIfToReturnIntention/description.html diff --git a/idea/resources/intentionDescriptions/FoldWhenToAssignmentIntention/after.kt.template b/idea/resources/intentionDescriptions/FoldBranchedExpressionIntentionFoldWhenToAssignmentIntention/after.kt.template similarity index 100% rename from idea/resources/intentionDescriptions/FoldWhenToAssignmentIntention/after.kt.template rename to idea/resources/intentionDescriptions/FoldBranchedExpressionIntentionFoldWhenToAssignmentIntention/after.kt.template diff --git a/idea/resources/intentionDescriptions/FoldWhenToAssignmentIntention/before.kt.template b/idea/resources/intentionDescriptions/FoldBranchedExpressionIntentionFoldWhenToAssignmentIntention/before.kt.template similarity index 100% rename from idea/resources/intentionDescriptions/FoldWhenToAssignmentIntention/before.kt.template rename to idea/resources/intentionDescriptions/FoldBranchedExpressionIntentionFoldWhenToAssignmentIntention/before.kt.template diff --git a/idea/resources/intentionDescriptions/FoldWhenToAssignmentIntention/description.html b/idea/resources/intentionDescriptions/FoldBranchedExpressionIntentionFoldWhenToAssignmentIntention/description.html similarity index 100% rename from idea/resources/intentionDescriptions/FoldWhenToAssignmentIntention/description.html rename to idea/resources/intentionDescriptions/FoldBranchedExpressionIntentionFoldWhenToAssignmentIntention/description.html diff --git a/idea/resources/intentionDescriptions/FoldWhenToReturnIntention/after.kt.template b/idea/resources/intentionDescriptions/FoldBranchedExpressionIntentionFoldWhenToReturnIntention/after.kt.template similarity index 100% rename from idea/resources/intentionDescriptions/FoldWhenToReturnIntention/after.kt.template rename to idea/resources/intentionDescriptions/FoldBranchedExpressionIntentionFoldWhenToReturnIntention/after.kt.template diff --git a/idea/resources/intentionDescriptions/FoldWhenToReturnIntention/before.kt.template b/idea/resources/intentionDescriptions/FoldBranchedExpressionIntentionFoldWhenToReturnIntention/before.kt.template similarity index 100% rename from idea/resources/intentionDescriptions/FoldWhenToReturnIntention/before.kt.template rename to idea/resources/intentionDescriptions/FoldBranchedExpressionIntentionFoldWhenToReturnIntention/before.kt.template diff --git a/idea/resources/intentionDescriptions/FoldWhenToReturnIntention/description.html b/idea/resources/intentionDescriptions/FoldBranchedExpressionIntentionFoldWhenToReturnIntention/description.html similarity index 100% rename from idea/resources/intentionDescriptions/FoldWhenToReturnIntention/description.html rename to idea/resources/intentionDescriptions/FoldBranchedExpressionIntentionFoldWhenToReturnIntention/description.html diff --git a/idea/resources/intentionDescriptions/UnfoldAssignmentToIfIntention/after.kt.template b/idea/resources/intentionDescriptions/UnfoldBranchedExpressionIntentionUnfoldAssignmentToIfIntention/after.kt.template similarity index 100% rename from idea/resources/intentionDescriptions/UnfoldAssignmentToIfIntention/after.kt.template rename to idea/resources/intentionDescriptions/UnfoldBranchedExpressionIntentionUnfoldAssignmentToIfIntention/after.kt.template diff --git a/idea/resources/intentionDescriptions/UnfoldAssignmentToIfIntention/before.kt.template b/idea/resources/intentionDescriptions/UnfoldBranchedExpressionIntentionUnfoldAssignmentToIfIntention/before.kt.template similarity index 100% rename from idea/resources/intentionDescriptions/UnfoldAssignmentToIfIntention/before.kt.template rename to idea/resources/intentionDescriptions/UnfoldBranchedExpressionIntentionUnfoldAssignmentToIfIntention/before.kt.template diff --git a/idea/resources/intentionDescriptions/UnfoldAssignmentToIfIntention/description.html b/idea/resources/intentionDescriptions/UnfoldBranchedExpressionIntentionUnfoldAssignmentToIfIntention/description.html similarity index 100% rename from idea/resources/intentionDescriptions/UnfoldAssignmentToIfIntention/description.html rename to idea/resources/intentionDescriptions/UnfoldBranchedExpressionIntentionUnfoldAssignmentToIfIntention/description.html diff --git a/idea/resources/intentionDescriptions/UnfoldAssignmentToWhenIntention/after.kt.template b/idea/resources/intentionDescriptions/UnfoldBranchedExpressionIntentionUnfoldAssignmentToWhenIntention/after.kt.template similarity index 100% rename from idea/resources/intentionDescriptions/UnfoldAssignmentToWhenIntention/after.kt.template rename to idea/resources/intentionDescriptions/UnfoldBranchedExpressionIntentionUnfoldAssignmentToWhenIntention/after.kt.template diff --git a/idea/resources/intentionDescriptions/UnfoldAssignmentToWhenIntention/before.kt.template b/idea/resources/intentionDescriptions/UnfoldBranchedExpressionIntentionUnfoldAssignmentToWhenIntention/before.kt.template similarity index 100% rename from idea/resources/intentionDescriptions/UnfoldAssignmentToWhenIntention/before.kt.template rename to idea/resources/intentionDescriptions/UnfoldBranchedExpressionIntentionUnfoldAssignmentToWhenIntention/before.kt.template diff --git a/idea/resources/intentionDescriptions/UnfoldAssignmentToWhenIntention/description.html b/idea/resources/intentionDescriptions/UnfoldBranchedExpressionIntentionUnfoldAssignmentToWhenIntention/description.html similarity index 100% rename from idea/resources/intentionDescriptions/UnfoldAssignmentToWhenIntention/description.html rename to idea/resources/intentionDescriptions/UnfoldBranchedExpressionIntentionUnfoldAssignmentToWhenIntention/description.html diff --git a/idea/resources/intentionDescriptions/UnfoldReturnToIfIntention/after.kt.template b/idea/resources/intentionDescriptions/UnfoldBranchedExpressionIntentionUnfoldReturnToIfIntention/after.kt.template similarity index 100% rename from idea/resources/intentionDescriptions/UnfoldReturnToIfIntention/after.kt.template rename to idea/resources/intentionDescriptions/UnfoldBranchedExpressionIntentionUnfoldReturnToIfIntention/after.kt.template diff --git a/idea/resources/intentionDescriptions/UnfoldReturnToIfIntention/before.kt.template b/idea/resources/intentionDescriptions/UnfoldBranchedExpressionIntentionUnfoldReturnToIfIntention/before.kt.template similarity index 100% rename from idea/resources/intentionDescriptions/UnfoldReturnToIfIntention/before.kt.template rename to idea/resources/intentionDescriptions/UnfoldBranchedExpressionIntentionUnfoldReturnToIfIntention/before.kt.template diff --git a/idea/resources/intentionDescriptions/UnfoldReturnToIfIntention/description.html b/idea/resources/intentionDescriptions/UnfoldBranchedExpressionIntentionUnfoldReturnToIfIntention/description.html similarity index 100% rename from idea/resources/intentionDescriptions/UnfoldReturnToIfIntention/description.html rename to idea/resources/intentionDescriptions/UnfoldBranchedExpressionIntentionUnfoldReturnToIfIntention/description.html diff --git a/idea/resources/intentionDescriptions/UnfoldReturnToWhenIntention/after.kt.template b/idea/resources/intentionDescriptions/UnfoldBranchedExpressionIntentionUnfoldReturnToWhenIntention/after.kt.template similarity index 100% rename from idea/resources/intentionDescriptions/UnfoldReturnToWhenIntention/after.kt.template rename to idea/resources/intentionDescriptions/UnfoldBranchedExpressionIntentionUnfoldReturnToWhenIntention/after.kt.template diff --git a/idea/resources/intentionDescriptions/UnfoldReturnToWhenIntention/before.kt.template b/idea/resources/intentionDescriptions/UnfoldBranchedExpressionIntentionUnfoldReturnToWhenIntention/before.kt.template similarity index 100% rename from idea/resources/intentionDescriptions/UnfoldReturnToWhenIntention/before.kt.template rename to idea/resources/intentionDescriptions/UnfoldBranchedExpressionIntentionUnfoldReturnToWhenIntention/before.kt.template diff --git a/idea/resources/intentionDescriptions/UnfoldReturnToWhenIntention/description.html b/idea/resources/intentionDescriptions/UnfoldBranchedExpressionIntentionUnfoldReturnToWhenIntention/description.html similarity index 100% rename from idea/resources/intentionDescriptions/UnfoldReturnToWhenIntention/description.html rename to idea/resources/intentionDescriptions/UnfoldBranchedExpressionIntentionUnfoldReturnToWhenIntention/description.html diff --git a/idea/src/META-INF/plugin.xml b/idea/src/META-INF/plugin.xml index 56dd14cd602..effb936cd4e 100644 --- a/idea/src/META-INF/plugin.xml +++ b/idea/src/META-INF/plugin.xml @@ -292,47 +292,47 @@ - org.jetbrains.jet.plugin.codeInsight.codeTransformations.branchedTransformations.intentions.FoldIfToAssignmentIntention + org.jetbrains.jet.plugin.codeInsight.codeTransformations.branchedTransformations.intentions.FoldBranchedExpressionIntention$FoldIfToAssignmentIntention Kotlin - org.jetbrains.jet.plugin.codeInsight.codeTransformations.branchedTransformations.intentions.FoldIfToReturnAsymmetricallyIntention + org.jetbrains.jet.plugin.codeInsight.codeTransformations.branchedTransformations.intentions.FoldBranchedExpressionIntention$FoldIfToReturnAsymmetricallyIntention Kotlin - org.jetbrains.jet.plugin.codeInsight.codeTransformations.branchedTransformations.intentions.FoldIfToReturnIntention + org.jetbrains.jet.plugin.codeInsight.codeTransformations.branchedTransformations.intentions.FoldBranchedExpressionIntention$FoldIfToReturnIntention Kotlin - org.jetbrains.jet.plugin.codeInsight.codeTransformations.branchedTransformations.intentions.FoldWhenToAssignmentIntention + org.jetbrains.jet.plugin.codeInsight.codeTransformations.branchedTransformations.intentions.FoldBranchedExpressionIntention$FoldWhenToAssignmentIntention Kotlin - org.jetbrains.jet.plugin.codeInsight.codeTransformations.branchedTransformations.intentions.FoldWhenToReturnIntention + org.jetbrains.jet.plugin.codeInsight.codeTransformations.branchedTransformations.intentions.FoldBranchedExpressionIntention$FoldWhenToReturnIntention Kotlin - org.jetbrains.jet.plugin.codeInsight.codeTransformations.branchedTransformations.intentions.UnfoldAssignmentToIfIntention + org.jetbrains.jet.plugin.codeInsight.codeTransformations.branchedTransformations.intentions.UnfoldBranchedExpressionIntention$UnfoldAssignmentToIfIntention Kotlin - org.jetbrains.jet.plugin.codeInsight.codeTransformations.branchedTransformations.intentions.UnfoldAssignmentToWhenIntention + org.jetbrains.jet.plugin.codeInsight.codeTransformations.branchedTransformations.intentions.UnfoldBranchedExpressionIntention$UnfoldAssignmentToWhenIntention Kotlin - org.jetbrains.jet.plugin.codeInsight.codeTransformations.branchedTransformations.intentions.UnfoldReturnToIfIntention + org.jetbrains.jet.plugin.codeInsight.codeTransformations.branchedTransformations.intentions.UnfoldBranchedExpressionIntention$UnfoldReturnToIfIntention Kotlin - org.jetbrains.jet.plugin.codeInsight.codeTransformations.branchedTransformations.intentions.UnfoldReturnToWhenIntention + org.jetbrains.jet.plugin.codeInsight.codeTransformations.branchedTransformations.intentions.UnfoldBranchedExpressionIntention$UnfoldReturnToWhenIntention Kotlin diff --git a/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/AbstractCodeTransformationIntention.java b/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/AbstractCodeTransformationIntention.java index 72aace46d98..f26858cf736 100644 --- a/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/AbstractCodeTransformationIntention.java +++ b/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/AbstractCodeTransformationIntention.java @@ -46,14 +46,6 @@ public abstract class AbstractCodeTransformationIntention return JetPsiUtil.getParentByTypeAndPredicate(element, JetElement.class, filter, false); } - protected final T getTransformer() { - return transformer; - } - - protected final Predicate getFilter() { - return filter; - } - @NotNull @Override public String getFamilyName() { diff --git a/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/core/Transformer.java b/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/core/Transformer.java index a2ce45fed31..1693b4b40b8 100644 --- a/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/core/Transformer.java +++ b/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/core/Transformer.java @@ -20,6 +20,7 @@ import com.intellij.psi.PsiElement; import org.jetbrains.annotations.NotNull; public interface Transformer { - public @NotNull String getKey(); + @NotNull + public String getKey(); public void transform(@NotNull PsiElement element); } diff --git a/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/intentions/FoldBranchedExpressionIntention.java b/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/intentions/FoldBranchedExpressionIntention.java index e61bcce509f..1c07527fe46 100644 --- a/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/intentions/FoldBranchedExpressionIntention.java +++ b/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/intentions/FoldBranchedExpressionIntention.java @@ -37,4 +37,34 @@ public abstract class FoldBranchedExpressionIntention extends AbstractCodeTransf } ); } + + public static class FoldIfToAssignmentIntention extends FoldBranchedExpressionIntention { + public FoldIfToAssignmentIntention() { + super(FoldableKind.IF_TO_ASSIGNMENT); + } + } + + public static class FoldIfToReturnAsymmetricallyIntention extends FoldBranchedExpressionIntention { + public FoldIfToReturnAsymmetricallyIntention() { + super(FoldableKind.IF_TO_RETURN_ASYMMETRICALLY); + } + } + + public static class FoldIfToReturnIntention extends FoldBranchedExpressionIntention { + public FoldIfToReturnIntention() { + super(FoldableKind.IF_TO_RETURN); + } + } + + public static class FoldWhenToAssignmentIntention extends FoldBranchedExpressionIntention { + public FoldWhenToAssignmentIntention() { + super(FoldableKind.WHEN_TO_ASSIGNMENT); + } + } + + public static class FoldWhenToReturnIntention extends FoldBranchedExpressionIntention { + public FoldWhenToReturnIntention() { + super(FoldableKind.WHEN_TO_RETURN); + } + } } diff --git a/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/intentions/FoldIfToAssignmentIntention.java b/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/intentions/FoldIfToAssignmentIntention.java deleted file mode 100644 index 30b2466f232..00000000000 --- a/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/intentions/FoldIfToAssignmentIntention.java +++ /dev/null @@ -1,25 +0,0 @@ -/* - * Copyright 2010-2013 JetBrains s.r.o. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.jetbrains.jet.plugin.codeInsight.codeTransformations.branchedTransformations.intentions; - -import org.jetbrains.jet.plugin.codeInsight.codeTransformations.branchedTransformations.FoldableKind; - -public class FoldIfToAssignmentIntention extends FoldBranchedExpressionIntention { - public FoldIfToAssignmentIntention() { - super(FoldableKind.IF_TO_ASSIGNMENT); - } -} diff --git a/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/intentions/FoldIfToReturnAsymmetricallyIntention.java b/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/intentions/FoldIfToReturnAsymmetricallyIntention.java deleted file mode 100644 index 128ecf8a25a..00000000000 --- a/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/intentions/FoldIfToReturnAsymmetricallyIntention.java +++ /dev/null @@ -1,25 +0,0 @@ -/* - * Copyright 2010-2013 JetBrains s.r.o. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.jetbrains.jet.plugin.codeInsight.codeTransformations.branchedTransformations.intentions; - -import org.jetbrains.jet.plugin.codeInsight.codeTransformations.branchedTransformations.FoldableKind; - -public class FoldIfToReturnAsymmetricallyIntention extends FoldBranchedExpressionIntention { - public FoldIfToReturnAsymmetricallyIntention() { - super(FoldableKind.IF_TO_RETURN_ASYMMETRICALLY); - } -} diff --git a/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/intentions/FoldIfToReturnIntention.java b/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/intentions/FoldIfToReturnIntention.java deleted file mode 100644 index a63fd84b868..00000000000 --- a/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/intentions/FoldIfToReturnIntention.java +++ /dev/null @@ -1,25 +0,0 @@ -/* - * Copyright 2010-2013 JetBrains s.r.o. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.jetbrains.jet.plugin.codeInsight.codeTransformations.branchedTransformations.intentions; - -import org.jetbrains.jet.plugin.codeInsight.codeTransformations.branchedTransformations.FoldableKind; - -public class FoldIfToReturnIntention extends FoldBranchedExpressionIntention { - public FoldIfToReturnIntention() { - super(FoldableKind.IF_TO_RETURN); - } -} diff --git a/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/intentions/FoldWhenToAssignmentIntention.java b/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/intentions/FoldWhenToAssignmentIntention.java deleted file mode 100644 index 3c307dc3b3d..00000000000 --- a/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/intentions/FoldWhenToAssignmentIntention.java +++ /dev/null @@ -1,25 +0,0 @@ -/* - * Copyright 2010-2013 JetBrains s.r.o. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.jetbrains.jet.plugin.codeInsight.codeTransformations.branchedTransformations.intentions; - -import org.jetbrains.jet.plugin.codeInsight.codeTransformations.branchedTransformations.FoldableKind; - -public class FoldWhenToAssignmentIntention extends FoldBranchedExpressionIntention { - public FoldWhenToAssignmentIntention() { - super(FoldableKind.WHEN_TO_ASSIGNMENT); - } -} diff --git a/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/intentions/FoldWhenToReturnIntention.java b/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/intentions/FoldWhenToReturnIntention.java deleted file mode 100644 index fd1bc61726c..00000000000 --- a/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/intentions/FoldWhenToReturnIntention.java +++ /dev/null @@ -1,25 +0,0 @@ -/* - * Copyright 2010-2013 JetBrains s.r.o. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.jetbrains.jet.plugin.codeInsight.codeTransformations.branchedTransformations.intentions; - -import org.jetbrains.jet.plugin.codeInsight.codeTransformations.branchedTransformations.FoldableKind; - -public class FoldWhenToReturnIntention extends FoldBranchedExpressionIntention { - public FoldWhenToReturnIntention() { - super(FoldableKind.WHEN_TO_RETURN); - } -} diff --git a/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/intentions/UnfoldAssignmentToIfIntention.java b/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/intentions/UnfoldAssignmentToIfIntention.java deleted file mode 100644 index a0db1a07526..00000000000 --- a/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/intentions/UnfoldAssignmentToIfIntention.java +++ /dev/null @@ -1,25 +0,0 @@ -/* - * Copyright 2010-2013 JetBrains s.r.o. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.jetbrains.jet.plugin.codeInsight.codeTransformations.branchedTransformations.intentions; - -import org.jetbrains.jet.plugin.codeInsight.codeTransformations.branchedTransformations.UnfoldableKind; - -public class UnfoldAssignmentToIfIntention extends UnfoldBranchedExpressionIntention { - public UnfoldAssignmentToIfIntention() { - super(UnfoldableKind.ASSIGNMENT_TO_IF); - } -} diff --git a/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/intentions/UnfoldAssignmentToWhenIntention.java b/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/intentions/UnfoldAssignmentToWhenIntention.java deleted file mode 100644 index 102c65ddd1f..00000000000 --- a/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/intentions/UnfoldAssignmentToWhenIntention.java +++ /dev/null @@ -1,25 +0,0 @@ -/* - * Copyright 2010-2013 JetBrains s.r.o. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.jetbrains.jet.plugin.codeInsight.codeTransformations.branchedTransformations.intentions; - -import org.jetbrains.jet.plugin.codeInsight.codeTransformations.branchedTransformations.UnfoldableKind; - -public class UnfoldAssignmentToWhenIntention extends UnfoldBranchedExpressionIntention { - public UnfoldAssignmentToWhenIntention() { - super(UnfoldableKind.ASSIGNMENT_TO_WHEN); - } -} diff --git a/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/intentions/UnfoldBranchedExpressionIntention.java b/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/intentions/UnfoldBranchedExpressionIntention.java index 6d21ec4afa9..40cf4066f8d 100644 --- a/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/intentions/UnfoldBranchedExpressionIntention.java +++ b/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/intentions/UnfoldBranchedExpressionIntention.java @@ -35,4 +35,28 @@ public abstract class UnfoldBranchedExpressionIntention extends AbstractCodeTran } ); } + + public static class UnfoldAssignmentToIfIntention extends UnfoldBranchedExpressionIntention { + public UnfoldAssignmentToIfIntention() { + super(UnfoldableKind.ASSIGNMENT_TO_IF); + } + } + + public static class UnfoldAssignmentToWhenIntention extends UnfoldBranchedExpressionIntention { + public UnfoldAssignmentToWhenIntention() { + super(UnfoldableKind.ASSIGNMENT_TO_WHEN); + } + } + + public static class UnfoldReturnToIfIntention extends UnfoldBranchedExpressionIntention { + public UnfoldReturnToIfIntention() { + super(UnfoldableKind.RETURN_TO_IF); + } + } + + public static class UnfoldReturnToWhenIntention extends UnfoldBranchedExpressionIntention { + public UnfoldReturnToWhenIntention() { + super(UnfoldableKind.RETURN_TO_WHEN); + } + } } diff --git a/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/intentions/UnfoldReturnToIfIntention.java b/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/intentions/UnfoldReturnToIfIntention.java deleted file mode 100644 index 4018d2dcfc2..00000000000 --- a/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/intentions/UnfoldReturnToIfIntention.java +++ /dev/null @@ -1,25 +0,0 @@ -/* - * Copyright 2010-2013 JetBrains s.r.o. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.jetbrains.jet.plugin.codeInsight.codeTransformations.branchedTransformations.intentions; - -import org.jetbrains.jet.plugin.codeInsight.codeTransformations.branchedTransformations.UnfoldableKind; - -public class UnfoldReturnToIfIntention extends UnfoldBranchedExpressionIntention { - public UnfoldReturnToIfIntention() { - super(UnfoldableKind.RETURN_TO_IF); - } -} diff --git a/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/intentions/UnfoldReturnToWhenIntention.java b/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/intentions/UnfoldReturnToWhenIntention.java deleted file mode 100644 index 156954aada1..00000000000 --- a/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/intentions/UnfoldReturnToWhenIntention.java +++ /dev/null @@ -1,25 +0,0 @@ -/* - * Copyright 2010-2013 JetBrains s.r.o. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.jetbrains.jet.plugin.codeInsight.codeTransformations.branchedTransformations.intentions; - -import org.jetbrains.jet.plugin.codeInsight.codeTransformations.branchedTransformations.UnfoldableKind; - -public class UnfoldReturnToWhenIntention extends UnfoldBranchedExpressionIntention { - public UnfoldReturnToWhenIntention() { - super(UnfoldableKind.RETURN_TO_WHEN); - } -} diff --git a/idea/tests/org/jetbrains/jet/plugin/codeInsight/codeTransformations/AbstractCodeTransformationTest.java b/idea/tests/org/jetbrains/jet/plugin/codeInsight/codeTransformations/AbstractCodeTransformationTest.java index 690abe64d19..b838ac1dcf7 100644 --- a/idea/tests/org/jetbrains/jet/plugin/codeInsight/codeTransformations/AbstractCodeTransformationTest.java +++ b/idea/tests/org/jetbrains/jet/plugin/codeInsight/codeTransformations/AbstractCodeTransformationTest.java @@ -27,39 +27,39 @@ import java.io.File; public abstract class AbstractCodeTransformationTest extends LightCodeInsightTestCase { public void doTestFoldIfToAssignment(@NotNull String path) throws Exception { - doTest(path, new FoldIfToAssignmentIntention()); + doTest(path, new FoldBranchedExpressionIntention.FoldIfToAssignmentIntention()); } public void doTestFoldIfToReturn(@NotNull String path) throws Exception { - doTest(path, new FoldIfToReturnIntention()); + doTest(path, new FoldBranchedExpressionIntention.FoldIfToReturnIntention()); } public void doTestFoldIfToReturnAsymmetrically(@NotNull String path) throws Exception { - doTest(path, new FoldIfToReturnAsymmetricallyIntention()); + doTest(path, new FoldBranchedExpressionIntention.FoldIfToReturnAsymmetricallyIntention()); } public void doTestFoldWhenToAssignment(@NotNull String path) throws Exception { - doTest(path, new FoldWhenToAssignmentIntention()); + doTest(path, new FoldBranchedExpressionIntention.FoldWhenToAssignmentIntention()); } public void doTestFoldWhenToReturn(@NotNull String path) throws Exception { - doTest(path, new FoldWhenToReturnIntention()); + doTest(path, new FoldBranchedExpressionIntention.FoldWhenToReturnIntention()); } public void doTestUnfoldAssignmentToIf(@NotNull String path) throws Exception { - doTest(path, new UnfoldAssignmentToIfIntention()); + doTest(path, new UnfoldBranchedExpressionIntention.UnfoldAssignmentToIfIntention()); } public void doTestUnfoldAssignmentToWhen(@NotNull String path) throws Exception { - doTest(path, new UnfoldAssignmentToWhenIntention()); + doTest(path, new UnfoldBranchedExpressionIntention.UnfoldAssignmentToWhenIntention()); } public void doTestUnfoldReturnToIf(@NotNull String path) throws Exception { - doTest(path, new UnfoldReturnToIfIntention()); + doTest(path, new UnfoldBranchedExpressionIntention.UnfoldReturnToIfIntention()); } public void doTestUnfoldReturnToWhen(@NotNull String path) throws Exception { - doTest(path, new UnfoldReturnToWhenIntention()); + doTest(path, new UnfoldBranchedExpressionIntention.UnfoldReturnToWhenIntention()); } public void doTestRemoveUnnecessaryParentheses(@NotNull String path) throws Exception { From f4c220e735864a3042bc712ace886dd1e54eb3b5 Mon Sep 17 00:00:00 2001 From: Alexey Sedunov Date: Thu, 18 Apr 2013 16:01:00 +0400 Subject: [PATCH 078/249] Rename intention predicate --- .../AbstractCodeTransformationIntention.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/AbstractCodeTransformationIntention.java b/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/AbstractCodeTransformationIntention.java index f26858cf736..28a55d3214b 100644 --- a/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/AbstractCodeTransformationIntention.java +++ b/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/AbstractCodeTransformationIntention.java @@ -32,18 +32,18 @@ import org.jetbrains.jet.plugin.codeInsight.codeTransformations.branchedTransfor public abstract class AbstractCodeTransformationIntention extends BaseIntentionAction { private final T transformer; - private final Predicate filter; + private final Predicate isApplicable; - protected AbstractCodeTransformationIntention(@NotNull T transformer, @NotNull Predicate filter) { + protected AbstractCodeTransformationIntention(@NotNull T transformer, @NotNull Predicate isApplicable) { this.transformer = transformer; - this.filter = filter; + this.isApplicable = isApplicable; setText(JetBundle.message(transformer.getKey())); } @Nullable private PsiElement getTarget(@NotNull Editor editor, @NotNull PsiFile file) { PsiElement element = file.findElementAt(editor.getCaretModel().getOffset()); - return JetPsiUtil.getParentByTypeAndPredicate(element, JetElement.class, filter, false); + return JetPsiUtil.getParentByTypeAndPredicate(element, JetElement.class, isApplicable, false); } @NotNull From f5b1706b3086f685bb4819d41b92e82b6f8fc18b Mon Sep 17 00:00:00 2001 From: Alexey Sedunov Date: Thu, 18 Apr 2013 16:10:41 +0400 Subject: [PATCH 079/249] Extract 'assertNotNull' method --- .../BranchedFoldingUtils.java | 69 ++++++++++++------- .../BranchedUnfoldingUtils.java | 28 +++++--- 2 files changed, 61 insertions(+), 36 deletions(-) diff --git a/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/BranchedFoldingUtils.java b/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/BranchedFoldingUtils.java index fdcf12eafeb..f22bf545edd 100644 --- a/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/BranchedFoldingUtils.java +++ b/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/BranchedFoldingUtils.java @@ -158,12 +158,16 @@ public class BranchedFoldingUtils { public static final String FOLD_WITHOUT_CHECK = "Expression must be checked before folding"; + private static void assertNotNull(JetExpression expression) { + assert expression != null : FOLD_WITHOUT_CHECK; + } + public static void foldIfExpressionWithAssignments(JetIfExpression ifExpression) { Project project = ifExpression.getProject(); JetBinaryExpression thenAssignment = getFoldableBranchedAssignment(ifExpression.getThen()); - assert thenAssignment != null : FOLD_WITHOUT_CHECK; + assertNotNull(thenAssignment); String op = thenAssignment.getOperationReference().getText(); JetSimpleNameExpression lhs = (JetSimpleNameExpression) thenAssignment.getLeft(); @@ -171,21 +175,24 @@ public class BranchedFoldingUtils { JetBinaryExpression assignment = JetPsiFactory.createBinaryExpression(project, lhs, op, ifExpression); JetIfExpression newIfExpression = (JetIfExpression)assignment.getRight(); - assert newIfExpression != null : FOLD_WITHOUT_CHECK; + assertNotNull(newIfExpression); + //noinspection ConstantConditions thenAssignment = getFoldableBranchedAssignment(newIfExpression.getThen()); JetBinaryExpression elseAssignment = getFoldableBranchedAssignment(newIfExpression.getElse()); - assert thenAssignment != null : FOLD_WITHOUT_CHECK; - assert elseAssignment != null : FOLD_WITHOUT_CHECK; + assertNotNull(thenAssignment); + assertNotNull(elseAssignment); JetExpression thenRhs = thenAssignment.getRight(); JetExpression elseRhs = elseAssignment.getRight(); - assert thenRhs != null : FOLD_WITHOUT_CHECK; - assert elseRhs != null : FOLD_WITHOUT_CHECK; + assertNotNull(thenRhs); + assertNotNull(elseRhs); + //noinspection ConstantConditions thenAssignment.replace(thenRhs); + //noinspection ConstantConditions elseAssignment.replace(elseRhs); ifExpression.replace(assignment); @@ -197,21 +204,24 @@ public class BranchedFoldingUtils { JetReturnExpression newReturnExpression = JetPsiFactory.createReturn(project, ifExpression); JetIfExpression newIfExpression = (JetIfExpression)newReturnExpression.getReturnedExpression(); - assert newIfExpression != null; + assertNotNull(newIfExpression); + //noinspection ConstantConditions JetReturnExpression thenReturn = getFoldableBranchedReturn(newIfExpression.getThen()); JetReturnExpression elseReturn = getFoldableBranchedReturn(newIfExpression.getElse()); - assert thenReturn != null : FOLD_WITHOUT_CHECK; - assert elseReturn != null : FOLD_WITHOUT_CHECK; + assertNotNull(thenReturn); + assertNotNull(elseReturn); JetExpression thenExpr = thenReturn.getReturnedExpression(); JetExpression elseExpr = elseReturn.getReturnedExpression(); - assert thenExpr != null : FOLD_WITHOUT_CHECK; - assert elseExpr != null : FOLD_WITHOUT_CHECK; + assertNotNull(thenExpr); + assertNotNull(elseExpr); + //noinspection ConstantConditions thenReturn.replace(thenExpr); + //noinspection ConstantConditions elseReturn.replace(elseExpr); ifExpression.replace(newReturnExpression); @@ -224,36 +234,41 @@ public class BranchedFoldingUtils { JetExpression thenRoot = ifExpression.getThen(); JetExpression elseRoot = (JetExpression)JetPsiUtil.skipTrailingWhitespacesAndComments(ifExpression); - assert condition != null : FOLD_WITHOUT_CHECK; - assert thenRoot != null : FOLD_WITHOUT_CHECK; - assert elseRoot != null : FOLD_WITHOUT_CHECK; + assertNotNull(condition); + assertNotNull(thenRoot); + assertNotNull(elseRoot); + //noinspection ConstantConditions JetIfExpression newIfExpression = JetPsiFactory.createIf(project, condition, thenRoot, elseRoot); JetReturnExpression newReturnExpression = JetPsiFactory.createReturn(project, newIfExpression); newIfExpression = (JetIfExpression)newReturnExpression.getReturnedExpression(); - assert newIfExpression != null : FOLD_WITHOUT_CHECK; + assertNotNull(newIfExpression); + //noinspection ConstantConditions JetReturnExpression thenReturn = getFoldableBranchedReturn(newIfExpression.getThen()); JetReturnExpression elseReturn = getFoldableBranchedReturn(newIfExpression.getElse()); - assert thenReturn != null : FOLD_WITHOUT_CHECK; - assert elseReturn != null : FOLD_WITHOUT_CHECK; + assertNotNull(thenReturn); + assertNotNull(elseReturn); JetExpression thenExpr = thenReturn.getReturnedExpression(); JetExpression elseExpr = elseReturn.getReturnedExpression(); - assert thenExpr != null : FOLD_WITHOUT_CHECK; - assert elseExpr != null : FOLD_WITHOUT_CHECK; + assertNotNull(thenExpr); + assertNotNull(elseExpr); + //noinspection ConstantConditions thenReturn.replace(thenExpr); + //noinspection ConstantConditions elseReturn.replace(elseExpr); elseRoot.delete(); ifExpression.replace(newReturnExpression); } + @SuppressWarnings("ConstantConditions") public static void foldWhenExpressionWithAssignments(JetWhenExpression whenExpression) { Project project = whenExpression.getProject(); @@ -261,7 +276,7 @@ public class BranchedFoldingUtils { JetBinaryExpression firstAssignment = getFoldableBranchedAssignment(whenExpression.getEntries().get(0).getExpression()); - assert firstAssignment != null : FOLD_WITHOUT_CHECK; + assertNotNull(firstAssignment); String op = firstAssignment.getOperationReference().getText(); JetSimpleNameExpression lhs = (JetSimpleNameExpression) firstAssignment.getLeft(); @@ -269,16 +284,16 @@ public class BranchedFoldingUtils { JetBinaryExpression assignment = JetPsiFactory.createBinaryExpression(project, lhs, op, whenExpression); JetWhenExpression newWhenExpression = (JetWhenExpression)assignment.getRight(); - assert newWhenExpression != null : FOLD_WITHOUT_CHECK; + assertNotNull(newWhenExpression); for (JetWhenEntry entry : newWhenExpression.getEntries()) { JetBinaryExpression currAssignment = getFoldableBranchedAssignment(entry.getExpression()); - assert currAssignment != null : FOLD_WITHOUT_CHECK; + assertNotNull(currAssignment); JetExpression currRhs = currAssignment.getRight(); - assert currRhs != null : FOLD_WITHOUT_CHECK; + assertNotNull(currRhs); currAssignment.replace(currRhs); } @@ -294,17 +309,19 @@ public class BranchedFoldingUtils { JetReturnExpression newReturnExpression = JetPsiFactory.createReturn(project, whenExpression); JetWhenExpression newWhenExpression = (JetWhenExpression)newReturnExpression.getReturnedExpression(); - assert newWhenExpression != null : FOLD_WITHOUT_CHECK; + assertNotNull(newWhenExpression); + //noinspection ConstantConditions for (JetWhenEntry entry : newWhenExpression.getEntries()) { JetReturnExpression currReturn = getFoldableBranchedReturn(entry.getExpression()); - assert currReturn != null : FOLD_WITHOUT_CHECK; + assertNotNull(currReturn); JetExpression currExpr = currReturn.getReturnedExpression(); - assert currExpr != null : FOLD_WITHOUT_CHECK; + assertNotNull(currExpr); + //noinspection ConstantConditions currReturn.replace(currExpr); } diff --git a/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/BranchedUnfoldingUtils.java b/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/BranchedUnfoldingUtils.java index d9b1c9c4e2d..f680d7524ac 100644 --- a/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/BranchedUnfoldingUtils.java +++ b/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/BranchedUnfoldingUtils.java @@ -54,21 +54,26 @@ public class BranchedUnfoldingUtils { public static final String UNFOLD_WITHOUT_CHECK = "Expression must be checked before unfolding"; + private static void assertNotNull(JetExpression expression) { + assert expression != null : UNFOLD_WITHOUT_CHECK; + } + public static void unfoldAssignmentToIf(@NotNull JetBinaryExpression assignment) { Project project = assignment.getProject(); String op = assignment.getOperationReference().getText(); JetExpression lhs = assignment.getLeft(); JetIfExpression ifExpression = (JetIfExpression)assignment.getRight(); - assert ifExpression != null : UNFOLD_WITHOUT_CHECK; + assertNotNull(ifExpression); + //noinspection ConstantConditions JetIfExpression newIfExpression = (JetIfExpression) ifExpression.copy(); JetExpression thenExpr = getOutermostLastBlockElement(newIfExpression.getThen()); JetExpression elseExpr = getOutermostLastBlockElement(newIfExpression.getElse()); - assert thenExpr != null : UNFOLD_WITHOUT_CHECK; - assert elseExpr != null : UNFOLD_WITHOUT_CHECK; + assertNotNull(thenExpr); + assertNotNull(elseExpr); thenExpr.replace(JetPsiFactory.createBinaryExpression(project, lhs, op, thenExpr)); elseExpr.replace(JetPsiFactory.createBinaryExpression(project, lhs, op, elseExpr)); @@ -82,14 +87,15 @@ public class BranchedUnfoldingUtils { JetExpression lhs = assignment.getLeft(); JetWhenExpression whenExpression = (JetWhenExpression)assignment.getRight(); - assert whenExpression != null : UNFOLD_WITHOUT_CHECK; + assertNotNull(whenExpression); + //noinspection ConstantConditions JetWhenExpression newWhenExpression = (JetWhenExpression) whenExpression.copy(); for (JetWhenEntry entry : newWhenExpression.getEntries()) { JetExpression currExpr = getOutermostLastBlockElement(entry.getExpression()); - assert currExpr != null : UNFOLD_WITHOUT_CHECK; + assertNotNull(currExpr); currExpr.replace(JetPsiFactory.createBinaryExpression(project, lhs, op, currExpr)); } @@ -101,15 +107,16 @@ public class BranchedUnfoldingUtils { Project project = returnExpression.getProject(); JetIfExpression ifExpression = (JetIfExpression)returnExpression.getReturnedExpression(); - assert ifExpression != null : UNFOLD_WITHOUT_CHECK; + assertNotNull(ifExpression); + //noinspection ConstantConditions JetIfExpression newIfExpression = (JetIfExpression) ifExpression.copy(); JetExpression thenExpr = getOutermostLastBlockElement(newIfExpression.getThen()); JetExpression elseExpr = getOutermostLastBlockElement(newIfExpression.getElse()); - assert thenExpr != null : UNFOLD_WITHOUT_CHECK; - assert elseExpr != null : UNFOLD_WITHOUT_CHECK; + assertNotNull(thenExpr); + assertNotNull(elseExpr); thenExpr.replace(JetPsiFactory.createReturn(project, thenExpr)); elseExpr.replace(JetPsiFactory.createReturn(project, elseExpr)); @@ -121,14 +128,15 @@ public class BranchedUnfoldingUtils { Project project = returnExpression.getProject(); JetWhenExpression whenExpression = (JetWhenExpression)returnExpression.getReturnedExpression(); - assert whenExpression != null : UNFOLD_WITHOUT_CHECK; + assertNotNull(whenExpression); + //noinspection ConstantConditions JetWhenExpression newWhenExpression = (JetWhenExpression) whenExpression.copy(); for (JetWhenEntry entry : newWhenExpression.getEntries()) { JetExpression currExpr = getOutermostLastBlockElement(entry.getExpression()); - assert currExpr != null : UNFOLD_WITHOUT_CHECK; + assertNotNull(currExpr); currExpr.replace(JetPsiFactory.createReturn(project, currExpr)); } From b7bc251311c4a01c081f749a7689334730ffb9bb Mon Sep 17 00:00:00 2001 From: Alexey Sedunov Date: Fri, 26 Apr 2013 13:36:14 +0400 Subject: [PATCH 080/249] Add extraction of 'else' branch of 'when' expression --- .../src/org/jetbrains/jet/lang/psi/JetPsiUtil.java | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetPsiUtil.java b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetPsiUtil.java index 73364aa0f56..e5c880dc45b 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetPsiUtil.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetPsiUtil.java @@ -693,6 +693,15 @@ public class JetPsiUtil { return (elseCount == 1); } + public static JetExpression getWhenElseBranch(@NotNull JetWhenExpression whenExpression) { + for (JetWhenEntry entry : whenExpression.getEntries()) { + if (entry.isElse()) { + return entry.getExpression(); + } + } + return null; + } + public static PsiElement skipTrailingWhitespacesAndComments(PsiElement element) { return PsiTreeUtil.skipSiblingsForward(element, PsiWhiteSpace.class, PsiComment.class); } From 057528eb39afc7d276591a21e7b346ed8af3e585 Mon Sep 17 00:00:00 2001 From: Alexey Sedunov Date: Fri, 26 Apr 2013 13:38:57 +0400 Subject: [PATCH 081/249] Add 'when' builder and creation of 'is' expressions --- .../jetbrains/jet/lang/psi/JetPsiFactory.java | 109 ++++++++++++++++++ 1 file changed, 109 insertions(+) diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetPsiFactory.java b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetPsiFactory.java index f925ca13211..6e5a58a2056 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetPsiFactory.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetPsiFactory.java @@ -275,6 +275,22 @@ public class JetPsiFactory { return new JetExpressionCodeFragmentImpl(project, "fragment.kt", text, context); } + @NotNull + public static JetIsExpression createIsExpression(Project project, @NotNull String lhs, @NotNull String rhs, boolean negated) { + return (JetIsExpression) createExpression(project, lhs + " " + (negated ? "!is" : "is") + " " + rhs); + } + + @SuppressWarnings("ConstantConditions") + @NotNull + public static JetIsExpression createIsExpression(Project project, @NotNull JetExpression lhs, @NotNull JetTypeReference rhs, boolean negated) { + JetIsExpression isExpression = createIsExpression(project, "_", "_", negated); + + isExpression = (JetIsExpression)isExpression.getLeftHandSide().replace(lhs).getParent(); + isExpression = (JetIsExpression)isExpression.getTypeRef().replace(rhs).getParent(); + + return isExpression; + } + @NotNull public static JetReturnExpression createReturn(Project project, @NotNull String text) { return (JetReturnExpression) createExpression(project, "return " + text); @@ -312,4 +328,97 @@ public class JetPsiFactory { return ifExpr; } + + public static class WhenTemplateBuilder { + private final StringBuilder sb = new StringBuilder("when "); + private boolean frozen = false; + private boolean inCondition = false; + + public WhenTemplateBuilder(boolean addSubject) { + if (addSubject) { + sb.append("(_) "); + } + sb.append("{\n"); + } + + private void finishAndFreeze() { + sb.append("else -> _\n}"); + frozen = true; + } + + private WhenTemplateBuilder addCondition(String text) { + assert !frozen; + + if (!inCondition) { + inCondition = true; + } else { + sb.append(", "); + } + sb.append(text); + + return this; + } + + public WhenTemplateBuilder addBranchWithSingleCondition() { + assert !frozen; + + sb.append("_ -> _\n"); + + return this; + } + + public WhenTemplateBuilder addBranchesWithSingleCondition(int count) { + for (int i = 0; i < count; i++) { + addBranchWithSingleCondition(); + } + + return this; + } + + public WhenTemplateBuilder addBranchWithMultiCondition(int conditionCount) { + assert !frozen; + assert conditionCount > 0; + + sb.append("_"); + for (int i = 0; i < conditionCount - 1; i++) { + sb.append(", _"); + } + sb.append(" -> _\n"); + + return this; + } + + public WhenTemplateBuilder addExpressionCondition() { + return addCondition("_"); + } + + public WhenTemplateBuilder addIsCondition(boolean negated) { + return addCondition((negated ? "!is" : "is") + " _"); + } + + public WhenTemplateBuilder addInCondition(boolean negated) { + return addCondition((negated ? "!in" : "in") + " _"); + } + + public WhenTemplateBuilder finishBranch() { + assert !frozen; + assert inCondition; + + inCondition = false; + sb.append(" -> _\n"); + + return this; + } + + public JetWhenExpression toExpression(Project project) { + if (!frozen) { + finishAndFreeze(); + } + return (JetWhenExpression) createExpression(project, sb.toString()); + } + } + + public static JetWhenExpression createWhenWithoutSubject(Project project, int positiveBranchCount) { + return new WhenTemplateBuilder(false).addBranchesWithSingleCondition(positiveBranchCount).toExpression(project); + } } From 36b68786b04a842baad380123baae6fbc57a9e47 Mon Sep 17 00:00:00 2001 From: Alexey Sedunov Date: Fri, 26 Apr 2013 13:40:12 +0400 Subject: [PATCH 082/249] Add new-line flags to 'if' factory method --- .../jetbrains/jet/lang/psi/JetPsiFactory.java | 16 ++++++++++++---- .../BranchedFoldingUtils.java | 2 +- 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetPsiFactory.java b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetPsiFactory.java index 6e5a58a2056..bbbb945a3d6 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetPsiFactory.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetPsiFactory.java @@ -307,14 +307,22 @@ public class JetPsiFactory { } @NotNull - public static JetIfExpression createIf(Project project, @NotNull String condText, @NotNull String thenText, @Nullable String elseText) { - return (JetIfExpression) createExpression(project, "if (" + condText + ") " + thenText + (elseText != null ? " else " + elseText : "")); + public static JetIfExpression createIf( + Project project, + @NotNull String condText, @NotNull String thenText, @Nullable String elseText, + boolean thenNewLine, boolean elseNewLine) { + String thenSpace = thenNewLine ? "\n" : " "; + String elseSpace = elseNewLine ? "\n" : " "; + return (JetIfExpression) createExpression(project, "if (" + condText + ")" + thenSpace + thenText + (elseText != null ? elseSpace + "else " + elseText : "")); } @SuppressWarnings("ConstantConditions") @NotNull - public static JetIfExpression createIf(Project project, @NotNull JetExpression condition, @NotNull JetExpression thenExpr, @Nullable JetExpression elseExpr) { - JetIfExpression ifExpr = createIf(project, "_", "_", elseExpr != null ? "_" : null); + public static JetIfExpression createIf( + Project project, + @NotNull JetExpression condition, @NotNull JetExpression thenExpr, @Nullable JetExpression elseExpr, + boolean thenNewLine, boolean elseNewLine) { + JetIfExpression ifExpr = createIf(project, "_", "_", elseExpr != null ? "_" : null, thenNewLine, elseNewLine); assert ifExpr.getCondition() != null; assert ifExpr.getThen() != null; diff --git a/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/BranchedFoldingUtils.java b/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/BranchedFoldingUtils.java index f22bf545edd..402a4094cae 100644 --- a/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/BranchedFoldingUtils.java +++ b/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/BranchedFoldingUtils.java @@ -239,7 +239,7 @@ public class BranchedFoldingUtils { assertNotNull(elseRoot); //noinspection ConstantConditions - JetIfExpression newIfExpression = JetPsiFactory.createIf(project, condition, thenRoot, elseRoot); + JetIfExpression newIfExpression = JetPsiFactory.createIf(project, condition, thenRoot, elseRoot, false, false); JetReturnExpression newReturnExpression = JetPsiFactory.createReturn(project, newIfExpression); newIfExpression = (JetIfExpression)newReturnExpression.getReturnedExpression(); From c054c0cdbef7e88dc9d09a6484608c61276b356d Mon Sep 17 00:00:00 2001 From: Alexey Sedunov Date: Fri, 26 Apr 2013 13:55:35 +0400 Subject: [PATCH 083/249] Add factory methods for parenthesized expressions --- .../jetbrains/jet/lang/psi/JetPsiFactory.java | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetPsiFactory.java b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetPsiFactory.java index bbbb945a3d6..e2657f13115 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetPsiFactory.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetPsiFactory.java @@ -429,4 +429,22 @@ public class JetPsiFactory { public static JetWhenExpression createWhenWithoutSubject(Project project, int positiveBranchCount) { return new WhenTemplateBuilder(false).addBranchesWithSingleCondition(positiveBranchCount).toExpression(project); } + + public static JetParenthesizedExpression createParenthesizedExpression(Project project, @NotNull String text) { + return (JetParenthesizedExpression)createExpression(project, "(" + text + ")"); + } + + @SuppressWarnings("ConstantConditions") + public static JetParenthesizedExpression createParenthesizedExpression(Project project, @NotNull JetExpression expression) { + JetParenthesizedExpression parenthesizedExpression = createParenthesizedExpression(project, "_"); + parenthesizedExpression.getExpression().replace(expression); + + return parenthesizedExpression; + } + + public static JetParenthesizedExpression createParenthesizedExpressionIfNeeded(Project project, @NotNull JetExpression expression) { + return (expression instanceof JetParenthesizedExpression) ? + (JetParenthesizedExpression) expression : + createParenthesizedExpression(project, expression); + } } From 3c691062adb1e4952c4a80bf823591a5c1084c4c Mon Sep 17 00:00:00 2001 From: Alexey Sedunov Date: Fri, 26 Apr 2013 14:10:00 +0400 Subject: [PATCH 084/249] Implement if-to-when and when-to-if transformations --- .../IfToWhenIntention/after.kt.template | 11 + .../IfToWhenIntention/before.kt.template | 7 + .../IfToWhenIntention/description.html | 5 + .../WhenToIfIntention/after.kt.template | 7 + .../WhenToIfIntention/before.kt.template | 11 + .../WhenToIfIntention/description.html | 5 + .../branchedTransformations/IfWhenUtils.java | 206 ++++++++++++++++++ .../intentions/IfToWhenIntention.java | 36 +++ .../intentions/WhenToIfIntention.java | 52 +++++ 9 files changed, 340 insertions(+) create mode 100644 idea/resources/intentionDescriptions/IfToWhenIntention/after.kt.template create mode 100644 idea/resources/intentionDescriptions/IfToWhenIntention/before.kt.template create mode 100644 idea/resources/intentionDescriptions/IfToWhenIntention/description.html create mode 100644 idea/resources/intentionDescriptions/WhenToIfIntention/after.kt.template create mode 100644 idea/resources/intentionDescriptions/WhenToIfIntention/before.kt.template create mode 100644 idea/resources/intentionDescriptions/WhenToIfIntention/description.html create mode 100644 idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/IfWhenUtils.java create mode 100644 idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/intentions/IfToWhenIntention.java create mode 100644 idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/intentions/WhenToIfIntention.java diff --git a/idea/resources/intentionDescriptions/IfToWhenIntention/after.kt.template b/idea/resources/intentionDescriptions/IfToWhenIntention/after.kt.template new file mode 100644 index 00000000000..949cf0ab13d --- /dev/null +++ b/idea/resources/intentionDescriptions/IfToWhenIntention/after.kt.template @@ -0,0 +1,11 @@ +when (n) { + 1 -> { + res = "one" + } + 2 -> { + res = "two" + } + else -> { + res = "???" + } +} \ No newline at end of file diff --git a/idea/resources/intentionDescriptions/IfToWhenIntention/before.kt.template b/idea/resources/intentionDescriptions/IfToWhenIntention/before.kt.template new file mode 100644 index 00000000000..0fd94490980 --- /dev/null +++ b/idea/resources/intentionDescriptions/IfToWhenIntention/before.kt.template @@ -0,0 +1,7 @@ +if (n == 1) { + res = "one" +} else if (n == 2) { + res = "two" +} else { + res = "???" +} \ No newline at end of file diff --git a/idea/resources/intentionDescriptions/IfToWhenIntention/description.html b/idea/resources/intentionDescriptions/IfToWhenIntention/description.html new file mode 100644 index 00000000000..170bacebb07 --- /dev/null +++ b/idea/resources/intentionDescriptions/IfToWhenIntention/description.html @@ -0,0 +1,5 @@ + + +This intention converts 'if' expression to equivalent 'when' expression + + \ No newline at end of file diff --git a/idea/resources/intentionDescriptions/WhenToIfIntention/after.kt.template b/idea/resources/intentionDescriptions/WhenToIfIntention/after.kt.template new file mode 100644 index 00000000000..0fd94490980 --- /dev/null +++ b/idea/resources/intentionDescriptions/WhenToIfIntention/after.kt.template @@ -0,0 +1,7 @@ +if (n == 1) { + res = "one" +} else if (n == 2) { + res = "two" +} else { + res = "???" +} \ No newline at end of file diff --git a/idea/resources/intentionDescriptions/WhenToIfIntention/before.kt.template b/idea/resources/intentionDescriptions/WhenToIfIntention/before.kt.template new file mode 100644 index 00000000000..949cf0ab13d --- /dev/null +++ b/idea/resources/intentionDescriptions/WhenToIfIntention/before.kt.template @@ -0,0 +1,11 @@ +when (n) { + 1 -> { + res = "one" + } + 2 -> { + res = "two" + } + else -> { + res = "???" + } +} \ No newline at end of file diff --git a/idea/resources/intentionDescriptions/WhenToIfIntention/description.html b/idea/resources/intentionDescriptions/WhenToIfIntention/description.html new file mode 100644 index 00000000000..e81fa8a7a38 --- /dev/null +++ b/idea/resources/intentionDescriptions/WhenToIfIntention/description.html @@ -0,0 +1,5 @@ + + +This intention converts 'when' expression to one or more 'if' expressions + + \ No newline at end of file diff --git a/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/IfWhenUtils.java b/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/IfWhenUtils.java new file mode 100644 index 00000000000..08e220ee152 --- /dev/null +++ b/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/IfWhenUtils.java @@ -0,0 +1,206 @@ +package org.jetbrains.jet.plugin.codeInsight.codeTransformations.branchedTransformations; + +import com.intellij.openapi.project.Project; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.jet.lang.psi.*; +import org.jetbrains.jet.lexer.JetTokens; + +import java.util.ArrayList; +import java.util.List; + +public class IfWhenUtils { + + public static final String TRANSFORM_WITHOUT_CHECK = + "Expression must be checked before applying transformation"; + + private IfWhenUtils() { + } + + public static boolean checkIfToWhen(@NotNull JetIfExpression ifExpression) { + return ifExpression.getCondition() != null && ifExpression.getThen() != null && ifExpression.getElse() != null; + } + + public static boolean checkWhenToIf(@NotNull JetWhenExpression whenExpression) { + return !whenExpression.getEntries().isEmpty() && JetPsiUtil.checkWhenExpressionHasSingleElse(whenExpression); + } + + private static void assertNotNull(JetExpression expression) { + assert expression != null : TRANSFORM_WITHOUT_CHECK; + } + + private static List splitExpressionToOrBranches(JetExpression expression) { + final List branches = new ArrayList(); + + expression.accept( + new JetVisitorVoid() { + @Override + public void visitBinaryExpression(JetBinaryExpression expression) { + if (expression.getOperationToken() == JetTokens.OROR) { + JetExpression left = expression.getLeft(); + JetExpression right = expression.getRight(); + + if (left != null) { + left.accept(this); + } + + if (right != null) { + right.accept(this); + } + } else { + visitExpression(expression); + } + } + + @Override + public void visitParenthesizedExpression(JetParenthesizedExpression expression) { + JetExpression baseExpression = expression.getExpression(); + + if (baseExpression != null) { + baseExpression.accept(this); + } + } + + @Override + public void visitExpression(JetExpression expression) { + branches.add(expression); + } + } + ); + + return branches; + } + + public static void transformIfToWhen(@NotNull JetIfExpression ifExpression) { + List positiveBranches = new ArrayList(); + JetExpression elseExpression = null; + + JetIfExpression currIfExpression = ifExpression; + do { + JetExpression condition = currIfExpression.getCondition(); + JetExpression thenBranch = currIfExpression.getThen(); + JetExpression elseBranch = currIfExpression.getElse(); + + assertNotNull(condition); + assertNotNull(thenBranch); + assertNotNull(elseBranch); + + //noinspection ConstantConditions + positiveBranches.add(new MultiGuardedExpression(splitExpressionToOrBranches(condition), thenBranch)); + + if (elseBranch instanceof JetIfExpression) { + currIfExpression = (JetIfExpression) elseBranch; + } + else { + currIfExpression = null; + elseExpression = elseBranch; + } + } while (currIfExpression != null); + + JetPsiFactory.WhenTemplateBuilder builder = new JetPsiFactory.WhenTemplateBuilder(false); + for (MultiGuardedExpression positiveBranch : positiveBranches) { + builder.addBranchWithMultiCondition(positiveBranch.getConditions().size()); + } + + JetWhenExpression whenExpression = builder.toExpression(ifExpression.getProject()); + + int i = 0; + List entries = whenExpression.getEntries(); + for (JetWhenEntry entry : entries) { + if (entry.isElse()) { + //noinspection ConstantConditions + entry.getExpression().replace(elseExpression); + break; + } + + MultiGuardedExpression branch = positiveBranches.get(i++); + + //noinspection ConstantConditions + entry.getExpression().replace(branch.getBaseExpression()); + + int j = 0; + JetWhenCondition[] conditions = entry.getConditions(); + for (JetWhenCondition condition : conditions) { + assert condition instanceof JetWhenConditionWithExpression : TRANSFORM_WITHOUT_CHECK; + + JetExpression conditionExpression = ((JetWhenConditionWithExpression) condition).getExpression(); + assertNotNull(conditionExpression); + + //noinspection ConstantConditions + conditionExpression.replace(branch.getConditions().get(j++)); + } + } + + ifExpression.replace(whenExpression); + } + + @SuppressWarnings("ConstantConditions") + private static JetExpression combineWhenConditions(Project project, JetWhenCondition[] conditions, JetExpression subject) { + int n = conditions.length; + assert n > 0 : TRANSFORM_WITHOUT_CHECK; + + JetWhenCondition condition = conditions[n - 1]; + assert condition != null : TRANSFORM_WITHOUT_CHECK; + + JetExpression resultExpr = WhenUtils.whenConditionToExpression(condition, subject); + if (n > 1) { + resultExpr = JetPsiFactory.createParenthesizedExpressionIfNeeded(project, resultExpr); + } + + for (int i = n - 2; i >= 0; i--) { + JetWhenCondition currCondition = conditions[i]; + + assert currCondition != null : TRANSFORM_WITHOUT_CHECK; + + resultExpr = JetPsiFactory.createBinaryExpression( + project, + JetPsiFactory.createParenthesizedExpressionIfNeeded(project, WhenUtils.whenConditionToExpression(currCondition, subject)), + "||", + resultExpr); + } + + return resultExpr; + } + + public static void transformWhenToIf(@NotNull JetWhenExpression whenExpression) { + Project project = whenExpression.getProject(); + + JetExpression elseExpression = null; + List positiveBranches = new ArrayList(); + + List entries = whenExpression.getEntries(); + for (JetWhenEntry entry : entries) { + JetExpression branch = entry.getExpression(); + + assertNotNull(branch); + + if (entry.isElse()) { + elseExpression = branch; + } else { + JetExpression branchCondition = combineWhenConditions(project, entry.getConditions(), whenExpression.getSubjectExpression()); + JetExpression branchExpression = entry.getExpression(); + + assertNotNull(branchExpression); + + //noinspection ConstantConditions + positiveBranches.add(new GuardedExpression(branchCondition, branchExpression)); + } + } + + assertNotNull(elseExpression); + assert !positiveBranches.isEmpty() : TRANSFORM_WITHOUT_CHECK; + + JetExpression outerExpression = elseExpression; + + for (int i = positiveBranches.size() - 1; i >= 0; i--) { + GuardedExpression branch = positiveBranches.get(i); + + outerExpression = JetPsiFactory.createIf( + project, + branch.getCondition(), branch.getBaseExpression(), outerExpression, + !(branch.getBaseExpression() instanceof JetBlockExpression), !(outerExpression instanceof JetBlockExpression)); + } + + //noinspection ConstantConditions + whenExpression.replace(outerExpression); + } +} diff --git a/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/intentions/IfToWhenIntention.java b/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/intentions/IfToWhenIntention.java new file mode 100644 index 00000000000..3d80248f2c3 --- /dev/null +++ b/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/intentions/IfToWhenIntention.java @@ -0,0 +1,36 @@ +package org.jetbrains.jet.plugin.codeInsight.codeTransformations.branchedTransformations.intentions; + +import com.google.common.base.Predicate; +import com.intellij.psi.PsiElement; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import org.jetbrains.jet.lang.psi.JetIfExpression; +import org.jetbrains.jet.plugin.codeInsight.codeTransformations.branchedTransformations.AbstractCodeTransformationIntention; +import org.jetbrains.jet.plugin.codeInsight.codeTransformations.branchedTransformations.IfWhenUtils; +import org.jetbrains.jet.plugin.codeInsight.codeTransformations.branchedTransformations.core.Transformer; + +public class IfToWhenIntention extends AbstractCodeTransformationIntention { + private static final Transformer TRANSFORMER = new Transformer() { + @NotNull + @Override + public String getKey() { + return "if.to.when"; + } + + @Override + public void transform(@NotNull PsiElement element) { + IfWhenUtils.transformIfToWhen((JetIfExpression) element); + } + }; + + private static final Predicate IS_APPLICABLE = new Predicate() { + @Override + public boolean apply(@Nullable PsiElement input) { + return (input instanceof JetIfExpression) && IfWhenUtils.checkIfToWhen((JetIfExpression) input); + } + }; + + public IfToWhenIntention() { + super(TRANSFORMER, IS_APPLICABLE); + } +} diff --git a/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/intentions/WhenToIfIntention.java b/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/intentions/WhenToIfIntention.java new file mode 100644 index 00000000000..42bfe16da12 --- /dev/null +++ b/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/intentions/WhenToIfIntention.java @@ -0,0 +1,52 @@ +/* + * Copyright 2010-2013 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.jetbrains.jet.plugin.codeInsight.codeTransformations.branchedTransformations.intentions; + +import com.google.common.base.Predicate; +import com.intellij.psi.PsiElement; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import org.jetbrains.jet.lang.psi.JetWhenExpression; +import org.jetbrains.jet.plugin.codeInsight.codeTransformations.branchedTransformations.AbstractCodeTransformationIntention; +import org.jetbrains.jet.plugin.codeInsight.codeTransformations.branchedTransformations.IfWhenUtils; +import org.jetbrains.jet.plugin.codeInsight.codeTransformations.branchedTransformations.core.Transformer; + +public class WhenToIfIntention extends AbstractCodeTransformationIntention { + private static final Transformer TRANSFORMER = new Transformer() { + @NotNull + @Override + public String getKey() { + return "when.to.if"; + } + + @Override + public void transform(@NotNull PsiElement element) { + IfWhenUtils.transformWhenToIf((JetWhenExpression) element); + } + }; + + private static final Predicate IS_APPLICABLE = new Predicate() { + @Override + public boolean apply(@Nullable PsiElement input) { + return (input instanceof JetWhenExpression) && IfWhenUtils.checkWhenToIf((JetWhenExpression) input); + } + }; + + public WhenToIfIntention() { + super(TRANSFORMER, IS_APPLICABLE); + } +} From a1613d8b819380cbbe7842062d3d69eb433d6d3b Mon Sep 17 00:00:00 2001 From: Alexey Sedunov Date: Fri, 26 Apr 2013 14:33:59 +0400 Subject: [PATCH 085/249] Implement 'when' transformations (flatten, introduce subject, eliminate subject) --- .../jetbrains/jet/lang/psi/JetPsiMatcher.java | 246 ++++++++++++++ .../after.kt.template | 11 + .../before.kt.template | 11 + .../description.html | 5 + .../FlattenWhenIntention/after.kt.template | 17 + .../FlattenWhenIntention/before.kt.template | 19 ++ .../FlattenWhenIntention/description.html | 5 + .../after.kt.template | 11 + .../before.kt.template | 11 + .../description.html | 5 + .../GuardedExpression.java | 27 ++ .../MultiGuardedExpression.java | 29 ++ .../branchedTransformations/WhenUtils.java | 320 ++++++++++++++++++ .../EliminateWhenSubjectIntention.java | 36 ++ .../intentions/FlattenWhenIntention.java | 36 ++ .../IntroduceWhenSubjectIntention.java | 36 ++ 16 files changed, 825 insertions(+) create mode 100644 compiler/frontend/src/org/jetbrains/jet/lang/psi/JetPsiMatcher.java create mode 100644 idea/resources/intentionDescriptions/EliminateWhenSubjectIntention/after.kt.template create mode 100644 idea/resources/intentionDescriptions/EliminateWhenSubjectIntention/before.kt.template create mode 100644 idea/resources/intentionDescriptions/EliminateWhenSubjectIntention/description.html create mode 100644 idea/resources/intentionDescriptions/FlattenWhenIntention/after.kt.template create mode 100644 idea/resources/intentionDescriptions/FlattenWhenIntention/before.kt.template create mode 100644 idea/resources/intentionDescriptions/FlattenWhenIntention/description.html create mode 100644 idea/resources/intentionDescriptions/IntroduceWhenSubjectIntention/after.kt.template create mode 100644 idea/resources/intentionDescriptions/IntroduceWhenSubjectIntention/before.kt.template create mode 100644 idea/resources/intentionDescriptions/IntroduceWhenSubjectIntention/description.html create mode 100644 idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/GuardedExpression.java create mode 100644 idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/MultiGuardedExpression.java create mode 100644 idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/WhenUtils.java create mode 100644 idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/intentions/EliminateWhenSubjectIntention.java create mode 100644 idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/intentions/FlattenWhenIntention.java create mode 100644 idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/intentions/IntroduceWhenSubjectIntention.java diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetPsiMatcher.java b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetPsiMatcher.java new file mode 100644 index 00000000000..5a7b8e04af8 --- /dev/null +++ b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetPsiMatcher.java @@ -0,0 +1,246 @@ +/* + * Copyright 2010-2013 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.jetbrains.jet.lang.psi; + +import java.util.List; + +public class JetPsiMatcher { + private JetPsiMatcher() { + } + + private static boolean checkTypeReferenceMatch(JetTypeReference t1, JetTypeReference t2) { + return (t1 == t2) || (t1 != null && t2 != null && t1.getText().equals(t2.getText())); + } + + private static boolean checkStringTemplateEntryMatch(JetStringTemplateEntry e1, JetStringTemplateEntry e2) { + if (e1 == e2) return true; + if (e1 == null || e2 == null) return false; + + return e1.getClass() == e2.getClass() && checkExpressionMatch(e1.getExpression(), e2.getExpression()); + } + + private static boolean checkWhenConditionMatch(JetWhenCondition cond1, JetWhenCondition cond2) { + if (cond1 == cond2) return true; + if (cond1 == null || cond2 == null) return false; + + if (cond1.getClass() != cond2.getClass()) return false; + + if (cond1 instanceof JetWhenConditionInRange) { + JetWhenConditionInRange inRange1 = (JetWhenConditionInRange) cond1; + JetWhenConditionInRange inRange2 = (JetWhenConditionInRange) cond2; + + return inRange1.isNegated() == inRange2.isNegated() && + checkExpressionMatch(inRange1.getRangeExpression(), inRange2.getRangeExpression()) && + checkExpressionMatch(inRange1.getOperationReference(), inRange2.getOperationReference()); + } + + if (cond1 instanceof JetWhenConditionIsPattern) { + JetWhenConditionIsPattern pattern1 = (JetWhenConditionIsPattern) cond1; + JetWhenConditionIsPattern pattern2 = (JetWhenConditionIsPattern) cond2; + + return pattern1.isNegated() == pattern2.isNegated() && + checkTypeReferenceMatch(pattern1.getTypeRef(), pattern2.getTypeRef()); + } + + if (cond1 instanceof JetWhenConditionWithExpression) { + return checkExpressionMatch(((JetWhenConditionWithExpression) cond1).getExpression(), ((JetWhenConditionWithExpression) cond2).getExpression()); + } + + return false; + } + + private static boolean checkWhenEntryMatch(JetWhenEntry e1, JetWhenEntry e2) { + if (e1 == e2) return true; + if (e1 == null || e2 == null) return false; + + if (!(e1.isElse() == e2.isElse() && checkExpressionMatch(e1.getExpression(), e2.getExpression()))) return false; + + JetWhenCondition[] conditions1 = e1.getConditions(); + JetWhenCondition[] conditions2 = e2.getConditions(); + + int n = conditions1.length; + if (conditions2.length != n) return false; + + for (int i = 0; i < n; i++) { + if (!checkWhenConditionMatch(conditions1[i], conditions2[i])) return false; + } + + return true; + } + + public static boolean checkExpressionMatch(JetExpression e1, JetExpression e2) { + if (e1 == e2) return true; + if (e1 == null || e2 == null) return false; + + e1 = JetPsiUtil.deparenthesizeWithNoTypeResolution(e1); + e2 = JetPsiUtil.deparenthesizeWithNoTypeResolution(e2); + + assert e1 != null && e2 != null; + + if (e1.getClass() != e2.getClass()) return false; + + if (e1 instanceof JetArrayAccessExpression) { + JetArrayAccessExpression aae1 = (JetArrayAccessExpression) e1; + JetArrayAccessExpression aae2 = (JetArrayAccessExpression) e2; + + if (!checkExpressionMatch(aae1.getArrayExpression(), aae2.getArrayExpression())) return false; + + List indexes1 = aae1.getIndexExpressions(); + List indexes2 = aae2.getIndexExpressions(); + + int n = indexes1.size(); + if (indexes2.size() != n) return false; + + for (int i = 0; i < n; i++) { + if (!checkExpressionMatch(indexes1.get(i), indexes2.get(i))) return false; + } + + return true; + } + + if (e1 instanceof JetBinaryExpression) { + JetBinaryExpression be1 = (JetBinaryExpression) e1; + JetBinaryExpression be2 = (JetBinaryExpression) e2; + + return be1.getOperationToken() == be2.getOperationToken() && + checkExpressionMatch(be1.getLeft(), be2.getLeft()) && + checkExpressionMatch(be1.getRight(), be2.getRight()); + } + + if (e1 instanceof JetBinaryExpressionWithTypeRHS) { + JetBinaryExpressionWithTypeRHS bet1 = (JetBinaryExpressionWithTypeRHS) e1; + JetBinaryExpressionWithTypeRHS bet2 = (JetBinaryExpressionWithTypeRHS) e2; + + return checkExpressionMatch(bet1.getLeft(), bet2.getLeft()) && + checkTypeReferenceMatch(bet1.getRight(), bet2.getRight()); + } + + if (e1 instanceof JetCallExpression) { + JetCallExpression call1 = (JetCallExpression) e1; + JetCallExpression call2 = (JetCallExpression) e2; + + if (!checkExpressionMatch(call1.getCalleeExpression(), call2.getCalleeExpression())) return false; + + List args1 = call1.getValueArguments(); + List args2 = call2.getValueArguments(); + + int argCount = args1.size(); + if (args2.size() != argCount) return false; + + for (int i = 0; i < argCount; i++) { + if (!checkExpressionMatch(args1.get(i).getArgumentExpression(), args2.get(i).getArgumentExpression())) return false; + } + + List funLiterals1 = call1.getFunctionLiteralArguments(); + List funLiterals2 = call2.getFunctionLiteralArguments(); + + int funLiteralCount = funLiterals1.size(); + if (funLiterals2.size() != funLiteralCount) return false; + + for (int i = 0; i < argCount; i++) { + if (!checkExpressionMatch(funLiterals1.get(i), funLiterals2.get(i))) return false; + } + + return true; + } + + if (e1 instanceof JetConstantExpression || e1 instanceof JetSimpleNameExpression) { + return e1.getText().equals(e2.getText()); + } + + if (e1 instanceof JetConstructorCalleeExpression) { + return checkTypeReferenceMatch(((JetConstructorCalleeExpression) e1).getTypeReference(), ((JetConstructorCalleeExpression) e2).getTypeReference()); + } + + if (e1 instanceof JetQualifiedExpression) { + return ((JetQualifiedExpression) e1).getOperationSign() == ((JetQualifiedExpression) e2).getOperationSign() && + checkExpressionMatch(((JetQualifiedExpression) e1).getReceiverExpression(), ((JetQualifiedExpression) e2).getReceiverExpression()) && + checkExpressionMatch(((JetQualifiedExpression) e1).getSelectorExpression(), ((JetQualifiedExpression) e2).getSelectorExpression()); + } + + if (e1 instanceof JetIfExpression) { + return checkExpressionMatch(((JetIfExpression) e1).getCondition(), ((JetIfExpression) e2).getCondition()) && + checkExpressionMatch(((JetIfExpression) e1).getThen(), ((JetIfExpression) e2).getThen()) && + checkExpressionMatch(((JetIfExpression) e1).getElse(), ((JetIfExpression) e2).getElse()); + } + + if (e1 instanceof JetIsExpression) { + return checkExpressionMatch(((JetIsExpression) e1).getLeftHandSide(), ((JetIsExpression) e2).getLeftHandSide()) && + checkTypeReferenceMatch(((JetIsExpression) e1).getTypeRef(), ((JetIsExpression) e2).getTypeRef()) && + ((JetIsExpression) e1).isNegated() == ((JetIsExpression) e2).isNegated(); + } + + if (e1 instanceof JetStringTemplateExpression) { + JetStringTemplateExpression str1 = (JetStringTemplateExpression) e1; + JetStringTemplateExpression str2 = (JetStringTemplateExpression) e2; + + JetStringTemplateEntry[] entries1 = str1.getEntries(); + JetStringTemplateEntry[] entries2 = str2.getEntries(); + + int n = entries1.length; + if (entries2.length != n) return false; + + for (int i = 0; i < n; i++) { + if (!checkStringTemplateEntryMatch(entries1[i], entries2[i])) return false; + } + + return true; + } + + if (e1 instanceof JetThrowExpression) { + return checkExpressionMatch(((JetThrowExpression) e1).getThrownExpression(), ((JetThrowExpression) e2).getThrownExpression()); + } + + if (e1 instanceof JetUnaryExpression) { + JetUnaryExpression ue1 = (JetUnaryExpression) e1; + JetUnaryExpression ue2 = (JetUnaryExpression) e2; + + return checkExpressionMatch(ue1.getBaseExpression(), ue2.getBaseExpression()) && + checkExpressionMatch(ue1.getOperationReference(), ue2.getOperationReference()); + } + + if (e1 instanceof JetWhenExpression) { + JetWhenExpression when1 = (JetWhenExpression) e1; + JetWhenExpression when2 = (JetWhenExpression) e2; + + if (checkExpressionMatch(when1.getSubjectExpression(), when2.getSubjectExpression())) return false; + + List entries1 = when1.getEntries(); + List entries2 = when2.getEntries(); + + int n = entries1.size(); + if (entries2.size() != n) return false; + + for (int i = 0; i < n; i++) { + if (!checkWhenEntryMatch(entries1.get(i), entries2.get(i))) return false; + } + } + + if (e1 instanceof JetThisExpression) return true; + + if (e1 instanceof JetSuperExpression) { + JetSuperExpression super1 = (JetSuperExpression) e1; + JetSuperExpression super2 = (JetSuperExpression) e2; + + return checkTypeReferenceMatch(super1.getSuperTypeQualifier(), super2.getSuperTypeQualifier()) && + checkExpressionMatch(super1.getInstanceReference(), super2.getInstanceReference()) && + checkExpressionMatch(super1.getTargetLabel(), super2.getTargetLabel()); + } + + return false; + } +} diff --git a/idea/resources/intentionDescriptions/EliminateWhenSubjectIntention/after.kt.template b/idea/resources/intentionDescriptions/EliminateWhenSubjectIntention/after.kt.template new file mode 100644 index 00000000000..a3b53a936d0 --- /dev/null +++ b/idea/resources/intentionDescriptions/EliminateWhenSubjectIntention/after.kt.template @@ -0,0 +1,11 @@ +when { + n == 1 -> { + res = "one" + } + n == 2 -> { + res = "two" + } + else -> { + res = "???" + } +} \ No newline at end of file diff --git a/idea/resources/intentionDescriptions/EliminateWhenSubjectIntention/before.kt.template b/idea/resources/intentionDescriptions/EliminateWhenSubjectIntention/before.kt.template new file mode 100644 index 00000000000..949cf0ab13d --- /dev/null +++ b/idea/resources/intentionDescriptions/EliminateWhenSubjectIntention/before.kt.template @@ -0,0 +1,11 @@ +when (n) { + 1 -> { + res = "one" + } + 2 -> { + res = "two" + } + else -> { + res = "???" + } +} \ No newline at end of file diff --git a/idea/resources/intentionDescriptions/EliminateWhenSubjectIntention/description.html b/idea/resources/intentionDescriptions/EliminateWhenSubjectIntention/description.html new file mode 100644 index 00000000000..88a7f9b48da --- /dev/null +++ b/idea/resources/intentionDescriptions/EliminateWhenSubjectIntention/description.html @@ -0,0 +1,5 @@ + + +This intention eliminates argument of 'when' expression transforming its pattern-matching conditions into boolean expressions + + \ No newline at end of file diff --git a/idea/resources/intentionDescriptions/FlattenWhenIntention/after.kt.template b/idea/resources/intentionDescriptions/FlattenWhenIntention/after.kt.template new file mode 100644 index 00000000000..42ac1855796 --- /dev/null +++ b/idea/resources/intentionDescriptions/FlattenWhenIntention/after.kt.template @@ -0,0 +1,17 @@ +when (n) { + 1 -> { + res = "one" + } + 2 -> { + res = "two" + } + 3 -> { + res = "three" + } + 4 -> { + res = "four" + } + else -> { + res = "???" + } +} \ No newline at end of file diff --git a/idea/resources/intentionDescriptions/FlattenWhenIntention/before.kt.template b/idea/resources/intentionDescriptions/FlattenWhenIntention/before.kt.template new file mode 100644 index 00000000000..3bbce3cf227 --- /dev/null +++ b/idea/resources/intentionDescriptions/FlattenWhenIntention/before.kt.template @@ -0,0 +1,19 @@ +when (n) { + 1 -> { + res = "one" + } + 2 -> { + res = "two" + } + else -> when (n) { + 3 -> { + res = "thress" + } + 4 -> { + res = "four" + } + else -> { + res = "???" + } + } +} \ No newline at end of file diff --git a/idea/resources/intentionDescriptions/FlattenWhenIntention/description.html b/idea/resources/intentionDescriptions/FlattenWhenIntention/description.html new file mode 100644 index 00000000000..a82e6bccc82 --- /dev/null +++ b/idea/resources/intentionDescriptions/FlattenWhenIntention/description.html @@ -0,0 +1,5 @@ + + +This intention merges branches of nested 'when' expression into enclosing one + + \ No newline at end of file diff --git a/idea/resources/intentionDescriptions/IntroduceWhenSubjectIntention/after.kt.template b/idea/resources/intentionDescriptions/IntroduceWhenSubjectIntention/after.kt.template new file mode 100644 index 00000000000..949cf0ab13d --- /dev/null +++ b/idea/resources/intentionDescriptions/IntroduceWhenSubjectIntention/after.kt.template @@ -0,0 +1,11 @@ +when (n) { + 1 -> { + res = "one" + } + 2 -> { + res = "two" + } + else -> { + res = "???" + } +} \ No newline at end of file diff --git a/idea/resources/intentionDescriptions/IntroduceWhenSubjectIntention/before.kt.template b/idea/resources/intentionDescriptions/IntroduceWhenSubjectIntention/before.kt.template new file mode 100644 index 00000000000..a3b53a936d0 --- /dev/null +++ b/idea/resources/intentionDescriptions/IntroduceWhenSubjectIntention/before.kt.template @@ -0,0 +1,11 @@ +when { + n == 1 -> { + res = "one" + } + n == 2 -> { + res = "two" + } + else -> { + res = "???" + } +} \ No newline at end of file diff --git a/idea/resources/intentionDescriptions/IntroduceWhenSubjectIntention/description.html b/idea/resources/intentionDescriptions/IntroduceWhenSubjectIntention/description.html new file mode 100644 index 00000000000..09ef51ee060 --- /dev/null +++ b/idea/resources/intentionDescriptions/IntroduceWhenSubjectIntention/description.html @@ -0,0 +1,5 @@ + + +This intention introduces argument into 'when' expression simplifying conditions of its branches + + \ No newline at end of file diff --git a/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/GuardedExpression.java b/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/GuardedExpression.java new file mode 100644 index 00000000000..73a94d72bc5 --- /dev/null +++ b/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/GuardedExpression.java @@ -0,0 +1,27 @@ +package org.jetbrains.jet.plugin.codeInsight.codeTransformations.branchedTransformations; + +import org.jetbrains.annotations.NotNull; +import org.jetbrains.jet.lang.psi.JetExpression; + +public class GuardedExpression { + @NotNull + private final JetExpression condition; + + @NotNull + private final JetExpression baseExpression; + + public GuardedExpression(@NotNull JetExpression condition, @NotNull JetExpression baseExpression) { + this.condition = condition; + this.baseExpression = baseExpression; + } + + @NotNull + public JetExpression getCondition() { + return condition; + } + + @NotNull + public JetExpression getBaseExpression() { + return baseExpression; + } +} diff --git a/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/MultiGuardedExpression.java b/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/MultiGuardedExpression.java new file mode 100644 index 00000000000..7e7c312cbfd --- /dev/null +++ b/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/MultiGuardedExpression.java @@ -0,0 +1,29 @@ +package org.jetbrains.jet.plugin.codeInsight.codeTransformations.branchedTransformations; + +import org.jetbrains.annotations.NotNull; +import org.jetbrains.jet.lang.psi.JetExpression; + +import java.util.List; + +public class MultiGuardedExpression { + @NotNull + private final List conditions; + + @NotNull + private final JetExpression baseExpression; + + public MultiGuardedExpression(@NotNull List conditions, @NotNull JetExpression baseExpression) { + this.conditions = conditions; + this.baseExpression = baseExpression; + } + + @NotNull + public List getConditions() { + return conditions; + } + + @NotNull + public JetExpression getBaseExpression() { + return baseExpression; + } +} diff --git a/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/WhenUtils.java b/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/WhenUtils.java new file mode 100644 index 00000000000..5429eeef779 --- /dev/null +++ b/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/WhenUtils.java @@ -0,0 +1,320 @@ +package org.jetbrains.jet.plugin.codeInsight.codeTransformations.branchedTransformations; + +import com.intellij.openapi.project.Project; +import com.intellij.psi.tree.IElementType; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.jet.lang.psi.*; +import org.jetbrains.jet.lexer.JetTokens; + +import java.util.List; + +public class WhenUtils { + private WhenUtils() { + } + + public static final String TRANSFORM_WITHOUT_CHECK = + "Expression must be checked before applying transformation"; + + private static JetExpression getWhenConditionSubjectCandidate(JetExpression condition) { + if (condition instanceof JetIsExpression) { + return ((JetIsExpression) condition).getLeftHandSide(); + } + + if (condition instanceof JetBinaryExpression) { + JetBinaryExpression binaryExpression = (JetBinaryExpression) condition; + IElementType op = binaryExpression.getOperationToken(); + if (op == JetTokens.EQEQ || op == JetTokens.IN_KEYWORD || op == JetTokens.NOT_IN) { + return ((JetBinaryExpression) condition).getLeft(); + } + } + + return null; + } + + private static JetExpression getWhenSubjectCandidate(@NotNull JetWhenExpression whenExpression) { + if (whenExpression.getSubjectExpression() != null) return null; + + JetExpression lastCandidate = null; + for (JetWhenEntry entry : whenExpression.getEntries()) { + JetWhenCondition[] conditions = entry.getConditions(); + + if (!entry.isElse() && conditions.length == 0) return null; + + for (JetWhenCondition condition : conditions) { + if (!(condition instanceof JetWhenConditionWithExpression)) return null; + + JetExpression currCandidate = getWhenConditionSubjectCandidate(((JetWhenConditionWithExpression) condition).getExpression()); + + if (!(currCandidate instanceof JetSimpleNameExpression)) return null; + + if (lastCandidate == null) { + lastCandidate = currCandidate; + } + else if (!JetPsiMatcher.checkExpressionMatch(lastCandidate, currCandidate)) return null; + } + } + + return lastCandidate; + } + + public static boolean checkFlattenWhen(@NotNull JetWhenExpression whenExpression) { + JetExpression subject = whenExpression.getSubjectExpression(); + + if (subject != null && !(subject instanceof JetSimpleNameExpression)) return false; + + if (!JetPsiUtil.checkWhenExpressionHasSingleElse(whenExpression)) return false; + + JetExpression elseBranch = JetPsiUtil.getWhenElseBranch(whenExpression); + if (!(elseBranch instanceof JetWhenExpression)) return false; + + JetWhenExpression nestedWhenExpression = (JetWhenExpression) elseBranch; + + return JetPsiUtil.checkWhenExpressionHasSingleElse(nestedWhenExpression) && + JetPsiMatcher.checkExpressionMatch(subject, nestedWhenExpression.getSubjectExpression()); + } + + public static boolean checkIntroduceWhenSubject(@NotNull JetWhenExpression whenExpression) { + return getWhenSubjectCandidate(whenExpression) != null; + } + + public static boolean checkEliminateWhenSubject(@NotNull JetWhenExpression whenExpression) { + return whenExpression.getSubjectExpression() instanceof JetSimpleNameExpression; + } + + public static void flattenWhen(@NotNull JetWhenExpression whenExpression) { + JetExpression subjectExpression = whenExpression.getSubjectExpression(); + boolean hasSubject = subjectExpression != null; + + JetExpression elseBranch = JetPsiUtil.getWhenElseBranch(whenExpression); + assert elseBranch instanceof JetWhenExpression : TRANSFORM_WITHOUT_CHECK; + + JetWhenExpression nestedWhenExpression = (JetWhenExpression) elseBranch; + + List outerEntries = whenExpression.getEntries(); + List innerEntries = nestedWhenExpression.getEntries(); + + JetWhenExpression newWhenExpression = new JetPsiFactory.WhenTemplateBuilder(hasSubject) + .addBranchesWithSingleCondition(outerEntries.size() + innerEntries.size() - 2) + .toExpression(whenExpression.getProject()); + + if (hasSubject) { + JetExpression dummySubjectExpression = newWhenExpression.getSubjectExpression(); + assert dummySubjectExpression != null : TRANSFORM_WITHOUT_CHECK; + + dummySubjectExpression.replace(subjectExpression); + } + + List newEntries = newWhenExpression.getEntries(); + + int i = 0; + for (JetWhenEntry entry : outerEntries) { + if (!entry.isElse()) { + newEntries.get(i++).replace(entry); + } + } + for (JetWhenEntry entry : innerEntries) { + newEntries.get(i++).replace(entry); + } + + whenExpression.replace(newWhenExpression); + } + + private static JetWhenExpression createWhenTemplateWithSubject(@NotNull JetWhenExpression whenExpression) { + JetPsiFactory.WhenTemplateBuilder builder = new JetPsiFactory.WhenTemplateBuilder(true); + + for (JetWhenEntry entry : whenExpression.getEntries()) { + if (entry.isElse()) continue; + + for (JetWhenCondition condition : entry.getConditions()) { + assert condition instanceof JetWhenConditionWithExpression : TRANSFORM_WITHOUT_CHECK; + + JetExpression conditionExpression = ((JetWhenConditionWithExpression) condition).getExpression(); + + if (conditionExpression instanceof JetIsExpression) { + builder.addIsCondition(((JetIsExpression) conditionExpression).isNegated()); + } + else if (conditionExpression instanceof JetBinaryExpression) { + JetBinaryExpression binaryExpression = (JetBinaryExpression) conditionExpression; + + IElementType op = binaryExpression.getOperationToken(); + if (op == JetTokens.IN_KEYWORD) { + builder.addInCondition(false); + } + else if (op == JetTokens.NOT_IN) { + builder.addInCondition(true); + } + else if (op == JetTokens.EQEQ) { + builder.addExpressionCondition(); + } + else assert false : TRANSFORM_WITHOUT_CHECK; + } + else assert false : TRANSFORM_WITHOUT_CHECK; + } + + builder.finishBranch(); + } + + return builder.toExpression(whenExpression.getProject()); + } + + public static void introduceWhenSubject(@NotNull JetWhenExpression whenExpression) { + JetExpression subject = getWhenSubjectCandidate(whenExpression); + assert subject != null : TRANSFORM_WITHOUT_CHECK; + + JetWhenExpression newWhenExpression = createWhenTemplateWithSubject(whenExpression); + + JetExpression newSubject = newWhenExpression.getSubjectExpression(); + assert newSubject != null : TRANSFORM_WITHOUT_CHECK; + + newSubject.replace(subject); + + int i = 0; + List entries = whenExpression.getEntries(); + List newEntries = newWhenExpression.getEntries(); + for (JetWhenEntry newEntry : newEntries) { + JetWhenEntry entry = entries.get(i++); + + JetExpression branchExpression = entry.getExpression(); + assert branchExpression != null : TRANSFORM_WITHOUT_CHECK; + + JetExpression newBranchExpression = newEntry.getExpression(); + assert newBranchExpression != null : TRANSFORM_WITHOUT_CHECK; + + newBranchExpression.replace(branchExpression); + + int j = 0; + JetWhenCondition[] conditions = entry.getConditions(); + JetWhenCondition[] newConditions = newEntry.getConditions(); + + for (JetWhenCondition newCondition : newConditions) { + JetWhenCondition condition = conditions[j++]; + + assert condition instanceof JetWhenConditionWithExpression : TRANSFORM_WITHOUT_CHECK; + + JetExpression conditionExpression = ((JetWhenConditionWithExpression) condition).getExpression(); + + if (conditionExpression instanceof JetIsExpression) { + assert newCondition instanceof JetWhenConditionIsPattern : TRANSFORM_WITHOUT_CHECK; + + JetTypeReference typeReference = ((JetIsExpression) conditionExpression).getTypeRef(); + assert typeReference != null : TRANSFORM_WITHOUT_CHECK; + + JetTypeReference newTypeReference = ((JetWhenConditionIsPattern) newCondition).getTypeRef(); + assert newTypeReference != null : TRANSFORM_WITHOUT_CHECK; + + newTypeReference.replace(typeReference); + } + else if (conditionExpression instanceof JetBinaryExpression) { + JetBinaryExpression binaryExpression = (JetBinaryExpression) conditionExpression; + + JetExpression rhs = binaryExpression.getRight(); + assert rhs != null : TRANSFORM_WITHOUT_CHECK; + + IElementType op = binaryExpression.getOperationToken(); + if (op == JetTokens.IN_KEYWORD || op == JetTokens.NOT_IN) { + assert newCondition instanceof JetWhenConditionInRange : TRANSFORM_WITHOUT_CHECK; + + JetExpression newRangeExpression = ((JetWhenConditionInRange) newCondition).getRangeExpression(); + assert newRangeExpression != null : TRANSFORM_WITHOUT_CHECK; + + newRangeExpression.replace(rhs); + } + else if (op == JetTokens.EQEQ) { + assert newCondition instanceof JetWhenConditionWithExpression : TRANSFORM_WITHOUT_CHECK; + + JetExpression newConditionExpression = ((JetWhenConditionWithExpression) newCondition).getExpression(); + assert newConditionExpression != null : TRANSFORM_WITHOUT_CHECK; + + newConditionExpression.replace(rhs); + } + else assert false : TRANSFORM_WITHOUT_CHECK; + } + else assert false : TRANSFORM_WITHOUT_CHECK; + } + } + + whenExpression.replace(newWhenExpression); + } + + private static JetWhenExpression createWhenTemplateWithoutSubject(@NotNull JetWhenExpression whenExpression) { + JetPsiFactory.WhenTemplateBuilder builder = new JetPsiFactory.WhenTemplateBuilder(false); + + for (JetWhenEntry entry : whenExpression.getEntries()) { + if (!entry.isElse()) { + builder.addBranchWithMultiCondition(entry.getConditions().length); + } + } + + return builder.toExpression(whenExpression.getProject()); + } + + static JetExpression whenConditionToExpression(@NotNull JetWhenCondition condition, JetExpression subject) { + Project project = condition.getProject(); + + if (condition instanceof JetWhenConditionIsPattern) { + JetWhenConditionIsPattern patternCondition = (JetWhenConditionIsPattern) condition; + + JetTypeReference typeReference = patternCondition.getTypeRef(); + assert typeReference != null : TRANSFORM_WITHOUT_CHECK; + + assert subject != null : TRANSFORM_WITHOUT_CHECK; + + return JetPsiFactory.createIsExpression(project, subject, typeReference, patternCondition.isNegated()); + } + + if (condition instanceof JetWhenConditionInRange) { + JetWhenConditionInRange rangeCondition = (JetWhenConditionInRange) condition; + + JetExpression rangeExpression = rangeCondition.getRangeExpression(); + assert rangeExpression != null : TRANSFORM_WITHOUT_CHECK; + + assert subject != null : TRANSFORM_WITHOUT_CHECK; + + return JetPsiFactory.createBinaryExpression(project, subject, rangeCondition.getOperationReference().getText(), rangeExpression); + } + + assert condition instanceof JetWhenConditionWithExpression : TRANSFORM_WITHOUT_CHECK; + + JetExpression conditionExpression = ((JetWhenConditionWithExpression) condition).getExpression(); + assert conditionExpression != null : TRANSFORM_WITHOUT_CHECK; + + return subject != null ? JetPsiFactory.createBinaryExpression(project, subject, "==", conditionExpression) : conditionExpression; + } + + public static void eliminateWhenSubject(@NotNull JetWhenExpression whenExpression) { + JetExpression subject = whenExpression.getSubjectExpression(); + assert subject != null : TRANSFORM_WITHOUT_CHECK; + + JetWhenExpression newWhenExpression = createWhenTemplateWithoutSubject(whenExpression); + + int i = 0; + List entries = whenExpression.getEntries(); + List newEntries = newWhenExpression.getEntries(); + for (JetWhenEntry newEntry : newEntries) { + JetWhenEntry entry = entries.get(i++); + + JetExpression branchExpression = entry.getExpression(); + assert branchExpression != null : TRANSFORM_WITHOUT_CHECK; + + JetExpression newBranchExpression = newEntry.getExpression(); + assert newBranchExpression != null : TRANSFORM_WITHOUT_CHECK; + + newBranchExpression.replace(branchExpression); + + int j = 0; + JetWhenCondition[] conditions = entry.getConditions(); + JetWhenCondition[] newConditions = newEntry.getConditions(); + + for (JetWhenCondition newCondition : newConditions) { + JetWhenCondition condition = conditions[j++]; + + JetExpression newConditionExpression = ((JetWhenConditionWithExpression) newCondition).getExpression(); + assert newConditionExpression != null : TRANSFORM_WITHOUT_CHECK; + + newConditionExpression.replace(whenConditionToExpression(condition, subject)); + } + } + + whenExpression.replace(newWhenExpression); + } +} diff --git a/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/intentions/EliminateWhenSubjectIntention.java b/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/intentions/EliminateWhenSubjectIntention.java new file mode 100644 index 00000000000..3ca7101fcf1 --- /dev/null +++ b/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/intentions/EliminateWhenSubjectIntention.java @@ -0,0 +1,36 @@ +package org.jetbrains.jet.plugin.codeInsight.codeTransformations.branchedTransformations.intentions; + +import com.google.common.base.Predicate; +import com.intellij.psi.PsiElement; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import org.jetbrains.jet.lang.psi.JetWhenExpression; +import org.jetbrains.jet.plugin.codeInsight.codeTransformations.branchedTransformations.AbstractCodeTransformationIntention; +import org.jetbrains.jet.plugin.codeInsight.codeTransformations.branchedTransformations.WhenUtils; +import org.jetbrains.jet.plugin.codeInsight.codeTransformations.branchedTransformations.core.Transformer; + +public class EliminateWhenSubjectIntention extends AbstractCodeTransformationIntention { + private static final Transformer TRANSFORMER = new Transformer() { + @NotNull + @Override + public String getKey() { + return "eliminate.when.subject"; + } + + @Override + public void transform(@NotNull PsiElement element) { + WhenUtils.eliminateWhenSubject((JetWhenExpression) element); + } + }; + + private static final Predicate IS_APPLICABLE = new Predicate() { + @Override + public boolean apply(@Nullable PsiElement input) { + return input instanceof JetWhenExpression && WhenUtils.checkEliminateWhenSubject((JetWhenExpression) input); + } + }; + + public EliminateWhenSubjectIntention() { + super(TRANSFORMER, IS_APPLICABLE); + } +} diff --git a/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/intentions/FlattenWhenIntention.java b/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/intentions/FlattenWhenIntention.java new file mode 100644 index 00000000000..c7df460ee97 --- /dev/null +++ b/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/intentions/FlattenWhenIntention.java @@ -0,0 +1,36 @@ +package org.jetbrains.jet.plugin.codeInsight.codeTransformations.branchedTransformations.intentions; + +import com.google.common.base.Predicate; +import com.intellij.psi.PsiElement; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import org.jetbrains.jet.lang.psi.JetWhenExpression; +import org.jetbrains.jet.plugin.codeInsight.codeTransformations.branchedTransformations.AbstractCodeTransformationIntention; +import org.jetbrains.jet.plugin.codeInsight.codeTransformations.branchedTransformations.WhenUtils; +import org.jetbrains.jet.plugin.codeInsight.codeTransformations.branchedTransformations.core.Transformer; + +public class FlattenWhenIntention extends AbstractCodeTransformationIntention { + private static final Transformer TRANSFORMER = new Transformer() { + @NotNull + @Override + public String getKey() { + return "flatten.when"; + } + + @Override + public void transform(@NotNull PsiElement element) { + WhenUtils.flattenWhen((JetWhenExpression) element); + } + }; + + private static final Predicate IS_APPLICABLE = new Predicate() { + @Override + public boolean apply(@Nullable PsiElement input) { + return input instanceof JetWhenExpression && WhenUtils.checkFlattenWhen((JetWhenExpression) input); + } + }; + + public FlattenWhenIntention() { + super(TRANSFORMER, IS_APPLICABLE); + } +} diff --git a/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/intentions/IntroduceWhenSubjectIntention.java b/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/intentions/IntroduceWhenSubjectIntention.java new file mode 100644 index 00000000000..b82dc453ed0 --- /dev/null +++ b/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/intentions/IntroduceWhenSubjectIntention.java @@ -0,0 +1,36 @@ +package org.jetbrains.jet.plugin.codeInsight.codeTransformations.branchedTransformations.intentions; + +import com.google.common.base.Predicate; +import com.intellij.psi.PsiElement; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import org.jetbrains.jet.lang.psi.JetWhenExpression; +import org.jetbrains.jet.plugin.codeInsight.codeTransformations.branchedTransformations.AbstractCodeTransformationIntention; +import org.jetbrains.jet.plugin.codeInsight.codeTransformations.branchedTransformations.WhenUtils; +import org.jetbrains.jet.plugin.codeInsight.codeTransformations.branchedTransformations.core.Transformer; + +public class IntroduceWhenSubjectIntention extends AbstractCodeTransformationIntention { + private static final Transformer TRANSFORMER = new Transformer() { + @NotNull + @Override + public String getKey() { + return "introduce.when.subject"; + } + + @Override + public void transform(@NotNull PsiElement element) { + WhenUtils.introduceWhenSubject((JetWhenExpression) element); + } + }; + + private static final Predicate IS_APPLICABLE = new Predicate() { + @Override + public boolean apply(@Nullable PsiElement input) { + return input instanceof JetWhenExpression && WhenUtils.checkIntroduceWhenSubject((JetWhenExpression) input); + } + }; + + public IntroduceWhenSubjectIntention() { + super(TRANSFORMER, IS_APPLICABLE); + } +} From 5a185ee495b396c3d7e799ac2e9dc83e086a54d9 Mon Sep 17 00:00:00 2001 From: Alexey Sedunov Date: Fri, 26 Apr 2013 14:34:38 +0400 Subject: [PATCH 086/249] Add intentions names to bundle --- .../org/jetbrains/jet/plugin/JetBundle.properties | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/idea/src/org/jetbrains/jet/plugin/JetBundle.properties b/idea/src/org/jetbrains/jet/plugin/JetBundle.properties index 39c51b4092c..c56c934fe75 100644 --- a/idea/src/org/jetbrains/jet/plugin/JetBundle.properties +++ b/idea/src/org/jetbrains/jet/plugin/JetBundle.properties @@ -175,7 +175,17 @@ unfold.assignment.to.when.family=Replace Assignment with 'when' Expression unfold.return.to.when=Replace return with 'when' expression unfold.return.to.when.family=Replace Return with 'when' Expression unfold.call.to.when=Replace method call with 'when' expression -unfold.call.to.when.family=Replace Method Call with 'when' Expressiontransform.if.statement.with.assignments.to.expression=Transform 'if' statement with assignments to expression +unfold.call.to.when.family=Replace Method Call with 'when' Expression +if.to.when=Replace 'if' with 'when' +if.to.when.family=Replace 'if' with 'when' +when.to.if=Replace 'when' with 'if' +when.to.if.family=Replace 'when' with 'if' +flatten.when=Flatten 'when' expression +flatten.when.family=Flatten 'when' Expression +introduce.when.subject=Introduce argument to 'when' +introduce.when.subject.family=Introduce Argument to 'when' +eliminate.when.subject=Eliminate argument of 'when' +eliminate.when.subject.family=Eliminate Argument of 'when' transform.if.statement.with.assignments.to.expression=Transform 'if' statement with assignments to expression transform.assignment.with.if.expression.to.statement=Transform assignment with 'if' expression to statement transform.if.statement.with.assignments.to.expression.family=Transform 'if' Statement with Assignments to Expression From 06d43a8ab3239250edb6e545857d37c0803362b8 Mon Sep 17 00:00:00 2001 From: Alexey Sedunov Date: Fri, 26 Apr 2013 14:35:05 +0400 Subject: [PATCH 087/249] Register intentions in plugin.xml --- idea/src/META-INF/plugin.xml | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/idea/src/META-INF/plugin.xml b/idea/src/META-INF/plugin.xml index effb936cd4e..a942b5d6e55 100644 --- a/idea/src/META-INF/plugin.xml +++ b/idea/src/META-INF/plugin.xml @@ -336,6 +336,31 @@ Kotlin + + org.jetbrains.jet.plugin.codeInsight.codeTransformations.branchedTransformations.intentions.IfToWhenIntention + Kotlin + + + + org.jetbrains.jet.plugin.codeInsight.codeTransformations.branchedTransformations.intentions.WhenToIfIntention + Kotlin + + + + org.jetbrains.jet.plugin.codeInsight.codeTransformations.branchedTransformations.intentions.FlattenWhenIntention + Kotlin + + + + org.jetbrains.jet.plugin.codeInsight.codeTransformations.branchedTransformations.intentions.IntroduceWhenSubjectIntention + Kotlin + + + + org.jetbrains.jet.plugin.codeInsight.codeTransformations.branchedTransformations.intentions.EliminateWhenSubjectIntention + Kotlin + + org.jetbrains.jet.plugin.codeInsight.codeTransformations.RemoveUnnecessaryParenthesesIntention Kotlin From 7dd5a2cfa46f6f8227d1cdba4ede7903ef719937 Mon Sep 17 00:00:00 2001 From: Alexey Sedunov Date: Fri, 26 Apr 2013 14:36:31 +0400 Subject: [PATCH 088/249] Add tests for 'if-when' and 'when' transformations --- .../jet/generators/tests/GenerateTests.java | 7 +- .../ifWhen/ifToWhen/ifWithEqualityTests.kt | 9 + .../ifToWhen/ifWithEqualityTests.kt.after | 8 + .../branched/ifWhen/ifToWhen/ifWithIs.kt | 9 + .../ifWhen/ifToWhen/ifWithIs.kt.after | 8 + .../ifWhen/ifToWhen/ifWithMultiConditions.kt | 9 + .../ifToWhen/ifWithMultiConditions.kt.after | 8 + .../ifWhen/ifToWhen/ifWithNegativeIs.kt | 9 + .../ifWhen/ifToWhen/ifWithNegativeIs.kt.after | 8 + .../ifToWhen/ifWithNegativeRangeTests.kt | 9 + .../ifWithNegativeRangeTests.kt.after | 8 + .../ifWhen/ifToWhen/ifWithRangeTests.kt | 9 + .../ifWhen/ifToWhen/ifWithRangeTests.kt.after | 8 + .../ifWithRangeTestsAndMultiConditions.kt | 9 + ...fWithRangeTestsAndMultiConditions.kt.after | 8 + ...eTestsAndUnparenthesizedMultiConditions.kt | 9 + ...AndUnparenthesizedMultiConditions.kt.after | 8 + .../ifWhen/whenToIf/whenWithEqualityTests.kt | 8 + .../whenToIf/whenWithEqualityTests.kt.after | 9 + .../whenToIf/whenWithMultiConditions.kt | 8 + .../whenToIf/whenWithMultiConditions.kt.after | 9 + .../whenToIf/whenWithNegativePatterns.kt | 8 + .../whenWithNegativePatterns.kt.after | 9 + .../whenToIf/whenWithNegativeRangeTests.kt | 8 + .../whenWithNegativeRangeTests.kt.after | 9 + .../ifWhen/whenToIf/whenWithPatterns.kt | 8 + .../ifWhen/whenToIf/whenWithPatterns.kt.after | 9 + .../ifWhen/whenToIf/whenWithRangeTests.kt | 8 + .../whenToIf/whenWithRangeTests.kt.after | 9 + .../whenWithRangeTestsAndMultiConditions.kt | 8 + ...nWithRangeTestsAndMultiConditions.kt.after | 9 + .../ifWhen/whenToIf/whenWithoutSubject.kt | 8 + .../whenToIf/whenWithoutSubject.kt.after | 9 + .../eliminateSubject/whenWithEqualityTests.kt | 8 + .../whenWithEqualityTests.kt.after | 8 + .../whenWithNegativePatterns.kt | 8 + .../whenWithNegativePatterns.kt.after | 8 + .../whenWithNegativeRangeTests.kt | 8 + .../whenWithNegativeRangeTests.kt.after | 8 + .../when/eliminateSubject/whenWithPatterns.kt | 8 + .../whenWithPatterns.kt.after | 8 + .../eliminateSubject/whenWithRangeTests.kt | 8 + .../whenWithRangeTests.kt.after | 8 + .../whenWithRangeTestsAndMultiConditions.kt | 8 + ...nWithRangeTestsAndMultiConditions.kt.after | 8 + .../eliminateSubject/whenWithoutSubject.kt | 9 + .../when/flatten/flattenWithSubject.kt | 11 + .../when/flatten/flattenWithSubject.kt.after | 9 + .../flatten/flattenWithUnmatchedSubjects.kt | 12 + .../when/flatten/flattenWithoutSubject.kt | 11 + .../flatten/flattenWithoutSubject.kt.after | 9 + .../introduceSubject/whenWithEqualityTests.kt | 8 + .../whenWithEqualityTests.kt.after | 8 + .../whenWithNegativePatterns.kt | 8 + .../whenWithNegativePatterns.kt.after | 8 + .../whenWithNegativeRangeTests.kt | 8 + .../whenWithNegativeRangeTests.kt.after | 8 + .../whenWithNondivisibleConditions.kt | 9 + .../when/introduceSubject/whenWithPatterns.kt | 8 + .../whenWithPatterns.kt.after | 8 + .../introduceSubject/whenWithRangeTests.kt | 8 + .../whenWithRangeTests.kt.after | 8 + .../whenWithRangeTestsAndMultiConditions.kt | 8 + ...nWithRangeTestsAndMultiConditions.kt.after | 8 + .../when/introduceSubject/whenWithSubject.kt | 9 + .../whenWithUnmatchedCandidateSubjects.kt | 9 + .../AbstractCodeTransformationTest.java | 20 ++ .../CodeTransformationsTestGenerated.java | 222 +++++++++++++++++- 68 files changed, 799 insertions(+), 2 deletions(-) create mode 100644 idea/testData/codeInsight/codeTransformations/branched/ifWhen/ifToWhen/ifWithEqualityTests.kt create mode 100644 idea/testData/codeInsight/codeTransformations/branched/ifWhen/ifToWhen/ifWithEqualityTests.kt.after create mode 100644 idea/testData/codeInsight/codeTransformations/branched/ifWhen/ifToWhen/ifWithIs.kt create mode 100644 idea/testData/codeInsight/codeTransformations/branched/ifWhen/ifToWhen/ifWithIs.kt.after create mode 100644 idea/testData/codeInsight/codeTransformations/branched/ifWhen/ifToWhen/ifWithMultiConditions.kt create mode 100644 idea/testData/codeInsight/codeTransformations/branched/ifWhen/ifToWhen/ifWithMultiConditions.kt.after create mode 100644 idea/testData/codeInsight/codeTransformations/branched/ifWhen/ifToWhen/ifWithNegativeIs.kt create mode 100644 idea/testData/codeInsight/codeTransformations/branched/ifWhen/ifToWhen/ifWithNegativeIs.kt.after create mode 100644 idea/testData/codeInsight/codeTransformations/branched/ifWhen/ifToWhen/ifWithNegativeRangeTests.kt create mode 100644 idea/testData/codeInsight/codeTransformations/branched/ifWhen/ifToWhen/ifWithNegativeRangeTests.kt.after create mode 100644 idea/testData/codeInsight/codeTransformations/branched/ifWhen/ifToWhen/ifWithRangeTests.kt create mode 100644 idea/testData/codeInsight/codeTransformations/branched/ifWhen/ifToWhen/ifWithRangeTests.kt.after create mode 100644 idea/testData/codeInsight/codeTransformations/branched/ifWhen/ifToWhen/ifWithRangeTestsAndMultiConditions.kt create mode 100644 idea/testData/codeInsight/codeTransformations/branched/ifWhen/ifToWhen/ifWithRangeTestsAndMultiConditions.kt.after create mode 100644 idea/testData/codeInsight/codeTransformations/branched/ifWhen/ifToWhen/ifWithRangeTestsAndUnparenthesizedMultiConditions.kt create mode 100644 idea/testData/codeInsight/codeTransformations/branched/ifWhen/ifToWhen/ifWithRangeTestsAndUnparenthesizedMultiConditions.kt.after create mode 100644 idea/testData/codeInsight/codeTransformations/branched/ifWhen/whenToIf/whenWithEqualityTests.kt create mode 100644 idea/testData/codeInsight/codeTransformations/branched/ifWhen/whenToIf/whenWithEqualityTests.kt.after create mode 100644 idea/testData/codeInsight/codeTransformations/branched/ifWhen/whenToIf/whenWithMultiConditions.kt create mode 100644 idea/testData/codeInsight/codeTransformations/branched/ifWhen/whenToIf/whenWithMultiConditions.kt.after create mode 100644 idea/testData/codeInsight/codeTransformations/branched/ifWhen/whenToIf/whenWithNegativePatterns.kt create mode 100644 idea/testData/codeInsight/codeTransformations/branched/ifWhen/whenToIf/whenWithNegativePatterns.kt.after create mode 100644 idea/testData/codeInsight/codeTransformations/branched/ifWhen/whenToIf/whenWithNegativeRangeTests.kt create mode 100644 idea/testData/codeInsight/codeTransformations/branched/ifWhen/whenToIf/whenWithNegativeRangeTests.kt.after create mode 100644 idea/testData/codeInsight/codeTransformations/branched/ifWhen/whenToIf/whenWithPatterns.kt create mode 100644 idea/testData/codeInsight/codeTransformations/branched/ifWhen/whenToIf/whenWithPatterns.kt.after create mode 100644 idea/testData/codeInsight/codeTransformations/branched/ifWhen/whenToIf/whenWithRangeTests.kt create mode 100644 idea/testData/codeInsight/codeTransformations/branched/ifWhen/whenToIf/whenWithRangeTests.kt.after create mode 100644 idea/testData/codeInsight/codeTransformations/branched/ifWhen/whenToIf/whenWithRangeTestsAndMultiConditions.kt create mode 100644 idea/testData/codeInsight/codeTransformations/branched/ifWhen/whenToIf/whenWithRangeTestsAndMultiConditions.kt.after create mode 100644 idea/testData/codeInsight/codeTransformations/branched/ifWhen/whenToIf/whenWithoutSubject.kt create mode 100644 idea/testData/codeInsight/codeTransformations/branched/ifWhen/whenToIf/whenWithoutSubject.kt.after create mode 100644 idea/testData/codeInsight/codeTransformations/branched/when/eliminateSubject/whenWithEqualityTests.kt create mode 100644 idea/testData/codeInsight/codeTransformations/branched/when/eliminateSubject/whenWithEqualityTests.kt.after create mode 100644 idea/testData/codeInsight/codeTransformations/branched/when/eliminateSubject/whenWithNegativePatterns.kt create mode 100644 idea/testData/codeInsight/codeTransformations/branched/when/eliminateSubject/whenWithNegativePatterns.kt.after create mode 100644 idea/testData/codeInsight/codeTransformations/branched/when/eliminateSubject/whenWithNegativeRangeTests.kt create mode 100644 idea/testData/codeInsight/codeTransformations/branched/when/eliminateSubject/whenWithNegativeRangeTests.kt.after create mode 100644 idea/testData/codeInsight/codeTransformations/branched/when/eliminateSubject/whenWithPatterns.kt create mode 100644 idea/testData/codeInsight/codeTransformations/branched/when/eliminateSubject/whenWithPatterns.kt.after create mode 100644 idea/testData/codeInsight/codeTransformations/branched/when/eliminateSubject/whenWithRangeTests.kt create mode 100644 idea/testData/codeInsight/codeTransformations/branched/when/eliminateSubject/whenWithRangeTests.kt.after create mode 100644 idea/testData/codeInsight/codeTransformations/branched/when/eliminateSubject/whenWithRangeTestsAndMultiConditions.kt create mode 100644 idea/testData/codeInsight/codeTransformations/branched/when/eliminateSubject/whenWithRangeTestsAndMultiConditions.kt.after create mode 100644 idea/testData/codeInsight/codeTransformations/branched/when/eliminateSubject/whenWithoutSubject.kt create mode 100644 idea/testData/codeInsight/codeTransformations/branched/when/flatten/flattenWithSubject.kt create mode 100644 idea/testData/codeInsight/codeTransformations/branched/when/flatten/flattenWithSubject.kt.after create mode 100644 idea/testData/codeInsight/codeTransformations/branched/when/flatten/flattenWithUnmatchedSubjects.kt create mode 100644 idea/testData/codeInsight/codeTransformations/branched/when/flatten/flattenWithoutSubject.kt create mode 100644 idea/testData/codeInsight/codeTransformations/branched/when/flatten/flattenWithoutSubject.kt.after create mode 100644 idea/testData/codeInsight/codeTransformations/branched/when/introduceSubject/whenWithEqualityTests.kt create mode 100644 idea/testData/codeInsight/codeTransformations/branched/when/introduceSubject/whenWithEqualityTests.kt.after create mode 100644 idea/testData/codeInsight/codeTransformations/branched/when/introduceSubject/whenWithNegativePatterns.kt create mode 100644 idea/testData/codeInsight/codeTransformations/branched/when/introduceSubject/whenWithNegativePatterns.kt.after create mode 100644 idea/testData/codeInsight/codeTransformations/branched/when/introduceSubject/whenWithNegativeRangeTests.kt create mode 100644 idea/testData/codeInsight/codeTransformations/branched/when/introduceSubject/whenWithNegativeRangeTests.kt.after create mode 100644 idea/testData/codeInsight/codeTransformations/branched/when/introduceSubject/whenWithNondivisibleConditions.kt create mode 100644 idea/testData/codeInsight/codeTransformations/branched/when/introduceSubject/whenWithPatterns.kt create mode 100644 idea/testData/codeInsight/codeTransformations/branched/when/introduceSubject/whenWithPatterns.kt.after create mode 100644 idea/testData/codeInsight/codeTransformations/branched/when/introduceSubject/whenWithRangeTests.kt create mode 100644 idea/testData/codeInsight/codeTransformations/branched/when/introduceSubject/whenWithRangeTests.kt.after create mode 100644 idea/testData/codeInsight/codeTransformations/branched/when/introduceSubject/whenWithRangeTestsAndMultiConditions.kt create mode 100644 idea/testData/codeInsight/codeTransformations/branched/when/introduceSubject/whenWithRangeTestsAndMultiConditions.kt.after create mode 100644 idea/testData/codeInsight/codeTransformations/branched/when/introduceSubject/whenWithSubject.kt create mode 100644 idea/testData/codeInsight/codeTransformations/branched/when/introduceSubject/whenWithUnmatchedCandidateSubjects.kt diff --git a/generators/org/jetbrains/jet/generators/tests/GenerateTests.java b/generators/org/jetbrains/jet/generators/tests/GenerateTests.java index 25e534362f2..ed3cde6478f 100644 --- a/generators/org/jetbrains/jet/generators/tests/GenerateTests.java +++ b/generators/org/jetbrains/jet/generators/tests/GenerateTests.java @@ -313,7 +313,12 @@ public class GenerateTests { testModel("idea/testData/codeInsight/codeTransformations/branched/unfolding/assignmentToIf", "doTestUnfoldAssignmentToIf"), testModel("idea/testData/codeInsight/codeTransformations/branched/unfolding/assignmentToWhen", "doTestUnfoldAssignmentToWhen"), testModel("idea/testData/codeInsight/codeTransformations/branched/unfolding/returnToIf", "doTestUnfoldReturnToIf"), - testModel("idea/testData/codeInsight/codeTransformations/branched/unfolding/returnToWhen", "doTestUnfoldReturnToWhen") + testModel("idea/testData/codeInsight/codeTransformations/branched/unfolding/returnToWhen", "doTestUnfoldReturnToWhen"), + testModel("idea/testData/codeInsight/codeTransformations/branched/ifWhen/ifToWhen", "doTestIfToWhen"), + testModel("idea/testData/codeInsight/codeTransformations/branched/ifWhen/whenToIf", "doTestWhenToIf"), + testModel("idea/testData/codeInsight/codeTransformations/branched/when/flatten", "doTestFlattenWhen"), + testModel("idea/testData/codeInsight/codeTransformations/branched/when/introduceSubject", "doTestIntroduceWhenSubject"), + testModel("idea/testData/codeInsight/codeTransformations/branched/when/eliminateSubject", "doTestEliminateWhenSubject") ); generateTest( diff --git a/idea/testData/codeInsight/codeTransformations/branched/ifWhen/ifToWhen/ifWithEqualityTests.kt b/idea/testData/codeInsight/codeTransformations/branched/ifWhen/ifToWhen/ifWithEqualityTests.kt new file mode 100644 index 00000000000..47fca307d3c --- /dev/null +++ b/idea/testData/codeInsight/codeTransformations/branched/ifWhen/ifToWhen/ifWithEqualityTests.kt @@ -0,0 +1,9 @@ +fun test(n: Int): String { + return if (n == 0) + "zero" + else if (n == 1) + "one" + else if (n == 2) + "two" + else "unknown" +} \ No newline at end of file diff --git a/idea/testData/codeInsight/codeTransformations/branched/ifWhen/ifToWhen/ifWithEqualityTests.kt.after b/idea/testData/codeInsight/codeTransformations/branched/ifWhen/ifToWhen/ifWithEqualityTests.kt.after new file mode 100644 index 00000000000..37e018ca2c2 --- /dev/null +++ b/idea/testData/codeInsight/codeTransformations/branched/ifWhen/ifToWhen/ifWithEqualityTests.kt.after @@ -0,0 +1,8 @@ +fun test(n: Int): String { + return when { + n == 0 -> "zero" + n == 1 -> "one" + n == 2 -> "two" + else -> "unknown" + } +} \ No newline at end of file diff --git a/idea/testData/codeInsight/codeTransformations/branched/ifWhen/ifToWhen/ifWithIs.kt b/idea/testData/codeInsight/codeTransformations/branched/ifWhen/ifToWhen/ifWithIs.kt new file mode 100644 index 00000000000..af99f2543d2 --- /dev/null +++ b/idea/testData/codeInsight/codeTransformations/branched/ifWhen/ifToWhen/ifWithIs.kt @@ -0,0 +1,9 @@ +fun test(obj: Any): String { + return if (obj is String) + "string" + else if (obj is Int) + "int" + else if (obj is Class<*>) + "class" + else "unknown" +} \ No newline at end of file diff --git a/idea/testData/codeInsight/codeTransformations/branched/ifWhen/ifToWhen/ifWithIs.kt.after b/idea/testData/codeInsight/codeTransformations/branched/ifWhen/ifToWhen/ifWithIs.kt.after new file mode 100644 index 00000000000..3fd81cd40a8 --- /dev/null +++ b/idea/testData/codeInsight/codeTransformations/branched/ifWhen/ifToWhen/ifWithIs.kt.after @@ -0,0 +1,8 @@ +fun test(obj: Any): String { + return when { + obj is String -> "string" + obj is Int -> "int" + obj is Class<*> -> "class" + else -> "unknown" + } +} \ No newline at end of file diff --git a/idea/testData/codeInsight/codeTransformations/branched/ifWhen/ifToWhen/ifWithMultiConditions.kt b/idea/testData/codeInsight/codeTransformations/branched/ifWhen/ifToWhen/ifWithMultiConditions.kt new file mode 100644 index 00000000000..1b1e1a0b2b8 --- /dev/null +++ b/idea/testData/codeInsight/codeTransformations/branched/ifWhen/ifToWhen/ifWithMultiConditions.kt @@ -0,0 +1,9 @@ +fun test(n: Int): String { + return if ((n < 0) || (n > 1000)) + "unknown" + else if (n <= 10) + "small" + else if (n <= 100) + "average" + else "big" +} \ No newline at end of file diff --git a/idea/testData/codeInsight/codeTransformations/branched/ifWhen/ifToWhen/ifWithMultiConditions.kt.after b/idea/testData/codeInsight/codeTransformations/branched/ifWhen/ifToWhen/ifWithMultiConditions.kt.after new file mode 100644 index 00000000000..c734c5f8f3b --- /dev/null +++ b/idea/testData/codeInsight/codeTransformations/branched/ifWhen/ifToWhen/ifWithMultiConditions.kt.after @@ -0,0 +1,8 @@ +fun test(n: Int): String { + return when { + n < 0, n > 1000 -> "unknown" + n <= 10 -> "small" + n <= 100 -> "average" + else -> "big" + } +} \ No newline at end of file diff --git a/idea/testData/codeInsight/codeTransformations/branched/ifWhen/ifToWhen/ifWithNegativeIs.kt b/idea/testData/codeInsight/codeTransformations/branched/ifWhen/ifToWhen/ifWithNegativeIs.kt new file mode 100644 index 00000000000..0fbe8294ffb --- /dev/null +++ b/idea/testData/codeInsight/codeTransformations/branched/ifWhen/ifToWhen/ifWithNegativeIs.kt @@ -0,0 +1,9 @@ +fun test(obj: Any): String { + return if (obj !is Iterable<*>) + "not iterable" + else if (obj !is Collection<*>) + "not collection" + else if (obj !is MutableCollection<*>) + "not mutable collection" + else "unknown" +} \ No newline at end of file diff --git a/idea/testData/codeInsight/codeTransformations/branched/ifWhen/ifToWhen/ifWithNegativeIs.kt.after b/idea/testData/codeInsight/codeTransformations/branched/ifWhen/ifToWhen/ifWithNegativeIs.kt.after new file mode 100644 index 00000000000..163677dcb22 --- /dev/null +++ b/idea/testData/codeInsight/codeTransformations/branched/ifWhen/ifToWhen/ifWithNegativeIs.kt.after @@ -0,0 +1,8 @@ +fun test(obj: Any): String { + return when { + obj !is Iterable<*> -> "not iterable" + obj !is Collection<*> -> "not collection" + obj !is MutableCollection<*> -> "not mutable collection" + else -> "unknown" + } +} \ No newline at end of file diff --git a/idea/testData/codeInsight/codeTransformations/branched/ifWhen/ifToWhen/ifWithNegativeRangeTests.kt b/idea/testData/codeInsight/codeTransformations/branched/ifWhen/ifToWhen/ifWithNegativeRangeTests.kt new file mode 100644 index 00000000000..9e02b8d24f7 --- /dev/null +++ b/idea/testData/codeInsight/codeTransformations/branched/ifWhen/ifToWhen/ifWithNegativeRangeTests.kt @@ -0,0 +1,9 @@ +fun test(n: Int): String { + return if (n !in 0..1000) + "unknown" + else if (n !in 0..100) + "big" + else if (n !in 0..10) + "average" + else "small" +} \ No newline at end of file diff --git a/idea/testData/codeInsight/codeTransformations/branched/ifWhen/ifToWhen/ifWithNegativeRangeTests.kt.after b/idea/testData/codeInsight/codeTransformations/branched/ifWhen/ifToWhen/ifWithNegativeRangeTests.kt.after new file mode 100644 index 00000000000..6216fc2f79e --- /dev/null +++ b/idea/testData/codeInsight/codeTransformations/branched/ifWhen/ifToWhen/ifWithNegativeRangeTests.kt.after @@ -0,0 +1,8 @@ +fun test(n: Int): String { + return when { + n !in 0..1000 -> "unknown" + n !in 0..100 -> "big" + n !in 0..10 -> "average" + else -> "small" + } +} \ No newline at end of file diff --git a/idea/testData/codeInsight/codeTransformations/branched/ifWhen/ifToWhen/ifWithRangeTests.kt b/idea/testData/codeInsight/codeTransformations/branched/ifWhen/ifToWhen/ifWithRangeTests.kt new file mode 100644 index 00000000000..d2d1cb0f735 --- /dev/null +++ b/idea/testData/codeInsight/codeTransformations/branched/ifWhen/ifToWhen/ifWithRangeTests.kt @@ -0,0 +1,9 @@ +fun test(n: Int): String { + return if (n in 0..10) + "small" + else if (n in 10..100) + "average" + else if (n in 100..1000) + "big" + else "unknown" +} \ No newline at end of file diff --git a/idea/testData/codeInsight/codeTransformations/branched/ifWhen/ifToWhen/ifWithRangeTests.kt.after b/idea/testData/codeInsight/codeTransformations/branched/ifWhen/ifToWhen/ifWithRangeTests.kt.after new file mode 100644 index 00000000000..f47641c76dc --- /dev/null +++ b/idea/testData/codeInsight/codeTransformations/branched/ifWhen/ifToWhen/ifWithRangeTests.kt.after @@ -0,0 +1,8 @@ +fun test(n: Int): String { + return when { + n in 0..10 -> "small" + n in 10..100 -> "average" + n in 100..1000 -> "big" + else -> "unknown" + } +} \ No newline at end of file diff --git a/idea/testData/codeInsight/codeTransformations/branched/ifWhen/ifToWhen/ifWithRangeTestsAndMultiConditions.kt b/idea/testData/codeInsight/codeTransformations/branched/ifWhen/ifToWhen/ifWithRangeTestsAndMultiConditions.kt new file mode 100644 index 00000000000..41ed971402b --- /dev/null +++ b/idea/testData/codeInsight/codeTransformations/branched/ifWhen/ifToWhen/ifWithRangeTestsAndMultiConditions.kt @@ -0,0 +1,9 @@ +fun test(n: Int): String { + return if ((n in 0..5) || (n in 5..10)) + "small" + else if ((n in 10..50) || (n in 50..100)) + "average" + else if ((n in 100..500) || (n in 500..1000)) + "big" + else "unknown" +} \ No newline at end of file diff --git a/idea/testData/codeInsight/codeTransformations/branched/ifWhen/ifToWhen/ifWithRangeTestsAndMultiConditions.kt.after b/idea/testData/codeInsight/codeTransformations/branched/ifWhen/ifToWhen/ifWithRangeTestsAndMultiConditions.kt.after new file mode 100644 index 00000000000..aa84b8524a0 --- /dev/null +++ b/idea/testData/codeInsight/codeTransformations/branched/ifWhen/ifToWhen/ifWithRangeTestsAndMultiConditions.kt.after @@ -0,0 +1,8 @@ +fun test(n: Int): String { + return when { + n in 0..5, n in 5..10 -> "small" + n in 10..50, n in 50..100 -> "average" + n in 100..500, n in 500..1000 -> "big" + else -> "unknown" + } +} \ No newline at end of file diff --git a/idea/testData/codeInsight/codeTransformations/branched/ifWhen/ifToWhen/ifWithRangeTestsAndUnparenthesizedMultiConditions.kt b/idea/testData/codeInsight/codeTransformations/branched/ifWhen/ifToWhen/ifWithRangeTestsAndUnparenthesizedMultiConditions.kt new file mode 100644 index 00000000000..41ed971402b --- /dev/null +++ b/idea/testData/codeInsight/codeTransformations/branched/ifWhen/ifToWhen/ifWithRangeTestsAndUnparenthesizedMultiConditions.kt @@ -0,0 +1,9 @@ +fun test(n: Int): String { + return if ((n in 0..5) || (n in 5..10)) + "small" + else if ((n in 10..50) || (n in 50..100)) + "average" + else if ((n in 100..500) || (n in 500..1000)) + "big" + else "unknown" +} \ No newline at end of file diff --git a/idea/testData/codeInsight/codeTransformations/branched/ifWhen/ifToWhen/ifWithRangeTestsAndUnparenthesizedMultiConditions.kt.after b/idea/testData/codeInsight/codeTransformations/branched/ifWhen/ifToWhen/ifWithRangeTestsAndUnparenthesizedMultiConditions.kt.after new file mode 100644 index 00000000000..aa84b8524a0 --- /dev/null +++ b/idea/testData/codeInsight/codeTransformations/branched/ifWhen/ifToWhen/ifWithRangeTestsAndUnparenthesizedMultiConditions.kt.after @@ -0,0 +1,8 @@ +fun test(n: Int): String { + return when { + n in 0..5, n in 5..10 -> "small" + n in 10..50, n in 50..100 -> "average" + n in 100..500, n in 500..1000 -> "big" + else -> "unknown" + } +} \ No newline at end of file diff --git a/idea/testData/codeInsight/codeTransformations/branched/ifWhen/whenToIf/whenWithEqualityTests.kt b/idea/testData/codeInsight/codeTransformations/branched/ifWhen/whenToIf/whenWithEqualityTests.kt new file mode 100644 index 00000000000..dba5a8e64d6 --- /dev/null +++ b/idea/testData/codeInsight/codeTransformations/branched/ifWhen/whenToIf/whenWithEqualityTests.kt @@ -0,0 +1,8 @@ +fun test(n: Int): String { + return when (n) { + 0 -> "zero" + 1 -> "one" + 2 -> "two" + else -> "unknown" + } +} \ No newline at end of file diff --git a/idea/testData/codeInsight/codeTransformations/branched/ifWhen/whenToIf/whenWithEqualityTests.kt.after b/idea/testData/codeInsight/codeTransformations/branched/ifWhen/whenToIf/whenWithEqualityTests.kt.after new file mode 100644 index 00000000000..47fca307d3c --- /dev/null +++ b/idea/testData/codeInsight/codeTransformations/branched/ifWhen/whenToIf/whenWithEqualityTests.kt.after @@ -0,0 +1,9 @@ +fun test(n: Int): String { + return if (n == 0) + "zero" + else if (n == 1) + "one" + else if (n == 2) + "two" + else "unknown" +} \ No newline at end of file diff --git a/idea/testData/codeInsight/codeTransformations/branched/ifWhen/whenToIf/whenWithMultiConditions.kt b/idea/testData/codeInsight/codeTransformations/branched/ifWhen/whenToIf/whenWithMultiConditions.kt new file mode 100644 index 00000000000..c734c5f8f3b --- /dev/null +++ b/idea/testData/codeInsight/codeTransformations/branched/ifWhen/whenToIf/whenWithMultiConditions.kt @@ -0,0 +1,8 @@ +fun test(n: Int): String { + return when { + n < 0, n > 1000 -> "unknown" + n <= 10 -> "small" + n <= 100 -> "average" + else -> "big" + } +} \ No newline at end of file diff --git a/idea/testData/codeInsight/codeTransformations/branched/ifWhen/whenToIf/whenWithMultiConditions.kt.after b/idea/testData/codeInsight/codeTransformations/branched/ifWhen/whenToIf/whenWithMultiConditions.kt.after new file mode 100644 index 00000000000..1b1e1a0b2b8 --- /dev/null +++ b/idea/testData/codeInsight/codeTransformations/branched/ifWhen/whenToIf/whenWithMultiConditions.kt.after @@ -0,0 +1,9 @@ +fun test(n: Int): String { + return if ((n < 0) || (n > 1000)) + "unknown" + else if (n <= 10) + "small" + else if (n <= 100) + "average" + else "big" +} \ No newline at end of file diff --git a/idea/testData/codeInsight/codeTransformations/branched/ifWhen/whenToIf/whenWithNegativePatterns.kt b/idea/testData/codeInsight/codeTransformations/branched/ifWhen/whenToIf/whenWithNegativePatterns.kt new file mode 100644 index 00000000000..aed8e7af095 --- /dev/null +++ b/idea/testData/codeInsight/codeTransformations/branched/ifWhen/whenToIf/whenWithNegativePatterns.kt @@ -0,0 +1,8 @@ +fun test(obj: Any): String { + return when (obj) { + !is Iterable<*> -> "not iterable" + !is Collection<*> -> "not collection" + !is MutableCollection<*> -> "not mutable collection" + else -> "unknown" + } +} \ No newline at end of file diff --git a/idea/testData/codeInsight/codeTransformations/branched/ifWhen/whenToIf/whenWithNegativePatterns.kt.after b/idea/testData/codeInsight/codeTransformations/branched/ifWhen/whenToIf/whenWithNegativePatterns.kt.after new file mode 100644 index 00000000000..0fbe8294ffb --- /dev/null +++ b/idea/testData/codeInsight/codeTransformations/branched/ifWhen/whenToIf/whenWithNegativePatterns.kt.after @@ -0,0 +1,9 @@ +fun test(obj: Any): String { + return if (obj !is Iterable<*>) + "not iterable" + else if (obj !is Collection<*>) + "not collection" + else if (obj !is MutableCollection<*>) + "not mutable collection" + else "unknown" +} \ No newline at end of file diff --git a/idea/testData/codeInsight/codeTransformations/branched/ifWhen/whenToIf/whenWithNegativeRangeTests.kt b/idea/testData/codeInsight/codeTransformations/branched/ifWhen/whenToIf/whenWithNegativeRangeTests.kt new file mode 100644 index 00000000000..22365e82db6 --- /dev/null +++ b/idea/testData/codeInsight/codeTransformations/branched/ifWhen/whenToIf/whenWithNegativeRangeTests.kt @@ -0,0 +1,8 @@ +fun test(n: Int): String { + return when (n) { + !in 0..1000 -> "unknown" + !in 0..100 -> "big" + !in 0..10 -> "average" + else -> "small" + } +} \ No newline at end of file diff --git a/idea/testData/codeInsight/codeTransformations/branched/ifWhen/whenToIf/whenWithNegativeRangeTests.kt.after b/idea/testData/codeInsight/codeTransformations/branched/ifWhen/whenToIf/whenWithNegativeRangeTests.kt.after new file mode 100644 index 00000000000..9e02b8d24f7 --- /dev/null +++ b/idea/testData/codeInsight/codeTransformations/branched/ifWhen/whenToIf/whenWithNegativeRangeTests.kt.after @@ -0,0 +1,9 @@ +fun test(n: Int): String { + return if (n !in 0..1000) + "unknown" + else if (n !in 0..100) + "big" + else if (n !in 0..10) + "average" + else "small" +} \ No newline at end of file diff --git a/idea/testData/codeInsight/codeTransformations/branched/ifWhen/whenToIf/whenWithPatterns.kt b/idea/testData/codeInsight/codeTransformations/branched/ifWhen/whenToIf/whenWithPatterns.kt new file mode 100644 index 00000000000..e2902c7666b --- /dev/null +++ b/idea/testData/codeInsight/codeTransformations/branched/ifWhen/whenToIf/whenWithPatterns.kt @@ -0,0 +1,8 @@ +fun test(obj: Any): String { + return when (obj) { + is String -> "string" + is Int -> "int" + is Class<*> -> "class" + else -> "unknown" + } +} \ No newline at end of file diff --git a/idea/testData/codeInsight/codeTransformations/branched/ifWhen/whenToIf/whenWithPatterns.kt.after b/idea/testData/codeInsight/codeTransformations/branched/ifWhen/whenToIf/whenWithPatterns.kt.after new file mode 100644 index 00000000000..af99f2543d2 --- /dev/null +++ b/idea/testData/codeInsight/codeTransformations/branched/ifWhen/whenToIf/whenWithPatterns.kt.after @@ -0,0 +1,9 @@ +fun test(obj: Any): String { + return if (obj is String) + "string" + else if (obj is Int) + "int" + else if (obj is Class<*>) + "class" + else "unknown" +} \ No newline at end of file diff --git a/idea/testData/codeInsight/codeTransformations/branched/ifWhen/whenToIf/whenWithRangeTests.kt b/idea/testData/codeInsight/codeTransformations/branched/ifWhen/whenToIf/whenWithRangeTests.kt new file mode 100644 index 00000000000..67f8dd5e022 --- /dev/null +++ b/idea/testData/codeInsight/codeTransformations/branched/ifWhen/whenToIf/whenWithRangeTests.kt @@ -0,0 +1,8 @@ +fun test(n: Int): String { + return when (n) { + in 0..10 -> "small" + in 10..100 -> "average" + in 100..1000 -> "big" + else -> "unknown" + } +} \ No newline at end of file diff --git a/idea/testData/codeInsight/codeTransformations/branched/ifWhen/whenToIf/whenWithRangeTests.kt.after b/idea/testData/codeInsight/codeTransformations/branched/ifWhen/whenToIf/whenWithRangeTests.kt.after new file mode 100644 index 00000000000..d2d1cb0f735 --- /dev/null +++ b/idea/testData/codeInsight/codeTransformations/branched/ifWhen/whenToIf/whenWithRangeTests.kt.after @@ -0,0 +1,9 @@ +fun test(n: Int): String { + return if (n in 0..10) + "small" + else if (n in 10..100) + "average" + else if (n in 100..1000) + "big" + else "unknown" +} \ No newline at end of file diff --git a/idea/testData/codeInsight/codeTransformations/branched/ifWhen/whenToIf/whenWithRangeTestsAndMultiConditions.kt b/idea/testData/codeInsight/codeTransformations/branched/ifWhen/whenToIf/whenWithRangeTestsAndMultiConditions.kt new file mode 100644 index 00000000000..88b38a37492 --- /dev/null +++ b/idea/testData/codeInsight/codeTransformations/branched/ifWhen/whenToIf/whenWithRangeTestsAndMultiConditions.kt @@ -0,0 +1,8 @@ +fun test(n: Int): String { + return when (n) { + in 0..5, in 5..10 -> "small" + in 10..50, in 50..100 -> "average" + in 100..500, in 500..1000 -> "big" + else -> "unknown" + } +} \ No newline at end of file diff --git a/idea/testData/codeInsight/codeTransformations/branched/ifWhen/whenToIf/whenWithRangeTestsAndMultiConditions.kt.after b/idea/testData/codeInsight/codeTransformations/branched/ifWhen/whenToIf/whenWithRangeTestsAndMultiConditions.kt.after new file mode 100644 index 00000000000..41ed971402b --- /dev/null +++ b/idea/testData/codeInsight/codeTransformations/branched/ifWhen/whenToIf/whenWithRangeTestsAndMultiConditions.kt.after @@ -0,0 +1,9 @@ +fun test(n: Int): String { + return if ((n in 0..5) || (n in 5..10)) + "small" + else if ((n in 10..50) || (n in 50..100)) + "average" + else if ((n in 100..500) || (n in 500..1000)) + "big" + else "unknown" +} \ No newline at end of file diff --git a/idea/testData/codeInsight/codeTransformations/branched/ifWhen/whenToIf/whenWithoutSubject.kt b/idea/testData/codeInsight/codeTransformations/branched/ifWhen/whenToIf/whenWithoutSubject.kt new file mode 100644 index 00000000000..f47641c76dc --- /dev/null +++ b/idea/testData/codeInsight/codeTransformations/branched/ifWhen/whenToIf/whenWithoutSubject.kt @@ -0,0 +1,8 @@ +fun test(n: Int): String { + return when { + n in 0..10 -> "small" + n in 10..100 -> "average" + n in 100..1000 -> "big" + else -> "unknown" + } +} \ No newline at end of file diff --git a/idea/testData/codeInsight/codeTransformations/branched/ifWhen/whenToIf/whenWithoutSubject.kt.after b/idea/testData/codeInsight/codeTransformations/branched/ifWhen/whenToIf/whenWithoutSubject.kt.after new file mode 100644 index 00000000000..d2d1cb0f735 --- /dev/null +++ b/idea/testData/codeInsight/codeTransformations/branched/ifWhen/whenToIf/whenWithoutSubject.kt.after @@ -0,0 +1,9 @@ +fun test(n: Int): String { + return if (n in 0..10) + "small" + else if (n in 10..100) + "average" + else if (n in 100..1000) + "big" + else "unknown" +} \ No newline at end of file diff --git a/idea/testData/codeInsight/codeTransformations/branched/when/eliminateSubject/whenWithEqualityTests.kt b/idea/testData/codeInsight/codeTransformations/branched/when/eliminateSubject/whenWithEqualityTests.kt new file mode 100644 index 00000000000..dba5a8e64d6 --- /dev/null +++ b/idea/testData/codeInsight/codeTransformations/branched/when/eliminateSubject/whenWithEqualityTests.kt @@ -0,0 +1,8 @@ +fun test(n: Int): String { + return when (n) { + 0 -> "zero" + 1 -> "one" + 2 -> "two" + else -> "unknown" + } +} \ No newline at end of file diff --git a/idea/testData/codeInsight/codeTransformations/branched/when/eliminateSubject/whenWithEqualityTests.kt.after b/idea/testData/codeInsight/codeTransformations/branched/when/eliminateSubject/whenWithEqualityTests.kt.after new file mode 100644 index 00000000000..37e018ca2c2 --- /dev/null +++ b/idea/testData/codeInsight/codeTransformations/branched/when/eliminateSubject/whenWithEqualityTests.kt.after @@ -0,0 +1,8 @@ +fun test(n: Int): String { + return when { + n == 0 -> "zero" + n == 1 -> "one" + n == 2 -> "two" + else -> "unknown" + } +} \ No newline at end of file diff --git a/idea/testData/codeInsight/codeTransformations/branched/when/eliminateSubject/whenWithNegativePatterns.kt b/idea/testData/codeInsight/codeTransformations/branched/when/eliminateSubject/whenWithNegativePatterns.kt new file mode 100644 index 00000000000..aed8e7af095 --- /dev/null +++ b/idea/testData/codeInsight/codeTransformations/branched/when/eliminateSubject/whenWithNegativePatterns.kt @@ -0,0 +1,8 @@ +fun test(obj: Any): String { + return when (obj) { + !is Iterable<*> -> "not iterable" + !is Collection<*> -> "not collection" + !is MutableCollection<*> -> "not mutable collection" + else -> "unknown" + } +} \ No newline at end of file diff --git a/idea/testData/codeInsight/codeTransformations/branched/when/eliminateSubject/whenWithNegativePatterns.kt.after b/idea/testData/codeInsight/codeTransformations/branched/when/eliminateSubject/whenWithNegativePatterns.kt.after new file mode 100644 index 00000000000..163677dcb22 --- /dev/null +++ b/idea/testData/codeInsight/codeTransformations/branched/when/eliminateSubject/whenWithNegativePatterns.kt.after @@ -0,0 +1,8 @@ +fun test(obj: Any): String { + return when { + obj !is Iterable<*> -> "not iterable" + obj !is Collection<*> -> "not collection" + obj !is MutableCollection<*> -> "not mutable collection" + else -> "unknown" + } +} \ No newline at end of file diff --git a/idea/testData/codeInsight/codeTransformations/branched/when/eliminateSubject/whenWithNegativeRangeTests.kt b/idea/testData/codeInsight/codeTransformations/branched/when/eliminateSubject/whenWithNegativeRangeTests.kt new file mode 100644 index 00000000000..22365e82db6 --- /dev/null +++ b/idea/testData/codeInsight/codeTransformations/branched/when/eliminateSubject/whenWithNegativeRangeTests.kt @@ -0,0 +1,8 @@ +fun test(n: Int): String { + return when (n) { + !in 0..1000 -> "unknown" + !in 0..100 -> "big" + !in 0..10 -> "average" + else -> "small" + } +} \ No newline at end of file diff --git a/idea/testData/codeInsight/codeTransformations/branched/when/eliminateSubject/whenWithNegativeRangeTests.kt.after b/idea/testData/codeInsight/codeTransformations/branched/when/eliminateSubject/whenWithNegativeRangeTests.kt.after new file mode 100644 index 00000000000..6216fc2f79e --- /dev/null +++ b/idea/testData/codeInsight/codeTransformations/branched/when/eliminateSubject/whenWithNegativeRangeTests.kt.after @@ -0,0 +1,8 @@ +fun test(n: Int): String { + return when { + n !in 0..1000 -> "unknown" + n !in 0..100 -> "big" + n !in 0..10 -> "average" + else -> "small" + } +} \ No newline at end of file diff --git a/idea/testData/codeInsight/codeTransformations/branched/when/eliminateSubject/whenWithPatterns.kt b/idea/testData/codeInsight/codeTransformations/branched/when/eliminateSubject/whenWithPatterns.kt new file mode 100644 index 00000000000..e2902c7666b --- /dev/null +++ b/idea/testData/codeInsight/codeTransformations/branched/when/eliminateSubject/whenWithPatterns.kt @@ -0,0 +1,8 @@ +fun test(obj: Any): String { + return when (obj) { + is String -> "string" + is Int -> "int" + is Class<*> -> "class" + else -> "unknown" + } +} \ No newline at end of file diff --git a/idea/testData/codeInsight/codeTransformations/branched/when/eliminateSubject/whenWithPatterns.kt.after b/idea/testData/codeInsight/codeTransformations/branched/when/eliminateSubject/whenWithPatterns.kt.after new file mode 100644 index 00000000000..3fd81cd40a8 --- /dev/null +++ b/idea/testData/codeInsight/codeTransformations/branched/when/eliminateSubject/whenWithPatterns.kt.after @@ -0,0 +1,8 @@ +fun test(obj: Any): String { + return when { + obj is String -> "string" + obj is Int -> "int" + obj is Class<*> -> "class" + else -> "unknown" + } +} \ No newline at end of file diff --git a/idea/testData/codeInsight/codeTransformations/branched/when/eliminateSubject/whenWithRangeTests.kt b/idea/testData/codeInsight/codeTransformations/branched/when/eliminateSubject/whenWithRangeTests.kt new file mode 100644 index 00000000000..67f8dd5e022 --- /dev/null +++ b/idea/testData/codeInsight/codeTransformations/branched/when/eliminateSubject/whenWithRangeTests.kt @@ -0,0 +1,8 @@ +fun test(n: Int): String { + return when (n) { + in 0..10 -> "small" + in 10..100 -> "average" + in 100..1000 -> "big" + else -> "unknown" + } +} \ No newline at end of file diff --git a/idea/testData/codeInsight/codeTransformations/branched/when/eliminateSubject/whenWithRangeTests.kt.after b/idea/testData/codeInsight/codeTransformations/branched/when/eliminateSubject/whenWithRangeTests.kt.after new file mode 100644 index 00000000000..f47641c76dc --- /dev/null +++ b/idea/testData/codeInsight/codeTransformations/branched/when/eliminateSubject/whenWithRangeTests.kt.after @@ -0,0 +1,8 @@ +fun test(n: Int): String { + return when { + n in 0..10 -> "small" + n in 10..100 -> "average" + n in 100..1000 -> "big" + else -> "unknown" + } +} \ No newline at end of file diff --git a/idea/testData/codeInsight/codeTransformations/branched/when/eliminateSubject/whenWithRangeTestsAndMultiConditions.kt b/idea/testData/codeInsight/codeTransformations/branched/when/eliminateSubject/whenWithRangeTestsAndMultiConditions.kt new file mode 100644 index 00000000000..88b38a37492 --- /dev/null +++ b/idea/testData/codeInsight/codeTransformations/branched/when/eliminateSubject/whenWithRangeTestsAndMultiConditions.kt @@ -0,0 +1,8 @@ +fun test(n: Int): String { + return when (n) { + in 0..5, in 5..10 -> "small" + in 10..50, in 50..100 -> "average" + in 100..500, in 500..1000 -> "big" + else -> "unknown" + } +} \ No newline at end of file diff --git a/idea/testData/codeInsight/codeTransformations/branched/when/eliminateSubject/whenWithRangeTestsAndMultiConditions.kt.after b/idea/testData/codeInsight/codeTransformations/branched/when/eliminateSubject/whenWithRangeTestsAndMultiConditions.kt.after new file mode 100644 index 00000000000..aa84b8524a0 --- /dev/null +++ b/idea/testData/codeInsight/codeTransformations/branched/when/eliminateSubject/whenWithRangeTestsAndMultiConditions.kt.after @@ -0,0 +1,8 @@ +fun test(n: Int): String { + return when { + n in 0..5, n in 5..10 -> "small" + n in 10..50, n in 50..100 -> "average" + n in 100..500, n in 500..1000 -> "big" + else -> "unknown" + } +} \ No newline at end of file diff --git a/idea/testData/codeInsight/codeTransformations/branched/when/eliminateSubject/whenWithoutSubject.kt b/idea/testData/codeInsight/codeTransformations/branched/when/eliminateSubject/whenWithoutSubject.kt new file mode 100644 index 00000000000..c6c5e2c9fab --- /dev/null +++ b/idea/testData/codeInsight/codeTransformations/branched/when/eliminateSubject/whenWithoutSubject.kt @@ -0,0 +1,9 @@ +//IS_APPLICABLE: false +fun test(n: Int): String { + return when { + n in 0..10 -> "small" + n in 10..100 -> "average" + n in 100..1000 -> "big" + else -> "unknown" + } +} \ No newline at end of file diff --git a/idea/testData/codeInsight/codeTransformations/branched/when/flatten/flattenWithSubject.kt b/idea/testData/codeInsight/codeTransformations/branched/when/flatten/flattenWithSubject.kt new file mode 100644 index 00000000000..ffb69fa9e71 --- /dev/null +++ b/idea/testData/codeInsight/codeTransformations/branched/when/flatten/flattenWithSubject.kt @@ -0,0 +1,11 @@ +fun test(n: Int): String { + return when(n) { + in 0..10 -> "small" + in 10..100 -> "average" + else -> when(n) { + in 100..1000 -> "big" + in 1000..10000 -> "very big" + else -> "unknown" + } + } +} \ No newline at end of file diff --git a/idea/testData/codeInsight/codeTransformations/branched/when/flatten/flattenWithSubject.kt.after b/idea/testData/codeInsight/codeTransformations/branched/when/flatten/flattenWithSubject.kt.after new file mode 100644 index 00000000000..99a3e1ae2ef --- /dev/null +++ b/idea/testData/codeInsight/codeTransformations/branched/when/flatten/flattenWithSubject.kt.after @@ -0,0 +1,9 @@ +fun test(n: Int): String { + return when (n) { + in 0..10 -> "small" + in 10..100 -> "average" + in 100..1000 -> "big" + in 1000..10000 -> "very big" + else -> "unknown" + } +} \ No newline at end of file diff --git a/idea/testData/codeInsight/codeTransformations/branched/when/flatten/flattenWithUnmatchedSubjects.kt b/idea/testData/codeInsight/codeTransformations/branched/when/flatten/flattenWithUnmatchedSubjects.kt new file mode 100644 index 00000000000..0238e6d6da6 --- /dev/null +++ b/idea/testData/codeInsight/codeTransformations/branched/when/flatten/flattenWithUnmatchedSubjects.kt @@ -0,0 +1,12 @@ +//IS_APPLICABLE: false +fun test(n: Int): String { + return when(n) { + in 0..10 -> "small" + in 10..100 -> "average" + else -> when { + n in 100..1000 -> "big" + n in 1000..10000 -> "very big" + else -> "unknown" + } + } +} \ No newline at end of file diff --git a/idea/testData/codeInsight/codeTransformations/branched/when/flatten/flattenWithoutSubject.kt b/idea/testData/codeInsight/codeTransformations/branched/when/flatten/flattenWithoutSubject.kt new file mode 100644 index 00000000000..bf5d3160bd2 --- /dev/null +++ b/idea/testData/codeInsight/codeTransformations/branched/when/flatten/flattenWithoutSubject.kt @@ -0,0 +1,11 @@ +fun test(n: Int): String { + return when { + n in 0..10 -> "small" + n in 10..100 -> "average" + else -> when { + n in 100..1000 -> "big" + n in 1000..10000 -> "very big" + else -> "unknown" + } + } +} \ No newline at end of file diff --git a/idea/testData/codeInsight/codeTransformations/branched/when/flatten/flattenWithoutSubject.kt.after b/idea/testData/codeInsight/codeTransformations/branched/when/flatten/flattenWithoutSubject.kt.after new file mode 100644 index 00000000000..0347610dae6 --- /dev/null +++ b/idea/testData/codeInsight/codeTransformations/branched/when/flatten/flattenWithoutSubject.kt.after @@ -0,0 +1,9 @@ +fun test(n: Int): String { + return when { + n in 0..10 -> "small" + n in 10..100 -> "average" + n in 100..1000 -> "big" + n in 1000..10000 -> "very big" + else -> "unknown" + } +} \ No newline at end of file diff --git a/idea/testData/codeInsight/codeTransformations/branched/when/introduceSubject/whenWithEqualityTests.kt b/idea/testData/codeInsight/codeTransformations/branched/when/introduceSubject/whenWithEqualityTests.kt new file mode 100644 index 00000000000..37e018ca2c2 --- /dev/null +++ b/idea/testData/codeInsight/codeTransformations/branched/when/introduceSubject/whenWithEqualityTests.kt @@ -0,0 +1,8 @@ +fun test(n: Int): String { + return when { + n == 0 -> "zero" + n == 1 -> "one" + n == 2 -> "two" + else -> "unknown" + } +} \ No newline at end of file diff --git a/idea/testData/codeInsight/codeTransformations/branched/when/introduceSubject/whenWithEqualityTests.kt.after b/idea/testData/codeInsight/codeTransformations/branched/when/introduceSubject/whenWithEqualityTests.kt.after new file mode 100644 index 00000000000..dba5a8e64d6 --- /dev/null +++ b/idea/testData/codeInsight/codeTransformations/branched/when/introduceSubject/whenWithEqualityTests.kt.after @@ -0,0 +1,8 @@ +fun test(n: Int): String { + return when (n) { + 0 -> "zero" + 1 -> "one" + 2 -> "two" + else -> "unknown" + } +} \ No newline at end of file diff --git a/idea/testData/codeInsight/codeTransformations/branched/when/introduceSubject/whenWithNegativePatterns.kt b/idea/testData/codeInsight/codeTransformations/branched/when/introduceSubject/whenWithNegativePatterns.kt new file mode 100644 index 00000000000..163677dcb22 --- /dev/null +++ b/idea/testData/codeInsight/codeTransformations/branched/when/introduceSubject/whenWithNegativePatterns.kt @@ -0,0 +1,8 @@ +fun test(obj: Any): String { + return when { + obj !is Iterable<*> -> "not iterable" + obj !is Collection<*> -> "not collection" + obj !is MutableCollection<*> -> "not mutable collection" + else -> "unknown" + } +} \ No newline at end of file diff --git a/idea/testData/codeInsight/codeTransformations/branched/when/introduceSubject/whenWithNegativePatterns.kt.after b/idea/testData/codeInsight/codeTransformations/branched/when/introduceSubject/whenWithNegativePatterns.kt.after new file mode 100644 index 00000000000..aed8e7af095 --- /dev/null +++ b/idea/testData/codeInsight/codeTransformations/branched/when/introduceSubject/whenWithNegativePatterns.kt.after @@ -0,0 +1,8 @@ +fun test(obj: Any): String { + return when (obj) { + !is Iterable<*> -> "not iterable" + !is Collection<*> -> "not collection" + !is MutableCollection<*> -> "not mutable collection" + else -> "unknown" + } +} \ No newline at end of file diff --git a/idea/testData/codeInsight/codeTransformations/branched/when/introduceSubject/whenWithNegativeRangeTests.kt b/idea/testData/codeInsight/codeTransformations/branched/when/introduceSubject/whenWithNegativeRangeTests.kt new file mode 100644 index 00000000000..6216fc2f79e --- /dev/null +++ b/idea/testData/codeInsight/codeTransformations/branched/when/introduceSubject/whenWithNegativeRangeTests.kt @@ -0,0 +1,8 @@ +fun test(n: Int): String { + return when { + n !in 0..1000 -> "unknown" + n !in 0..100 -> "big" + n !in 0..10 -> "average" + else -> "small" + } +} \ No newline at end of file diff --git a/idea/testData/codeInsight/codeTransformations/branched/when/introduceSubject/whenWithNegativeRangeTests.kt.after b/idea/testData/codeInsight/codeTransformations/branched/when/introduceSubject/whenWithNegativeRangeTests.kt.after new file mode 100644 index 00000000000..22365e82db6 --- /dev/null +++ b/idea/testData/codeInsight/codeTransformations/branched/when/introduceSubject/whenWithNegativeRangeTests.kt.after @@ -0,0 +1,8 @@ +fun test(n: Int): String { + return when (n) { + !in 0..1000 -> "unknown" + !in 0..100 -> "big" + !in 0..10 -> "average" + else -> "small" + } +} \ No newline at end of file diff --git a/idea/testData/codeInsight/codeTransformations/branched/when/introduceSubject/whenWithNondivisibleConditions.kt b/idea/testData/codeInsight/codeTransformations/branched/when/introduceSubject/whenWithNondivisibleConditions.kt new file mode 100644 index 00000000000..6f2669017f5 --- /dev/null +++ b/idea/testData/codeInsight/codeTransformations/branched/when/introduceSubject/whenWithNondivisibleConditions.kt @@ -0,0 +1,9 @@ +//IS_APPLICABLE: false +fun test(n: Int): String { + return when { + n in 0..10 -> "small" + n >= 10 && n <= 100 -> "average" + n < 0, n > 1000 -> "unknown" + else -> "big" + } +} \ No newline at end of file diff --git a/idea/testData/codeInsight/codeTransformations/branched/when/introduceSubject/whenWithPatterns.kt b/idea/testData/codeInsight/codeTransformations/branched/when/introduceSubject/whenWithPatterns.kt new file mode 100644 index 00000000000..3fd81cd40a8 --- /dev/null +++ b/idea/testData/codeInsight/codeTransformations/branched/when/introduceSubject/whenWithPatterns.kt @@ -0,0 +1,8 @@ +fun test(obj: Any): String { + return when { + obj is String -> "string" + obj is Int -> "int" + obj is Class<*> -> "class" + else -> "unknown" + } +} \ No newline at end of file diff --git a/idea/testData/codeInsight/codeTransformations/branched/when/introduceSubject/whenWithPatterns.kt.after b/idea/testData/codeInsight/codeTransformations/branched/when/introduceSubject/whenWithPatterns.kt.after new file mode 100644 index 00000000000..e2902c7666b --- /dev/null +++ b/idea/testData/codeInsight/codeTransformations/branched/when/introduceSubject/whenWithPatterns.kt.after @@ -0,0 +1,8 @@ +fun test(obj: Any): String { + return when (obj) { + is String -> "string" + is Int -> "int" + is Class<*> -> "class" + else -> "unknown" + } +} \ No newline at end of file diff --git a/idea/testData/codeInsight/codeTransformations/branched/when/introduceSubject/whenWithRangeTests.kt b/idea/testData/codeInsight/codeTransformations/branched/when/introduceSubject/whenWithRangeTests.kt new file mode 100644 index 00000000000..f47641c76dc --- /dev/null +++ b/idea/testData/codeInsight/codeTransformations/branched/when/introduceSubject/whenWithRangeTests.kt @@ -0,0 +1,8 @@ +fun test(n: Int): String { + return when { + n in 0..10 -> "small" + n in 10..100 -> "average" + n in 100..1000 -> "big" + else -> "unknown" + } +} \ No newline at end of file diff --git a/idea/testData/codeInsight/codeTransformations/branched/when/introduceSubject/whenWithRangeTests.kt.after b/idea/testData/codeInsight/codeTransformations/branched/when/introduceSubject/whenWithRangeTests.kt.after new file mode 100644 index 00000000000..67f8dd5e022 --- /dev/null +++ b/idea/testData/codeInsight/codeTransformations/branched/when/introduceSubject/whenWithRangeTests.kt.after @@ -0,0 +1,8 @@ +fun test(n: Int): String { + return when (n) { + in 0..10 -> "small" + in 10..100 -> "average" + in 100..1000 -> "big" + else -> "unknown" + } +} \ No newline at end of file diff --git a/idea/testData/codeInsight/codeTransformations/branched/when/introduceSubject/whenWithRangeTestsAndMultiConditions.kt b/idea/testData/codeInsight/codeTransformations/branched/when/introduceSubject/whenWithRangeTestsAndMultiConditions.kt new file mode 100644 index 00000000000..aa84b8524a0 --- /dev/null +++ b/idea/testData/codeInsight/codeTransformations/branched/when/introduceSubject/whenWithRangeTestsAndMultiConditions.kt @@ -0,0 +1,8 @@ +fun test(n: Int): String { + return when { + n in 0..5, n in 5..10 -> "small" + n in 10..50, n in 50..100 -> "average" + n in 100..500, n in 500..1000 -> "big" + else -> "unknown" + } +} \ No newline at end of file diff --git a/idea/testData/codeInsight/codeTransformations/branched/when/introduceSubject/whenWithRangeTestsAndMultiConditions.kt.after b/idea/testData/codeInsight/codeTransformations/branched/when/introduceSubject/whenWithRangeTestsAndMultiConditions.kt.after new file mode 100644 index 00000000000..88b38a37492 --- /dev/null +++ b/idea/testData/codeInsight/codeTransformations/branched/when/introduceSubject/whenWithRangeTestsAndMultiConditions.kt.after @@ -0,0 +1,8 @@ +fun test(n: Int): String { + return when (n) { + in 0..5, in 5..10 -> "small" + in 10..50, in 50..100 -> "average" + in 100..500, in 500..1000 -> "big" + else -> "unknown" + } +} \ No newline at end of file diff --git a/idea/testData/codeInsight/codeTransformations/branched/when/introduceSubject/whenWithSubject.kt b/idea/testData/codeInsight/codeTransformations/branched/when/introduceSubject/whenWithSubject.kt new file mode 100644 index 00000000000..2aaf349558d --- /dev/null +++ b/idea/testData/codeInsight/codeTransformations/branched/when/introduceSubject/whenWithSubject.kt @@ -0,0 +1,9 @@ +//IS_APPLICABLE: false +fun test(n: Int): String { + return when(n) { + in 0..10 -> "small" + in 10..100 -> "average" + in 100..1000 -> "big" + else -> "unknown" + } +} \ No newline at end of file diff --git a/idea/testData/codeInsight/codeTransformations/branched/when/introduceSubject/whenWithUnmatchedCandidateSubjects.kt b/idea/testData/codeInsight/codeTransformations/branched/when/introduceSubject/whenWithUnmatchedCandidateSubjects.kt new file mode 100644 index 00000000000..1077ec19255 --- /dev/null +++ b/idea/testData/codeInsight/codeTransformations/branched/when/introduceSubject/whenWithUnmatchedCandidateSubjects.kt @@ -0,0 +1,9 @@ +//IS_APPLICABLE: false +fun test(n: Int): String { + return when { + n in 0..10 -> "n is small" + n/10 in 0..10 -> "m is average" + n/100 in 0..10 -> "n is big" + else -> "unknown" + } +} \ No newline at end of file diff --git a/idea/tests/org/jetbrains/jet/plugin/codeInsight/codeTransformations/AbstractCodeTransformationTest.java b/idea/tests/org/jetbrains/jet/plugin/codeInsight/codeTransformations/AbstractCodeTransformationTest.java index b838ac1dcf7..c0db705a380 100644 --- a/idea/tests/org/jetbrains/jet/plugin/codeInsight/codeTransformations/AbstractCodeTransformationTest.java +++ b/idea/tests/org/jetbrains/jet/plugin/codeInsight/codeTransformations/AbstractCodeTransformationTest.java @@ -62,6 +62,26 @@ public abstract class AbstractCodeTransformationTest extends LightCodeInsightTes doTest(path, new UnfoldBranchedExpressionIntention.UnfoldReturnToWhenIntention()); } + public void doTestIfToWhen(@NotNull String path) throws Exception { + doTest(path, new IfToWhenIntention()); + } + + public void doTestWhenToIf(@NotNull String path) throws Exception { + doTest(path, new WhenToIfIntention()); + } + + public void doTestFlattenWhen(@NotNull String path) throws Exception { + doTest(path, new FlattenWhenIntention()); + } + + public void doTestIntroduceWhenSubject(@NotNull String path) throws Exception { + doTest(path, new IntroduceWhenSubjectIntention()); + } + + public void doTestEliminateWhenSubject(@NotNull String path) throws Exception { + doTest(path, new EliminateWhenSubjectIntention()); + } + public void doTestRemoveUnnecessaryParentheses(@NotNull String path) throws Exception { doTest(path, new RemoveUnnecessaryParenthesesIntention()); } diff --git a/idea/tests/org/jetbrains/jet/plugin/codeInsight/codeTransformations/CodeTransformationsTestGenerated.java b/idea/tests/org/jetbrains/jet/plugin/codeInsight/codeTransformations/CodeTransformationsTestGenerated.java index 4ec4671eee3..71da5f98dfc 100644 --- a/idea/tests/org/jetbrains/jet/plugin/codeInsight/codeTransformations/CodeTransformationsTestGenerated.java +++ b/idea/tests/org/jetbrains/jet/plugin/codeInsight/codeTransformations/CodeTransformationsTestGenerated.java @@ -30,7 +30,7 @@ import org.jetbrains.jet.plugin.codeInsight.codeTransformations.AbstractCodeTran /** This class is generated by {@link org.jetbrains.jet.generators.tests.GenerateTests}. DO NOT MODIFY MANUALLY */ @SuppressWarnings("all") -@InnerTestClasses({CodeTransformationsTestGenerated.IfToAssignment.class, CodeTransformationsTestGenerated.IfToReturn.class, CodeTransformationsTestGenerated.IfToReturnAsymmetrically.class, CodeTransformationsTestGenerated.WhenToAssignment.class, CodeTransformationsTestGenerated.WhenToReturn.class, CodeTransformationsTestGenerated.AssignmentToIf.class, CodeTransformationsTestGenerated.AssignmentToWhen.class, CodeTransformationsTestGenerated.ReturnToIf.class, CodeTransformationsTestGenerated.ReturnToWhen.class}) +@InnerTestClasses({CodeTransformationsTestGenerated.IfToAssignment.class, CodeTransformationsTestGenerated.IfToReturn.class, CodeTransformationsTestGenerated.IfToReturnAsymmetrically.class, CodeTransformationsTestGenerated.WhenToAssignment.class, CodeTransformationsTestGenerated.WhenToReturn.class, CodeTransformationsTestGenerated.AssignmentToIf.class, CodeTransformationsTestGenerated.AssignmentToWhen.class, CodeTransformationsTestGenerated.ReturnToIf.class, CodeTransformationsTestGenerated.ReturnToWhen.class, CodeTransformationsTestGenerated.IfToWhen.class, CodeTransformationsTestGenerated.WhenToIf.class, CodeTransformationsTestGenerated.Flatten.class, CodeTransformationsTestGenerated.IntroduceSubject.class, CodeTransformationsTestGenerated.EliminateSubject.class}) public class CodeTransformationsTestGenerated extends AbstractCodeTransformationTest { @TestMetadata("idea/testData/codeInsight/codeTransformations/branched/folding/ifToAssignment") public static class IfToAssignment extends AbstractCodeTransformationTest { @@ -299,6 +299,221 @@ public class CodeTransformationsTestGenerated extends AbstractCodeTransformation } + @TestMetadata("idea/testData/codeInsight/codeTransformations/branched/ifWhen/ifToWhen") + public static class IfToWhen extends AbstractCodeTransformationTest { + public void testAllFilesPresentInIfToWhen() throws Exception { + JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.GenerateTests", new File("idea/testData/codeInsight/codeTransformations/branched/ifWhen/ifToWhen"), Pattern.compile("^(.+)\\.kt$"), true); + } + + @TestMetadata("ifWithEqualityTests.kt") + public void testIfWithEqualityTests() throws Exception { + doTestIfToWhen("idea/testData/codeInsight/codeTransformations/branched/ifWhen/ifToWhen/ifWithEqualityTests.kt"); + } + + @TestMetadata("ifWithIs.kt") + public void testIfWithIs() throws Exception { + doTestIfToWhen("idea/testData/codeInsight/codeTransformations/branched/ifWhen/ifToWhen/ifWithIs.kt"); + } + + @TestMetadata("ifWithMultiConditions.kt") + public void testIfWithMultiConditions() throws Exception { + doTestIfToWhen("idea/testData/codeInsight/codeTransformations/branched/ifWhen/ifToWhen/ifWithMultiConditions.kt"); + } + + @TestMetadata("ifWithNegativeIs.kt") + public void testIfWithNegativeIs() throws Exception { + doTestIfToWhen("idea/testData/codeInsight/codeTransformations/branched/ifWhen/ifToWhen/ifWithNegativeIs.kt"); + } + + @TestMetadata("ifWithNegativeRangeTests.kt") + public void testIfWithNegativeRangeTests() throws Exception { + doTestIfToWhen("idea/testData/codeInsight/codeTransformations/branched/ifWhen/ifToWhen/ifWithNegativeRangeTests.kt"); + } + + @TestMetadata("ifWithRangeTests.kt") + public void testIfWithRangeTests() throws Exception { + doTestIfToWhen("idea/testData/codeInsight/codeTransformations/branched/ifWhen/ifToWhen/ifWithRangeTests.kt"); + } + + @TestMetadata("ifWithRangeTestsAndMultiConditions.kt") + public void testIfWithRangeTestsAndMultiConditions() throws Exception { + doTestIfToWhen("idea/testData/codeInsight/codeTransformations/branched/ifWhen/ifToWhen/ifWithRangeTestsAndMultiConditions.kt"); + } + + @TestMetadata("ifWithRangeTestsAndUnparenthesizedMultiConditions.kt") + public void testIfWithRangeTestsAndUnparenthesizedMultiConditions() throws Exception { + doTestIfToWhen("idea/testData/codeInsight/codeTransformations/branched/ifWhen/ifToWhen/ifWithRangeTestsAndUnparenthesizedMultiConditions.kt"); + } + + } + + @TestMetadata("idea/testData/codeInsight/codeTransformations/branched/ifWhen/whenToIf") + public static class WhenToIf extends AbstractCodeTransformationTest { + public void testAllFilesPresentInWhenToIf() throws Exception { + JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.GenerateTests", new File("idea/testData/codeInsight/codeTransformations/branched/ifWhen/whenToIf"), Pattern.compile("^(.+)\\.kt$"), true); + } + + @TestMetadata("whenWithEqualityTests.kt") + public void testWhenWithEqualityTests() throws Exception { + doTestWhenToIf("idea/testData/codeInsight/codeTransformations/branched/ifWhen/whenToIf/whenWithEqualityTests.kt"); + } + + @TestMetadata("whenWithMultiConditions.kt") + public void testWhenWithMultiConditions() throws Exception { + doTestWhenToIf("idea/testData/codeInsight/codeTransformations/branched/ifWhen/whenToIf/whenWithMultiConditions.kt"); + } + + @TestMetadata("whenWithNegativePatterns.kt") + public void testWhenWithNegativePatterns() throws Exception { + doTestWhenToIf("idea/testData/codeInsight/codeTransformations/branched/ifWhen/whenToIf/whenWithNegativePatterns.kt"); + } + + @TestMetadata("whenWithNegativeRangeTests.kt") + public void testWhenWithNegativeRangeTests() throws Exception { + doTestWhenToIf("idea/testData/codeInsight/codeTransformations/branched/ifWhen/whenToIf/whenWithNegativeRangeTests.kt"); + } + + @TestMetadata("whenWithPatterns.kt") + public void testWhenWithPatterns() throws Exception { + doTestWhenToIf("idea/testData/codeInsight/codeTransformations/branched/ifWhen/whenToIf/whenWithPatterns.kt"); + } + + @TestMetadata("whenWithRangeTests.kt") + public void testWhenWithRangeTests() throws Exception { + doTestWhenToIf("idea/testData/codeInsight/codeTransformations/branched/ifWhen/whenToIf/whenWithRangeTests.kt"); + } + + @TestMetadata("whenWithRangeTestsAndMultiConditions.kt") + public void testWhenWithRangeTestsAndMultiConditions() throws Exception { + doTestWhenToIf("idea/testData/codeInsight/codeTransformations/branched/ifWhen/whenToIf/whenWithRangeTestsAndMultiConditions.kt"); + } + + @TestMetadata("whenWithoutSubject.kt") + public void testWhenWithoutSubject() throws Exception { + doTestWhenToIf("idea/testData/codeInsight/codeTransformations/branched/ifWhen/whenToIf/whenWithoutSubject.kt"); + } + + } + + @TestMetadata("idea/testData/codeInsight/codeTransformations/branched/when/flatten") + public static class Flatten extends AbstractCodeTransformationTest { + public void testAllFilesPresentInFlatten() throws Exception { + JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.GenerateTests", new File("idea/testData/codeInsight/codeTransformations/branched/when/flatten"), Pattern.compile("^(.+)\\.kt$"), true); + } + + @TestMetadata("flattenWithSubject.kt") + public void testFlattenWithSubject() throws Exception { + doTestFlattenWhen("idea/testData/codeInsight/codeTransformations/branched/when/flatten/flattenWithSubject.kt"); + } + + @TestMetadata("flattenWithUnmatchedSubjects.kt") + public void testFlattenWithUnmatchedSubjects() throws Exception { + doTestFlattenWhen("idea/testData/codeInsight/codeTransformations/branched/when/flatten/flattenWithUnmatchedSubjects.kt"); + } + + @TestMetadata("flattenWithoutSubject.kt") + public void testFlattenWithoutSubject() throws Exception { + doTestFlattenWhen("idea/testData/codeInsight/codeTransformations/branched/when/flatten/flattenWithoutSubject.kt"); + } + + } + + @TestMetadata("idea/testData/codeInsight/codeTransformations/branched/when/introduceSubject") + public static class IntroduceSubject extends AbstractCodeTransformationTest { + public void testAllFilesPresentInIntroduceSubject() throws Exception { + JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.GenerateTests", new File("idea/testData/codeInsight/codeTransformations/branched/when/introduceSubject"), Pattern.compile("^(.+)\\.kt$"), true); + } + + @TestMetadata("whenWithEqualityTests.kt") + public void testWhenWithEqualityTests() throws Exception { + doTestIntroduceWhenSubject("idea/testData/codeInsight/codeTransformations/branched/when/introduceSubject/whenWithEqualityTests.kt"); + } + + @TestMetadata("whenWithNegativePatterns.kt") + public void testWhenWithNegativePatterns() throws Exception { + doTestIntroduceWhenSubject("idea/testData/codeInsight/codeTransformations/branched/when/introduceSubject/whenWithNegativePatterns.kt"); + } + + @TestMetadata("whenWithNegativeRangeTests.kt") + public void testWhenWithNegativeRangeTests() throws Exception { + doTestIntroduceWhenSubject("idea/testData/codeInsight/codeTransformations/branched/when/introduceSubject/whenWithNegativeRangeTests.kt"); + } + + @TestMetadata("whenWithNondivisibleConditions.kt") + public void testWhenWithNondivisibleConditions() throws Exception { + doTestIntroduceWhenSubject("idea/testData/codeInsight/codeTransformations/branched/when/introduceSubject/whenWithNondivisibleConditions.kt"); + } + + @TestMetadata("whenWithPatterns.kt") + public void testWhenWithPatterns() throws Exception { + doTestIntroduceWhenSubject("idea/testData/codeInsight/codeTransformations/branched/when/introduceSubject/whenWithPatterns.kt"); + } + + @TestMetadata("whenWithRangeTests.kt") + public void testWhenWithRangeTests() throws Exception { + doTestIntroduceWhenSubject("idea/testData/codeInsight/codeTransformations/branched/when/introduceSubject/whenWithRangeTests.kt"); + } + + @TestMetadata("whenWithRangeTestsAndMultiConditions.kt") + public void testWhenWithRangeTestsAndMultiConditions() throws Exception { + doTestIntroduceWhenSubject("idea/testData/codeInsight/codeTransformations/branched/when/introduceSubject/whenWithRangeTestsAndMultiConditions.kt"); + } + + @TestMetadata("whenWithSubject.kt") + public void testWhenWithSubject() throws Exception { + doTestIntroduceWhenSubject("idea/testData/codeInsight/codeTransformations/branched/when/introduceSubject/whenWithSubject.kt"); + } + + @TestMetadata("whenWithUnmatchedCandidateSubjects.kt") + public void testWhenWithUnmatchedCandidateSubjects() throws Exception { + doTestIntroduceWhenSubject("idea/testData/codeInsight/codeTransformations/branched/when/introduceSubject/whenWithUnmatchedCandidateSubjects.kt"); + } + + } + + @TestMetadata("idea/testData/codeInsight/codeTransformations/branched/when/eliminateSubject") + public static class EliminateSubject extends AbstractCodeTransformationTest { + public void testAllFilesPresentInEliminateSubject() throws Exception { + JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.GenerateTests", new File("idea/testData/codeInsight/codeTransformations/branched/when/eliminateSubject"), Pattern.compile("^(.+)\\.kt$"), true); + } + + @TestMetadata("whenWithEqualityTests.kt") + public void testWhenWithEqualityTests() throws Exception { + doTestEliminateWhenSubject("idea/testData/codeInsight/codeTransformations/branched/when/eliminateSubject/whenWithEqualityTests.kt"); + } + + @TestMetadata("whenWithNegativePatterns.kt") + public void testWhenWithNegativePatterns() throws Exception { + doTestEliminateWhenSubject("idea/testData/codeInsight/codeTransformations/branched/when/eliminateSubject/whenWithNegativePatterns.kt"); + } + + @TestMetadata("whenWithNegativeRangeTests.kt") + public void testWhenWithNegativeRangeTests() throws Exception { + doTestEliminateWhenSubject("idea/testData/codeInsight/codeTransformations/branched/when/eliminateSubject/whenWithNegativeRangeTests.kt"); + } + + @TestMetadata("whenWithPatterns.kt") + public void testWhenWithPatterns() throws Exception { + doTestEliminateWhenSubject("idea/testData/codeInsight/codeTransformations/branched/when/eliminateSubject/whenWithPatterns.kt"); + } + + @TestMetadata("whenWithRangeTests.kt") + public void testWhenWithRangeTests() throws Exception { + doTestEliminateWhenSubject("idea/testData/codeInsight/codeTransformations/branched/when/eliminateSubject/whenWithRangeTests.kt"); + } + + @TestMetadata("whenWithRangeTestsAndMultiConditions.kt") + public void testWhenWithRangeTestsAndMultiConditions() throws Exception { + doTestEliminateWhenSubject("idea/testData/codeInsight/codeTransformations/branched/when/eliminateSubject/whenWithRangeTestsAndMultiConditions.kt"); + } + + @TestMetadata("whenWithoutSubject.kt") + public void testWhenWithoutSubject() throws Exception { + doTestEliminateWhenSubject("idea/testData/codeInsight/codeTransformations/branched/when/eliminateSubject/whenWithoutSubject.kt"); + } + + } + public static Test suite() { TestSuite suite = new TestSuite("CodeTransformationsTestGenerated"); suite.addTestSuite(IfToAssignment.class); @@ -310,6 +525,11 @@ public class CodeTransformationsTestGenerated extends AbstractCodeTransformation suite.addTestSuite(AssignmentToWhen.class); suite.addTestSuite(ReturnToIf.class); suite.addTestSuite(ReturnToWhen.class); + suite.addTestSuite(IfToWhen.class); + suite.addTestSuite(WhenToIf.class); + suite.addTestSuite(Flatten.class); + suite.addTestSuite(IntroduceSubject.class); + suite.addTestSuite(EliminateSubject.class); return suite; } } From 3383679928617595d6cd3a77d760bb79c43e3a92 Mon Sep 17 00:00:00 2001 From: Alexey Sedunov Date: Fri, 26 Apr 2013 14:48:22 +0400 Subject: [PATCH 089/249] Extract 'assertNotNull' method --- .../branchedTransformations/WhenUtils.java | 53 ++++++++++++------- 1 file changed, 34 insertions(+), 19 deletions(-) diff --git a/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/WhenUtils.java b/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/WhenUtils.java index 5429eeef779..a40291df86f 100644 --- a/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/WhenUtils.java +++ b/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/WhenUtils.java @@ -15,6 +15,10 @@ public class WhenUtils { public static final String TRANSFORM_WITHOUT_CHECK = "Expression must be checked before applying transformation"; + private static void assertNotNull(Object expression) { + assert expression != null : TRANSFORM_WITHOUT_CHECK; + } + private static JetExpression getWhenConditionSubjectCandidate(JetExpression condition) { if (condition instanceof JetIsExpression) { return ((JetIsExpression) condition).getLeftHandSide(); @@ -99,8 +103,9 @@ public class WhenUtils { if (hasSubject) { JetExpression dummySubjectExpression = newWhenExpression.getSubjectExpression(); - assert dummySubjectExpression != null : TRANSFORM_WITHOUT_CHECK; + assertNotNull(dummySubjectExpression); + //noinspection ConstantConditions dummySubjectExpression.replace(subjectExpression); } @@ -159,13 +164,14 @@ public class WhenUtils { public static void introduceWhenSubject(@NotNull JetWhenExpression whenExpression) { JetExpression subject = getWhenSubjectCandidate(whenExpression); - assert subject != null : TRANSFORM_WITHOUT_CHECK; + assertNotNull(subject); JetWhenExpression newWhenExpression = createWhenTemplateWithSubject(whenExpression); JetExpression newSubject = newWhenExpression.getSubjectExpression(); - assert newSubject != null : TRANSFORM_WITHOUT_CHECK; + assertNotNull(newSubject); + //noinspection ConstantConditions newSubject.replace(subject); int i = 0; @@ -175,11 +181,12 @@ public class WhenUtils { JetWhenEntry entry = entries.get(i++); JetExpression branchExpression = entry.getExpression(); - assert branchExpression != null : TRANSFORM_WITHOUT_CHECK; + assertNotNull(branchExpression); JetExpression newBranchExpression = newEntry.getExpression(); - assert newBranchExpression != null : TRANSFORM_WITHOUT_CHECK; + assertNotNull(newBranchExpression); + //noinspection ConstantConditions newBranchExpression.replace(branchExpression); int j = 0; @@ -197,34 +204,37 @@ public class WhenUtils { assert newCondition instanceof JetWhenConditionIsPattern : TRANSFORM_WITHOUT_CHECK; JetTypeReference typeReference = ((JetIsExpression) conditionExpression).getTypeRef(); - assert typeReference != null : TRANSFORM_WITHOUT_CHECK; + assertNotNull(typeReference); JetTypeReference newTypeReference = ((JetWhenConditionIsPattern) newCondition).getTypeRef(); - assert newTypeReference != null : TRANSFORM_WITHOUT_CHECK; + assertNotNull(newTypeReference); + //noinspection ConstantConditions newTypeReference.replace(typeReference); } else if (conditionExpression instanceof JetBinaryExpression) { JetBinaryExpression binaryExpression = (JetBinaryExpression) conditionExpression; JetExpression rhs = binaryExpression.getRight(); - assert rhs != null : TRANSFORM_WITHOUT_CHECK; + assertNotNull(rhs); IElementType op = binaryExpression.getOperationToken(); if (op == JetTokens.IN_KEYWORD || op == JetTokens.NOT_IN) { assert newCondition instanceof JetWhenConditionInRange : TRANSFORM_WITHOUT_CHECK; JetExpression newRangeExpression = ((JetWhenConditionInRange) newCondition).getRangeExpression(); - assert newRangeExpression != null : TRANSFORM_WITHOUT_CHECK; + assertNotNull(newRangeExpression); + //noinspection ConstantConditions newRangeExpression.replace(rhs); } else if (op == JetTokens.EQEQ) { assert newCondition instanceof JetWhenConditionWithExpression : TRANSFORM_WITHOUT_CHECK; JetExpression newConditionExpression = ((JetWhenConditionWithExpression) newCondition).getExpression(); - assert newConditionExpression != null : TRANSFORM_WITHOUT_CHECK; + assertNotNull(newConditionExpression); + //noinspection ConstantConditions newConditionExpression.replace(rhs); } else assert false : TRANSFORM_WITHOUT_CHECK; @@ -255,10 +265,11 @@ public class WhenUtils { JetWhenConditionIsPattern patternCondition = (JetWhenConditionIsPattern) condition; JetTypeReference typeReference = patternCondition.getTypeRef(); - assert typeReference != null : TRANSFORM_WITHOUT_CHECK; + assertNotNull(typeReference); - assert subject != null : TRANSFORM_WITHOUT_CHECK; + assertNotNull(subject); + //noinspection ConstantConditions return JetPsiFactory.createIsExpression(project, subject, typeReference, patternCondition.isNegated()); } @@ -266,24 +277,26 @@ public class WhenUtils { JetWhenConditionInRange rangeCondition = (JetWhenConditionInRange) condition; JetExpression rangeExpression = rangeCondition.getRangeExpression(); - assert rangeExpression != null : TRANSFORM_WITHOUT_CHECK; + assertNotNull(rangeExpression); - assert subject != null : TRANSFORM_WITHOUT_CHECK; + assertNotNull(subject); + //noinspection ConstantConditions return JetPsiFactory.createBinaryExpression(project, subject, rangeCondition.getOperationReference().getText(), rangeExpression); } assert condition instanceof JetWhenConditionWithExpression : TRANSFORM_WITHOUT_CHECK; JetExpression conditionExpression = ((JetWhenConditionWithExpression) condition).getExpression(); - assert conditionExpression != null : TRANSFORM_WITHOUT_CHECK; + assertNotNull(conditionExpression); + //noinspection ConstantConditions return subject != null ? JetPsiFactory.createBinaryExpression(project, subject, "==", conditionExpression) : conditionExpression; } public static void eliminateWhenSubject(@NotNull JetWhenExpression whenExpression) { JetExpression subject = whenExpression.getSubjectExpression(); - assert subject != null : TRANSFORM_WITHOUT_CHECK; + assertNotNull(subject); JetWhenExpression newWhenExpression = createWhenTemplateWithoutSubject(whenExpression); @@ -294,11 +307,12 @@ public class WhenUtils { JetWhenEntry entry = entries.get(i++); JetExpression branchExpression = entry.getExpression(); - assert branchExpression != null : TRANSFORM_WITHOUT_CHECK; + assertNotNull(branchExpression); JetExpression newBranchExpression = newEntry.getExpression(); - assert newBranchExpression != null : TRANSFORM_WITHOUT_CHECK; + assertNotNull(newBranchExpression); + //noinspection ConstantConditions newBranchExpression.replace(branchExpression); int j = 0; @@ -309,8 +323,9 @@ public class WhenUtils { JetWhenCondition condition = conditions[j++]; JetExpression newConditionExpression = ((JetWhenConditionWithExpression) newCondition).getExpression(); - assert newConditionExpression != null : TRANSFORM_WITHOUT_CHECK; + assertNotNull(newConditionExpression); + //noinspection ConstantConditions newConditionExpression.replace(whenConditionToExpression(condition, subject)); } } From d30e8d88fbced70e3f83a53052881518c5afa6b9 Mon Sep 17 00:00:00 2001 From: Alexey Sedunov Date: Tue, 30 Apr 2013 12:15:20 +0400 Subject: [PATCH 090/249] Get rid of excessive replaces --- .../jetbrains/jet/lang/psi/JetPsiFactory.java | 214 ++++++++++-------- .../jet/lang/psi/JetPsiUnparsingUtils.java | 59 +++++ .../jetbrains/jet/lang/psi/JetPsiUtil.java | 10 + .../BranchedFoldingUtils.java | 3 +- .../BranchedUnfoldingUtils.java | 9 +- .../GuardedExpression.java | 27 --- .../branchedTransformations/IfWhenUtils.java | 108 +++------ .../MultiGuardedExpression.java | 29 --- .../branchedTransformations/WhenUtils.java | 212 +++++------------ .../folding/whenToReturn/simpleWhen.kt.after | 4 +- .../whenToReturn/simpleWhenWithBlocks.kt | 15 +- .../simpleWhenWithBlocks.kt.after | 15 +- .../whenToIf/whenWithEqualityTests.kt.after | 9 +- .../whenToIf/whenWithMultiConditions.kt.after | 9 +- .../whenWithNegativePatterns.kt.after | 9 +- .../whenWithNegativeRangeTests.kt.after | 9 +- .../ifWhen/whenToIf/whenWithPatterns.kt.after | 9 +- .../whenToIf/whenWithRangeTests.kt.after | 9 +- ...nWithRangeTestsAndMultiConditions.kt.after | 9 +- .../whenToIf/whenWithoutSubject.kt.after | 9 +- 20 files changed, 320 insertions(+), 457 deletions(-) create mode 100644 compiler/frontend/src/org/jetbrains/jet/lang/psi/JetPsiUnparsingUtils.java delete mode 100644 idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/GuardedExpression.java delete mode 100644 idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/MultiGuardedExpression.java diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetPsiFactory.java b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetPsiFactory.java index e2657f13115..77918af1f81 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetPsiFactory.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetPsiFactory.java @@ -254,17 +254,9 @@ public class JetPsiFactory { return (JetBinaryExpression) createExpression(project, lhs + " " + op + " " + rhs); } - @SuppressWarnings("ConstantConditions") @NotNull public static JetBinaryExpression createBinaryExpression(Project project, @NotNull JetExpression lhs, @NotNull String op, @NotNull JetExpression rhs) { - JetBinaryExpression assignment = createBinaryExpression(project, "_", op, "_"); - - assert assignment.getRight() != null; - - assignment = (JetBinaryExpression)assignment.getLeft().replace(lhs).getParent(); - assignment = (JetBinaryExpression)assignment.getRight().replace(rhs).getParent(); - - return assignment; + return createBinaryExpression(project, lhs.getText(), op, rhs.getText()); } public static JetTypeCodeFragment createTypeCodeFragment(Project project, String text, PsiElement context) { @@ -280,15 +272,9 @@ public class JetPsiFactory { return (JetIsExpression) createExpression(project, lhs + " " + (negated ? "!is" : "is") + " " + rhs); } - @SuppressWarnings("ConstantConditions") @NotNull public static JetIsExpression createIsExpression(Project project, @NotNull JetExpression lhs, @NotNull JetTypeReference rhs, boolean negated) { - JetIsExpression isExpression = createIsExpression(project, "_", "_", negated); - - isExpression = (JetIsExpression)isExpression.getLeftHandSide().replace(lhs).getParent(); - isExpression = (JetIsExpression)isExpression.getTypeRef().replace(rhs).getParent(); - - return isExpression; + return createIsExpression(project, lhs.getText(), rhs.getText(), negated); } @NotNull @@ -296,65 +282,84 @@ public class JetPsiFactory { return (JetReturnExpression) createExpression(project, "return " + text); } - @SuppressWarnings("ConstantConditions") @NotNull public static JetReturnExpression createReturn(Project project, @NotNull JetExpression expression) { - JetReturnExpression returnExpr = createReturn(project, "_"); - - assert returnExpr.getReturnedExpression() != null; - - return (JetReturnExpression)returnExpr.getReturnedExpression().replace(expression).getParent(); + return createReturn(project, expression.getText()); } @NotNull - public static JetIfExpression createIf( - Project project, - @NotNull String condText, @NotNull String thenText, @Nullable String elseText, - boolean thenNewLine, boolean elseNewLine) { - String thenSpace = thenNewLine ? "\n" : " "; - String elseSpace = elseNewLine ? "\n" : " "; - return (JetIfExpression) createExpression(project, "if (" + condText + ")" + thenSpace + thenText + (elseText != null ? elseSpace + "else " + elseText : "")); + public static JetIfExpression createIf(Project project, + @NotNull JetExpression condition, @NotNull JetExpression thenExpr, @Nullable JetExpression elseExpr) { + return (JetIfExpression) createExpression(project, JetPsiUnparsingUtils.toIf(condition, thenExpr, elseExpr)); } - @SuppressWarnings("ConstantConditions") - @NotNull - public static JetIfExpression createIf( - Project project, - @NotNull JetExpression condition, @NotNull JetExpression thenExpr, @Nullable JetExpression elseExpr, - boolean thenNewLine, boolean elseNewLine) { - JetIfExpression ifExpr = createIf(project, "_", "_", elseExpr != null ? "_" : null, thenNewLine, elseNewLine); + public static class IfChainBuilder { + private final StringBuilder sb = new StringBuilder(); + private boolean first = true; + private boolean frozen = false; - assert ifExpr.getCondition() != null; - assert ifExpr.getThen() != null; - assert elseExpr == null || ifExpr.getElse() != null; - - ifExpr = (JetIfExpression)ifExpr.getCondition().replace(condition).getParent().getParent(); - ifExpr = (JetIfExpression)ifExpr.getThen().replace(thenExpr).getParent().getParent(); - if (elseExpr != null) { - ifExpr = (JetIfExpression)ifExpr.getElse().replace(elseExpr).getParent().getParent(); + public IfChainBuilder() { } - return ifExpr; + @NotNull + public IfChainBuilder ifBranch(@NotNull String conditionText, @NotNull String expressionText) { + if (first) { + first = false; + } else { + sb.append("else "); + } + + sb.append("if (").append(conditionText).append(") ").append(expressionText).append("\n"); + return this; + } + + @NotNull + public IfChainBuilder ifBranch(@NotNull JetExpression condition, @NotNull JetExpression expression) { + return ifBranch(condition.getText(), expression.getText()); + } + + @NotNull + public IfChainBuilder elseBranch(@NotNull String expressionText) { + sb.append("else ").append(expressionText); + return this; + } + + @NotNull + public IfChainBuilder elseBranch(@NotNull JetExpression expression) { + return elseBranch(expression.getText()); + } + + @NotNull + public JetIfExpression toExpression(Project project) { + if (!frozen) { + frozen = true; + } + return (JetIfExpression) createExpression(project, sb.toString()); + } } - public static class WhenTemplateBuilder { + public static class WhenBuilder { private final StringBuilder sb = new StringBuilder("when "); private boolean frozen = false; private boolean inCondition = false; - public WhenTemplateBuilder(boolean addSubject) { - if (addSubject) { - sb.append("(_) "); + public WhenBuilder() { + this((String)null); + } + + public WhenBuilder(@Nullable String subjectText) { + if (subjectText != null) { + sb.append("(").append(subjectText).append(") "); } sb.append("{\n"); } - private void finishAndFreeze() { - sb.append("else -> _\n}"); - frozen = true; + public WhenBuilder(@Nullable JetExpression subject) { + this(subject != null ? subject.getText() : null); } - private WhenTemplateBuilder addCondition(String text) { + @NotNull + public WhenBuilder condition(@NotNull String text) { assert !frozen; if (!inCondition) { @@ -367,84 +372,95 @@ public class JetPsiFactory { return this; } - public WhenTemplateBuilder addBranchWithSingleCondition() { - assert !frozen; - - sb.append("_ -> _\n"); - - return this; + @NotNull + public WhenBuilder condition(@NotNull JetExpression expression) { + return condition(expression.getText()); } - public WhenTemplateBuilder addBranchesWithSingleCondition(int count) { - for (int i = 0; i < count; i++) { - addBranchWithSingleCondition(); - } - - return this; + @NotNull + public WhenBuilder pattern(@NotNull String typeReferenceText, boolean negated) { + return condition((negated ? "!is" : "is") + " " + typeReferenceText); } - public WhenTemplateBuilder addBranchWithMultiCondition(int conditionCount) { - assert !frozen; - assert conditionCount > 0; - - sb.append("_"); - for (int i = 0; i < conditionCount - 1; i++) { - sb.append(", _"); - } - sb.append(" -> _\n"); - - return this; + @NotNull + public WhenBuilder pattern(@NotNull JetTypeReference typeReference, boolean negated) { + return pattern(typeReference.getText(), negated); } - public WhenTemplateBuilder addExpressionCondition() { - return addCondition("_"); + @NotNull + public WhenBuilder range(@NotNull String argumentText, boolean negated) { + return condition((negated ? "!in" : "in") + " " + argumentText); } - public WhenTemplateBuilder addIsCondition(boolean negated) { - return addCondition((negated ? "!is" : "is") + " _"); + @NotNull + public WhenBuilder range(@NotNull JetExpression argument, boolean negated) { + return range(argument.getText(), negated); } - public WhenTemplateBuilder addInCondition(boolean negated) { - return addCondition((negated ? "!in" : "in") + " _"); - } - - public WhenTemplateBuilder finishBranch() { + @NotNull + public WhenBuilder branchExpression(@NotNull String expressionText) { assert !frozen; assert inCondition; inCondition = false; - sb.append(" -> _\n"); + sb.append(" -> ").append(expressionText).append("\n"); return this; } + @NotNull + public WhenBuilder branchExpression(@NotNull JetExpression expression) { + return branchExpression(expression.getText()); + } + + @NotNull + public WhenBuilder entry(@NotNull String entryText) { + assert !frozen; + assert !inCondition; + + sb.append(entryText).append("\n"); + + return this; + } + + @NotNull + public WhenBuilder entry(@NotNull JetWhenEntry whenEntry) { + return entry(whenEntry.getText()); + } + + @NotNull + public WhenBuilder elseEntry(@NotNull String text) { + return entry("else -> " + text); + } + + @NotNull + public WhenBuilder elseEntry(@NotNull JetExpression expression) { + return elseEntry(expression.getText()); + } + + @NotNull public JetWhenExpression toExpression(Project project) { if (!frozen) { - finishAndFreeze(); + sb.append("}"); + frozen = true; } return (JetWhenExpression) createExpression(project, sb.toString()); } } - public static JetWhenExpression createWhenWithoutSubject(Project project, int positiveBranchCount) { - return new WhenTemplateBuilder(false).addBranchesWithSingleCondition(positiveBranchCount).toExpression(project); - } - + @NotNull public static JetParenthesizedExpression createParenthesizedExpression(Project project, @NotNull String text) { - return (JetParenthesizedExpression)createExpression(project, "(" + text + ")"); + return (JetParenthesizedExpression) createExpression(project, "(" + text + ")"); } - @SuppressWarnings("ConstantConditions") + @NotNull public static JetParenthesizedExpression createParenthesizedExpression(Project project, @NotNull JetExpression expression) { - JetParenthesizedExpression parenthesizedExpression = createParenthesizedExpression(project, "_"); - parenthesizedExpression.getExpression().replace(expression); - - return parenthesizedExpression; + return createParenthesizedExpression(project, expression.getText()); } + @NotNull public static JetParenthesizedExpression createParenthesizedExpressionIfNeeded(Project project, @NotNull JetExpression expression) { return (expression instanceof JetParenthesizedExpression) ? - (JetParenthesizedExpression) expression : - createParenthesizedExpression(project, expression); + (JetParenthesizedExpression) expression : createParenthesizedExpression(project, expression); } } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetPsiUnparsingUtils.java b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetPsiUnparsingUtils.java new file mode 100644 index 00000000000..7995a3fbab2 --- /dev/null +++ b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetPsiUnparsingUtils.java @@ -0,0 +1,59 @@ +/* + * Copyright 2010-2013 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.jetbrains.jet.lang.psi; + +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; + +public class JetPsiUnparsingUtils { + private JetPsiUnparsingUtils() { + } + + @NotNull + public static String toIf(@NotNull JetExpression condition, @NotNull JetExpression thenExpression, @Nullable JetExpression elseExpression) { + return toIf(condition.getText(), thenExpression.getText(), elseExpression != null ? elseExpression.getText() : null); + } + + @NotNull + public static String toIf(@NotNull String condition, @NotNull String thenExpression, @Nullable String elseExpression) { + return "if " + parenthesizeTextIfNeeded(condition) + " " + thenExpression + (elseExpression != null ? " else " + elseExpression : ""); + } + + @NotNull + public static String toBinaryExpression(@NotNull JetExpression left, @NotNull String op, @NotNull JetElement right) { + return toBinaryExpression(left.getText(), op, right.getText()); + } + + @NotNull + public static String toBinaryExpression(@NotNull String left, @NotNull String op, @NotNull String right) { + return left + " " + op + " " + right; + } + + @NotNull + public static String parenthesizeIfNeeded(@NotNull JetExpression expression) { + String text = expression.getText(); + return (expression instanceof JetParenthesizedExpression || + expression instanceof JetConstantExpression || + expression instanceof JetSimpleNameExpression) + ? text : "(" + text + ")"; + } + + @NotNull + public static String parenthesizeTextIfNeeded(@NotNull String expressionText) { + return (expressionText.startsWith("(") && expressionText.endsWith(")")) ? expressionText : "(" + expressionText + ")"; + } +} diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetPsiUtil.java b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetPsiUtil.java index e5c880dc45b..5d5612fa35e 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetPsiUtil.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetPsiUtil.java @@ -683,6 +683,16 @@ public class JetPsiUtil { return false; } + public static > C getBlockVariableDeclarations(@NotNull JetBlockExpression block, @NotNull C collection) { + for (JetElement element : block.getStatements()) { + if (element instanceof JetVariableDeclaration) { + collection.add((JetVariableDeclaration) element); + } + } + + return collection; + } + public static boolean checkWhenExpressionHasSingleElse(JetWhenExpression whenExpression) { int elseCount = 0; for (JetWhenEntry entry : whenExpression.getEntries()) { diff --git a/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/BranchedFoldingUtils.java b/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/BranchedFoldingUtils.java index 402a4094cae..ca8dc54d57f 100644 --- a/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/BranchedFoldingUtils.java +++ b/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/BranchedFoldingUtils.java @@ -47,6 +47,7 @@ public class BranchedFoldingUtils { } if (assignment.getParent() instanceof JetBlockExpression) { + //noinspection ConstantConditions return !JetPsiUtil.checkVariableDeclarationInBlock((JetBlockExpression) assignment.getParent(), assignment.getLeft().getText()); } @@ -239,7 +240,7 @@ public class BranchedFoldingUtils { assertNotNull(elseRoot); //noinspection ConstantConditions - JetIfExpression newIfExpression = JetPsiFactory.createIf(project, condition, thenRoot, elseRoot, false, false); + JetIfExpression newIfExpression = JetPsiFactory.createIf(project, condition, thenRoot, elseRoot); JetReturnExpression newReturnExpression = JetPsiFactory.createReturn(project, newIfExpression); newIfExpression = (JetIfExpression)newReturnExpression.getReturnedExpression(); diff --git a/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/BranchedUnfoldingUtils.java b/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/BranchedUnfoldingUtils.java index f680d7524ac..e713c50468a 100644 --- a/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/BranchedUnfoldingUtils.java +++ b/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/BranchedUnfoldingUtils.java @@ -35,11 +35,10 @@ public class BranchedUnfoldingUtils { if (JetPsiUtil.isAssignment(root)) { JetBinaryExpression assignment = (JetBinaryExpression)root; - JetExpression lhs = assignment.getLeft(); + + assertNotNull(assignment.getLeft()); + JetExpression rhs = assignment.getRight(); - - if (!(lhs instanceof JetSimpleNameExpression)) return null; - if (rhs instanceof JetIfExpression) return UnfoldableKind.ASSIGNMENT_TO_IF; if (rhs instanceof JetWhenExpression) return UnfoldableKind.ASSIGNMENT_TO_WHEN; } else if (root instanceof JetReturnExpression) { @@ -75,6 +74,7 @@ public class BranchedUnfoldingUtils { assertNotNull(thenExpr); assertNotNull(elseExpr); + //noinspection ConstantConditions thenExpr.replace(JetPsiFactory.createBinaryExpression(project, lhs, op, thenExpr)); elseExpr.replace(JetPsiFactory.createBinaryExpression(project, lhs, op, elseExpr)); @@ -97,6 +97,7 @@ public class BranchedUnfoldingUtils { assertNotNull(currExpr); + //noinspection ConstantConditions currExpr.replace(JetPsiFactory.createBinaryExpression(project, lhs, op, currExpr)); } diff --git a/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/GuardedExpression.java b/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/GuardedExpression.java deleted file mode 100644 index 73a94d72bc5..00000000000 --- a/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/GuardedExpression.java +++ /dev/null @@ -1,27 +0,0 @@ -package org.jetbrains.jet.plugin.codeInsight.codeTransformations.branchedTransformations; - -import org.jetbrains.annotations.NotNull; -import org.jetbrains.jet.lang.psi.JetExpression; - -public class GuardedExpression { - @NotNull - private final JetExpression condition; - - @NotNull - private final JetExpression baseExpression; - - public GuardedExpression(@NotNull JetExpression condition, @NotNull JetExpression baseExpression) { - this.condition = condition; - this.baseExpression = baseExpression; - } - - @NotNull - public JetExpression getCondition() { - return condition; - } - - @NotNull - public JetExpression getBaseExpression() { - return baseExpression; - } -} diff --git a/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/IfWhenUtils.java b/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/IfWhenUtils.java index 08e220ee152..020a7076f0b 100644 --- a/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/IfWhenUtils.java +++ b/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/IfWhenUtils.java @@ -1,6 +1,5 @@ package org.jetbrains.jet.plugin.codeInsight.codeTransformations.branchedTransformations; -import com.intellij.openapi.project.Project; import org.jetbrains.annotations.NotNull; import org.jetbrains.jet.lang.psi.*; import org.jetbrains.jet.lexer.JetTokens; @@ -8,6 +7,8 @@ import org.jetbrains.jet.lexer.JetTokens; import java.util.ArrayList; import java.util.List; +import static org.jetbrains.jet.lang.psi.JetPsiUnparsingUtils.*; + public class IfWhenUtils { public static final String TRANSFORM_WITHOUT_CHECK = @@ -71,8 +72,7 @@ public class IfWhenUtils { } public static void transformIfToWhen(@NotNull JetIfExpression ifExpression) { - List positiveBranches = new ArrayList(); - JetExpression elseExpression = null; + JetPsiFactory.WhenBuilder builder = new JetPsiFactory.WhenBuilder(); JetIfExpression currIfExpression = ifExpression; do { @@ -84,123 +84,73 @@ public class IfWhenUtils { assertNotNull(thenBranch); assertNotNull(elseBranch); + List orBranches = splitExpressionToOrBranches(condition); + for (JetExpression orBranch : orBranches) { + builder.condition(orBranch); + } //noinspection ConstantConditions - positiveBranches.add(new MultiGuardedExpression(splitExpressionToOrBranches(condition), thenBranch)); + builder.branchExpression(thenBranch); if (elseBranch instanceof JetIfExpression) { currIfExpression = (JetIfExpression) elseBranch; } else { currIfExpression = null; - elseExpression = elseBranch; + //noinspection ConstantConditions + builder.elseEntry(elseBranch); } } while (currIfExpression != null); - JetPsiFactory.WhenTemplateBuilder builder = new JetPsiFactory.WhenTemplateBuilder(false); - for (MultiGuardedExpression positiveBranch : positiveBranches) { - builder.addBranchWithMultiCondition(positiveBranch.getConditions().size()); - } - - JetWhenExpression whenExpression = builder.toExpression(ifExpression.getProject()); - - int i = 0; - List entries = whenExpression.getEntries(); - for (JetWhenEntry entry : entries) { - if (entry.isElse()) { - //noinspection ConstantConditions - entry.getExpression().replace(elseExpression); - break; - } - - MultiGuardedExpression branch = positiveBranches.get(i++); - - //noinspection ConstantConditions - entry.getExpression().replace(branch.getBaseExpression()); - - int j = 0; - JetWhenCondition[] conditions = entry.getConditions(); - for (JetWhenCondition condition : conditions) { - assert condition instanceof JetWhenConditionWithExpression : TRANSFORM_WITHOUT_CHECK; - - JetExpression conditionExpression = ((JetWhenConditionWithExpression) condition).getExpression(); - assertNotNull(conditionExpression); - - //noinspection ConstantConditions - conditionExpression.replace(branch.getConditions().get(j++)); - } - } - - ifExpression.replace(whenExpression); + ifExpression.replace(builder.toExpression(ifExpression.getProject())); } - @SuppressWarnings("ConstantConditions") - private static JetExpression combineWhenConditions(Project project, JetWhenCondition[] conditions, JetExpression subject) { + private static String combineWhenConditions(JetWhenCondition[] conditions, JetExpression subject) { int n = conditions.length; - assert n > 0 : TRANSFORM_WITHOUT_CHECK; + if (n == 0) return ""; - JetWhenCondition condition = conditions[n - 1]; + JetWhenCondition condition = conditions[0]; assert condition != null : TRANSFORM_WITHOUT_CHECK; - JetExpression resultExpr = WhenUtils.whenConditionToExpression(condition, subject); + StringBuilder sb = new StringBuilder(); + + String text = WhenUtils.whenConditionToExpressionText(condition, subject); if (n > 1) { - resultExpr = JetPsiFactory.createParenthesizedExpressionIfNeeded(project, resultExpr); + text = parenthesizeTextIfNeeded(text); } + sb.append(text); - for (int i = n - 2; i >= 0; i--) { + for (int i = 1; i < n; i++) { JetWhenCondition currCondition = conditions[i]; - assert currCondition != null : TRANSFORM_WITHOUT_CHECK; - resultExpr = JetPsiFactory.createBinaryExpression( - project, - JetPsiFactory.createParenthesizedExpressionIfNeeded(project, WhenUtils.whenConditionToExpression(currCondition, subject)), - "||", - resultExpr); + sb.append(" || ").append(parenthesizeTextIfNeeded(WhenUtils.whenConditionToExpressionText(currCondition, subject))); } - return resultExpr; + return sb.toString(); } public static void transformWhenToIf(@NotNull JetWhenExpression whenExpression) { - Project project = whenExpression.getProject(); - - JetExpression elseExpression = null; - List positiveBranches = new ArrayList(); + JetPsiFactory.IfChainBuilder builder = new JetPsiFactory.IfChainBuilder(); List entries = whenExpression.getEntries(); for (JetWhenEntry entry : entries) { JetExpression branch = entry.getExpression(); - assertNotNull(branch); if (entry.isElse()) { - elseExpression = branch; + //noinspection ConstantConditions + builder.elseBranch(branch); } else { - JetExpression branchCondition = combineWhenConditions(project, entry.getConditions(), whenExpression.getSubjectExpression()); - JetExpression branchExpression = entry.getExpression(); + String branchConditionText = combineWhenConditions(entry.getConditions(), whenExpression.getSubjectExpression()); + JetExpression branchExpression = entry.getExpression(); assertNotNull(branchExpression); //noinspection ConstantConditions - positiveBranches.add(new GuardedExpression(branchCondition, branchExpression)); + builder.ifBranch(branchConditionText, branchExpression.getText()); } } - assertNotNull(elseExpression); - assert !positiveBranches.isEmpty() : TRANSFORM_WITHOUT_CHECK; - - JetExpression outerExpression = elseExpression; - - for (int i = positiveBranches.size() - 1; i >= 0; i--) { - GuardedExpression branch = positiveBranches.get(i); - - outerExpression = JetPsiFactory.createIf( - project, - branch.getCondition(), branch.getBaseExpression(), outerExpression, - !(branch.getBaseExpression() instanceof JetBlockExpression), !(outerExpression instanceof JetBlockExpression)); - } - - //noinspection ConstantConditions - whenExpression.replace(outerExpression); + whenExpression.replace(builder.toExpression(whenExpression.getProject())); } } diff --git a/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/MultiGuardedExpression.java b/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/MultiGuardedExpression.java deleted file mode 100644 index 7e7c312cbfd..00000000000 --- a/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/MultiGuardedExpression.java +++ /dev/null @@ -1,29 +0,0 @@ -package org.jetbrains.jet.plugin.codeInsight.codeTransformations.branchedTransformations; - -import org.jetbrains.annotations.NotNull; -import org.jetbrains.jet.lang.psi.JetExpression; - -import java.util.List; - -public class MultiGuardedExpression { - @NotNull - private final List conditions; - - @NotNull - private final JetExpression baseExpression; - - public MultiGuardedExpression(@NotNull List conditions, @NotNull JetExpression baseExpression) { - this.conditions = conditions; - this.baseExpression = baseExpression; - } - - @NotNull - public List getConditions() { - return conditions; - } - - @NotNull - public JetExpression getBaseExpression() { - return baseExpression; - } -} diff --git a/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/WhenUtils.java b/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/WhenUtils.java index a40291df86f..b17bd974abc 100644 --- a/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/WhenUtils.java +++ b/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/WhenUtils.java @@ -1,11 +1,12 @@ package org.jetbrains.jet.plugin.codeInsight.codeTransformations.branchedTransformations; -import com.intellij.openapi.project.Project; import com.intellij.psi.tree.IElementType; import org.jetbrains.annotations.NotNull; import org.jetbrains.jet.lang.psi.*; import org.jetbrains.jet.lexer.JetTokens; +import static org.jetbrains.jet.lang.psi.JetPsiUnparsingUtils.*; + import java.util.List; public class WhenUtils { @@ -87,7 +88,6 @@ public class WhenUtils { public static void flattenWhen(@NotNull JetWhenExpression whenExpression) { JetExpression subjectExpression = whenExpression.getSubjectExpression(); - boolean hasSubject = subjectExpression != null; JetExpression elseBranch = JetPsiUtil.getWhenElseBranch(whenExpression); assert elseBranch instanceof JetWhenExpression : TRANSFORM_WITHOUT_CHECK; @@ -97,38 +97,36 @@ public class WhenUtils { List outerEntries = whenExpression.getEntries(); List innerEntries = nestedWhenExpression.getEntries(); - JetWhenExpression newWhenExpression = new JetPsiFactory.WhenTemplateBuilder(hasSubject) - .addBranchesWithSingleCondition(outerEntries.size() + innerEntries.size() - 2) - .toExpression(whenExpression.getProject()); + JetPsiFactory.WhenBuilder builder = new JetPsiFactory.WhenBuilder(subjectExpression); - if (hasSubject) { - JetExpression dummySubjectExpression = newWhenExpression.getSubjectExpression(); - assertNotNull(dummySubjectExpression); - - //noinspection ConstantConditions - dummySubjectExpression.replace(subjectExpression); - } - - List newEntries = newWhenExpression.getEntries(); - - int i = 0; for (JetWhenEntry entry : outerEntries) { - if (!entry.isElse()) { - newEntries.get(i++).replace(entry); - } - } - for (JetWhenEntry entry : innerEntries) { - newEntries.get(i++).replace(entry); + if (entry.isElse()) continue; + + builder.entry(entry); } - whenExpression.replace(newWhenExpression); + for (JetWhenEntry entry : innerEntries) { + builder.entry(entry); + } + + whenExpression.replace(builder.toExpression(whenExpression.getProject())); } - private static JetWhenExpression createWhenTemplateWithSubject(@NotNull JetWhenExpression whenExpression) { - JetPsiFactory.WhenTemplateBuilder builder = new JetPsiFactory.WhenTemplateBuilder(true); + public static void introduceWhenSubject(@NotNull JetWhenExpression whenExpression) { + JetExpression subject = getWhenSubjectCandidate(whenExpression); + assertNotNull(subject); + + JetPsiFactory.WhenBuilder builder = new JetPsiFactory.WhenBuilder(subject); for (JetWhenEntry entry : whenExpression.getEntries()) { - if (entry.isElse()) continue; + JetExpression branchExpression = entry.getExpression(); + assertNotNull(branchExpression); + + if (entry.isElse()) { + //noinspection ConstantConditions + builder.elseEntry(branchExpression); + continue; + } for (JetWhenCondition condition : entry.getConditions()) { assert condition instanceof JetWhenConditionWithExpression : TRANSFORM_WITHOUT_CHECK; @@ -136,81 +134,13 @@ public class WhenUtils { JetExpression conditionExpression = ((JetWhenConditionWithExpression) condition).getExpression(); if (conditionExpression instanceof JetIsExpression) { - builder.addIsCondition(((JetIsExpression) conditionExpression).isNegated()); - } - else if (conditionExpression instanceof JetBinaryExpression) { - JetBinaryExpression binaryExpression = (JetBinaryExpression) conditionExpression; + JetIsExpression isExpression = (JetIsExpression) conditionExpression; - IElementType op = binaryExpression.getOperationToken(); - if (op == JetTokens.IN_KEYWORD) { - builder.addInCondition(false); - } - else if (op == JetTokens.NOT_IN) { - builder.addInCondition(true); - } - else if (op == JetTokens.EQEQ) { - builder.addExpressionCondition(); - } - else assert false : TRANSFORM_WITHOUT_CHECK; - } - else assert false : TRANSFORM_WITHOUT_CHECK; - } - - builder.finishBranch(); - } - - return builder.toExpression(whenExpression.getProject()); - } - - public static void introduceWhenSubject(@NotNull JetWhenExpression whenExpression) { - JetExpression subject = getWhenSubjectCandidate(whenExpression); - assertNotNull(subject); - - JetWhenExpression newWhenExpression = createWhenTemplateWithSubject(whenExpression); - - JetExpression newSubject = newWhenExpression.getSubjectExpression(); - assertNotNull(newSubject); - - //noinspection ConstantConditions - newSubject.replace(subject); - - int i = 0; - List entries = whenExpression.getEntries(); - List newEntries = newWhenExpression.getEntries(); - for (JetWhenEntry newEntry : newEntries) { - JetWhenEntry entry = entries.get(i++); - - JetExpression branchExpression = entry.getExpression(); - assertNotNull(branchExpression); - - JetExpression newBranchExpression = newEntry.getExpression(); - assertNotNull(newBranchExpression); - - //noinspection ConstantConditions - newBranchExpression.replace(branchExpression); - - int j = 0; - JetWhenCondition[] conditions = entry.getConditions(); - JetWhenCondition[] newConditions = newEntry.getConditions(); - - for (JetWhenCondition newCondition : newConditions) { - JetWhenCondition condition = conditions[j++]; - - assert condition instanceof JetWhenConditionWithExpression : TRANSFORM_WITHOUT_CHECK; - - JetExpression conditionExpression = ((JetWhenConditionWithExpression) condition).getExpression(); - - if (conditionExpression instanceof JetIsExpression) { - assert newCondition instanceof JetWhenConditionIsPattern : TRANSFORM_WITHOUT_CHECK; - - JetTypeReference typeReference = ((JetIsExpression) conditionExpression).getTypeRef(); + JetTypeReference typeReference = isExpression.getTypeRef(); assertNotNull(typeReference); - JetTypeReference newTypeReference = ((JetWhenConditionIsPattern) newCondition).getTypeRef(); - assertNotNull(newTypeReference); - //noinspection ConstantConditions - newTypeReference.replace(typeReference); + builder.pattern(typeReference, isExpression.isNegated()); } else if (conditionExpression instanceof JetBinaryExpression) { JetBinaryExpression binaryExpression = (JetBinaryExpression) conditionExpression; @@ -219,48 +149,31 @@ public class WhenUtils { assertNotNull(rhs); IElementType op = binaryExpression.getOperationToken(); - if (op == JetTokens.IN_KEYWORD || op == JetTokens.NOT_IN) { - assert newCondition instanceof JetWhenConditionInRange : TRANSFORM_WITHOUT_CHECK; - - JetExpression newRangeExpression = ((JetWhenConditionInRange) newCondition).getRangeExpression(); - assertNotNull(newRangeExpression); - + if (op == JetTokens.IN_KEYWORD) { //noinspection ConstantConditions - newRangeExpression.replace(rhs); + builder.range(rhs, false); + } + else if (op == JetTokens.NOT_IN) { + //noinspection ConstantConditions + builder.range(rhs, true); } else if (op == JetTokens.EQEQ) { - assert newCondition instanceof JetWhenConditionWithExpression : TRANSFORM_WITHOUT_CHECK; - - JetExpression newConditionExpression = ((JetWhenConditionWithExpression) newCondition).getExpression(); - assertNotNull(newConditionExpression); - //noinspection ConstantConditions - newConditionExpression.replace(rhs); + builder.condition(rhs); } else assert false : TRANSFORM_WITHOUT_CHECK; } else assert false : TRANSFORM_WITHOUT_CHECK; } + + //noinspection ConstantConditions + builder.branchExpression(branchExpression); } - whenExpression.replace(newWhenExpression); + whenExpression.replace(builder.toExpression(whenExpression.getProject())); } - private static JetWhenExpression createWhenTemplateWithoutSubject(@NotNull JetWhenExpression whenExpression) { - JetPsiFactory.WhenTemplateBuilder builder = new JetPsiFactory.WhenTemplateBuilder(false); - - for (JetWhenEntry entry : whenExpression.getEntries()) { - if (!entry.isElse()) { - builder.addBranchWithMultiCondition(entry.getConditions().length); - } - } - - return builder.toExpression(whenExpression.getProject()); - } - - static JetExpression whenConditionToExpression(@NotNull JetWhenCondition condition, JetExpression subject) { - Project project = condition.getProject(); - + static String whenConditionToExpressionText(@NotNull JetWhenCondition condition, JetExpression subject) { if (condition instanceof JetWhenConditionIsPattern) { JetWhenConditionIsPattern patternCondition = (JetWhenConditionIsPattern) condition; @@ -270,7 +183,7 @@ public class WhenUtils { assertNotNull(subject); //noinspection ConstantConditions - return JetPsiFactory.createIsExpression(project, subject, typeReference, patternCondition.isNegated()); + return toBinaryExpression(subject, (patternCondition.isNegated() ? "!is" : "is"), typeReference); } if (condition instanceof JetWhenConditionInRange) { @@ -282,7 +195,7 @@ public class WhenUtils { assertNotNull(subject); //noinspection ConstantConditions - return JetPsiFactory.createBinaryExpression(project, subject, rangeCondition.getOperationReference().getText(), rangeExpression); + return toBinaryExpression(subject, rangeCondition.getOperationReference().getText(), rangeExpression); } assert condition instanceof JetWhenConditionWithExpression : TRANSFORM_WITHOUT_CHECK; @@ -291,45 +204,36 @@ public class WhenUtils { assertNotNull(conditionExpression); //noinspection ConstantConditions - return subject != null ? JetPsiFactory.createBinaryExpression(project, subject, "==", conditionExpression) : conditionExpression; + return subject != null ? + toBinaryExpression(parenthesizeIfNeeded(subject), "==", parenthesizeIfNeeded(conditionExpression)) + : conditionExpression.getText(); } public static void eliminateWhenSubject(@NotNull JetWhenExpression whenExpression) { JetExpression subject = whenExpression.getSubjectExpression(); assertNotNull(subject); - JetWhenExpression newWhenExpression = createWhenTemplateWithoutSubject(whenExpression); - - int i = 0; - List entries = whenExpression.getEntries(); - List newEntries = newWhenExpression.getEntries(); - for (JetWhenEntry newEntry : newEntries) { - JetWhenEntry entry = entries.get(i++); + JetPsiFactory.WhenBuilder builder = new JetPsiFactory.WhenBuilder(); + for (JetWhenEntry entry : whenExpression.getEntries()) { JetExpression branchExpression = entry.getExpression(); assertNotNull(branchExpression); - JetExpression newBranchExpression = newEntry.getExpression(); - assertNotNull(newBranchExpression); + if (entry.isElse()) { + //noinspection ConstantConditions + builder.elseEntry(branchExpression); + + continue; + } + + for (JetWhenCondition condition : entry.getConditions()) { + builder.condition(whenConditionToExpressionText(condition, subject)); + } //noinspection ConstantConditions - newBranchExpression.replace(branchExpression); - - int j = 0; - JetWhenCondition[] conditions = entry.getConditions(); - JetWhenCondition[] newConditions = newEntry.getConditions(); - - for (JetWhenCondition newCondition : newConditions) { - JetWhenCondition condition = conditions[j++]; - - JetExpression newConditionExpression = ((JetWhenConditionWithExpression) newCondition).getExpression(); - assertNotNull(newConditionExpression); - - //noinspection ConstantConditions - newConditionExpression.replace(whenConditionToExpression(condition, subject)); - } + builder.branchExpression(branchExpression); } - whenExpression.replace(newWhenExpression); + whenExpression.replace(builder.toExpression(whenExpression.getProject())); } } diff --git a/idea/testData/codeInsight/codeTransformations/branched/folding/whenToReturn/simpleWhen.kt.after b/idea/testData/codeInsight/codeTransformations/branched/folding/whenToReturn/simpleWhen.kt.after index 83a1dee18ec..d31b98306dd 100644 --- a/idea/testData/codeInsight/codeTransformations/branched/folding/whenToReturn/simpleWhen.kt.after +++ b/idea/testData/codeInsight/codeTransformations/branched/folding/whenToReturn/simpleWhen.kt.after @@ -1,6 +1,6 @@ fun test(n: Int): String { return when (n) { - 1 -> "one" - else -> "two" + 1 -> "one" + else -> "two" } } \ No newline at end of file diff --git a/idea/testData/codeInsight/codeTransformations/branched/folding/whenToReturn/simpleWhenWithBlocks.kt b/idea/testData/codeInsight/codeTransformations/branched/folding/whenToReturn/simpleWhenWithBlocks.kt index 1c9b980257f..73a8c4fa415 100644 --- a/idea/testData/codeInsight/codeTransformations/branched/folding/whenToReturn/simpleWhenWithBlocks.kt +++ b/idea/testData/codeInsight/codeTransformations/branched/folding/whenToReturn/simpleWhenWithBlocks.kt @@ -1,11 +1,12 @@ fun test(n: Int): String { when(n) { - 1 -> { - println("***") - return "one" - } - else -> { - println("***") - return "two" + 1 -> { + println("***") + return "one" + } + else -> { + println("***") + return "two" + } } } \ No newline at end of file diff --git a/idea/testData/codeInsight/codeTransformations/branched/folding/whenToReturn/simpleWhenWithBlocks.kt.after b/idea/testData/codeInsight/codeTransformations/branched/folding/whenToReturn/simpleWhenWithBlocks.kt.after index 5565cdc2ecd..e90363e53dd 100644 --- a/idea/testData/codeInsight/codeTransformations/branched/folding/whenToReturn/simpleWhenWithBlocks.kt.after +++ b/idea/testData/codeInsight/codeTransformations/branched/folding/whenToReturn/simpleWhenWithBlocks.kt.after @@ -1,11 +1,12 @@ fun test(n: Int): String { return when(n) { - 1 -> { - println("***") - "one" - } - else -> { - println("***") - "two" + 1 -> { + println("***") + "one" + } + else -> { + println("***") + "two" + } } } \ No newline at end of file diff --git a/idea/testData/codeInsight/codeTransformations/branched/ifWhen/whenToIf/whenWithEqualityTests.kt.after b/idea/testData/codeInsight/codeTransformations/branched/ifWhen/whenToIf/whenWithEqualityTests.kt.after index 47fca307d3c..6a8e28bb851 100644 --- a/idea/testData/codeInsight/codeTransformations/branched/ifWhen/whenToIf/whenWithEqualityTests.kt.after +++ b/idea/testData/codeInsight/codeTransformations/branched/ifWhen/whenToIf/whenWithEqualityTests.kt.after @@ -1,9 +1,6 @@ fun test(n: Int): String { - return if (n == 0) - "zero" - else if (n == 1) - "one" - else if (n == 2) - "two" + return if (n == 0) "zero" + else if (n == 1) "one" + else if (n == 2) "two" else "unknown" } \ No newline at end of file diff --git a/idea/testData/codeInsight/codeTransformations/branched/ifWhen/whenToIf/whenWithMultiConditions.kt.after b/idea/testData/codeInsight/codeTransformations/branched/ifWhen/whenToIf/whenWithMultiConditions.kt.after index 1b1e1a0b2b8..677a6a448e5 100644 --- a/idea/testData/codeInsight/codeTransformations/branched/ifWhen/whenToIf/whenWithMultiConditions.kt.after +++ b/idea/testData/codeInsight/codeTransformations/branched/ifWhen/whenToIf/whenWithMultiConditions.kt.after @@ -1,9 +1,6 @@ fun test(n: Int): String { - return if ((n < 0) || (n > 1000)) - "unknown" - else if (n <= 10) - "small" - else if (n <= 100) - "average" + return if ((n < 0) || (n > 1000)) "unknown" + else if (n <= 10) "small" + else if (n <= 100) "average" else "big" } \ No newline at end of file diff --git a/idea/testData/codeInsight/codeTransformations/branched/ifWhen/whenToIf/whenWithNegativePatterns.kt.after b/idea/testData/codeInsight/codeTransformations/branched/ifWhen/whenToIf/whenWithNegativePatterns.kt.after index 0fbe8294ffb..4abebde0ef2 100644 --- a/idea/testData/codeInsight/codeTransformations/branched/ifWhen/whenToIf/whenWithNegativePatterns.kt.after +++ b/idea/testData/codeInsight/codeTransformations/branched/ifWhen/whenToIf/whenWithNegativePatterns.kt.after @@ -1,9 +1,6 @@ fun test(obj: Any): String { - return if (obj !is Iterable<*>) - "not iterable" - else if (obj !is Collection<*>) - "not collection" - else if (obj !is MutableCollection<*>) - "not mutable collection" + return if (obj !is Iterable<*>) "not iterable" + else if (obj !is Collection<*>) "not collection" + else if (obj !is MutableCollection<*>) "not mutable collection" else "unknown" } \ No newline at end of file diff --git a/idea/testData/codeInsight/codeTransformations/branched/ifWhen/whenToIf/whenWithNegativeRangeTests.kt.after b/idea/testData/codeInsight/codeTransformations/branched/ifWhen/whenToIf/whenWithNegativeRangeTests.kt.after index 9e02b8d24f7..d550d564769 100644 --- a/idea/testData/codeInsight/codeTransformations/branched/ifWhen/whenToIf/whenWithNegativeRangeTests.kt.after +++ b/idea/testData/codeInsight/codeTransformations/branched/ifWhen/whenToIf/whenWithNegativeRangeTests.kt.after @@ -1,9 +1,6 @@ fun test(n: Int): String { - return if (n !in 0..1000) - "unknown" - else if (n !in 0..100) - "big" - else if (n !in 0..10) - "average" + return if (n !in 0..1000) "unknown" + else if (n !in 0..100) "big" + else if (n !in 0..10) "average" else "small" } \ No newline at end of file diff --git a/idea/testData/codeInsight/codeTransformations/branched/ifWhen/whenToIf/whenWithPatterns.kt.after b/idea/testData/codeInsight/codeTransformations/branched/ifWhen/whenToIf/whenWithPatterns.kt.after index af99f2543d2..ac6b419228f 100644 --- a/idea/testData/codeInsight/codeTransformations/branched/ifWhen/whenToIf/whenWithPatterns.kt.after +++ b/idea/testData/codeInsight/codeTransformations/branched/ifWhen/whenToIf/whenWithPatterns.kt.after @@ -1,9 +1,6 @@ fun test(obj: Any): String { - return if (obj is String) - "string" - else if (obj is Int) - "int" - else if (obj is Class<*>) - "class" + return if (obj is String) "string" + else if (obj is Int) "int" + else if (obj is Class<*>) "class" else "unknown" } \ No newline at end of file diff --git a/idea/testData/codeInsight/codeTransformations/branched/ifWhen/whenToIf/whenWithRangeTests.kt.after b/idea/testData/codeInsight/codeTransformations/branched/ifWhen/whenToIf/whenWithRangeTests.kt.after index d2d1cb0f735..9e5e951468e 100644 --- a/idea/testData/codeInsight/codeTransformations/branched/ifWhen/whenToIf/whenWithRangeTests.kt.after +++ b/idea/testData/codeInsight/codeTransformations/branched/ifWhen/whenToIf/whenWithRangeTests.kt.after @@ -1,9 +1,6 @@ fun test(n: Int): String { - return if (n in 0..10) - "small" - else if (n in 10..100) - "average" - else if (n in 100..1000) - "big" + return if (n in 0..10) "small" + else if (n in 10..100) "average" + else if (n in 100..1000) "big" else "unknown" } \ No newline at end of file diff --git a/idea/testData/codeInsight/codeTransformations/branched/ifWhen/whenToIf/whenWithRangeTestsAndMultiConditions.kt.after b/idea/testData/codeInsight/codeTransformations/branched/ifWhen/whenToIf/whenWithRangeTestsAndMultiConditions.kt.after index 41ed971402b..9e918445401 100644 --- a/idea/testData/codeInsight/codeTransformations/branched/ifWhen/whenToIf/whenWithRangeTestsAndMultiConditions.kt.after +++ b/idea/testData/codeInsight/codeTransformations/branched/ifWhen/whenToIf/whenWithRangeTestsAndMultiConditions.kt.after @@ -1,9 +1,6 @@ fun test(n: Int): String { - return if ((n in 0..5) || (n in 5..10)) - "small" - else if ((n in 10..50) || (n in 50..100)) - "average" - else if ((n in 100..500) || (n in 500..1000)) - "big" + return if ((n in 0..5) || (n in 5..10)) "small" + else if ((n in 10..50) || (n in 50..100)) "average" + else if ((n in 100..500) || (n in 500..1000)) "big" else "unknown" } \ No newline at end of file diff --git a/idea/testData/codeInsight/codeTransformations/branched/ifWhen/whenToIf/whenWithoutSubject.kt.after b/idea/testData/codeInsight/codeTransformations/branched/ifWhen/whenToIf/whenWithoutSubject.kt.after index d2d1cb0f735..9e5e951468e 100644 --- a/idea/testData/codeInsight/codeTransformations/branched/ifWhen/whenToIf/whenWithoutSubject.kt.after +++ b/idea/testData/codeInsight/codeTransformations/branched/ifWhen/whenToIf/whenWithoutSubject.kt.after @@ -1,9 +1,6 @@ fun test(n: Int): String { - return if (n in 0..10) - "small" - else if (n in 10..100) - "average" - else if (n in 100..1000) - "big" + return if (n in 0..10) "small" + else if (n in 10..100) "average" + else if (n in 100..1000) "big" else "unknown" } \ No newline at end of file From 4ee59e351bc6e5c0201caf16897e9cf7aa7b77cc Mon Sep 17 00:00:00 2001 From: Alexey Sedunov Date: Tue, 30 Apr 2013 16:08:30 +0400 Subject: [PATCH 091/249] Move "else" extractor to JetWhenExpression --- .../src/org/jetbrains/jet/lang/psi/JetPsiUtil.java | 9 --------- .../org/jetbrains/jet/lang/psi/JetWhenExpression.java | 10 ++++++++++ .../branchedTransformations/WhenUtils.java | 4 ++-- 3 files changed, 12 insertions(+), 11 deletions(-) diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetPsiUtil.java b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetPsiUtil.java index 5d5612fa35e..2d130fa4faa 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetPsiUtil.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetPsiUtil.java @@ -703,15 +703,6 @@ public class JetPsiUtil { return (elseCount == 1); } - public static JetExpression getWhenElseBranch(@NotNull JetWhenExpression whenExpression) { - for (JetWhenEntry entry : whenExpression.getEntries()) { - if (entry.isElse()) { - return entry.getExpression(); - } - } - return null; - } - public static PsiElement skipTrailingWhitespacesAndComments(PsiElement element) { return PsiTreeUtil.skipSiblingsForward(element, PsiWhiteSpace.class, PsiComment.class); } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetWhenExpression.java b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetWhenExpression.java index 1a313791735..7ff507478bf 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetWhenExpression.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetWhenExpression.java @@ -60,4 +60,14 @@ public class JetWhenExpression extends JetExpressionImpl { ASTNode openBraceNode = getNode().findChildByType(JetTokens.RBRACE); return openBraceNode != null ? openBraceNode.getPsi() : null; } + + @Nullable + public JetExpression getElseExpression() { + for (JetWhenEntry entry : getEntries()) { + if (entry.isElse()) { + return entry.getExpression(); + } + } + return null; + } } diff --git a/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/WhenUtils.java b/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/WhenUtils.java index b17bd974abc..fde43685005 100644 --- a/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/WhenUtils.java +++ b/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/WhenUtils.java @@ -69,7 +69,7 @@ public class WhenUtils { if (!JetPsiUtil.checkWhenExpressionHasSingleElse(whenExpression)) return false; - JetExpression elseBranch = JetPsiUtil.getWhenElseBranch(whenExpression); + JetExpression elseBranch = whenExpression.getElseExpression(); if (!(elseBranch instanceof JetWhenExpression)) return false; JetWhenExpression nestedWhenExpression = (JetWhenExpression) elseBranch; @@ -89,7 +89,7 @@ public class WhenUtils { public static void flattenWhen(@NotNull JetWhenExpression whenExpression) { JetExpression subjectExpression = whenExpression.getSubjectExpression(); - JetExpression elseBranch = JetPsiUtil.getWhenElseBranch(whenExpression); + JetExpression elseBranch = whenExpression.getElseExpression(); assert elseBranch instanceof JetWhenExpression : TRANSFORM_WITHOUT_CHECK; JetWhenExpression nestedWhenExpression = (JetWhenExpression) elseBranch; From d2f3dd162927a71196548e9b8b78f8b0d47ee136 Mon Sep 17 00:00:00 2001 From: Alexey Sedunov Date: Tue, 30 Apr 2013 16:45:52 +0400 Subject: [PATCH 092/249] JetPsiMatcher: reimplement using visitor, add structural type matching --- .../jetbrains/jet/lang/psi/JetPsiMatcher.java | 336 +++++++-------- .../expressions/arrayAccess/_arrayAccess1.kt | 2 + .../arrayAccess/_arrayAccess1.kt.2 | 1 + .../expressions/arrayAccess/_arrayAccess2.kt | 2 + .../arrayAccess/_arrayAccess2.kt.2 | 1 + .../expressions/arrayAccess/_arrayAccess3.kt | 2 + .../arrayAccess/_arrayAccess3.kt.2 | 1 + .../expressions/arrayAccess/arrayAccess1.kt | 1 + .../expressions/arrayAccess/arrayAccess1.kt.2 | 1 + .../expressions/arrayAccess/arrayAccess2.kt | 1 + .../expressions/arrayAccess/arrayAccess2.kt.2 | 1 + .../expressions/binaryExpr/_binaryExpr1.kt | 2 + .../expressions/binaryExpr/_binaryExpr1.kt.2 | 1 + .../expressions/binaryExpr/_binaryExpr2.kt | 2 + .../expressions/binaryExpr/_binaryExpr2.kt.2 | 1 + .../expressions/binaryExpr/_binaryExpr3.kt | 2 + .../expressions/binaryExpr/_binaryExpr3.kt.2 | 1 + .../expressions/binaryExpr/_binaryExpr4.kt | 2 + .../expressions/binaryExpr/_binaryExpr4.kt.2 | 1 + .../expressions/binaryExpr/_binaryExpr5.kt | 2 + .../expressions/binaryExpr/_binaryExpr5.kt.2 | 1 + .../expressions/binaryExpr/_binaryExpr6.kt | 2 + .../expressions/binaryExpr/_binaryExpr6.kt.2 | 1 + .../expressions/binaryExpr/binaryExpr1.kt | 1 + .../expressions/binaryExpr/binaryExpr1.kt.2 | 1 + .../expressions/binaryExpr/binaryExpr2.kt | 1 + .../expressions/binaryExpr/binaryExpr2.kt.2 | 1 + .../expressions/binaryExpr/binaryExpr3.kt | 1 + .../expressions/binaryExpr/binaryExpr3.kt.2 | 1 + .../expressions/binaryExpr/binaryExpr4.kt | 1 + .../expressions/binaryExpr/binaryExpr4.kt.2 | 1 + .../expressions/binaryExpr/binaryExpr5.kt | 1 + .../expressions/binaryExpr/binaryExpr5.kt.2 | 1 + .../jetPsiMatcher/expressions/call/_call1.kt | 2 + .../expressions/call/_call1.kt.2 | 1 + .../jetPsiMatcher/expressions/call/_call2.kt | 2 + .../expressions/call/_call2.kt.2 | 1 + .../jetPsiMatcher/expressions/call/_call3.kt | 2 + .../expressions/call/_call3.kt.2 | 1 + .../jetPsiMatcher/expressions/call/_call4.kt | 2 + .../expressions/call/_call4.kt.2 | 1 + .../jetPsiMatcher/expressions/call/call1.kt | 1 + .../jetPsiMatcher/expressions/call/call1.kt.2 | 1 + .../jetPsiMatcher/expressions/call/call2.kt | 1 + .../jetPsiMatcher/expressions/call/call2.kt.2 | 1 + .../jetPsiMatcher/expressions/call/call3.kt | 1 + .../jetPsiMatcher/expressions/call/call3.kt.2 | 1 + .../jetPsiMatcher/expressions/call/call4.kt | 1 + .../jetPsiMatcher/expressions/call/call4.kt.2 | 1 + .../jetPsiMatcher/expressions/const/_const.kt | 2 + .../expressions/const/_const.kt.2 | 1 + .../jetPsiMatcher/expressions/const/const.kt | 1 + .../expressions/const/const.kt.2 | 1 + .../jetPsiMatcher/expressions/misc/_misc1.kt | 2 + .../expressions/misc/_misc1.kt.2 | 1 + .../jetPsiMatcher/expressions/misc/_misc2.kt | 2 + .../expressions/misc/_misc2.kt.2 | 1 + .../jetPsiMatcher/expressions/misc/_misc3.kt | 2 + .../expressions/misc/_misc3.kt.2 | 1 + .../jetPsiMatcher/expressions/misc/misc1.kt | 1 + .../jetPsiMatcher/expressions/misc/misc1.kt.2 | 1 + .../jetPsiMatcher/expressions/misc/misc2.kt | 1 + .../jetPsiMatcher/expressions/misc/misc2.kt.2 | 1 + .../jetPsiMatcher/expressions/misc/misc3.kt | 1 + .../jetPsiMatcher/expressions/misc/misc3.kt.2 | 1 + .../expressions/simpleName/_simpleName.kt | 2 + .../expressions/simpleName/_simpleName.kt.2 | 2 + .../expressions/simpleName/simpleName.kt | 1 + .../expressions/simpleName/simpleName.kt.2 | 1 + .../expressions/super/_super1.kt | 2 + .../expressions/super/_super1.kt.2 | 1 + .../expressions/super/_super2.kt | 2 + .../expressions/super/_super2.kt.2 | 1 + .../expressions/super/_super3.kt | 2 + .../expressions/super/_super3.kt.2 | 1 + .../expressions/super/_super4.kt | 2 + .../expressions/super/_super4.kt.2 | 1 + .../jetPsiMatcher/expressions/super/super1.kt | 1 + .../expressions/super/super1.kt.2 | 1 + .../jetPsiMatcher/expressions/super/super2.kt | 1 + .../expressions/super/super2.kt.2 | 1 + .../jetPsiMatcher/expressions/super/super3.kt | 1 + .../expressions/super/super3.kt.2 | 1 + .../jetPsiMatcher/expressions/super/super4.kt | 1 + .../expressions/super/super4.kt.2 | 1 + .../jetPsiMatcher/expressions/throw/_throw.kt | 2 + .../expressions/throw/_throw.kt.2 | 2 + .../jetPsiMatcher/expressions/throw/throw.kt | 1 + .../expressions/throw/throw.kt.2 | 1 + .../expressions/unaryExpr/_unaryExpr1.kt | 2 + .../expressions/unaryExpr/_unaryExpr1.kt.2 | 1 + .../expressions/unaryExpr/_unaryExpr2.kt | 2 + .../expressions/unaryExpr/_unaryExpr2.kt.2 | 2 + .../expressions/unaryExpr/_unaryExpr3.kt | 2 + .../expressions/unaryExpr/_unaryExpr3.kt.2 | 2 + .../expressions/unaryExpr/unaryExpr1.kt | 1 + .../expressions/unaryExpr/unaryExpr1.kt.2 | 1 + .../expressions/unaryExpr/unaryExpr2.kt | 1 + .../expressions/unaryExpr/unaryExpr2.kt.2 | 1 + .../lang/psi/AbstractJetPsiMatcherTest.java | 48 +++ .../jet/lang/psi/JetPsiMatcherTest.java | 386 ++++++++++++++++++ .../jet/generators/tests/GenerateTests.java | 8 + .../branchedTransformations/WhenUtils.java | 4 +- 103 files changed, 741 insertions(+), 169 deletions(-) create mode 100644 compiler/testData/psi/jetPsiMatcher/expressions/arrayAccess/_arrayAccess1.kt create mode 100644 compiler/testData/psi/jetPsiMatcher/expressions/arrayAccess/_arrayAccess1.kt.2 create mode 100644 compiler/testData/psi/jetPsiMatcher/expressions/arrayAccess/_arrayAccess2.kt create mode 100644 compiler/testData/psi/jetPsiMatcher/expressions/arrayAccess/_arrayAccess2.kt.2 create mode 100644 compiler/testData/psi/jetPsiMatcher/expressions/arrayAccess/_arrayAccess3.kt create mode 100644 compiler/testData/psi/jetPsiMatcher/expressions/arrayAccess/_arrayAccess3.kt.2 create mode 100644 compiler/testData/psi/jetPsiMatcher/expressions/arrayAccess/arrayAccess1.kt create mode 100644 compiler/testData/psi/jetPsiMatcher/expressions/arrayAccess/arrayAccess1.kt.2 create mode 100644 compiler/testData/psi/jetPsiMatcher/expressions/arrayAccess/arrayAccess2.kt create mode 100644 compiler/testData/psi/jetPsiMatcher/expressions/arrayAccess/arrayAccess2.kt.2 create mode 100644 compiler/testData/psi/jetPsiMatcher/expressions/binaryExpr/_binaryExpr1.kt create mode 100644 compiler/testData/psi/jetPsiMatcher/expressions/binaryExpr/_binaryExpr1.kt.2 create mode 100644 compiler/testData/psi/jetPsiMatcher/expressions/binaryExpr/_binaryExpr2.kt create mode 100644 compiler/testData/psi/jetPsiMatcher/expressions/binaryExpr/_binaryExpr2.kt.2 create mode 100644 compiler/testData/psi/jetPsiMatcher/expressions/binaryExpr/_binaryExpr3.kt create mode 100644 compiler/testData/psi/jetPsiMatcher/expressions/binaryExpr/_binaryExpr3.kt.2 create mode 100644 compiler/testData/psi/jetPsiMatcher/expressions/binaryExpr/_binaryExpr4.kt create mode 100644 compiler/testData/psi/jetPsiMatcher/expressions/binaryExpr/_binaryExpr4.kt.2 create mode 100644 compiler/testData/psi/jetPsiMatcher/expressions/binaryExpr/_binaryExpr5.kt create mode 100644 compiler/testData/psi/jetPsiMatcher/expressions/binaryExpr/_binaryExpr5.kt.2 create mode 100644 compiler/testData/psi/jetPsiMatcher/expressions/binaryExpr/_binaryExpr6.kt create mode 100644 compiler/testData/psi/jetPsiMatcher/expressions/binaryExpr/_binaryExpr6.kt.2 create mode 100644 compiler/testData/psi/jetPsiMatcher/expressions/binaryExpr/binaryExpr1.kt create mode 100644 compiler/testData/psi/jetPsiMatcher/expressions/binaryExpr/binaryExpr1.kt.2 create mode 100644 compiler/testData/psi/jetPsiMatcher/expressions/binaryExpr/binaryExpr2.kt create mode 100644 compiler/testData/psi/jetPsiMatcher/expressions/binaryExpr/binaryExpr2.kt.2 create mode 100644 compiler/testData/psi/jetPsiMatcher/expressions/binaryExpr/binaryExpr3.kt create mode 100644 compiler/testData/psi/jetPsiMatcher/expressions/binaryExpr/binaryExpr3.kt.2 create mode 100644 compiler/testData/psi/jetPsiMatcher/expressions/binaryExpr/binaryExpr4.kt create mode 100644 compiler/testData/psi/jetPsiMatcher/expressions/binaryExpr/binaryExpr4.kt.2 create mode 100644 compiler/testData/psi/jetPsiMatcher/expressions/binaryExpr/binaryExpr5.kt create mode 100644 compiler/testData/psi/jetPsiMatcher/expressions/binaryExpr/binaryExpr5.kt.2 create mode 100644 compiler/testData/psi/jetPsiMatcher/expressions/call/_call1.kt create mode 100644 compiler/testData/psi/jetPsiMatcher/expressions/call/_call1.kt.2 create mode 100644 compiler/testData/psi/jetPsiMatcher/expressions/call/_call2.kt create mode 100644 compiler/testData/psi/jetPsiMatcher/expressions/call/_call2.kt.2 create mode 100644 compiler/testData/psi/jetPsiMatcher/expressions/call/_call3.kt create mode 100644 compiler/testData/psi/jetPsiMatcher/expressions/call/_call3.kt.2 create mode 100644 compiler/testData/psi/jetPsiMatcher/expressions/call/_call4.kt create mode 100644 compiler/testData/psi/jetPsiMatcher/expressions/call/_call4.kt.2 create mode 100644 compiler/testData/psi/jetPsiMatcher/expressions/call/call1.kt create mode 100644 compiler/testData/psi/jetPsiMatcher/expressions/call/call1.kt.2 create mode 100644 compiler/testData/psi/jetPsiMatcher/expressions/call/call2.kt create mode 100644 compiler/testData/psi/jetPsiMatcher/expressions/call/call2.kt.2 create mode 100644 compiler/testData/psi/jetPsiMatcher/expressions/call/call3.kt create mode 100644 compiler/testData/psi/jetPsiMatcher/expressions/call/call3.kt.2 create mode 100644 compiler/testData/psi/jetPsiMatcher/expressions/call/call4.kt create mode 100644 compiler/testData/psi/jetPsiMatcher/expressions/call/call4.kt.2 create mode 100644 compiler/testData/psi/jetPsiMatcher/expressions/const/_const.kt create mode 100644 compiler/testData/psi/jetPsiMatcher/expressions/const/_const.kt.2 create mode 100644 compiler/testData/psi/jetPsiMatcher/expressions/const/const.kt create mode 100644 compiler/testData/psi/jetPsiMatcher/expressions/const/const.kt.2 create mode 100644 compiler/testData/psi/jetPsiMatcher/expressions/misc/_misc1.kt create mode 100644 compiler/testData/psi/jetPsiMatcher/expressions/misc/_misc1.kt.2 create mode 100644 compiler/testData/psi/jetPsiMatcher/expressions/misc/_misc2.kt create mode 100644 compiler/testData/psi/jetPsiMatcher/expressions/misc/_misc2.kt.2 create mode 100644 compiler/testData/psi/jetPsiMatcher/expressions/misc/_misc3.kt create mode 100644 compiler/testData/psi/jetPsiMatcher/expressions/misc/_misc3.kt.2 create mode 100644 compiler/testData/psi/jetPsiMatcher/expressions/misc/misc1.kt create mode 100644 compiler/testData/psi/jetPsiMatcher/expressions/misc/misc1.kt.2 create mode 100644 compiler/testData/psi/jetPsiMatcher/expressions/misc/misc2.kt create mode 100644 compiler/testData/psi/jetPsiMatcher/expressions/misc/misc2.kt.2 create mode 100644 compiler/testData/psi/jetPsiMatcher/expressions/misc/misc3.kt create mode 100644 compiler/testData/psi/jetPsiMatcher/expressions/misc/misc3.kt.2 create mode 100644 compiler/testData/psi/jetPsiMatcher/expressions/simpleName/_simpleName.kt create mode 100644 compiler/testData/psi/jetPsiMatcher/expressions/simpleName/_simpleName.kt.2 create mode 100644 compiler/testData/psi/jetPsiMatcher/expressions/simpleName/simpleName.kt create mode 100644 compiler/testData/psi/jetPsiMatcher/expressions/simpleName/simpleName.kt.2 create mode 100644 compiler/testData/psi/jetPsiMatcher/expressions/super/_super1.kt create mode 100644 compiler/testData/psi/jetPsiMatcher/expressions/super/_super1.kt.2 create mode 100644 compiler/testData/psi/jetPsiMatcher/expressions/super/_super2.kt create mode 100644 compiler/testData/psi/jetPsiMatcher/expressions/super/_super2.kt.2 create mode 100644 compiler/testData/psi/jetPsiMatcher/expressions/super/_super3.kt create mode 100644 compiler/testData/psi/jetPsiMatcher/expressions/super/_super3.kt.2 create mode 100644 compiler/testData/psi/jetPsiMatcher/expressions/super/_super4.kt create mode 100644 compiler/testData/psi/jetPsiMatcher/expressions/super/_super4.kt.2 create mode 100644 compiler/testData/psi/jetPsiMatcher/expressions/super/super1.kt create mode 100644 compiler/testData/psi/jetPsiMatcher/expressions/super/super1.kt.2 create mode 100644 compiler/testData/psi/jetPsiMatcher/expressions/super/super2.kt create mode 100644 compiler/testData/psi/jetPsiMatcher/expressions/super/super2.kt.2 create mode 100644 compiler/testData/psi/jetPsiMatcher/expressions/super/super3.kt create mode 100644 compiler/testData/psi/jetPsiMatcher/expressions/super/super3.kt.2 create mode 100644 compiler/testData/psi/jetPsiMatcher/expressions/super/super4.kt create mode 100644 compiler/testData/psi/jetPsiMatcher/expressions/super/super4.kt.2 create mode 100644 compiler/testData/psi/jetPsiMatcher/expressions/throw/_throw.kt create mode 100644 compiler/testData/psi/jetPsiMatcher/expressions/throw/_throw.kt.2 create mode 100644 compiler/testData/psi/jetPsiMatcher/expressions/throw/throw.kt create mode 100644 compiler/testData/psi/jetPsiMatcher/expressions/throw/throw.kt.2 create mode 100644 compiler/testData/psi/jetPsiMatcher/expressions/unaryExpr/_unaryExpr1.kt create mode 100644 compiler/testData/psi/jetPsiMatcher/expressions/unaryExpr/_unaryExpr1.kt.2 create mode 100644 compiler/testData/psi/jetPsiMatcher/expressions/unaryExpr/_unaryExpr2.kt create mode 100644 compiler/testData/psi/jetPsiMatcher/expressions/unaryExpr/_unaryExpr2.kt.2 create mode 100644 compiler/testData/psi/jetPsiMatcher/expressions/unaryExpr/_unaryExpr3.kt create mode 100644 compiler/testData/psi/jetPsiMatcher/expressions/unaryExpr/_unaryExpr3.kt.2 create mode 100644 compiler/testData/psi/jetPsiMatcher/expressions/unaryExpr/unaryExpr1.kt create mode 100644 compiler/testData/psi/jetPsiMatcher/expressions/unaryExpr/unaryExpr1.kt.2 create mode 100644 compiler/testData/psi/jetPsiMatcher/expressions/unaryExpr/unaryExpr2.kt create mode 100644 compiler/testData/psi/jetPsiMatcher/expressions/unaryExpr/unaryExpr2.kt.2 create mode 100644 compiler/tests/org/jetbrains/jet/lang/psi/AbstractJetPsiMatcherTest.java create mode 100644 compiler/tests/org/jetbrains/jet/lang/psi/JetPsiMatcherTest.java diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetPsiMatcher.java b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetPsiMatcher.java index 5a7b8e04af8..4c10080a68b 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetPsiMatcher.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetPsiMatcher.java @@ -16,6 +16,10 @@ package org.jetbrains.jet.lang.psi; +import com.google.common.collect.Lists; +import org.jetbrains.annotations.Nullable; + +import java.util.Arrays; import java.util.List; public class JetPsiMatcher { @@ -26,221 +30,219 @@ public class JetPsiMatcher { return (t1 == t2) || (t1 != null && t2 != null && t1.getText().equals(t2.getText())); } - private static boolean checkStringTemplateEntryMatch(JetStringTemplateEntry e1, JetStringTemplateEntry e2) { - if (e1 == e2) return true; - if (e1 == null || e2 == null) return false; - - return e1.getClass() == e2.getClass() && checkExpressionMatch(e1.getExpression(), e2.getExpression()); + private interface Predicate2 { + boolean apply(A a, B b); } - private static boolean checkWhenConditionMatch(JetWhenCondition cond1, JetWhenCondition cond2) { - if (cond1 == cond2) return true; - if (cond1 == null || cond2 == null) return false; - - if (cond1.getClass() != cond2.getClass()) return false; - - if (cond1 instanceof JetWhenConditionInRange) { - JetWhenConditionInRange inRange1 = (JetWhenConditionInRange) cond1; - JetWhenConditionInRange inRange2 = (JetWhenConditionInRange) cond2; - - return inRange1.isNegated() == inRange2.isNegated() && - checkExpressionMatch(inRange1.getRangeExpression(), inRange2.getRangeExpression()) && - checkExpressionMatch(inRange1.getOperationReference(), inRange2.getOperationReference()); + private static final Predicate2 DEFAULT_CHECKER = new Predicate2() { + @Override + public boolean apply(JetElement element1, JetElement element2) { + return checkElementMatch(element1, element2); } + }; - if (cond1 instanceof JetWhenConditionIsPattern) { - JetWhenConditionIsPattern pattern1 = (JetWhenConditionIsPattern) cond1; - JetWhenConditionIsPattern pattern2 = (JetWhenConditionIsPattern) cond2; + private static final Predicate2 VALUE_ARGUMENT_CHECKER = new Predicate2() { + @Override + public boolean apply(ValueArgument a1, ValueArgument a2) { + if (a1 == a2) return true; + if (a1 == null || a2 == null) return false; - return pattern1.isNegated() == pattern2.isNegated() && - checkTypeReferenceMatch(pattern1.getTypeRef(), pattern2.getTypeRef()); + if (a1.getClass() != a2.getClass()) return false; + + if (a1.isNamed() != a2.isNamed()) return false; + + if (!checkElementMatch(a1.getArgumentExpression(), a2.getArgumentExpression())) return false; + + if (a1.isNamed()) { + return checkElementMatch(a1.getArgumentName(), a2.getArgumentName()); + } + + return true; } + }; - if (cond1 instanceof JetWhenConditionWithExpression) { - return checkExpressionMatch(((JetWhenConditionWithExpression) cond1).getExpression(), ((JetWhenConditionWithExpression) cond2).getExpression()); - } - - return false; - } - - private static boolean checkWhenEntryMatch(JetWhenEntry e1, JetWhenEntry e2) { - if (e1 == e2) return true; - if (e1 == null || e2 == null) return false; - - if (!(e1.isElse() == e2.isElse() && checkExpressionMatch(e1.getExpression(), e2.getExpression()))) return false; - - JetWhenCondition[] conditions1 = e1.getConditions(); - JetWhenCondition[] conditions2 = e2.getConditions(); - - int n = conditions1.length; - if (conditions2.length != n) return false; + private static boolean checkListMatch(List list1, List list2, Predicate2 checker) { + int n = list1.size(); + if (list2.size() != n) return false; for (int i = 0; i < n; i++) { - if (!checkWhenConditionMatch(conditions1[i], conditions2[i])) return false; + if (!checker.apply(list1.get(i), list2.get(i))) return false; } return true; } - public static boolean checkExpressionMatch(JetExpression e1, JetExpression e2) { - if (e1 == e2) return true; - if (e1 == null || e2 == null) return false; + private static boolean checkListMatch(List list1, List list2) { + return checkListMatch(list1, list2, DEFAULT_CHECKER); + } - e1 = JetPsiUtil.deparenthesizeWithNoTypeResolution(e1); - e2 = JetPsiUtil.deparenthesizeWithNoTypeResolution(e2); - - assert e1 != null && e2 != null; - - if (e1.getClass() != e2.getClass()) return false; - - if (e1 instanceof JetArrayAccessExpression) { - JetArrayAccessExpression aae1 = (JetArrayAccessExpression) e1; - JetArrayAccessExpression aae2 = (JetArrayAccessExpression) e2; - - if (!checkExpressionMatch(aae1.getArrayExpression(), aae2.getArrayExpression())) return false; - - List indexes1 = aae1.getIndexExpressions(); - List indexes2 = aae2.getIndexExpressions(); - - int n = indexes1.size(); - if (indexes2.size() != n) return false; - - for (int i = 0; i < n; i++) { - if (!checkExpressionMatch(indexes1.get(i), indexes2.get(i))) return false; - } - - return true; + private static final JetVisitor VISITOR = new JetVisitor() { + @Override + public Boolean visitJetElement(JetElement element, JetElement data) { + return false; } - if (e1 instanceof JetBinaryExpression) { - JetBinaryExpression be1 = (JetBinaryExpression) e1; - JetBinaryExpression be2 = (JetBinaryExpression) e2; + @Override + public Boolean visitArrayAccessExpression(JetArrayAccessExpression aae1, JetElement data) { + JetArrayAccessExpression aae2 = (JetArrayAccessExpression) data; + + return checkElementMatch(aae1.getArrayExpression(), aae2.getArrayExpression()) && + checkListMatch(aae1.getIndexExpressions(), aae2.getIndexExpressions()); + } + + @Override + public Boolean visitBinaryExpression(JetBinaryExpression be1, JetElement data) { + JetBinaryExpression be2 = (JetBinaryExpression) data; return be1.getOperationToken() == be2.getOperationToken() && - checkExpressionMatch(be1.getLeft(), be2.getLeft()) && - checkExpressionMatch(be1.getRight(), be2.getRight()); + checkElementMatch(be1.getLeft(), be2.getLeft()) && + checkElementMatch(be1.getRight(), be2.getRight()); } - if (e1 instanceof JetBinaryExpressionWithTypeRHS) { - JetBinaryExpressionWithTypeRHS bet1 = (JetBinaryExpressionWithTypeRHS) e1; - JetBinaryExpressionWithTypeRHS bet2 = (JetBinaryExpressionWithTypeRHS) e2; + @Override + public Boolean visitBinaryWithTypeRHSExpression(JetBinaryExpressionWithTypeRHS bet1, JetElement data) { + JetBinaryExpressionWithTypeRHS bet2 = (JetBinaryExpressionWithTypeRHS) data; - return checkExpressionMatch(bet1.getLeft(), bet2.getLeft()) && + return checkElementMatch(bet1.getLeft(), bet2.getLeft()) && checkTypeReferenceMatch(bet1.getRight(), bet2.getRight()); } - if (e1 instanceof JetCallExpression) { - JetCallExpression call1 = (JetCallExpression) e1; - JetCallExpression call2 = (JetCallExpression) e2; + @Override + public Boolean visitCallExpression(JetCallExpression call1, JetElement data) { + JetCallExpression call2 = (JetCallExpression) data; - if (!checkExpressionMatch(call1.getCalleeExpression(), call2.getCalleeExpression())) return false; + if (!checkElementMatch(call1.getCalleeExpression(), call2.getCalleeExpression())) return false; - List args1 = call1.getValueArguments(); - List args2 = call2.getValueArguments(); - - int argCount = args1.size(); - if (args2.size() != argCount) return false; - - for (int i = 0; i < argCount; i++) { - if (!checkExpressionMatch(args1.get(i).getArgumentExpression(), args2.get(i).getArgumentExpression())) return false; - } - - List funLiterals1 = call1.getFunctionLiteralArguments(); - List funLiterals2 = call2.getFunctionLiteralArguments(); - - int funLiteralCount = funLiterals1.size(); - if (funLiterals2.size() != funLiteralCount) return false; - - for (int i = 0; i < argCount; i++) { - if (!checkExpressionMatch(funLiterals1.get(i), funLiterals2.get(i))) return false; - } - - return true; + return checkListMatch(call1.getValueArguments(), call2.getValueArguments(), VALUE_ARGUMENT_CHECKER) && + checkListMatch(call1.getFunctionLiteralArguments(), call2.getFunctionLiteralArguments()); } - if (e1 instanceof JetConstantExpression || e1 instanceof JetSimpleNameExpression) { - return e1.getText().equals(e2.getText()); + @Override + public Boolean visitSimpleNameExpression(JetSimpleNameExpression expression, JetElement data) { + return expression.getText().equals(data.getText()); } - if (e1 instanceof JetConstructorCalleeExpression) { - return checkTypeReferenceMatch(((JetConstructorCalleeExpression) e1).getTypeReference(), ((JetConstructorCalleeExpression) e2).getTypeReference()); + @Override + public Boolean visitConstantExpression(JetConstantExpression expression, JetElement data) { + return expression.getText().equals(data.getText()); } - if (e1 instanceof JetQualifiedExpression) { - return ((JetQualifiedExpression) e1).getOperationSign() == ((JetQualifiedExpression) e2).getOperationSign() && - checkExpressionMatch(((JetQualifiedExpression) e1).getReceiverExpression(), ((JetQualifiedExpression) e2).getReceiverExpression()) && - checkExpressionMatch(((JetQualifiedExpression) e1).getSelectorExpression(), ((JetQualifiedExpression) e2).getSelectorExpression()); + @Override + public Boolean visitIsExpression(JetIsExpression is1, JetElement data) { + JetIsExpression is2 = (JetIsExpression) data; + + return checkElementMatch(is1.getLeftHandSide(), is2.getLeftHandSide()) && + checkTypeReferenceMatch(is1.getTypeRef(), is2.getTypeRef()) && + is1.isNegated() == is2.isNegated(); } - if (e1 instanceof JetIfExpression) { - return checkExpressionMatch(((JetIfExpression) e1).getCondition(), ((JetIfExpression) e2).getCondition()) && - checkExpressionMatch(((JetIfExpression) e1).getThen(), ((JetIfExpression) e2).getThen()) && - checkExpressionMatch(((JetIfExpression) e1).getElse(), ((JetIfExpression) e2).getElse()); + @Override + public Boolean visitQualifiedExpression(JetQualifiedExpression qe1, JetElement data) { + JetQualifiedExpression qe2 = (JetQualifiedExpression) data; + + return qe1.getOperationSign() == qe2.getOperationSign() && + checkElementMatch(qe1.getReceiverExpression(), qe2.getReceiverExpression()) && + checkElementMatch(qe1.getSelectorExpression(), qe2.getSelectorExpression()); } - if (e1 instanceof JetIsExpression) { - return checkExpressionMatch(((JetIsExpression) e1).getLeftHandSide(), ((JetIsExpression) e2).getLeftHandSide()) && - checkTypeReferenceMatch(((JetIsExpression) e1).getTypeRef(), ((JetIsExpression) e2).getTypeRef()) && - ((JetIsExpression) e1).isNegated() == ((JetIsExpression) e2).isNegated(); + @Override + public Boolean visitStringTemplateExpression(JetStringTemplateExpression expression, JetElement data) { + return checkListMatch( + Arrays.asList(expression.getEntries()), + Arrays.asList(((JetStringTemplateExpression) data).getEntries()) + ); } - if (e1 instanceof JetStringTemplateExpression) { - JetStringTemplateExpression str1 = (JetStringTemplateExpression) e1; - JetStringTemplateExpression str2 = (JetStringTemplateExpression) e2; - - JetStringTemplateEntry[] entries1 = str1.getEntries(); - JetStringTemplateEntry[] entries2 = str2.getEntries(); - - int n = entries1.length; - if (entries2.length != n) return false; - - for (int i = 0; i < n; i++) { - if (!checkStringTemplateEntryMatch(entries1[i], entries2[i])) return false; - } - - return true; + @Override + public Boolean visitStringTemplateEntryWithExpression(JetStringTemplateEntryWithExpression entry, JetElement data) { + return checkElementMatch(entry.getExpression(), ((JetStringTemplateEntryWithExpression) data).getExpression()); } - if (e1 instanceof JetThrowExpression) { - return checkExpressionMatch(((JetThrowExpression) e1).getThrownExpression(), ((JetThrowExpression) e2).getThrownExpression()); + @Override + public Boolean visitLiteralStringTemplateEntry(JetLiteralStringTemplateEntry entry, JetElement data) { + return entry.getText().equals(data.getText()); } - if (e1 instanceof JetUnaryExpression) { - JetUnaryExpression ue1 = (JetUnaryExpression) e1; - JetUnaryExpression ue2 = (JetUnaryExpression) e2; - - return checkExpressionMatch(ue1.getBaseExpression(), ue2.getBaseExpression()) && - checkExpressionMatch(ue1.getOperationReference(), ue2.getOperationReference()); + @Override + public Boolean visitEscapeStringTemplateEntry(JetEscapeStringTemplateEntry entry, JetElement data) { + return entry.getText().equals(data.getText()); } - if (e1 instanceof JetWhenExpression) { - JetWhenExpression when1 = (JetWhenExpression) e1; - JetWhenExpression when2 = (JetWhenExpression) e2; - - if (checkExpressionMatch(when1.getSubjectExpression(), when2.getSubjectExpression())) return false; - - List entries1 = when1.getEntries(); - List entries2 = when2.getEntries(); - - int n = entries1.size(); - if (entries2.size() != n) return false; - - for (int i = 0; i < n; i++) { - if (!checkWhenEntryMatch(entries1.get(i), entries2.get(i))) return false; - } - } - - if (e1 instanceof JetThisExpression) return true; - - if (e1 instanceof JetSuperExpression) { - JetSuperExpression super1 = (JetSuperExpression) e1; - JetSuperExpression super2 = (JetSuperExpression) e2; + @Override + public Boolean visitSuperExpression(JetSuperExpression super1, JetElement data) { + JetSuperExpression super2 = (JetSuperExpression) data; return checkTypeReferenceMatch(super1.getSuperTypeQualifier(), super2.getSuperTypeQualifier()) && - checkExpressionMatch(super1.getInstanceReference(), super2.getInstanceReference()) && - checkExpressionMatch(super1.getTargetLabel(), super2.getTargetLabel()); + checkElementMatch(super1.getInstanceReference(), super2.getInstanceReference()) && + checkElementMatch(super1.getTargetLabel(), super2.getTargetLabel()); } - return false; + @Override + public Boolean visitThrowExpression(JetThrowExpression expression, JetElement data) { + return checkElementMatch(expression.getThrownExpression(), ((JetThrowExpression) data).getThrownExpression()); + } + + @Override + public Boolean visitThisExpression(JetThisExpression this1, JetElement data) { + return checkElementMatch(this1.getTargetLabel(), ((JetThisExpression) data).getTargetLabel()); + } + + @Override + public Boolean visitUnaryExpression(JetUnaryExpression ue1, JetElement data) { + JetUnaryExpression ue2 = (JetUnaryExpression) data; + + return checkElementMatch(ue1.getBaseExpression(), ue2.getBaseExpression()) && + checkElementMatch(ue1.getOperationReference(), ue2.getOperationReference()); + } + + @Override + public Boolean visitTypeReference(JetTypeReference typeReference, JetElement data) { + return checkElementMatch(typeReference.getTypeElement(), ((JetTypeReference) data).getTypeElement()); + } + + @Override + public Boolean visitFunctionType(JetFunctionType type1, JetElement data) { + JetFunctionType type2 = (JetFunctionType) data; + + return checkListMatch(type1.getTypeArgumentsAsTypes(), type2.getTypeArgumentsAsTypes()); + } + + @Override + public Boolean visitUserType(JetUserType type1, JetElement data) { + JetUserType type2 = (JetUserType) data; + + return checkElementMatch(type1.getReferenceExpression(), type2.getReferenceExpression()) && + checkElementMatch(type1.getQualifier(), type2.getQualifier()) && + checkListMatch(type1.getTypeArgumentsAsTypes(), type2.getTypeArgumentsAsTypes()); + } + + @Override + public Boolean visitSelfType(JetSelfType type, JetElement data) { + return true; + } + + @Override + public Boolean visitNullableType(JetNullableType nullableType, JetElement data) { + return checkElementMatch(nullableType.getInnerType(), ((JetNullableType) data).getInnerType()); + } + }; + + private static JetElement unwrap(JetElement e) { + if (e instanceof JetExpression) { + return JetPsiUtil.deparenthesizeWithNoTypeResolution((JetExpression) e); + } + return e; + } + + public static boolean checkElementMatch(@Nullable JetElement e1, @Nullable JetElement e2) { + e1 = unwrap(e1); + e2 = unwrap(e2); + + if (e1 == e2) return true; + if (e1 == null || e2 == null) return false; + + if (e1.getClass() != e2.getClass()) return false; + + return e1.accept(VISITOR, e2); } } diff --git a/compiler/testData/psi/jetPsiMatcher/expressions/arrayAccess/_arrayAccess1.kt b/compiler/testData/psi/jetPsiMatcher/expressions/arrayAccess/_arrayAccess1.kt new file mode 100644 index 00000000000..aead762075d --- /dev/null +++ b/compiler/testData/psi/jetPsiMatcher/expressions/arrayAccess/_arrayAccess1.kt @@ -0,0 +1,2 @@ +// NOT_EQUAL +a[0] \ No newline at end of file diff --git a/compiler/testData/psi/jetPsiMatcher/expressions/arrayAccess/_arrayAccess1.kt.2 b/compiler/testData/psi/jetPsiMatcher/expressions/arrayAccess/_arrayAccess1.kt.2 new file mode 100644 index 00000000000..7e47cf58a31 --- /dev/null +++ b/compiler/testData/psi/jetPsiMatcher/expressions/arrayAccess/_arrayAccess1.kt.2 @@ -0,0 +1 @@ +b[0] \ No newline at end of file diff --git a/compiler/testData/psi/jetPsiMatcher/expressions/arrayAccess/_arrayAccess2.kt b/compiler/testData/psi/jetPsiMatcher/expressions/arrayAccess/_arrayAccess2.kt new file mode 100644 index 00000000000..aead762075d --- /dev/null +++ b/compiler/testData/psi/jetPsiMatcher/expressions/arrayAccess/_arrayAccess2.kt @@ -0,0 +1,2 @@ +// NOT_EQUAL +a[0] \ No newline at end of file diff --git a/compiler/testData/psi/jetPsiMatcher/expressions/arrayAccess/_arrayAccess2.kt.2 b/compiler/testData/psi/jetPsiMatcher/expressions/arrayAccess/_arrayAccess2.kt.2 new file mode 100644 index 00000000000..e4ce9c1e8bb --- /dev/null +++ b/compiler/testData/psi/jetPsiMatcher/expressions/arrayAccess/_arrayAccess2.kt.2 @@ -0,0 +1 @@ +a[2] \ No newline at end of file diff --git a/compiler/testData/psi/jetPsiMatcher/expressions/arrayAccess/_arrayAccess3.kt b/compiler/testData/psi/jetPsiMatcher/expressions/arrayAccess/_arrayAccess3.kt new file mode 100644 index 00000000000..aead762075d --- /dev/null +++ b/compiler/testData/psi/jetPsiMatcher/expressions/arrayAccess/_arrayAccess3.kt @@ -0,0 +1,2 @@ +// NOT_EQUAL +a[0] \ No newline at end of file diff --git a/compiler/testData/psi/jetPsiMatcher/expressions/arrayAccess/_arrayAccess3.kt.2 b/compiler/testData/psi/jetPsiMatcher/expressions/arrayAccess/_arrayAccess3.kt.2 new file mode 100644 index 00000000000..f8d9bf02262 --- /dev/null +++ b/compiler/testData/psi/jetPsiMatcher/expressions/arrayAccess/_arrayAccess3.kt.2 @@ -0,0 +1 @@ +a[n] \ No newline at end of file diff --git a/compiler/testData/psi/jetPsiMatcher/expressions/arrayAccess/arrayAccess1.kt b/compiler/testData/psi/jetPsiMatcher/expressions/arrayAccess/arrayAccess1.kt new file mode 100644 index 00000000000..1727bf901f2 --- /dev/null +++ b/compiler/testData/psi/jetPsiMatcher/expressions/arrayAccess/arrayAccess1.kt @@ -0,0 +1 @@ +a[0] \ No newline at end of file diff --git a/compiler/testData/psi/jetPsiMatcher/expressions/arrayAccess/arrayAccess1.kt.2 b/compiler/testData/psi/jetPsiMatcher/expressions/arrayAccess/arrayAccess1.kt.2 new file mode 100644 index 00000000000..1727bf901f2 --- /dev/null +++ b/compiler/testData/psi/jetPsiMatcher/expressions/arrayAccess/arrayAccess1.kt.2 @@ -0,0 +1 @@ +a[0] \ No newline at end of file diff --git a/compiler/testData/psi/jetPsiMatcher/expressions/arrayAccess/arrayAccess2.kt b/compiler/testData/psi/jetPsiMatcher/expressions/arrayAccess/arrayAccess2.kt new file mode 100644 index 00000000000..f8d9bf02262 --- /dev/null +++ b/compiler/testData/psi/jetPsiMatcher/expressions/arrayAccess/arrayAccess2.kt @@ -0,0 +1 @@ +a[n] \ No newline at end of file diff --git a/compiler/testData/psi/jetPsiMatcher/expressions/arrayAccess/arrayAccess2.kt.2 b/compiler/testData/psi/jetPsiMatcher/expressions/arrayAccess/arrayAccess2.kt.2 new file mode 100644 index 00000000000..f8d9bf02262 --- /dev/null +++ b/compiler/testData/psi/jetPsiMatcher/expressions/arrayAccess/arrayAccess2.kt.2 @@ -0,0 +1 @@ +a[n] \ No newline at end of file diff --git a/compiler/testData/psi/jetPsiMatcher/expressions/binaryExpr/_binaryExpr1.kt b/compiler/testData/psi/jetPsiMatcher/expressions/binaryExpr/_binaryExpr1.kt new file mode 100644 index 00000000000..cb38a52f476 --- /dev/null +++ b/compiler/testData/psi/jetPsiMatcher/expressions/binaryExpr/_binaryExpr1.kt @@ -0,0 +1,2 @@ +// NOT_EQUAL +1 + 2 \ No newline at end of file diff --git a/compiler/testData/psi/jetPsiMatcher/expressions/binaryExpr/_binaryExpr1.kt.2 b/compiler/testData/psi/jetPsiMatcher/expressions/binaryExpr/_binaryExpr1.kt.2 new file mode 100644 index 00000000000..1ad61fe45a2 --- /dev/null +++ b/compiler/testData/psi/jetPsiMatcher/expressions/binaryExpr/_binaryExpr1.kt.2 @@ -0,0 +1 @@ +2 + 1 \ No newline at end of file diff --git a/compiler/testData/psi/jetPsiMatcher/expressions/binaryExpr/_binaryExpr2.kt b/compiler/testData/psi/jetPsiMatcher/expressions/binaryExpr/_binaryExpr2.kt new file mode 100644 index 00000000000..cb38a52f476 --- /dev/null +++ b/compiler/testData/psi/jetPsiMatcher/expressions/binaryExpr/_binaryExpr2.kt @@ -0,0 +1,2 @@ +// NOT_EQUAL +1 + 2 \ No newline at end of file diff --git a/compiler/testData/psi/jetPsiMatcher/expressions/binaryExpr/_binaryExpr2.kt.2 b/compiler/testData/psi/jetPsiMatcher/expressions/binaryExpr/_binaryExpr2.kt.2 new file mode 100644 index 00000000000..7ec0a893aef --- /dev/null +++ b/compiler/testData/psi/jetPsiMatcher/expressions/binaryExpr/_binaryExpr2.kt.2 @@ -0,0 +1 @@ +1 - 2 \ No newline at end of file diff --git a/compiler/testData/psi/jetPsiMatcher/expressions/binaryExpr/_binaryExpr3.kt b/compiler/testData/psi/jetPsiMatcher/expressions/binaryExpr/_binaryExpr3.kt new file mode 100644 index 00000000000..2e1a1bf0cbd --- /dev/null +++ b/compiler/testData/psi/jetPsiMatcher/expressions/binaryExpr/_binaryExpr3.kt @@ -0,0 +1,2 @@ +// NOT_EQUAL +a + 2 \ No newline at end of file diff --git a/compiler/testData/psi/jetPsiMatcher/expressions/binaryExpr/_binaryExpr3.kt.2 b/compiler/testData/psi/jetPsiMatcher/expressions/binaryExpr/_binaryExpr3.kt.2 new file mode 100644 index 00000000000..fe98fcd3d5a --- /dev/null +++ b/compiler/testData/psi/jetPsiMatcher/expressions/binaryExpr/_binaryExpr3.kt.2 @@ -0,0 +1 @@ +b + 2 \ No newline at end of file diff --git a/compiler/testData/psi/jetPsiMatcher/expressions/binaryExpr/_binaryExpr4.kt b/compiler/testData/psi/jetPsiMatcher/expressions/binaryExpr/_binaryExpr4.kt new file mode 100644 index 00000000000..be8c0c96fd4 --- /dev/null +++ b/compiler/testData/psi/jetPsiMatcher/expressions/binaryExpr/_binaryExpr4.kt @@ -0,0 +1,2 @@ +// NOT_EQUAL +a + b \ No newline at end of file diff --git a/compiler/testData/psi/jetPsiMatcher/expressions/binaryExpr/_binaryExpr4.kt.2 b/compiler/testData/psi/jetPsiMatcher/expressions/binaryExpr/_binaryExpr4.kt.2 new file mode 100644 index 00000000000..68bdebaba7f --- /dev/null +++ b/compiler/testData/psi/jetPsiMatcher/expressions/binaryExpr/_binaryExpr4.kt.2 @@ -0,0 +1 @@ +c/d \ No newline at end of file diff --git a/compiler/testData/psi/jetPsiMatcher/expressions/binaryExpr/_binaryExpr5.kt b/compiler/testData/psi/jetPsiMatcher/expressions/binaryExpr/_binaryExpr5.kt new file mode 100644 index 00000000000..fcce78399aa --- /dev/null +++ b/compiler/testData/psi/jetPsiMatcher/expressions/binaryExpr/_binaryExpr5.kt @@ -0,0 +1,2 @@ +// NOT_EQUAL +a is String \ No newline at end of file diff --git a/compiler/testData/psi/jetPsiMatcher/expressions/binaryExpr/_binaryExpr5.kt.2 b/compiler/testData/psi/jetPsiMatcher/expressions/binaryExpr/_binaryExpr5.kt.2 new file mode 100644 index 00000000000..01823a34497 --- /dev/null +++ b/compiler/testData/psi/jetPsiMatcher/expressions/binaryExpr/_binaryExpr5.kt.2 @@ -0,0 +1 @@ +a as String \ No newline at end of file diff --git a/compiler/testData/psi/jetPsiMatcher/expressions/binaryExpr/_binaryExpr6.kt b/compiler/testData/psi/jetPsiMatcher/expressions/binaryExpr/_binaryExpr6.kt new file mode 100644 index 00000000000..1383f3c6743 --- /dev/null +++ b/compiler/testData/psi/jetPsiMatcher/expressions/binaryExpr/_binaryExpr6.kt @@ -0,0 +1,2 @@ +// NOT_EQUAL +a !is String \ No newline at end of file diff --git a/compiler/testData/psi/jetPsiMatcher/expressions/binaryExpr/_binaryExpr6.kt.2 b/compiler/testData/psi/jetPsiMatcher/expressions/binaryExpr/_binaryExpr6.kt.2 new file mode 100644 index 00000000000..7ccaa0c9744 --- /dev/null +++ b/compiler/testData/psi/jetPsiMatcher/expressions/binaryExpr/_binaryExpr6.kt.2 @@ -0,0 +1 @@ +a is String \ No newline at end of file diff --git a/compiler/testData/psi/jetPsiMatcher/expressions/binaryExpr/binaryExpr1.kt b/compiler/testData/psi/jetPsiMatcher/expressions/binaryExpr/binaryExpr1.kt new file mode 100644 index 00000000000..193df0b550b --- /dev/null +++ b/compiler/testData/psi/jetPsiMatcher/expressions/binaryExpr/binaryExpr1.kt @@ -0,0 +1 @@ +1 + 2 \ No newline at end of file diff --git a/compiler/testData/psi/jetPsiMatcher/expressions/binaryExpr/binaryExpr1.kt.2 b/compiler/testData/psi/jetPsiMatcher/expressions/binaryExpr/binaryExpr1.kt.2 new file mode 100644 index 00000000000..193df0b550b --- /dev/null +++ b/compiler/testData/psi/jetPsiMatcher/expressions/binaryExpr/binaryExpr1.kt.2 @@ -0,0 +1 @@ +1 + 2 \ No newline at end of file diff --git a/compiler/testData/psi/jetPsiMatcher/expressions/binaryExpr/binaryExpr2.kt b/compiler/testData/psi/jetPsiMatcher/expressions/binaryExpr/binaryExpr2.kt new file mode 100644 index 00000000000..2fdfd51e8d7 --- /dev/null +++ b/compiler/testData/psi/jetPsiMatcher/expressions/binaryExpr/binaryExpr2.kt @@ -0,0 +1 @@ +a + b \ No newline at end of file diff --git a/compiler/testData/psi/jetPsiMatcher/expressions/binaryExpr/binaryExpr2.kt.2 b/compiler/testData/psi/jetPsiMatcher/expressions/binaryExpr/binaryExpr2.kt.2 new file mode 100644 index 00000000000..2fdfd51e8d7 --- /dev/null +++ b/compiler/testData/psi/jetPsiMatcher/expressions/binaryExpr/binaryExpr2.kt.2 @@ -0,0 +1 @@ +a + b \ No newline at end of file diff --git a/compiler/testData/psi/jetPsiMatcher/expressions/binaryExpr/binaryExpr3.kt b/compiler/testData/psi/jetPsiMatcher/expressions/binaryExpr/binaryExpr3.kt new file mode 100644 index 00000000000..64dd70ad082 --- /dev/null +++ b/compiler/testData/psi/jetPsiMatcher/expressions/binaryExpr/binaryExpr3.kt @@ -0,0 +1 @@ +a*10 \ No newline at end of file diff --git a/compiler/testData/psi/jetPsiMatcher/expressions/binaryExpr/binaryExpr3.kt.2 b/compiler/testData/psi/jetPsiMatcher/expressions/binaryExpr/binaryExpr3.kt.2 new file mode 100644 index 00000000000..64dd70ad082 --- /dev/null +++ b/compiler/testData/psi/jetPsiMatcher/expressions/binaryExpr/binaryExpr3.kt.2 @@ -0,0 +1 @@ +a*10 \ No newline at end of file diff --git a/compiler/testData/psi/jetPsiMatcher/expressions/binaryExpr/binaryExpr4.kt b/compiler/testData/psi/jetPsiMatcher/expressions/binaryExpr/binaryExpr4.kt new file mode 100644 index 00000000000..7ccaa0c9744 --- /dev/null +++ b/compiler/testData/psi/jetPsiMatcher/expressions/binaryExpr/binaryExpr4.kt @@ -0,0 +1 @@ +a is String \ No newline at end of file diff --git a/compiler/testData/psi/jetPsiMatcher/expressions/binaryExpr/binaryExpr4.kt.2 b/compiler/testData/psi/jetPsiMatcher/expressions/binaryExpr/binaryExpr4.kt.2 new file mode 100644 index 00000000000..7ccaa0c9744 --- /dev/null +++ b/compiler/testData/psi/jetPsiMatcher/expressions/binaryExpr/binaryExpr4.kt.2 @@ -0,0 +1 @@ +a is String \ No newline at end of file diff --git a/compiler/testData/psi/jetPsiMatcher/expressions/binaryExpr/binaryExpr5.kt b/compiler/testData/psi/jetPsiMatcher/expressions/binaryExpr/binaryExpr5.kt new file mode 100644 index 00000000000..36601b5c09b --- /dev/null +++ b/compiler/testData/psi/jetPsiMatcher/expressions/binaryExpr/binaryExpr5.kt @@ -0,0 +1 @@ +a !is String \ No newline at end of file diff --git a/compiler/testData/psi/jetPsiMatcher/expressions/binaryExpr/binaryExpr5.kt.2 b/compiler/testData/psi/jetPsiMatcher/expressions/binaryExpr/binaryExpr5.kt.2 new file mode 100644 index 00000000000..36601b5c09b --- /dev/null +++ b/compiler/testData/psi/jetPsiMatcher/expressions/binaryExpr/binaryExpr5.kt.2 @@ -0,0 +1 @@ +a !is String \ No newline at end of file diff --git a/compiler/testData/psi/jetPsiMatcher/expressions/call/_call1.kt b/compiler/testData/psi/jetPsiMatcher/expressions/call/_call1.kt new file mode 100644 index 00000000000..a0a6cc8e2f9 --- /dev/null +++ b/compiler/testData/psi/jetPsiMatcher/expressions/call/_call1.kt @@ -0,0 +1,2 @@ +// NOT_EQUAL +f() \ No newline at end of file diff --git a/compiler/testData/psi/jetPsiMatcher/expressions/call/_call1.kt.2 b/compiler/testData/psi/jetPsiMatcher/expressions/call/_call1.kt.2 new file mode 100644 index 00000000000..7476967925d --- /dev/null +++ b/compiler/testData/psi/jetPsiMatcher/expressions/call/_call1.kt.2 @@ -0,0 +1 @@ +f(0) \ No newline at end of file diff --git a/compiler/testData/psi/jetPsiMatcher/expressions/call/_call2.kt b/compiler/testData/psi/jetPsiMatcher/expressions/call/_call2.kt new file mode 100644 index 00000000000..a0a6cc8e2f9 --- /dev/null +++ b/compiler/testData/psi/jetPsiMatcher/expressions/call/_call2.kt @@ -0,0 +1,2 @@ +// NOT_EQUAL +f() \ No newline at end of file diff --git a/compiler/testData/psi/jetPsiMatcher/expressions/call/_call2.kt.2 b/compiler/testData/psi/jetPsiMatcher/expressions/call/_call2.kt.2 new file mode 100644 index 00000000000..3a2765afd1e --- /dev/null +++ b/compiler/testData/psi/jetPsiMatcher/expressions/call/_call2.kt.2 @@ -0,0 +1 @@ +g() \ No newline at end of file diff --git a/compiler/testData/psi/jetPsiMatcher/expressions/call/_call3.kt b/compiler/testData/psi/jetPsiMatcher/expressions/call/_call3.kt new file mode 100644 index 00000000000..02e0aa5de2d --- /dev/null +++ b/compiler/testData/psi/jetPsiMatcher/expressions/call/_call3.kt @@ -0,0 +1,2 @@ +// NOT_EQUAL +f(a, b) \ No newline at end of file diff --git a/compiler/testData/psi/jetPsiMatcher/expressions/call/_call3.kt.2 b/compiler/testData/psi/jetPsiMatcher/expressions/call/_call3.kt.2 new file mode 100644 index 00000000000..1bf42070b82 --- /dev/null +++ b/compiler/testData/psi/jetPsiMatcher/expressions/call/_call3.kt.2 @@ -0,0 +1 @@ +a.f(b) \ No newline at end of file diff --git a/compiler/testData/psi/jetPsiMatcher/expressions/call/_call4.kt b/compiler/testData/psi/jetPsiMatcher/expressions/call/_call4.kt new file mode 100644 index 00000000000..41e44980678 --- /dev/null +++ b/compiler/testData/psi/jetPsiMatcher/expressions/call/_call4.kt @@ -0,0 +1,2 @@ +// NOT_EQUAL +x.f(a, b) \ No newline at end of file diff --git a/compiler/testData/psi/jetPsiMatcher/expressions/call/_call4.kt.2 b/compiler/testData/psi/jetPsiMatcher/expressions/call/_call4.kt.2 new file mode 100644 index 00000000000..259b9c7f0be --- /dev/null +++ b/compiler/testData/psi/jetPsiMatcher/expressions/call/_call4.kt.2 @@ -0,0 +1 @@ +y.f(c, z) \ No newline at end of file diff --git a/compiler/testData/psi/jetPsiMatcher/expressions/call/call1.kt b/compiler/testData/psi/jetPsiMatcher/expressions/call/call1.kt new file mode 100644 index 00000000000..300ddfaeb1d --- /dev/null +++ b/compiler/testData/psi/jetPsiMatcher/expressions/call/call1.kt @@ -0,0 +1 @@ +f() \ No newline at end of file diff --git a/compiler/testData/psi/jetPsiMatcher/expressions/call/call1.kt.2 b/compiler/testData/psi/jetPsiMatcher/expressions/call/call1.kt.2 new file mode 100644 index 00000000000..300ddfaeb1d --- /dev/null +++ b/compiler/testData/psi/jetPsiMatcher/expressions/call/call1.kt.2 @@ -0,0 +1 @@ +f() \ No newline at end of file diff --git a/compiler/testData/psi/jetPsiMatcher/expressions/call/call2.kt b/compiler/testData/psi/jetPsiMatcher/expressions/call/call2.kt new file mode 100644 index 00000000000..7326bb66e0a --- /dev/null +++ b/compiler/testData/psi/jetPsiMatcher/expressions/call/call2.kt @@ -0,0 +1 @@ +f(a) \ No newline at end of file diff --git a/compiler/testData/psi/jetPsiMatcher/expressions/call/call2.kt.2 b/compiler/testData/psi/jetPsiMatcher/expressions/call/call2.kt.2 new file mode 100644 index 00000000000..7326bb66e0a --- /dev/null +++ b/compiler/testData/psi/jetPsiMatcher/expressions/call/call2.kt.2 @@ -0,0 +1 @@ +f(a) \ No newline at end of file diff --git a/compiler/testData/psi/jetPsiMatcher/expressions/call/call3.kt b/compiler/testData/psi/jetPsiMatcher/expressions/call/call3.kt new file mode 100644 index 00000000000..655ee57c2c8 --- /dev/null +++ b/compiler/testData/psi/jetPsiMatcher/expressions/call/call3.kt @@ -0,0 +1 @@ +f(a, 1) \ No newline at end of file diff --git a/compiler/testData/psi/jetPsiMatcher/expressions/call/call3.kt.2 b/compiler/testData/psi/jetPsiMatcher/expressions/call/call3.kt.2 new file mode 100644 index 00000000000..655ee57c2c8 --- /dev/null +++ b/compiler/testData/psi/jetPsiMatcher/expressions/call/call3.kt.2 @@ -0,0 +1 @@ +f(a, 1) \ No newline at end of file diff --git a/compiler/testData/psi/jetPsiMatcher/expressions/call/call4.kt b/compiler/testData/psi/jetPsiMatcher/expressions/call/call4.kt new file mode 100644 index 00000000000..2c8c8598b91 --- /dev/null +++ b/compiler/testData/psi/jetPsiMatcher/expressions/call/call4.kt @@ -0,0 +1 @@ +x.f(a, 1) \ No newline at end of file diff --git a/compiler/testData/psi/jetPsiMatcher/expressions/call/call4.kt.2 b/compiler/testData/psi/jetPsiMatcher/expressions/call/call4.kt.2 new file mode 100644 index 00000000000..2c8c8598b91 --- /dev/null +++ b/compiler/testData/psi/jetPsiMatcher/expressions/call/call4.kt.2 @@ -0,0 +1 @@ +x.f(a, 1) \ No newline at end of file diff --git a/compiler/testData/psi/jetPsiMatcher/expressions/const/_const.kt b/compiler/testData/psi/jetPsiMatcher/expressions/const/_const.kt new file mode 100644 index 00000000000..ebd1a599403 --- /dev/null +++ b/compiler/testData/psi/jetPsiMatcher/expressions/const/_const.kt @@ -0,0 +1,2 @@ +// NOT_EQUAL +123 \ No newline at end of file diff --git a/compiler/testData/psi/jetPsiMatcher/expressions/const/_const.kt.2 b/compiler/testData/psi/jetPsiMatcher/expressions/const/_const.kt.2 new file mode 100644 index 00000000000..5ca234cb538 --- /dev/null +++ b/compiler/testData/psi/jetPsiMatcher/expressions/const/_const.kt.2 @@ -0,0 +1 @@ +345 \ No newline at end of file diff --git a/compiler/testData/psi/jetPsiMatcher/expressions/const/const.kt b/compiler/testData/psi/jetPsiMatcher/expressions/const/const.kt new file mode 100644 index 00000000000..d800886d9c8 --- /dev/null +++ b/compiler/testData/psi/jetPsiMatcher/expressions/const/const.kt @@ -0,0 +1 @@ +123 \ No newline at end of file diff --git a/compiler/testData/psi/jetPsiMatcher/expressions/const/const.kt.2 b/compiler/testData/psi/jetPsiMatcher/expressions/const/const.kt.2 new file mode 100644 index 00000000000..d800886d9c8 --- /dev/null +++ b/compiler/testData/psi/jetPsiMatcher/expressions/const/const.kt.2 @@ -0,0 +1 @@ +123 \ No newline at end of file diff --git a/compiler/testData/psi/jetPsiMatcher/expressions/misc/_misc1.kt b/compiler/testData/psi/jetPsiMatcher/expressions/misc/_misc1.kt new file mode 100644 index 00000000000..2901e88f945 --- /dev/null +++ b/compiler/testData/psi/jetPsiMatcher/expressions/misc/_misc1.kt @@ -0,0 +1,2 @@ +// NOT_EQUAL +(a + b*x.f(n - 1)) \ No newline at end of file diff --git a/compiler/testData/psi/jetPsiMatcher/expressions/misc/_misc1.kt.2 b/compiler/testData/psi/jetPsiMatcher/expressions/misc/_misc1.kt.2 new file mode 100644 index 00000000000..dc0753c5111 --- /dev/null +++ b/compiler/testData/psi/jetPsiMatcher/expressions/misc/_misc1.kt.2 @@ -0,0 +1 @@ +(a + b)*x.f(n - 1) \ No newline at end of file diff --git a/compiler/testData/psi/jetPsiMatcher/expressions/misc/_misc2.kt b/compiler/testData/psi/jetPsiMatcher/expressions/misc/_misc2.kt new file mode 100644 index 00000000000..ca5f2ff5574 --- /dev/null +++ b/compiler/testData/psi/jetPsiMatcher/expressions/misc/_misc2.kt @@ -0,0 +1,2 @@ +// NOT_EQUAL +(a.foo((n + 2)*(m - 1))[k[i]] is MyClass?) || (b.foo(n - 2)[i + 1] !is YourClass) \ No newline at end of file diff --git a/compiler/testData/psi/jetPsiMatcher/expressions/misc/_misc2.kt.2 b/compiler/testData/psi/jetPsiMatcher/expressions/misc/_misc2.kt.2 new file mode 100644 index 00000000000..f4b610a2ea8 --- /dev/null +++ b/compiler/testData/psi/jetPsiMatcher/expressions/misc/_misc2.kt.2 @@ -0,0 +1 @@ +a.foo((n + 2*m - 1))[k[i]] is MyClass? || b.foo[n - 2](i + 1) !is YourClass \ No newline at end of file diff --git a/compiler/testData/psi/jetPsiMatcher/expressions/misc/_misc3.kt b/compiler/testData/psi/jetPsiMatcher/expressions/misc/_misc3.kt new file mode 100644 index 00000000000..21f39b31af4 --- /dev/null +++ b/compiler/testData/psi/jetPsiMatcher/expressions/misc/_misc3.kt @@ -0,0 +1,2 @@ +// NOT_EQUAL +a > b[n] && (a < foo(x.bar(n + 2)) || a == n) && b[n - 1] != foo(a + 2) \ No newline at end of file diff --git a/compiler/testData/psi/jetPsiMatcher/expressions/misc/_misc3.kt.2 b/compiler/testData/psi/jetPsiMatcher/expressions/misc/_misc3.kt.2 new file mode 100644 index 00000000000..26464ee1ae7 --- /dev/null +++ b/compiler/testData/psi/jetPsiMatcher/expressions/misc/_misc3.kt.2 @@ -0,0 +1 @@ +a > b[n] && a < foo(x.bar(n + 2)) || (a == n) && (b[n - 1] != foo(a + 2)) \ No newline at end of file diff --git a/compiler/testData/psi/jetPsiMatcher/expressions/misc/misc1.kt b/compiler/testData/psi/jetPsiMatcher/expressions/misc/misc1.kt new file mode 100644 index 00000000000..a3cccb1e9b4 --- /dev/null +++ b/compiler/testData/psi/jetPsiMatcher/expressions/misc/misc1.kt @@ -0,0 +1 @@ +(a + b*x.f(n - 1)) \ No newline at end of file diff --git a/compiler/testData/psi/jetPsiMatcher/expressions/misc/misc1.kt.2 b/compiler/testData/psi/jetPsiMatcher/expressions/misc/misc1.kt.2 new file mode 100644 index 00000000000..b1a5c6058d7 --- /dev/null +++ b/compiler/testData/psi/jetPsiMatcher/expressions/misc/misc1.kt.2 @@ -0,0 +1 @@ +(a) + b*x.f(n - 1) \ No newline at end of file diff --git a/compiler/testData/psi/jetPsiMatcher/expressions/misc/misc2.kt b/compiler/testData/psi/jetPsiMatcher/expressions/misc/misc2.kt new file mode 100644 index 00000000000..0970212b5a9 --- /dev/null +++ b/compiler/testData/psi/jetPsiMatcher/expressions/misc/misc2.kt @@ -0,0 +1 @@ +(a.foo((n + 2)*(m - 1))[k[i]] is MyClass?) || (b.foo(n - 2)[i + 1] !is YourClass) \ No newline at end of file diff --git a/compiler/testData/psi/jetPsiMatcher/expressions/misc/misc2.kt.2 b/compiler/testData/psi/jetPsiMatcher/expressions/misc/misc2.kt.2 new file mode 100644 index 00000000000..4a37455cfcc --- /dev/null +++ b/compiler/testData/psi/jetPsiMatcher/expressions/misc/misc2.kt.2 @@ -0,0 +1 @@ +a.foo((n + 2)*(m - 1))[k[i]] is MyClass? || b.foo(n - 2)[i + 1] !is YourClass \ No newline at end of file diff --git a/compiler/testData/psi/jetPsiMatcher/expressions/misc/misc3.kt b/compiler/testData/psi/jetPsiMatcher/expressions/misc/misc3.kt new file mode 100644 index 00000000000..8f350410c20 --- /dev/null +++ b/compiler/testData/psi/jetPsiMatcher/expressions/misc/misc3.kt @@ -0,0 +1 @@ +a > b[n] && (a < foo(x.bar(n + 2)) || a == n) && b[n - 1] != foo(a + 2) \ No newline at end of file diff --git a/compiler/testData/psi/jetPsiMatcher/expressions/misc/misc3.kt.2 b/compiler/testData/psi/jetPsiMatcher/expressions/misc/misc3.kt.2 new file mode 100644 index 00000000000..b1fc711a891 --- /dev/null +++ b/compiler/testData/psi/jetPsiMatcher/expressions/misc/misc3.kt.2 @@ -0,0 +1 @@ +a > b[n] && (a < foo(x.bar(n + 2)) || (a == n)) && (b[n - 1] != foo(a + 2)) \ No newline at end of file diff --git a/compiler/testData/psi/jetPsiMatcher/expressions/simpleName/_simpleName.kt b/compiler/testData/psi/jetPsiMatcher/expressions/simpleName/_simpleName.kt new file mode 100644 index 00000000000..2244cd77052 --- /dev/null +++ b/compiler/testData/psi/jetPsiMatcher/expressions/simpleName/_simpleName.kt @@ -0,0 +1,2 @@ +// NOT_EQUAL +test \ No newline at end of file diff --git a/compiler/testData/psi/jetPsiMatcher/expressions/simpleName/_simpleName.kt.2 b/compiler/testData/psi/jetPsiMatcher/expressions/simpleName/_simpleName.kt.2 new file mode 100644 index 00000000000..17f7fcd1dc9 --- /dev/null +++ b/compiler/testData/psi/jetPsiMatcher/expressions/simpleName/_simpleName.kt.2 @@ -0,0 +1,2 @@ +// NOT_EQUAL +abcd \ No newline at end of file diff --git a/compiler/testData/psi/jetPsiMatcher/expressions/simpleName/simpleName.kt b/compiler/testData/psi/jetPsiMatcher/expressions/simpleName/simpleName.kt new file mode 100644 index 00000000000..30d74d25844 --- /dev/null +++ b/compiler/testData/psi/jetPsiMatcher/expressions/simpleName/simpleName.kt @@ -0,0 +1 @@ +test \ No newline at end of file diff --git a/compiler/testData/psi/jetPsiMatcher/expressions/simpleName/simpleName.kt.2 b/compiler/testData/psi/jetPsiMatcher/expressions/simpleName/simpleName.kt.2 new file mode 100644 index 00000000000..30d74d25844 --- /dev/null +++ b/compiler/testData/psi/jetPsiMatcher/expressions/simpleName/simpleName.kt.2 @@ -0,0 +1 @@ +test \ No newline at end of file diff --git a/compiler/testData/psi/jetPsiMatcher/expressions/super/_super1.kt b/compiler/testData/psi/jetPsiMatcher/expressions/super/_super1.kt new file mode 100644 index 00000000000..1f5a6ca4d7f --- /dev/null +++ b/compiler/testData/psi/jetPsiMatcher/expressions/super/_super1.kt @@ -0,0 +1,2 @@ +// NOT_EQUAL +super.foo() \ No newline at end of file diff --git a/compiler/testData/psi/jetPsiMatcher/expressions/super/_super1.kt.2 b/compiler/testData/psi/jetPsiMatcher/expressions/super/_super1.kt.2 new file mode 100644 index 00000000000..426ee4d61c0 --- /dev/null +++ b/compiler/testData/psi/jetPsiMatcher/expressions/super/_super1.kt.2 @@ -0,0 +1 @@ +super.bar() \ No newline at end of file diff --git a/compiler/testData/psi/jetPsiMatcher/expressions/super/_super2.kt b/compiler/testData/psi/jetPsiMatcher/expressions/super/_super2.kt new file mode 100644 index 00000000000..b48a3487a9b --- /dev/null +++ b/compiler/testData/psi/jetPsiMatcher/expressions/super/_super2.kt @@ -0,0 +1,2 @@ +// NOT_EQUAL +super.foo() \ No newline at end of file diff --git a/compiler/testData/psi/jetPsiMatcher/expressions/super/_super2.kt.2 b/compiler/testData/psi/jetPsiMatcher/expressions/super/_super2.kt.2 new file mode 100644 index 00000000000..c051b54557e --- /dev/null +++ b/compiler/testData/psi/jetPsiMatcher/expressions/super/_super2.kt.2 @@ -0,0 +1 @@ +super.foo() \ No newline at end of file diff --git a/compiler/testData/psi/jetPsiMatcher/expressions/super/_super3.kt b/compiler/testData/psi/jetPsiMatcher/expressions/super/_super3.kt new file mode 100644 index 00000000000..d169cbad4ef --- /dev/null +++ b/compiler/testData/psi/jetPsiMatcher/expressions/super/_super3.kt @@ -0,0 +1,2 @@ +// NOT_EQUAL +super<>.foo() \ No newline at end of file diff --git a/compiler/testData/psi/jetPsiMatcher/expressions/super/_super3.kt.2 b/compiler/testData/psi/jetPsiMatcher/expressions/super/_super3.kt.2 new file mode 100644 index 00000000000..dfe6ebb4165 --- /dev/null +++ b/compiler/testData/psi/jetPsiMatcher/expressions/super/_super3.kt.2 @@ -0,0 +1 @@ +super.foo() \ No newline at end of file diff --git a/compiler/testData/psi/jetPsiMatcher/expressions/super/_super4.kt b/compiler/testData/psi/jetPsiMatcher/expressions/super/_super4.kt new file mode 100644 index 00000000000..307bad345cc --- /dev/null +++ b/compiler/testData/psi/jetPsiMatcher/expressions/super/_super4.kt @@ -0,0 +1,2 @@ +// NOT_EQUAL +super@B.foo() \ No newline at end of file diff --git a/compiler/testData/psi/jetPsiMatcher/expressions/super/_super4.kt.2 b/compiler/testData/psi/jetPsiMatcher/expressions/super/_super4.kt.2 new file mode 100644 index 00000000000..d1e2e856f56 --- /dev/null +++ b/compiler/testData/psi/jetPsiMatcher/expressions/super/_super4.kt.2 @@ -0,0 +1 @@ +super@A.foo() \ No newline at end of file diff --git a/compiler/testData/psi/jetPsiMatcher/expressions/super/super1.kt b/compiler/testData/psi/jetPsiMatcher/expressions/super/super1.kt new file mode 100644 index 00000000000..dfe6ebb4165 --- /dev/null +++ b/compiler/testData/psi/jetPsiMatcher/expressions/super/super1.kt @@ -0,0 +1 @@ +super.foo() \ No newline at end of file diff --git a/compiler/testData/psi/jetPsiMatcher/expressions/super/super1.kt.2 b/compiler/testData/psi/jetPsiMatcher/expressions/super/super1.kt.2 new file mode 100644 index 00000000000..dfe6ebb4165 --- /dev/null +++ b/compiler/testData/psi/jetPsiMatcher/expressions/super/super1.kt.2 @@ -0,0 +1 @@ +super.foo() \ No newline at end of file diff --git a/compiler/testData/psi/jetPsiMatcher/expressions/super/super2.kt b/compiler/testData/psi/jetPsiMatcher/expressions/super/super2.kt new file mode 100644 index 00000000000..c051b54557e --- /dev/null +++ b/compiler/testData/psi/jetPsiMatcher/expressions/super/super2.kt @@ -0,0 +1 @@ +super.foo() \ No newline at end of file diff --git a/compiler/testData/psi/jetPsiMatcher/expressions/super/super2.kt.2 b/compiler/testData/psi/jetPsiMatcher/expressions/super/super2.kt.2 new file mode 100644 index 00000000000..c051b54557e --- /dev/null +++ b/compiler/testData/psi/jetPsiMatcher/expressions/super/super2.kt.2 @@ -0,0 +1 @@ +super.foo() \ No newline at end of file diff --git a/compiler/testData/psi/jetPsiMatcher/expressions/super/super3.kt b/compiler/testData/psi/jetPsiMatcher/expressions/super/super3.kt new file mode 100644 index 00000000000..64f2753245e --- /dev/null +++ b/compiler/testData/psi/jetPsiMatcher/expressions/super/super3.kt @@ -0,0 +1 @@ +super<>.foo() \ No newline at end of file diff --git a/compiler/testData/psi/jetPsiMatcher/expressions/super/super3.kt.2 b/compiler/testData/psi/jetPsiMatcher/expressions/super/super3.kt.2 new file mode 100644 index 00000000000..64f2753245e --- /dev/null +++ b/compiler/testData/psi/jetPsiMatcher/expressions/super/super3.kt.2 @@ -0,0 +1 @@ +super<>.foo() \ No newline at end of file diff --git a/compiler/testData/psi/jetPsiMatcher/expressions/super/super4.kt b/compiler/testData/psi/jetPsiMatcher/expressions/super/super4.kt new file mode 100644 index 00000000000..7520ea9ff7d --- /dev/null +++ b/compiler/testData/psi/jetPsiMatcher/expressions/super/super4.kt @@ -0,0 +1 @@ +super@label.foo() \ No newline at end of file diff --git a/compiler/testData/psi/jetPsiMatcher/expressions/super/super4.kt.2 b/compiler/testData/psi/jetPsiMatcher/expressions/super/super4.kt.2 new file mode 100644 index 00000000000..7520ea9ff7d --- /dev/null +++ b/compiler/testData/psi/jetPsiMatcher/expressions/super/super4.kt.2 @@ -0,0 +1 @@ +super@label.foo() \ No newline at end of file diff --git a/compiler/testData/psi/jetPsiMatcher/expressions/throw/_throw.kt b/compiler/testData/psi/jetPsiMatcher/expressions/throw/_throw.kt new file mode 100644 index 00000000000..cbd29c6905b --- /dev/null +++ b/compiler/testData/psi/jetPsiMatcher/expressions/throw/_throw.kt @@ -0,0 +1,2 @@ +// NOT_EQUAL +throw X() \ No newline at end of file diff --git a/compiler/testData/psi/jetPsiMatcher/expressions/throw/_throw.kt.2 b/compiler/testData/psi/jetPsiMatcher/expressions/throw/_throw.kt.2 new file mode 100644 index 00000000000..d6766b53139 --- /dev/null +++ b/compiler/testData/psi/jetPsiMatcher/expressions/throw/_throw.kt.2 @@ -0,0 +1,2 @@ +// NOT_EQUAL +throw Z() \ No newline at end of file diff --git a/compiler/testData/psi/jetPsiMatcher/expressions/throw/throw.kt b/compiler/testData/psi/jetPsiMatcher/expressions/throw/throw.kt new file mode 100644 index 00000000000..36381ca5aef --- /dev/null +++ b/compiler/testData/psi/jetPsiMatcher/expressions/throw/throw.kt @@ -0,0 +1 @@ +throw X() \ No newline at end of file diff --git a/compiler/testData/psi/jetPsiMatcher/expressions/throw/throw.kt.2 b/compiler/testData/psi/jetPsiMatcher/expressions/throw/throw.kt.2 new file mode 100644 index 00000000000..36381ca5aef --- /dev/null +++ b/compiler/testData/psi/jetPsiMatcher/expressions/throw/throw.kt.2 @@ -0,0 +1 @@ +throw X() \ No newline at end of file diff --git a/compiler/testData/psi/jetPsiMatcher/expressions/unaryExpr/_unaryExpr1.kt b/compiler/testData/psi/jetPsiMatcher/expressions/unaryExpr/_unaryExpr1.kt new file mode 100644 index 00000000000..5bfaf586de2 --- /dev/null +++ b/compiler/testData/psi/jetPsiMatcher/expressions/unaryExpr/_unaryExpr1.kt @@ -0,0 +1,2 @@ +// NOT_EQUAL +!false \ No newline at end of file diff --git a/compiler/testData/psi/jetPsiMatcher/expressions/unaryExpr/_unaryExpr1.kt.2 b/compiler/testData/psi/jetPsiMatcher/expressions/unaryExpr/_unaryExpr1.kt.2 new file mode 100644 index 00000000000..3dc7170e670 --- /dev/null +++ b/compiler/testData/psi/jetPsiMatcher/expressions/unaryExpr/_unaryExpr1.kt.2 @@ -0,0 +1 @@ +!true \ No newline at end of file diff --git a/compiler/testData/psi/jetPsiMatcher/expressions/unaryExpr/_unaryExpr2.kt b/compiler/testData/psi/jetPsiMatcher/expressions/unaryExpr/_unaryExpr2.kt new file mode 100644 index 00000000000..bf2fa63cc04 --- /dev/null +++ b/compiler/testData/psi/jetPsiMatcher/expressions/unaryExpr/_unaryExpr2.kt @@ -0,0 +1,2 @@ +// NOT_EQUAL +!a \ No newline at end of file diff --git a/compiler/testData/psi/jetPsiMatcher/expressions/unaryExpr/_unaryExpr2.kt.2 b/compiler/testData/psi/jetPsiMatcher/expressions/unaryExpr/_unaryExpr2.kt.2 new file mode 100644 index 00000000000..ce85aad2824 --- /dev/null +++ b/compiler/testData/psi/jetPsiMatcher/expressions/unaryExpr/_unaryExpr2.kt.2 @@ -0,0 +1,2 @@ +// NOT_EQUAL +++a \ No newline at end of file diff --git a/compiler/testData/psi/jetPsiMatcher/expressions/unaryExpr/_unaryExpr3.kt b/compiler/testData/psi/jetPsiMatcher/expressions/unaryExpr/_unaryExpr3.kt new file mode 100644 index 00000000000..bf2fa63cc04 --- /dev/null +++ b/compiler/testData/psi/jetPsiMatcher/expressions/unaryExpr/_unaryExpr3.kt @@ -0,0 +1,2 @@ +// NOT_EQUAL +!a \ No newline at end of file diff --git a/compiler/testData/psi/jetPsiMatcher/expressions/unaryExpr/_unaryExpr3.kt.2 b/compiler/testData/psi/jetPsiMatcher/expressions/unaryExpr/_unaryExpr3.kt.2 new file mode 100644 index 00000000000..c42c7cce71f --- /dev/null +++ b/compiler/testData/psi/jetPsiMatcher/expressions/unaryExpr/_unaryExpr3.kt.2 @@ -0,0 +1,2 @@ +// NOT_EQUAL +!x \ No newline at end of file diff --git a/compiler/testData/psi/jetPsiMatcher/expressions/unaryExpr/unaryExpr1.kt b/compiler/testData/psi/jetPsiMatcher/expressions/unaryExpr/unaryExpr1.kt new file mode 100644 index 00000000000..dfec184200f --- /dev/null +++ b/compiler/testData/psi/jetPsiMatcher/expressions/unaryExpr/unaryExpr1.kt @@ -0,0 +1 @@ +!false \ No newline at end of file diff --git a/compiler/testData/psi/jetPsiMatcher/expressions/unaryExpr/unaryExpr1.kt.2 b/compiler/testData/psi/jetPsiMatcher/expressions/unaryExpr/unaryExpr1.kt.2 new file mode 100644 index 00000000000..dfec184200f --- /dev/null +++ b/compiler/testData/psi/jetPsiMatcher/expressions/unaryExpr/unaryExpr1.kt.2 @@ -0,0 +1 @@ +!false \ No newline at end of file diff --git a/compiler/testData/psi/jetPsiMatcher/expressions/unaryExpr/unaryExpr2.kt b/compiler/testData/psi/jetPsiMatcher/expressions/unaryExpr/unaryExpr2.kt new file mode 100644 index 00000000000..fa7cdb18c3e --- /dev/null +++ b/compiler/testData/psi/jetPsiMatcher/expressions/unaryExpr/unaryExpr2.kt @@ -0,0 +1 @@ +!a \ No newline at end of file diff --git a/compiler/testData/psi/jetPsiMatcher/expressions/unaryExpr/unaryExpr2.kt.2 b/compiler/testData/psi/jetPsiMatcher/expressions/unaryExpr/unaryExpr2.kt.2 new file mode 100644 index 00000000000..fa7cdb18c3e --- /dev/null +++ b/compiler/testData/psi/jetPsiMatcher/expressions/unaryExpr/unaryExpr2.kt.2 @@ -0,0 +1 @@ +!a \ No newline at end of file diff --git a/compiler/tests/org/jetbrains/jet/lang/psi/AbstractJetPsiMatcherTest.java b/compiler/tests/org/jetbrains/jet/lang/psi/AbstractJetPsiMatcherTest.java new file mode 100644 index 00000000000..68f543b7342 --- /dev/null +++ b/compiler/tests/org/jetbrains/jet/lang/psi/AbstractJetPsiMatcherTest.java @@ -0,0 +1,48 @@ +/* + * Copyright 2010-2013 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.jetbrains.jet.lang.psi; + +import com.intellij.openapi.util.io.FileUtil; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.jet.InTextDirectivesUtils; +import org.jetbrains.jet.JetLiteFixture; +import org.jetbrains.jet.cli.jvm.compiler.JetCoreEnvironment; +import org.jetbrains.jet.config.CompilerConfiguration; + +import java.io.File; + +public abstract class AbstractJetPsiMatcherTest extends JetLiteFixture { + public void doTestExpressions(@NotNull String path) throws Exception { + String fileText = FileUtil.loadFile(new File(path)); + String fileText2 = FileUtil.loadFile(new File(path + ".2")); + + boolean equalityExpected = InTextDirectivesUtils.findStringWithPrefixes(fileText, "// NOT_EQUAL") == null; + + JetExpression expr = JetPsiFactory.createExpression(getProject(), fileText); + JetExpression expr2 = JetPsiFactory.createExpression(getProject(), fileText2); + + assertTrue( + "JetPsiMatcher.checkElementMatch() should return " + equalityExpected, + equalityExpected == JetPsiMatcher.checkElementMatch(expr, expr2) + ); + } + + @Override + protected JetCoreEnvironment createEnvironment() { + return new JetCoreEnvironment(getTestRootDisposable(), new CompilerConfiguration()); + } +} diff --git a/compiler/tests/org/jetbrains/jet/lang/psi/JetPsiMatcherTest.java b/compiler/tests/org/jetbrains/jet/lang/psi/JetPsiMatcherTest.java new file mode 100644 index 00000000000..726cc5153ed --- /dev/null +++ b/compiler/tests/org/jetbrains/jet/lang/psi/JetPsiMatcherTest.java @@ -0,0 +1,386 @@ +/* + * Copyright 2010-2013 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.jetbrains.jet.lang.psi; + +import junit.framework.Assert; +import junit.framework.Test; +import junit.framework.TestSuite; + +import java.io.File; +import java.util.regex.Pattern; +import org.jetbrains.jet.JetTestUtils; +import org.jetbrains.jet.test.InnerTestClasses; +import org.jetbrains.jet.test.TestMetadata; + +import org.jetbrains.jet.lang.psi.AbstractJetPsiMatcherTest; + +/** This class is generated by {@link org.jetbrains.jet.generators.tests.GenerateTests}. DO NOT MODIFY MANUALLY */ +@SuppressWarnings("all") +@TestMetadata("compiler/testData/psi/jetPsiMatcher") +@InnerTestClasses({JetPsiMatcherTest.Expressions.class}) +public class JetPsiMatcherTest extends AbstractJetPsiMatcherTest { + public void testAllFilesPresentInJetPsiMatcher() throws Exception { + JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.GenerateTests", new File("compiler/testData/psi/jetPsiMatcher"), Pattern.compile("^(.+)\\.kt$"), true); + } + + @TestMetadata("compiler/testData/psi/jetPsiMatcher/expressions") + @InnerTestClasses({Expressions.ArrayAccess.class, Expressions.BinaryExpr.class, Expressions.Call.class, Expressions.Const.class, Expressions.Misc.class, Expressions.SimpleName.class, Expressions.Super.class, Expressions.Throw.class, Expressions.UnaryExpr.class}) + public static class Expressions extends AbstractJetPsiMatcherTest { + public void testAllFilesPresentInExpressions() throws Exception { + JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.GenerateTests", new File("compiler/testData/psi/jetPsiMatcher/expressions"), Pattern.compile("^(.+)\\.kt$"), true); + } + + @TestMetadata("compiler/testData/psi/jetPsiMatcher/expressions/arrayAccess") + public static class ArrayAccess extends AbstractJetPsiMatcherTest { + public void testAllFilesPresentInArrayAccess() throws Exception { + JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.GenerateTests", new File("compiler/testData/psi/jetPsiMatcher/expressions/arrayAccess"), Pattern.compile("^(.+)\\.kt$"), true); + } + + @TestMetadata("arrayAccess1.kt") + public void testArrayAccess1() throws Exception { + doTestExpressions("compiler/testData/psi/jetPsiMatcher/expressions/arrayAccess/arrayAccess1.kt"); + } + + @TestMetadata("arrayAccess2.kt") + public void testArrayAccess2() throws Exception { + doTestExpressions("compiler/testData/psi/jetPsiMatcher/expressions/arrayAccess/arrayAccess2.kt"); + } + + @TestMetadata("_arrayAccess1.kt") + public void test_arrayAccess1() throws Exception { + doTestExpressions("compiler/testData/psi/jetPsiMatcher/expressions/arrayAccess/_arrayAccess1.kt"); + } + + @TestMetadata("_arrayAccess2.kt") + public void test_arrayAccess2() throws Exception { + doTestExpressions("compiler/testData/psi/jetPsiMatcher/expressions/arrayAccess/_arrayAccess2.kt"); + } + + @TestMetadata("_arrayAccess3.kt") + public void test_arrayAccess3() throws Exception { + doTestExpressions("compiler/testData/psi/jetPsiMatcher/expressions/arrayAccess/_arrayAccess3.kt"); + } + + } + + @TestMetadata("compiler/testData/psi/jetPsiMatcher/expressions/binaryExpr") + public static class BinaryExpr extends AbstractJetPsiMatcherTest { + public void testAllFilesPresentInBinaryExpr() throws Exception { + JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.GenerateTests", new File("compiler/testData/psi/jetPsiMatcher/expressions/binaryExpr"), Pattern.compile("^(.+)\\.kt$"), true); + } + + @TestMetadata("binaryExpr1.kt") + public void testBinaryExpr1() throws Exception { + doTestExpressions("compiler/testData/psi/jetPsiMatcher/expressions/binaryExpr/binaryExpr1.kt"); + } + + @TestMetadata("binaryExpr2.kt") + public void testBinaryExpr2() throws Exception { + doTestExpressions("compiler/testData/psi/jetPsiMatcher/expressions/binaryExpr/binaryExpr2.kt"); + } + + @TestMetadata("binaryExpr3.kt") + public void testBinaryExpr3() throws Exception { + doTestExpressions("compiler/testData/psi/jetPsiMatcher/expressions/binaryExpr/binaryExpr3.kt"); + } + + @TestMetadata("binaryExpr4.kt") + public void testBinaryExpr4() throws Exception { + doTestExpressions("compiler/testData/psi/jetPsiMatcher/expressions/binaryExpr/binaryExpr4.kt"); + } + + @TestMetadata("binaryExpr5.kt") + public void testBinaryExpr5() throws Exception { + doTestExpressions("compiler/testData/psi/jetPsiMatcher/expressions/binaryExpr/binaryExpr5.kt"); + } + + @TestMetadata("_binaryExpr1.kt") + public void test_binaryExpr1() throws Exception { + doTestExpressions("compiler/testData/psi/jetPsiMatcher/expressions/binaryExpr/_binaryExpr1.kt"); + } + + @TestMetadata("_binaryExpr2.kt") + public void test_binaryExpr2() throws Exception { + doTestExpressions("compiler/testData/psi/jetPsiMatcher/expressions/binaryExpr/_binaryExpr2.kt"); + } + + @TestMetadata("_binaryExpr3.kt") + public void test_binaryExpr3() throws Exception { + doTestExpressions("compiler/testData/psi/jetPsiMatcher/expressions/binaryExpr/_binaryExpr3.kt"); + } + + @TestMetadata("_binaryExpr4.kt") + public void test_binaryExpr4() throws Exception { + doTestExpressions("compiler/testData/psi/jetPsiMatcher/expressions/binaryExpr/_binaryExpr4.kt"); + } + + @TestMetadata("_binaryExpr5.kt") + public void test_binaryExpr5() throws Exception { + doTestExpressions("compiler/testData/psi/jetPsiMatcher/expressions/binaryExpr/_binaryExpr5.kt"); + } + + @TestMetadata("_binaryExpr6.kt") + public void test_binaryExpr6() throws Exception { + doTestExpressions("compiler/testData/psi/jetPsiMatcher/expressions/binaryExpr/_binaryExpr6.kt"); + } + + } + + @TestMetadata("compiler/testData/psi/jetPsiMatcher/expressions/call") + public static class Call extends AbstractJetPsiMatcherTest { + public void testAllFilesPresentInCall() throws Exception { + JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.GenerateTests", new File("compiler/testData/psi/jetPsiMatcher/expressions/call"), Pattern.compile("^(.+)\\.kt$"), true); + } + + @TestMetadata("call1.kt") + public void testCall1() throws Exception { + doTestExpressions("compiler/testData/psi/jetPsiMatcher/expressions/call/call1.kt"); + } + + @TestMetadata("call2.kt") + public void testCall2() throws Exception { + doTestExpressions("compiler/testData/psi/jetPsiMatcher/expressions/call/call2.kt"); + } + + @TestMetadata("call3.kt") + public void testCall3() throws Exception { + doTestExpressions("compiler/testData/psi/jetPsiMatcher/expressions/call/call3.kt"); + } + + @TestMetadata("call4.kt") + public void testCall4() throws Exception { + doTestExpressions("compiler/testData/psi/jetPsiMatcher/expressions/call/call4.kt"); + } + + @TestMetadata("_call1.kt") + public void test_call1() throws Exception { + doTestExpressions("compiler/testData/psi/jetPsiMatcher/expressions/call/_call1.kt"); + } + + @TestMetadata("_call2.kt") + public void test_call2() throws Exception { + doTestExpressions("compiler/testData/psi/jetPsiMatcher/expressions/call/_call2.kt"); + } + + @TestMetadata("_call3.kt") + public void test_call3() throws Exception { + doTestExpressions("compiler/testData/psi/jetPsiMatcher/expressions/call/_call3.kt"); + } + + @TestMetadata("_call4.kt") + public void test_call4() throws Exception { + doTestExpressions("compiler/testData/psi/jetPsiMatcher/expressions/call/_call4.kt"); + } + + } + + @TestMetadata("compiler/testData/psi/jetPsiMatcher/expressions/const") + public static class Const extends AbstractJetPsiMatcherTest { + public void testAllFilesPresentInConst() throws Exception { + JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.GenerateTests", new File("compiler/testData/psi/jetPsiMatcher/expressions/const"), Pattern.compile("^(.+)\\.kt$"), true); + } + + @TestMetadata("const.kt") + public void testConst() throws Exception { + doTestExpressions("compiler/testData/psi/jetPsiMatcher/expressions/const/const.kt"); + } + + @TestMetadata("_const.kt") + public void test_const() throws Exception { + doTestExpressions("compiler/testData/psi/jetPsiMatcher/expressions/const/_const.kt"); + } + + } + + @TestMetadata("compiler/testData/psi/jetPsiMatcher/expressions/misc") + public static class Misc extends AbstractJetPsiMatcherTest { + public void testAllFilesPresentInMisc() throws Exception { + JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.GenerateTests", new File("compiler/testData/psi/jetPsiMatcher/expressions/misc"), Pattern.compile("^(.+)\\.kt$"), true); + } + + @TestMetadata("misc1.kt") + public void testMisc1() throws Exception { + doTestExpressions("compiler/testData/psi/jetPsiMatcher/expressions/misc/misc1.kt"); + } + + @TestMetadata("misc2.kt") + public void testMisc2() throws Exception { + doTestExpressions("compiler/testData/psi/jetPsiMatcher/expressions/misc/misc2.kt"); + } + + @TestMetadata("misc3.kt") + public void testMisc3() throws Exception { + doTestExpressions("compiler/testData/psi/jetPsiMatcher/expressions/misc/misc3.kt"); + } + + @TestMetadata("_misc1.kt") + public void test_misc1() throws Exception { + doTestExpressions("compiler/testData/psi/jetPsiMatcher/expressions/misc/_misc1.kt"); + } + + @TestMetadata("_misc2.kt") + public void test_misc2() throws Exception { + doTestExpressions("compiler/testData/psi/jetPsiMatcher/expressions/misc/_misc2.kt"); + } + + @TestMetadata("_misc3.kt") + public void test_misc3() throws Exception { + doTestExpressions("compiler/testData/psi/jetPsiMatcher/expressions/misc/_misc3.kt"); + } + + } + + @TestMetadata("compiler/testData/psi/jetPsiMatcher/expressions/simpleName") + public static class SimpleName extends AbstractJetPsiMatcherTest { + public void testAllFilesPresentInSimpleName() throws Exception { + JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.GenerateTests", new File("compiler/testData/psi/jetPsiMatcher/expressions/simpleName"), Pattern.compile("^(.+)\\.kt$"), true); + } + + @TestMetadata("simpleName.kt") + public void testSimpleName() throws Exception { + doTestExpressions("compiler/testData/psi/jetPsiMatcher/expressions/simpleName/simpleName.kt"); + } + + @TestMetadata("_simpleName.kt") + public void test_simpleName() throws Exception { + doTestExpressions("compiler/testData/psi/jetPsiMatcher/expressions/simpleName/_simpleName.kt"); + } + + } + + @TestMetadata("compiler/testData/psi/jetPsiMatcher/expressions/super") + public static class Super extends AbstractJetPsiMatcherTest { + public void testAllFilesPresentInSuper() throws Exception { + JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.GenerateTests", new File("compiler/testData/psi/jetPsiMatcher/expressions/super"), Pattern.compile("^(.+)\\.kt$"), true); + } + + @TestMetadata("super1.kt") + public void testSuper1() throws Exception { + doTestExpressions("compiler/testData/psi/jetPsiMatcher/expressions/super/super1.kt"); + } + + @TestMetadata("super2.kt") + public void testSuper2() throws Exception { + doTestExpressions("compiler/testData/psi/jetPsiMatcher/expressions/super/super2.kt"); + } + + @TestMetadata("super3.kt") + public void testSuper3() throws Exception { + doTestExpressions("compiler/testData/psi/jetPsiMatcher/expressions/super/super3.kt"); + } + + @TestMetadata("super4.kt") + public void testSuper4() throws Exception { + doTestExpressions("compiler/testData/psi/jetPsiMatcher/expressions/super/super4.kt"); + } + + @TestMetadata("_super1.kt") + public void test_super1() throws Exception { + doTestExpressions("compiler/testData/psi/jetPsiMatcher/expressions/super/_super1.kt"); + } + + @TestMetadata("_super2.kt") + public void test_super2() throws Exception { + doTestExpressions("compiler/testData/psi/jetPsiMatcher/expressions/super/_super2.kt"); + } + + @TestMetadata("_super3.kt") + public void test_super3() throws Exception { + doTestExpressions("compiler/testData/psi/jetPsiMatcher/expressions/super/_super3.kt"); + } + + @TestMetadata("_super4.kt") + public void test_super4() throws Exception { + doTestExpressions("compiler/testData/psi/jetPsiMatcher/expressions/super/_super4.kt"); + } + + } + + @TestMetadata("compiler/testData/psi/jetPsiMatcher/expressions/throw") + public static class Throw extends AbstractJetPsiMatcherTest { + public void testAllFilesPresentInThrow() throws Exception { + JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.GenerateTests", new File("compiler/testData/psi/jetPsiMatcher/expressions/throw"), Pattern.compile("^(.+)\\.kt$"), true); + } + + @TestMetadata("throw.kt") + public void testThrow() throws Exception { + doTestExpressions("compiler/testData/psi/jetPsiMatcher/expressions/throw/throw.kt"); + } + + @TestMetadata("_throw.kt") + public void test_throw() throws Exception { + doTestExpressions("compiler/testData/psi/jetPsiMatcher/expressions/throw/_throw.kt"); + } + + } + + @TestMetadata("compiler/testData/psi/jetPsiMatcher/expressions/unaryExpr") + public static class UnaryExpr extends AbstractJetPsiMatcherTest { + public void testAllFilesPresentInUnaryExpr() throws Exception { + JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.GenerateTests", new File("compiler/testData/psi/jetPsiMatcher/expressions/unaryExpr"), Pattern.compile("^(.+)\\.kt$"), true); + } + + @TestMetadata("unaryExpr1.kt") + public void testUnaryExpr1() throws Exception { + doTestExpressions("compiler/testData/psi/jetPsiMatcher/expressions/unaryExpr/unaryExpr1.kt"); + } + + @TestMetadata("unaryExpr2.kt") + public void testUnaryExpr2() throws Exception { + doTestExpressions("compiler/testData/psi/jetPsiMatcher/expressions/unaryExpr/unaryExpr2.kt"); + } + + @TestMetadata("_unaryExpr1.kt") + public void test_unaryExpr1() throws Exception { + doTestExpressions("compiler/testData/psi/jetPsiMatcher/expressions/unaryExpr/_unaryExpr1.kt"); + } + + @TestMetadata("_unaryExpr2.kt") + public void test_unaryExpr2() throws Exception { + doTestExpressions("compiler/testData/psi/jetPsiMatcher/expressions/unaryExpr/_unaryExpr2.kt"); + } + + @TestMetadata("_unaryExpr3.kt") + public void test_unaryExpr3() throws Exception { + doTestExpressions("compiler/testData/psi/jetPsiMatcher/expressions/unaryExpr/_unaryExpr3.kt"); + } + + } + + public static Test innerSuite() { + TestSuite suite = new TestSuite("Expressions"); + suite.addTestSuite(Expressions.class); + suite.addTestSuite(ArrayAccess.class); + suite.addTestSuite(BinaryExpr.class); + suite.addTestSuite(Call.class); + suite.addTestSuite(Const.class); + suite.addTestSuite(Misc.class); + suite.addTestSuite(SimpleName.class); + suite.addTestSuite(Super.class); + suite.addTestSuite(Throw.class); + suite.addTestSuite(UnaryExpr.class); + return suite; + } + } + + public static Test suite() { + TestSuite suite = new TestSuite("JetPsiMatcherTest"); + suite.addTestSuite(JetPsiMatcherTest.class); + suite.addTest(Expressions.innerSuite()); + return suite; + } +} diff --git a/generators/org/jetbrains/jet/generators/tests/GenerateTests.java b/generators/org/jetbrains/jet/generators/tests/GenerateTests.java index ed3cde6478f..cdcda21f2e6 100644 --- a/generators/org/jetbrains/jet/generators/tests/GenerateTests.java +++ b/generators/org/jetbrains/jet/generators/tests/GenerateTests.java @@ -32,6 +32,7 @@ import org.jetbrains.jet.completion.AbstractJavaWithLibCompletionTest; import org.jetbrains.jet.completion.AbstractJetJSCompletionTest; import org.jetbrains.jet.completion.AbstractKeywordCompletionTest; import org.jetbrains.jet.jvm.compiler.*; +import org.jetbrains.jet.lang.psi.AbstractJetPsiMatcherTest; import org.jetbrains.jet.lang.resolve.lazy.AbstractLazyResolveDescriptorRendererTest; import org.jetbrains.jet.lang.resolve.lazy.AbstractLazyResolveNamespaceComparingTest; import org.jetbrains.jet.lang.resolve.lazy.AbstractLazyResolveTest; @@ -211,6 +212,13 @@ public class GenerateTests { testModel("compiler/testData/modules.xml", true, "xml", "doTest") ); + generateTest( + "compiler/tests/", + "JetPsiMatcherTest", + AbstractJetPsiMatcherTest.class, + testModel("compiler/testData/psi/jetPsiMatcher", "doTestExpressions") + ); + generateTest( "idea/tests/", "JetPsiCheckerTestGenerated", diff --git a/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/WhenUtils.java b/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/WhenUtils.java index fde43685005..1b0bb1e06db 100644 --- a/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/WhenUtils.java +++ b/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/WhenUtils.java @@ -55,7 +55,7 @@ public class WhenUtils { if (lastCandidate == null) { lastCandidate = currCandidate; } - else if (!JetPsiMatcher.checkExpressionMatch(lastCandidate, currCandidate)) return null; + else if (!JetPsiMatcher.checkElementMatch(lastCandidate, currCandidate)) return null; } } @@ -75,7 +75,7 @@ public class WhenUtils { JetWhenExpression nestedWhenExpression = (JetWhenExpression) elseBranch; return JetPsiUtil.checkWhenExpressionHasSingleElse(nestedWhenExpression) && - JetPsiMatcher.checkExpressionMatch(subject, nestedWhenExpression.getSubjectExpression()); + JetPsiMatcher.checkElementMatch(subject, nestedWhenExpression.getSubjectExpression()); } public static boolean checkIntroduceWhenSubject(@NotNull JetWhenExpression whenExpression) { From 4ab816a8880fa8808d761ae3714e997f3ac62316 Mon Sep 17 00:00:00 2001 From: Alexey Sedunov Date: Tue, 30 Apr 2013 16:52:32 +0400 Subject: [PATCH 093/249] Add nullability annotations --- .../jetbrains/jet/lang/psi/JetPsiUtil.java | 21 ++++++++++++------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetPsiUtil.java b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetPsiUtil.java index 2d130fa4faa..cb9fa86166f 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetPsiUtil.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetPsiUtil.java @@ -158,13 +158,14 @@ public class JetPsiUtil { } } - public static FqName getFQName(JetFile file) { + @NotNull + public static FqName getFQName(@NotNull JetFile file) { JetNamespaceHeader header = file.getNamespaceHeader(); return header != null ? header.getFqName() : FqName.ROOT; } @Nullable - public static FqName getFQName(JetNamedDeclaration namedDeclaration) { + public static FqName getFQName(@NotNull JetNamedDeclaration namedDeclaration) { if (namedDeclaration instanceof JetObjectDeclarationName) { JetNamedDeclaration objectDeclaration = PsiTreeUtil.getParentOfType(namedDeclaration, JetObjectDeclaration.class); if (objectDeclaration == null) { @@ -233,7 +234,7 @@ public class JetPsiUtil { } @Nullable - public static Name getShortName(JetAnnotationEntry annotation) { + public static Name getShortName(@NotNull JetAnnotationEntry annotation) { JetTypeReference typeReference = annotation.getTypeReference(); assert typeReference != null : "Annotation entry hasn't typeReference " + annotation.getText(); JetTypeElement typeElement = typeReference.getTypeElement(); @@ -247,7 +248,7 @@ public class JetPsiUtil { return null; } - public static boolean isDeprecated(JetModifierListOwner owner) { + public static boolean isDeprecated(@NotNull JetModifierListOwner owner) { JetModifierList modifierList = owner.getModifierList(); if (modifierList != null) { List annotationEntries = modifierList.getAnnotationEntries(); @@ -263,7 +264,7 @@ public class JetPsiUtil { @Nullable @IfNotParsed - public static ImportPath getImportPath(JetImportDirective importDirective) { + public static ImportPath getImportPath(@NotNull JetImportDirective importDirective) { if (PsiTreeUtil.hasErrorElements(importDirective)) { return null; } @@ -410,7 +411,7 @@ public class JetPsiUtil { return callOperationNode != null && callOperationNode.getElementType() == JetTokens.SAFE_ACCESS; } - public static boolean isFunctionLiteralWithoutDeclaredParameterTypes(JetExpression expression) { + public static boolean isFunctionLiteralWithoutDeclaredParameterTypes(@Nullable JetExpression expression) { if (!(expression instanceof JetFunctionLiteralExpression)) return false; JetFunctionLiteralExpression functionLiteral = (JetFunctionLiteralExpression) expression; for (JetParameter parameter : functionLiteral.getValueParameters()) { @@ -462,6 +463,7 @@ public class JetPsiUtil { return null; } + @Nullable public static PsiElement getTopmostParentOfTypes(@Nullable PsiElement element, @NotNull Class... parentTypes) { if (element == null) { return null; @@ -568,6 +570,7 @@ public class JetPsiUtil { } } + @Nullable private static IElementType getOperation(@NotNull JetExpression expression) { if (expression instanceof JetQualifiedExpression) { return ((JetQualifiedExpression) expression).getOperationSign(); @@ -683,6 +686,7 @@ public class JetPsiUtil { return false; } + @NotNull public static > C getBlockVariableDeclarations(@NotNull JetBlockExpression block, @NotNull C collection) { for (JetElement element : block.getStatements()) { if (element instanceof JetVariableDeclaration) { @@ -693,7 +697,7 @@ public class JetPsiUtil { return collection; } - public static boolean checkWhenExpressionHasSingleElse(JetWhenExpression whenExpression) { + public static boolean checkWhenExpressionHasSingleElse(@NotNull JetWhenExpression whenExpression) { int elseCount = 0; for (JetWhenEntry entry : whenExpression.getEntries()) { if (entry.isElse()) { @@ -703,7 +707,8 @@ public class JetPsiUtil { return (elseCount == 1); } - public static PsiElement skipTrailingWhitespacesAndComments(PsiElement element) { + @Nullable + public static PsiElement skipTrailingWhitespacesAndComments(@Nullable PsiElement element) { return PsiTreeUtil.skipSiblingsForward(element, PsiWhiteSpace.class, PsiComment.class); } From 5dc08a5d25793de94634859a2d98c0f0b4328a70 Mon Sep 17 00:00:00 2001 From: Alexey Sedunov Date: Tue, 14 May 2013 16:50:06 +0400 Subject: [PATCH 094/249] Add tests with multiple conditions types in 'when' --- .../whenWithMultipleConditionTypes.kt | 10 +++++++++ .../whenWithMultipleConditionTypes.kt.after | 12 ++++++++++ .../whenWithMultipleConditionTypes.kt | 12 ++++++++++ .../whenWithMultipleConditionTypes.kt.after | 10 +++++++++ .../whenWithMultipleConditionTypes.kt | 12 ++++++++++ .../whenWithMultipleConditionTypes.kt.after | 12 ++++++++++ .../whenWithMultipleConditionTypes.kt | 12 ++++++++++ .../whenWithMultipleConditionTypes.kt.after | 12 ++++++++++ .../CodeTransformationsTestGenerated.java | 22 ++++++++++++++++++- 9 files changed, 113 insertions(+), 1 deletion(-) create mode 100644 idea/testData/codeInsight/codeTransformations/branched/ifWhen/ifToWhen/whenWithMultipleConditionTypes.kt create mode 100644 idea/testData/codeInsight/codeTransformations/branched/ifWhen/ifToWhen/whenWithMultipleConditionTypes.kt.after create mode 100644 idea/testData/codeInsight/codeTransformations/branched/ifWhen/whenToIf/whenWithMultipleConditionTypes.kt create mode 100644 idea/testData/codeInsight/codeTransformations/branched/ifWhen/whenToIf/whenWithMultipleConditionTypes.kt.after create mode 100644 idea/testData/codeInsight/codeTransformations/branched/when/eliminateSubject/whenWithMultipleConditionTypes.kt create mode 100644 idea/testData/codeInsight/codeTransformations/branched/when/eliminateSubject/whenWithMultipleConditionTypes.kt.after create mode 100644 idea/testData/codeInsight/codeTransformations/branched/when/introduceSubject/whenWithMultipleConditionTypes.kt create mode 100644 idea/testData/codeInsight/codeTransformations/branched/when/introduceSubject/whenWithMultipleConditionTypes.kt.after diff --git a/idea/testData/codeInsight/codeTransformations/branched/ifWhen/ifToWhen/whenWithMultipleConditionTypes.kt b/idea/testData/codeInsight/codeTransformations/branched/ifWhen/ifToWhen/whenWithMultipleConditionTypes.kt new file mode 100644 index 00000000000..59da552daeb --- /dev/null +++ b/idea/testData/codeInsight/codeTransformations/branched/ifWhen/ifToWhen/whenWithMultipleConditionTypes.kt @@ -0,0 +1,10 @@ +fun test(n: Int): String { + return if (n !is Int) "???" + else if (n in 0..10) "small" + else if (n in 10..100) "average" + else if (n in 100..1000) "big" + else if (n == 1000000) "million" + else if (n !in -100..-10) "good" + else if (n is Int) "unknown" + else "unknown" +} \ No newline at end of file diff --git a/idea/testData/codeInsight/codeTransformations/branched/ifWhen/ifToWhen/whenWithMultipleConditionTypes.kt.after b/idea/testData/codeInsight/codeTransformations/branched/ifWhen/ifToWhen/whenWithMultipleConditionTypes.kt.after new file mode 100644 index 00000000000..6babe750cc6 --- /dev/null +++ b/idea/testData/codeInsight/codeTransformations/branched/ifWhen/ifToWhen/whenWithMultipleConditionTypes.kt.after @@ -0,0 +1,12 @@ +fun test(n: Int): String { + return when { + n !is Int -> "???" + n in 0..10 -> "small" + n in 10..100 -> "average" + n in 100..1000 -> "big" + n == 1000000 -> "million" + n !in -100..-10 -> "good" + n is Int -> "unknown" + else -> "unknown" + } +} \ No newline at end of file diff --git a/idea/testData/codeInsight/codeTransformations/branched/ifWhen/whenToIf/whenWithMultipleConditionTypes.kt b/idea/testData/codeInsight/codeTransformations/branched/ifWhen/whenToIf/whenWithMultipleConditionTypes.kt new file mode 100644 index 00000000000..ea4d863fb5d --- /dev/null +++ b/idea/testData/codeInsight/codeTransformations/branched/ifWhen/whenToIf/whenWithMultipleConditionTypes.kt @@ -0,0 +1,12 @@ +fun test(n: Int): String { + return when (n) { + !is Int -> "???" + in 0..10 -> "small" + in 10..100 -> "average" + in 100..1000 -> "big" + 1000000 -> "million" + !in -100..-10 -> "good" + is Int -> "unknown" + else -> "unknown" + } +} \ No newline at end of file diff --git a/idea/testData/codeInsight/codeTransformations/branched/ifWhen/whenToIf/whenWithMultipleConditionTypes.kt.after b/idea/testData/codeInsight/codeTransformations/branched/ifWhen/whenToIf/whenWithMultipleConditionTypes.kt.after new file mode 100644 index 00000000000..59da552daeb --- /dev/null +++ b/idea/testData/codeInsight/codeTransformations/branched/ifWhen/whenToIf/whenWithMultipleConditionTypes.kt.after @@ -0,0 +1,10 @@ +fun test(n: Int): String { + return if (n !is Int) "???" + else if (n in 0..10) "small" + else if (n in 10..100) "average" + else if (n in 100..1000) "big" + else if (n == 1000000) "million" + else if (n !in -100..-10) "good" + else if (n is Int) "unknown" + else "unknown" +} \ No newline at end of file diff --git a/idea/testData/codeInsight/codeTransformations/branched/when/eliminateSubject/whenWithMultipleConditionTypes.kt b/idea/testData/codeInsight/codeTransformations/branched/when/eliminateSubject/whenWithMultipleConditionTypes.kt new file mode 100644 index 00000000000..ea4d863fb5d --- /dev/null +++ b/idea/testData/codeInsight/codeTransformations/branched/when/eliminateSubject/whenWithMultipleConditionTypes.kt @@ -0,0 +1,12 @@ +fun test(n: Int): String { + return when (n) { + !is Int -> "???" + in 0..10 -> "small" + in 10..100 -> "average" + in 100..1000 -> "big" + 1000000 -> "million" + !in -100..-10 -> "good" + is Int -> "unknown" + else -> "unknown" + } +} \ No newline at end of file diff --git a/idea/testData/codeInsight/codeTransformations/branched/when/eliminateSubject/whenWithMultipleConditionTypes.kt.after b/idea/testData/codeInsight/codeTransformations/branched/when/eliminateSubject/whenWithMultipleConditionTypes.kt.after new file mode 100644 index 00000000000..6babe750cc6 --- /dev/null +++ b/idea/testData/codeInsight/codeTransformations/branched/when/eliminateSubject/whenWithMultipleConditionTypes.kt.after @@ -0,0 +1,12 @@ +fun test(n: Int): String { + return when { + n !is Int -> "???" + n in 0..10 -> "small" + n in 10..100 -> "average" + n in 100..1000 -> "big" + n == 1000000 -> "million" + n !in -100..-10 -> "good" + n is Int -> "unknown" + else -> "unknown" + } +} \ No newline at end of file diff --git a/idea/testData/codeInsight/codeTransformations/branched/when/introduceSubject/whenWithMultipleConditionTypes.kt b/idea/testData/codeInsight/codeTransformations/branched/when/introduceSubject/whenWithMultipleConditionTypes.kt new file mode 100644 index 00000000000..6babe750cc6 --- /dev/null +++ b/idea/testData/codeInsight/codeTransformations/branched/when/introduceSubject/whenWithMultipleConditionTypes.kt @@ -0,0 +1,12 @@ +fun test(n: Int): String { + return when { + n !is Int -> "???" + n in 0..10 -> "small" + n in 10..100 -> "average" + n in 100..1000 -> "big" + n == 1000000 -> "million" + n !in -100..-10 -> "good" + n is Int -> "unknown" + else -> "unknown" + } +} \ No newline at end of file diff --git a/idea/testData/codeInsight/codeTransformations/branched/when/introduceSubject/whenWithMultipleConditionTypes.kt.after b/idea/testData/codeInsight/codeTransformations/branched/when/introduceSubject/whenWithMultipleConditionTypes.kt.after new file mode 100644 index 00000000000..ea4d863fb5d --- /dev/null +++ b/idea/testData/codeInsight/codeTransformations/branched/when/introduceSubject/whenWithMultipleConditionTypes.kt.after @@ -0,0 +1,12 @@ +fun test(n: Int): String { + return when (n) { + !is Int -> "???" + in 0..10 -> "small" + in 10..100 -> "average" + in 100..1000 -> "big" + 1000000 -> "million" + !in -100..-10 -> "good" + is Int -> "unknown" + else -> "unknown" + } +} \ No newline at end of file diff --git a/idea/tests/org/jetbrains/jet/plugin/codeInsight/codeTransformations/CodeTransformationsTestGenerated.java b/idea/tests/org/jetbrains/jet/plugin/codeInsight/codeTransformations/CodeTransformationsTestGenerated.java index 71da5f98dfc..3c2918daea9 100644 --- a/idea/tests/org/jetbrains/jet/plugin/codeInsight/codeTransformations/CodeTransformationsTestGenerated.java +++ b/idea/tests/org/jetbrains/jet/plugin/codeInsight/codeTransformations/CodeTransformationsTestGenerated.java @@ -252,7 +252,7 @@ public class CodeTransformationsTestGenerated extends AbstractCodeTransformation } } - + @TestMetadata("idea/testData/codeInsight/codeTransformations/branched/unfolding/returnToIf") public static class ReturnToIf extends AbstractCodeTransformationTest { public void testAllFilesPresentInReturnToIf() throws Exception { @@ -345,6 +345,11 @@ public class CodeTransformationsTestGenerated extends AbstractCodeTransformation doTestIfToWhen("idea/testData/codeInsight/codeTransformations/branched/ifWhen/ifToWhen/ifWithRangeTestsAndUnparenthesizedMultiConditions.kt"); } + @TestMetadata("whenWithMultipleConditionTypes.kt") + public void testWhenWithMultipleConditionTypes() throws Exception { + doTestIfToWhen("idea/testData/codeInsight/codeTransformations/branched/ifWhen/ifToWhen/whenWithMultipleConditionTypes.kt"); + } + } @TestMetadata("idea/testData/codeInsight/codeTransformations/branched/ifWhen/whenToIf") @@ -363,6 +368,11 @@ public class CodeTransformationsTestGenerated extends AbstractCodeTransformation doTestWhenToIf("idea/testData/codeInsight/codeTransformations/branched/ifWhen/whenToIf/whenWithMultiConditions.kt"); } + @TestMetadata("whenWithMultipleConditionTypes.kt") + public void testWhenWithMultipleConditionTypes() throws Exception { + doTestWhenToIf("idea/testData/codeInsight/codeTransformations/branched/ifWhen/whenToIf/whenWithMultipleConditionTypes.kt"); + } + @TestMetadata("whenWithNegativePatterns.kt") public void testWhenWithNegativePatterns() throws Exception { doTestWhenToIf("idea/testData/codeInsight/codeTransformations/branched/ifWhen/whenToIf/whenWithNegativePatterns.kt"); @@ -429,6 +439,11 @@ public class CodeTransformationsTestGenerated extends AbstractCodeTransformation doTestIntroduceWhenSubject("idea/testData/codeInsight/codeTransformations/branched/when/introduceSubject/whenWithEqualityTests.kt"); } + @TestMetadata("whenWithMultipleConditionTypes.kt") + public void testWhenWithMultipleConditionTypes() throws Exception { + doTestIntroduceWhenSubject("idea/testData/codeInsight/codeTransformations/branched/when/introduceSubject/whenWithMultipleConditionTypes.kt"); + } + @TestMetadata("whenWithNegativePatterns.kt") public void testWhenWithNegativePatterns() throws Exception { doTestIntroduceWhenSubject("idea/testData/codeInsight/codeTransformations/branched/when/introduceSubject/whenWithNegativePatterns.kt"); @@ -482,6 +497,11 @@ public class CodeTransformationsTestGenerated extends AbstractCodeTransformation doTestEliminateWhenSubject("idea/testData/codeInsight/codeTransformations/branched/when/eliminateSubject/whenWithEqualityTests.kt"); } + @TestMetadata("whenWithMultipleConditionTypes.kt") + public void testWhenWithMultipleConditionTypes() throws Exception { + doTestEliminateWhenSubject("idea/testData/codeInsight/codeTransformations/branched/when/eliminateSubject/whenWithMultipleConditionTypes.kt"); + } + @TestMetadata("whenWithNegativePatterns.kt") public void testWhenWithNegativePatterns() throws Exception { doTestEliminateWhenSubject("idea/testData/codeInsight/codeTransformations/branched/when/eliminateSubject/whenWithNegativePatterns.kt"); From 82bd796bc007ccae2dcf69228c151e593036e456 Mon Sep 17 00:00:00 2001 From: Alexey Sedunov Date: Tue, 14 May 2013 17:36:56 +0400 Subject: [PATCH 095/249] Add editor reference to transform() method --- .../AbstractCodeTransformationIntention.java | 2 +- .../BranchedUnfoldingUtils.java | 5 +++-- .../branchedTransformations/FoldableKind.java | 11 ++++++----- .../branchedTransformations/UnfoldableKind.java | 13 +++++++------ .../branchedTransformations/core/Transformer.java | 5 +++-- .../intentions/EliminateWhenSubjectIntention.java | 3 ++- .../intentions/FlattenWhenIntention.java | 3 ++- .../intentions/IfToWhenIntention.java | 3 ++- .../intentions/IntroduceWhenSubjectIntention.java | 3 ++- .../intentions/WhenToIfIntention.java | 3 ++- 10 files changed, 30 insertions(+), 21 deletions(-) diff --git a/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/AbstractCodeTransformationIntention.java b/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/AbstractCodeTransformationIntention.java index 28a55d3214b..f30ceb3a156 100644 --- a/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/AbstractCodeTransformationIntention.java +++ b/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/AbstractCodeTransformationIntention.java @@ -63,6 +63,6 @@ public abstract class AbstractCodeTransformationIntention assert target != null : "Intention is not applicable"; - transformer.transform(target); + transformer.transform(target, editor); } } diff --git a/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/BranchedUnfoldingUtils.java b/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/BranchedUnfoldingUtils.java index e713c50468a..406478d7efc 100644 --- a/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/BranchedUnfoldingUtils.java +++ b/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/BranchedUnfoldingUtils.java @@ -16,6 +16,7 @@ package org.jetbrains.jet.plugin.codeInsight.codeTransformations.branchedTransformations; +import com.intellij.openapi.editor.Editor; import com.intellij.openapi.project.Project; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -57,7 +58,7 @@ public class BranchedUnfoldingUtils { assert expression != null : UNFOLD_WITHOUT_CHECK; } - public static void unfoldAssignmentToIf(@NotNull JetBinaryExpression assignment) { + public static void unfoldAssignmentToIf(@NotNull JetBinaryExpression assignment, @NotNull Editor editor) { Project project = assignment.getProject(); String op = assignment.getOperationReference().getText(); JetExpression lhs = assignment.getLeft(); @@ -81,7 +82,7 @@ public class BranchedUnfoldingUtils { assignment.replace(newIfExpression); } - public static void unfoldAssignmentToWhen(@NotNull JetBinaryExpression assignment) { + public static void unfoldAssignmentToWhen(@NotNull JetBinaryExpression assignment, @NotNull Editor editor) { Project project = assignment.getProject(); String op = assignment.getOperationReference().getText(); JetExpression lhs = assignment.getLeft(); diff --git a/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/FoldableKind.java b/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/FoldableKind.java index 0bc3b8e9ac1..e8503d216c0 100644 --- a/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/FoldableKind.java +++ b/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/FoldableKind.java @@ -16,6 +16,7 @@ package org.jetbrains.jet.plugin.codeInsight.codeTransformations.branchedTransformations; +import com.intellij.openapi.editor.Editor; import com.intellij.psi.PsiElement; import org.jetbrains.annotations.NotNull; import org.jetbrains.jet.lang.psi.JetIfExpression; @@ -25,31 +26,31 @@ import org.jetbrains.jet.plugin.codeInsight.codeTransformations.branchedTransfor public enum FoldableKind implements Transformer { IF_TO_ASSIGNMENT("fold.if.to.assignment") { @Override - public void transform(@NotNull PsiElement element) { + public void transform(@NotNull PsiElement element, @NotNull Editor editor) { BranchedFoldingUtils.foldIfExpressionWithAssignments((JetIfExpression) element); } }, IF_TO_RETURN("fold.if.to.return") { @Override - public void transform(@NotNull PsiElement element) { + public void transform(@NotNull PsiElement element, @NotNull Editor editor) { BranchedFoldingUtils.foldIfExpressionWithReturns((JetIfExpression) element); } }, IF_TO_RETURN_ASYMMETRICALLY("fold.if.to.return") { @Override - public void transform(@NotNull PsiElement element) { + public void transform(@NotNull PsiElement element, @NotNull Editor editor) { BranchedFoldingUtils.foldIfExpressionWithAsymmetricReturns((JetIfExpression) element); } }, WHEN_TO_ASSIGNMENT("fold.when.to.assignment") { @Override - public void transform(@NotNull PsiElement element) { + public void transform(@NotNull PsiElement element, @NotNull Editor editor) { BranchedFoldingUtils.foldWhenExpressionWithAssignments((JetWhenExpression) element); } }, WHEN_TO_RETURN("fold.when.to.return") { @Override - public void transform(@NotNull PsiElement element) { + public void transform(@NotNull PsiElement element, @NotNull Editor editor) { BranchedFoldingUtils.foldWhenExpressionWithReturns((JetWhenExpression) element); } }; diff --git a/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/UnfoldableKind.java b/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/UnfoldableKind.java index c27b330118f..07bf3f3134f 100644 --- a/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/UnfoldableKind.java +++ b/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/UnfoldableKind.java @@ -16,6 +16,7 @@ package org.jetbrains.jet.plugin.codeInsight.codeTransformations.branchedTransformations; +import com.intellij.openapi.editor.Editor; import com.intellij.psi.PsiElement; import org.jetbrains.annotations.NotNull; import org.jetbrains.jet.lang.psi.JetBinaryExpression; @@ -25,25 +26,25 @@ import org.jetbrains.jet.plugin.codeInsight.codeTransformations.branchedTransfor public enum UnfoldableKind implements Transformer { ASSIGNMENT_TO_IF("unfold.assignment.to.if") { @Override - public void transform(@NotNull PsiElement element) { - BranchedUnfoldingUtils.unfoldAssignmentToIf((JetBinaryExpression) element); + public void transform(@NotNull PsiElement element, @NotNull Editor editor) { + BranchedUnfoldingUtils.unfoldAssignmentToIf((JetBinaryExpression) element, editor); } }, RETURN_TO_IF("unfold.return.to.if") { @Override - public void transform(@NotNull PsiElement element) { + public void transform(@NotNull PsiElement element, @NotNull Editor editor) { BranchedUnfoldingUtils.unfoldReturnToIf((JetReturnExpression) element); } }, ASSIGNMENT_TO_WHEN("unfold.assignment.to.when") { @Override - public void transform(@NotNull PsiElement element) { - BranchedUnfoldingUtils.unfoldAssignmentToWhen((JetBinaryExpression) element); + public void transform(@NotNull PsiElement element, @NotNull Editor editor) { + BranchedUnfoldingUtils.unfoldAssignmentToWhen((JetBinaryExpression) element, editor); } }, RETURN_TO_WHEN("unfold.return.to.when") { @Override - public void transform(@NotNull PsiElement element) { + public void transform(@NotNull PsiElement element, @NotNull Editor editor) { BranchedUnfoldingUtils.unfoldReturnToWhen((JetReturnExpression) element); } }; diff --git a/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/core/Transformer.java b/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/core/Transformer.java index 1693b4b40b8..82f5154f2aa 100644 --- a/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/core/Transformer.java +++ b/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/core/Transformer.java @@ -16,11 +16,12 @@ package org.jetbrains.jet.plugin.codeInsight.codeTransformations.branchedTransformations.core; +import com.intellij.openapi.editor.Editor; import com.intellij.psi.PsiElement; import org.jetbrains.annotations.NotNull; public interface Transformer { @NotNull - public String getKey(); - public void transform(@NotNull PsiElement element); + String getKey(); + void transform(@NotNull PsiElement element, @NotNull Editor editor); } diff --git a/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/intentions/EliminateWhenSubjectIntention.java b/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/intentions/EliminateWhenSubjectIntention.java index 3ca7101fcf1..225a36b770a 100644 --- a/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/intentions/EliminateWhenSubjectIntention.java +++ b/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/intentions/EliminateWhenSubjectIntention.java @@ -1,6 +1,7 @@ package org.jetbrains.jet.plugin.codeInsight.codeTransformations.branchedTransformations.intentions; import com.google.common.base.Predicate; +import com.intellij.openapi.editor.Editor; import com.intellij.psi.PsiElement; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -18,7 +19,7 @@ public class EliminateWhenSubjectIntention extends AbstractCodeTransformationInt } @Override - public void transform(@NotNull PsiElement element) { + public void transform(@NotNull PsiElement element, @NotNull Editor editor) { WhenUtils.eliminateWhenSubject((JetWhenExpression) element); } }; diff --git a/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/intentions/FlattenWhenIntention.java b/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/intentions/FlattenWhenIntention.java index c7df460ee97..6cc9dc00320 100644 --- a/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/intentions/FlattenWhenIntention.java +++ b/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/intentions/FlattenWhenIntention.java @@ -1,6 +1,7 @@ package org.jetbrains.jet.plugin.codeInsight.codeTransformations.branchedTransformations.intentions; import com.google.common.base.Predicate; +import com.intellij.openapi.editor.Editor; import com.intellij.psi.PsiElement; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -18,7 +19,7 @@ public class FlattenWhenIntention extends AbstractCodeTransformationIntention Date: Tue, 14 May 2013 17:38:13 +0400 Subject: [PATCH 096/249] Fix caret positioning in unfolded assignments --- .../BranchedUnfoldingUtils.java | 9 +++++++-- .../simpleIfWithComplexAssignmentLHS.kt | 7 +++++++ .../simpleIfWithComplexAssignmentLHS.kt.after | 7 +++++++ .../simpleWhenWithComplexAssignmentLHS.kt | 12 ++++++++++++ .../simpleWhenWithComplexAssignmentLHS.kt.after | 12 ++++++++++++ .../CodeTransformationsTestGenerated.java | 12 +++++++++++- 6 files changed, 56 insertions(+), 3 deletions(-) create mode 100644 idea/testData/codeInsight/codeTransformations/branched/unfolding/assignmentToIf/simpleIfWithComplexAssignmentLHS.kt create mode 100644 idea/testData/codeInsight/codeTransformations/branched/unfolding/assignmentToIf/simpleIfWithComplexAssignmentLHS.kt.after create mode 100644 idea/testData/codeInsight/codeTransformations/branched/unfolding/assignmentToWhen/simpleWhenWithComplexAssignmentLHS.kt create mode 100644 idea/testData/codeInsight/codeTransformations/branched/unfolding/assignmentToWhen/simpleWhenWithComplexAssignmentLHS.kt.after diff --git a/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/BranchedUnfoldingUtils.java b/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/BranchedUnfoldingUtils.java index 406478d7efc..e45924b8b12 100644 --- a/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/BranchedUnfoldingUtils.java +++ b/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/BranchedUnfoldingUtils.java @@ -18,6 +18,7 @@ package org.jetbrains.jet.plugin.codeInsight.codeTransformations.branchedTransfo import com.intellij.openapi.editor.Editor; import com.intellij.openapi.project.Project; +import com.intellij.psi.PsiElement; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.jet.lang.psi.*; @@ -79,7 +80,9 @@ public class BranchedUnfoldingUtils { thenExpr.replace(JetPsiFactory.createBinaryExpression(project, lhs, op, thenExpr)); elseExpr.replace(JetPsiFactory.createBinaryExpression(project, lhs, op, elseExpr)); - assignment.replace(newIfExpression); + PsiElement resultElement = assignment.replace(newIfExpression); + + editor.getCaretModel().moveToOffset(resultElement.getTextOffset()); } public static void unfoldAssignmentToWhen(@NotNull JetBinaryExpression assignment, @NotNull Editor editor) { @@ -102,7 +105,9 @@ public class BranchedUnfoldingUtils { currExpr.replace(JetPsiFactory.createBinaryExpression(project, lhs, op, currExpr)); } - assignment.replace(newWhenExpression); + PsiElement resultElement = assignment.replace(newWhenExpression); + + editor.getCaretModel().moveToOffset(resultElement.getTextOffset()); } public static void unfoldReturnToIf(@NotNull JetReturnExpression returnExpression) { diff --git a/idea/testData/codeInsight/codeTransformations/branched/unfolding/assignmentToIf/simpleIfWithComplexAssignmentLHS.kt b/idea/testData/codeInsight/codeTransformations/branched/unfolding/assignmentToIf/simpleIfWithComplexAssignmentLHS.kt new file mode 100644 index 00000000000..95b23707c7f --- /dev/null +++ b/idea/testData/codeInsight/codeTransformations/branched/unfolding/assignmentToIf/simpleIfWithComplexAssignmentLHS.kt @@ -0,0 +1,7 @@ +fun test(n: Int): Array { + var x: Array = Array(1, {""}) + + x[0] = if (n > 5) "A" else "B" + + return x +} diff --git a/idea/testData/codeInsight/codeTransformations/branched/unfolding/assignmentToIf/simpleIfWithComplexAssignmentLHS.kt.after b/idea/testData/codeInsight/codeTransformations/branched/unfolding/assignmentToIf/simpleIfWithComplexAssignmentLHS.kt.after new file mode 100644 index 00000000000..5357d193e43 --- /dev/null +++ b/idea/testData/codeInsight/codeTransformations/branched/unfolding/assignmentToIf/simpleIfWithComplexAssignmentLHS.kt.after @@ -0,0 +1,7 @@ +fun test(n: Int): Array { + var x: Array = Array(1, {""}) + + if (n > 5) x[0] = "A" else x[0] = "B" + + return x +} diff --git a/idea/testData/codeInsight/codeTransformations/branched/unfolding/assignmentToWhen/simpleWhenWithComplexAssignmentLHS.kt b/idea/testData/codeInsight/codeTransformations/branched/unfolding/assignmentToWhen/simpleWhenWithComplexAssignmentLHS.kt new file mode 100644 index 00000000000..61387c22de6 --- /dev/null +++ b/idea/testData/codeInsight/codeTransformations/branched/unfolding/assignmentToWhen/simpleWhenWithComplexAssignmentLHS.kt @@ -0,0 +1,12 @@ +fun test(n: Int): Array { + var x: Array = Array(1, {""}) + + x[0] = when(n) { + in 0..10 -> "small" + in 10..100 -> "average" + in 100..1000 -> "big" + else -> "unknown" + } + + return x +} diff --git a/idea/testData/codeInsight/codeTransformations/branched/unfolding/assignmentToWhen/simpleWhenWithComplexAssignmentLHS.kt.after b/idea/testData/codeInsight/codeTransformations/branched/unfolding/assignmentToWhen/simpleWhenWithComplexAssignmentLHS.kt.after new file mode 100644 index 00000000000..627976ee478 --- /dev/null +++ b/idea/testData/codeInsight/codeTransformations/branched/unfolding/assignmentToWhen/simpleWhenWithComplexAssignmentLHS.kt.after @@ -0,0 +1,12 @@ +fun test(n: Int): Array { + var x: Array = Array(1, {""}) + + when(n) { + in 0..10 -> x[0] = "small" + in 10..100 -> x[0] = "average" + in 100..1000 -> x[0] = "big" + else -> x[0] = "unknown" + } + + return x +} diff --git a/idea/tests/org/jetbrains/jet/plugin/codeInsight/codeTransformations/CodeTransformationsTestGenerated.java b/idea/tests/org/jetbrains/jet/plugin/codeInsight/codeTransformations/CodeTransformationsTestGenerated.java index 3c2918daea9..ab6c63001dd 100644 --- a/idea/tests/org/jetbrains/jet/plugin/codeInsight/codeTransformations/CodeTransformationsTestGenerated.java +++ b/idea/tests/org/jetbrains/jet/plugin/codeInsight/codeTransformations/CodeTransformationsTestGenerated.java @@ -223,6 +223,11 @@ public class CodeTransformationsTestGenerated extends AbstractCodeTransformation doTestUnfoldAssignmentToIf("idea/testData/codeInsight/codeTransformations/branched/unfolding/assignmentToIf/simpleIfWithBlocks.kt"); } + @TestMetadata("simpleIfWithComplexAssignmentLHS.kt") + public void testSimpleIfWithComplexAssignmentLHS() throws Exception { + doTestUnfoldAssignmentToIf("idea/testData/codeInsight/codeTransformations/branched/unfolding/assignmentToIf/simpleIfWithComplexAssignmentLHS.kt"); + } + @TestMetadata("simpleIfWithoutAssignment.kt") public void testSimpleIfWithoutAssignment() throws Exception { doTestUnfoldAssignmentToIf("idea/testData/codeInsight/codeTransformations/branched/unfolding/assignmentToIf/simpleIfWithoutAssignment.kt"); @@ -251,8 +256,13 @@ public class CodeTransformationsTestGenerated extends AbstractCodeTransformation doTestUnfoldAssignmentToWhen("idea/testData/codeInsight/codeTransformations/branched/unfolding/assignmentToWhen/simpleWhenWithBlocks.kt"); } + @TestMetadata("simpleWhenWithComplexAssignmentLHS.kt") + public void testSimpleWhenWithComplexAssignmentLHS() throws Exception { + doTestUnfoldAssignmentToWhen("idea/testData/codeInsight/codeTransformations/branched/unfolding/assignmentToWhen/simpleWhenWithComplexAssignmentLHS.kt"); + } + } - + @TestMetadata("idea/testData/codeInsight/codeTransformations/branched/unfolding/returnToIf") public static class ReturnToIf extends AbstractCodeTransformationTest { public void testAllFilesPresentInReturnToIf() throws Exception { From b2b7bce99a4a3aca52851059cb0db0d37a14472e Mon Sep 17 00:00:00 2001 From: Alexey Sedunov Date: Wed, 15 May 2013 14:02:32 +0400 Subject: [PATCH 097/249] Relax transformation assertions --- .../jetbrains/jet/lang/psi/JetPsiFactory.java | 64 ++++++------------- .../jet/lang/psi/JetPsiUnparsingUtils.java | 16 +++-- .../branchedTransformations/IfWhenUtils.java | 28 ++++---- .../branchedTransformations/WhenUtils.java | 44 ++----------- 4 files changed, 52 insertions(+), 100 deletions(-) diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetPsiFactory.java b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetPsiFactory.java index 77918af1f81..c349daa3c95 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetPsiFactory.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetPsiFactory.java @@ -255,8 +255,8 @@ public class JetPsiFactory { } @NotNull - public static JetBinaryExpression createBinaryExpression(Project project, @NotNull JetExpression lhs, @NotNull String op, @NotNull JetExpression rhs) { - return createBinaryExpression(project, lhs.getText(), op, rhs.getText()); + public static JetBinaryExpression createBinaryExpression(Project project, @Nullable JetExpression lhs, @NotNull String op, @Nullable JetExpression rhs) { + return createBinaryExpression(project, lhs != null ? lhs.getText() : "", op, rhs != null ? rhs.getText() : ""); } public static JetTypeCodeFragment createTypeCodeFragment(Project project, String text, PsiElement context) { @@ -267,29 +267,19 @@ public class JetPsiFactory { return new JetExpressionCodeFragmentImpl(project, "fragment.kt", text, context); } - @NotNull - public static JetIsExpression createIsExpression(Project project, @NotNull String lhs, @NotNull String rhs, boolean negated) { - return (JetIsExpression) createExpression(project, lhs + " " + (negated ? "!is" : "is") + " " + rhs); - } - - @NotNull - public static JetIsExpression createIsExpression(Project project, @NotNull JetExpression lhs, @NotNull JetTypeReference rhs, boolean negated) { - return createIsExpression(project, lhs.getText(), rhs.getText(), negated); - } - @NotNull public static JetReturnExpression createReturn(Project project, @NotNull String text) { return (JetReturnExpression) createExpression(project, "return " + text); } @NotNull - public static JetReturnExpression createReturn(Project project, @NotNull JetExpression expression) { - return createReturn(project, expression.getText()); + public static JetReturnExpression createReturn(Project project, @Nullable JetExpression expression) { + return createReturn(project, expression != null ? expression.getText() : ""); } @NotNull public static JetIfExpression createIf(Project project, - @NotNull JetExpression condition, @NotNull JetExpression thenExpr, @Nullable JetExpression elseExpr) { + @Nullable JetExpression condition, @Nullable JetExpression thenExpr, @Nullable JetExpression elseExpr) { return (JetIfExpression) createExpression(project, JetPsiUnparsingUtils.toIf(condition, thenExpr, elseExpr)); } @@ -325,8 +315,8 @@ public class JetPsiFactory { } @NotNull - public IfChainBuilder elseBranch(@NotNull JetExpression expression) { - return elseBranch(expression.getText()); + public IfChainBuilder elseBranch(@Nullable JetExpression expression) { + return elseBranch(expression != null ? expression.getText() : ""); } @NotNull @@ -373,8 +363,8 @@ public class JetPsiFactory { } @NotNull - public WhenBuilder condition(@NotNull JetExpression expression) { - return condition(expression.getText()); + public WhenBuilder condition(@Nullable JetExpression expression) { + return condition(expression != null ? expression.getText() : ""); } @NotNull @@ -383,8 +373,8 @@ public class JetPsiFactory { } @NotNull - public WhenBuilder pattern(@NotNull JetTypeReference typeReference, boolean negated) { - return pattern(typeReference.getText(), negated); + public WhenBuilder pattern(@Nullable JetTypeReference typeReference, boolean negated) { + return pattern(typeReference != null ? typeReference.getText() : "", negated); } @NotNull @@ -393,8 +383,8 @@ public class JetPsiFactory { } @NotNull - public WhenBuilder range(@NotNull JetExpression argument, boolean negated) { - return range(argument.getText(), negated); + public WhenBuilder range(@Nullable JetExpression argument, boolean negated) { + return range(argument != null ? argument.getText() : "", negated); } @NotNull @@ -409,8 +399,8 @@ public class JetPsiFactory { } @NotNull - public WhenBuilder branchExpression(@NotNull JetExpression expression) { - return branchExpression(expression.getText()); + public WhenBuilder branchExpression(@Nullable JetExpression expression) { + return branchExpression(expression != null ? expression.getText() : ""); } @NotNull @@ -424,8 +414,8 @@ public class JetPsiFactory { } @NotNull - public WhenBuilder entry(@NotNull JetWhenEntry whenEntry) { - return entry(whenEntry.getText()); + public WhenBuilder entry(@Nullable JetWhenEntry whenEntry) { + return entry(whenEntry != null ? whenEntry.getText() : ""); } @NotNull @@ -434,8 +424,8 @@ public class JetPsiFactory { } @NotNull - public WhenBuilder elseEntry(@NotNull JetExpression expression) { - return elseEntry(expression.getText()); + public WhenBuilder elseEntry(@Nullable JetExpression expression) { + return elseEntry(expression != null ? expression.getText() : ""); } @NotNull @@ -447,20 +437,4 @@ public class JetPsiFactory { return (JetWhenExpression) createExpression(project, sb.toString()); } } - - @NotNull - public static JetParenthesizedExpression createParenthesizedExpression(Project project, @NotNull String text) { - return (JetParenthesizedExpression) createExpression(project, "(" + text + ")"); - } - - @NotNull - public static JetParenthesizedExpression createParenthesizedExpression(Project project, @NotNull JetExpression expression) { - return createParenthesizedExpression(project, expression.getText()); - } - - @NotNull - public static JetParenthesizedExpression createParenthesizedExpressionIfNeeded(Project project, @NotNull JetExpression expression) { - return (expression instanceof JetParenthesizedExpression) ? - (JetParenthesizedExpression) expression : createParenthesizedExpression(project, expression); - } } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetPsiUnparsingUtils.java b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetPsiUnparsingUtils.java index 7995a3fbab2..ed3b8a7adfe 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetPsiUnparsingUtils.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetPsiUnparsingUtils.java @@ -24,8 +24,12 @@ public class JetPsiUnparsingUtils { } @NotNull - public static String toIf(@NotNull JetExpression condition, @NotNull JetExpression thenExpression, @Nullable JetExpression elseExpression) { - return toIf(condition.getText(), thenExpression.getText(), elseExpression != null ? elseExpression.getText() : null); + public static String toIf(@Nullable JetExpression condition, @Nullable JetExpression thenExpression, @Nullable JetExpression elseExpression) { + return toIf( + condition != null ? condition.getText() : "", + thenExpression != null ? thenExpression.getText() : "", + elseExpression != null ? elseExpression.getText() : null + ); } @NotNull @@ -34,8 +38,8 @@ public class JetPsiUnparsingUtils { } @NotNull - public static String toBinaryExpression(@NotNull JetExpression left, @NotNull String op, @NotNull JetElement right) { - return toBinaryExpression(left.getText(), op, right.getText()); + public static String toBinaryExpression(@Nullable JetExpression left, @NotNull String op, @Nullable JetElement right) { + return toBinaryExpression(left != null ? left.getText() : "", op, right != null ? right.getText() : ""); } @NotNull @@ -44,7 +48,9 @@ public class JetPsiUnparsingUtils { } @NotNull - public static String parenthesizeIfNeeded(@NotNull JetExpression expression) { + public static String parenthesizeIfNeeded(@Nullable JetExpression expression) { + if (expression == null) return ""; + String text = expression.getText(); return (expression instanceof JetParenthesizedExpression || expression instanceof JetConstantExpression || diff --git a/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/IfWhenUtils.java b/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/IfWhenUtils.java index 020a7076f0b..5d7fabec852 100644 --- a/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/IfWhenUtils.java +++ b/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/IfWhenUtils.java @@ -1,10 +1,12 @@ package org.jetbrains.jet.plugin.codeInsight.codeTransformations.branchedTransformations; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import org.jetbrains.jet.lang.psi.*; import org.jetbrains.jet.lexer.JetTokens; import java.util.ArrayList; +import java.util.Collections; import java.util.List; import static org.jetbrains.jet.lang.psi.JetPsiUnparsingUtils.*; @@ -18,7 +20,7 @@ public class IfWhenUtils { } public static boolean checkIfToWhen(@NotNull JetIfExpression ifExpression) { - return ifExpression.getCondition() != null && ifExpression.getThen() != null && ifExpression.getElse() != null; + return ifExpression.getThen() != null && ifExpression.getElse() != null; } public static boolean checkWhenToIf(@NotNull JetWhenExpression whenExpression) { @@ -29,7 +31,9 @@ public class IfWhenUtils { assert expression != null : TRANSFORM_WITHOUT_CHECK; } - private static List splitExpressionToOrBranches(JetExpression expression) { + private static List splitExpressionToOrBranches(@Nullable JetExpression expression) { + if (expression == null) return Collections.emptyList(); + final List branches = new ArrayList(); expression.accept( @@ -80,14 +84,19 @@ public class IfWhenUtils { JetExpression thenBranch = currIfExpression.getThen(); JetExpression elseBranch = currIfExpression.getElse(); - assertNotNull(condition); assertNotNull(thenBranch); assertNotNull(elseBranch); List orBranches = splitExpressionToOrBranches(condition); - for (JetExpression orBranch : orBranches) { - builder.condition(orBranch); + + if (orBranches.isEmpty()) { + builder.condition(""); + } else { + for (JetExpression orBranch : orBranches) { + builder.condition(orBranch); + } } + //noinspection ConstantConditions builder.branchExpression(thenBranch); @@ -135,19 +144,12 @@ public class IfWhenUtils { List entries = whenExpression.getEntries(); for (JetWhenEntry entry : entries) { JetExpression branch = entry.getExpression(); - assertNotNull(branch); if (entry.isElse()) { - //noinspection ConstantConditions builder.elseBranch(branch); } else { String branchConditionText = combineWhenConditions(entry.getConditions(), whenExpression.getSubjectExpression()); - - JetExpression branchExpression = entry.getExpression(); - assertNotNull(branchExpression); - - //noinspection ConstantConditions - builder.ifBranch(branchConditionText, branchExpression.getText()); + builder.ifBranch(branchConditionText, branch != null ? branch.getText() : ""); } } diff --git a/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/WhenUtils.java b/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/WhenUtils.java index 1b0bb1e06db..fbe4d9236f2 100644 --- a/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/WhenUtils.java +++ b/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/WhenUtils.java @@ -120,10 +120,8 @@ public class WhenUtils { for (JetWhenEntry entry : whenExpression.getEntries()) { JetExpression branchExpression = entry.getExpression(); - assertNotNull(branchExpression); if (entry.isElse()) { - //noinspection ConstantConditions builder.elseEntry(branchExpression); continue; } @@ -135,30 +133,21 @@ public class WhenUtils { if (conditionExpression instanceof JetIsExpression) { JetIsExpression isExpression = (JetIsExpression) conditionExpression; - - JetTypeReference typeReference = isExpression.getTypeRef(); - assertNotNull(typeReference); - - //noinspection ConstantConditions - builder.pattern(typeReference, isExpression.isNegated()); + builder.pattern(isExpression.getTypeRef(), isExpression.isNegated()); } else if (conditionExpression instanceof JetBinaryExpression) { JetBinaryExpression binaryExpression = (JetBinaryExpression) conditionExpression; JetExpression rhs = binaryExpression.getRight(); - assertNotNull(rhs); IElementType op = binaryExpression.getOperationToken(); if (op == JetTokens.IN_KEYWORD) { - //noinspection ConstantConditions builder.range(rhs, false); } else if (op == JetTokens.NOT_IN) { - //noinspection ConstantConditions builder.range(rhs, true); } else if (op == JetTokens.EQEQ) { - //noinspection ConstantConditions builder.condition(rhs); } else assert false : TRANSFORM_WITHOUT_CHECK; @@ -166,7 +155,6 @@ public class WhenUtils { else assert false : TRANSFORM_WITHOUT_CHECK; } - //noinspection ConstantConditions builder.branchExpression(branchExpression); } @@ -176,37 +164,22 @@ public class WhenUtils { static String whenConditionToExpressionText(@NotNull JetWhenCondition condition, JetExpression subject) { if (condition instanceof JetWhenConditionIsPattern) { JetWhenConditionIsPattern patternCondition = (JetWhenConditionIsPattern) condition; - - JetTypeReference typeReference = patternCondition.getTypeRef(); - assertNotNull(typeReference); - - assertNotNull(subject); - - //noinspection ConstantConditions - return toBinaryExpression(subject, (patternCondition.isNegated() ? "!is" : "is"), typeReference); + return toBinaryExpression(subject, (patternCondition.isNegated() ? "!is" : "is"), patternCondition.getTypeRef()); } if (condition instanceof JetWhenConditionInRange) { JetWhenConditionInRange rangeCondition = (JetWhenConditionInRange) condition; - - JetExpression rangeExpression = rangeCondition.getRangeExpression(); - assertNotNull(rangeExpression); - - assertNotNull(subject); - - //noinspection ConstantConditions - return toBinaryExpression(subject, rangeCondition.getOperationReference().getText(), rangeExpression); + return toBinaryExpression(subject, rangeCondition.getOperationReference().getText(), rangeCondition.getRangeExpression()); } assert condition instanceof JetWhenConditionWithExpression : TRANSFORM_WITHOUT_CHECK; JetExpression conditionExpression = ((JetWhenConditionWithExpression) condition).getExpression(); - assertNotNull(conditionExpression); - //noinspection ConstantConditions - return subject != null ? - toBinaryExpression(parenthesizeIfNeeded(subject), "==", parenthesizeIfNeeded(conditionExpression)) - : conditionExpression.getText(); + if (subject != null) { + return toBinaryExpression(parenthesizeIfNeeded(subject), "==", parenthesizeIfNeeded(conditionExpression)); + } + return conditionExpression != null ? conditionExpression.getText() : ""; } public static void eliminateWhenSubject(@NotNull JetWhenExpression whenExpression) { @@ -217,10 +190,8 @@ public class WhenUtils { for (JetWhenEntry entry : whenExpression.getEntries()) { JetExpression branchExpression = entry.getExpression(); - assertNotNull(branchExpression); if (entry.isElse()) { - //noinspection ConstantConditions builder.elseEntry(branchExpression); continue; @@ -230,7 +201,6 @@ public class WhenUtils { builder.condition(whenConditionToExpressionText(condition, subject)); } - //noinspection ConstantConditions builder.branchExpression(branchExpression); } From 158c2753b8891b25ede0be4925ea456555f4944d Mon Sep 17 00:00:00 2001 From: Alexey Sedunov Date: Wed, 15 May 2013 15:43:11 +0400 Subject: [PATCH 098/249] Transform 'if' to 'when' with subject if possible --- .../branchedTransformations/IfWhenUtils.java | 7 +++++- .../branchedTransformations/WhenUtils.java | 25 ++++++++++++++----- .../ifToWhen/ifWithEqualityTests.kt.after | 8 +++--- .../ifWhen/ifToWhen/ifWithIs.kt.after | 8 +++--- .../ifWhen/ifToWhen/ifWithNegativeIs.kt.after | 8 +++--- .../ifWithNegativeRangeTests.kt.after | 8 +++--- .../ifWhen/ifToWhen/ifWithRangeTests.kt.after | 8 +++--- ...fWithRangeTestsAndMultiConditions.kt.after | 8 +++--- ...AndUnparenthesizedMultiConditions.kt.after | 8 +++--- .../whenWithMultipleConditionTypes.kt.after | 16 ++++++------ 10 files changed, 61 insertions(+), 43 deletions(-) diff --git a/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/IfWhenUtils.java b/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/IfWhenUtils.java index 5d7fabec852..92d1562ebe6 100644 --- a/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/IfWhenUtils.java +++ b/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/IfWhenUtils.java @@ -110,7 +110,12 @@ public class IfWhenUtils { } } while (currIfExpression != null); - ifExpression.replace(builder.toExpression(ifExpression.getProject())); + JetWhenExpression whenExpression = builder.toExpression(ifExpression.getProject()); + if (WhenUtils.checkIntroduceWhenSubject(whenExpression)) { + whenExpression = WhenUtils.introduceWhenSubject(whenExpression); + } + + ifExpression.replace(whenExpression); } private static String combineWhenConditions(JetWhenCondition[] conditions, JetExpression subject) { diff --git a/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/WhenUtils.java b/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/WhenUtils.java index fbe4d9236f2..5037371dee7 100644 --- a/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/WhenUtils.java +++ b/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/WhenUtils.java @@ -86,7 +86,8 @@ public class WhenUtils { return whenExpression.getSubjectExpression() instanceof JetSimpleNameExpression; } - public static void flattenWhen(@NotNull JetWhenExpression whenExpression) { + @NotNull + public static JetWhenExpression flattenWhen(@NotNull JetWhenExpression whenExpression) { JetExpression subjectExpression = whenExpression.getSubjectExpression(); JetExpression elseBranch = whenExpression.getElseExpression(); @@ -109,10 +110,14 @@ public class WhenUtils { builder.entry(entry); } - whenExpression.replace(builder.toExpression(whenExpression.getProject())); + JetWhenExpression newWhenExpression = builder.toExpression(whenExpression.getProject()); + whenExpression.replace(newWhenExpression); + + return newWhenExpression; } - public static void introduceWhenSubject(@NotNull JetWhenExpression whenExpression) { + @NotNull + public static JetWhenExpression introduceWhenSubject(@NotNull JetWhenExpression whenExpression) { JetExpression subject = getWhenSubjectCandidate(whenExpression); assertNotNull(subject); @@ -158,9 +163,13 @@ public class WhenUtils { builder.branchExpression(branchExpression); } - whenExpression.replace(builder.toExpression(whenExpression.getProject())); + JetWhenExpression newWhenExpression = builder.toExpression(whenExpression.getProject()); + whenExpression.replace(newWhenExpression); + + return newWhenExpression; } + @NotNull static String whenConditionToExpressionText(@NotNull JetWhenCondition condition, JetExpression subject) { if (condition instanceof JetWhenConditionIsPattern) { JetWhenConditionIsPattern patternCondition = (JetWhenConditionIsPattern) condition; @@ -182,7 +191,8 @@ public class WhenUtils { return conditionExpression != null ? conditionExpression.getText() : ""; } - public static void eliminateWhenSubject(@NotNull JetWhenExpression whenExpression) { + @NotNull + public static JetWhenExpression eliminateWhenSubject(@NotNull JetWhenExpression whenExpression) { JetExpression subject = whenExpression.getSubjectExpression(); assertNotNull(subject); @@ -204,6 +214,9 @@ public class WhenUtils { builder.branchExpression(branchExpression); } - whenExpression.replace(builder.toExpression(whenExpression.getProject())); + JetWhenExpression newWhenExpression = builder.toExpression(whenExpression.getProject()); + whenExpression.replace(newWhenExpression); + + return newWhenExpression; } } diff --git a/idea/testData/codeInsight/codeTransformations/branched/ifWhen/ifToWhen/ifWithEqualityTests.kt.after b/idea/testData/codeInsight/codeTransformations/branched/ifWhen/ifToWhen/ifWithEqualityTests.kt.after index 37e018ca2c2..dba5a8e64d6 100644 --- a/idea/testData/codeInsight/codeTransformations/branched/ifWhen/ifToWhen/ifWithEqualityTests.kt.after +++ b/idea/testData/codeInsight/codeTransformations/branched/ifWhen/ifToWhen/ifWithEqualityTests.kt.after @@ -1,8 +1,8 @@ fun test(n: Int): String { - return when { - n == 0 -> "zero" - n == 1 -> "one" - n == 2 -> "two" + return when (n) { + 0 -> "zero" + 1 -> "one" + 2 -> "two" else -> "unknown" } } \ No newline at end of file diff --git a/idea/testData/codeInsight/codeTransformations/branched/ifWhen/ifToWhen/ifWithIs.kt.after b/idea/testData/codeInsight/codeTransformations/branched/ifWhen/ifToWhen/ifWithIs.kt.after index 3fd81cd40a8..e2902c7666b 100644 --- a/idea/testData/codeInsight/codeTransformations/branched/ifWhen/ifToWhen/ifWithIs.kt.after +++ b/idea/testData/codeInsight/codeTransformations/branched/ifWhen/ifToWhen/ifWithIs.kt.after @@ -1,8 +1,8 @@ fun test(obj: Any): String { - return when { - obj is String -> "string" - obj is Int -> "int" - obj is Class<*> -> "class" + return when (obj) { + is String -> "string" + is Int -> "int" + is Class<*> -> "class" else -> "unknown" } } \ No newline at end of file diff --git a/idea/testData/codeInsight/codeTransformations/branched/ifWhen/ifToWhen/ifWithNegativeIs.kt.after b/idea/testData/codeInsight/codeTransformations/branched/ifWhen/ifToWhen/ifWithNegativeIs.kt.after index 163677dcb22..aed8e7af095 100644 --- a/idea/testData/codeInsight/codeTransformations/branched/ifWhen/ifToWhen/ifWithNegativeIs.kt.after +++ b/idea/testData/codeInsight/codeTransformations/branched/ifWhen/ifToWhen/ifWithNegativeIs.kt.after @@ -1,8 +1,8 @@ fun test(obj: Any): String { - return when { - obj !is Iterable<*> -> "not iterable" - obj !is Collection<*> -> "not collection" - obj !is MutableCollection<*> -> "not mutable collection" + return when (obj) { + !is Iterable<*> -> "not iterable" + !is Collection<*> -> "not collection" + !is MutableCollection<*> -> "not mutable collection" else -> "unknown" } } \ No newline at end of file diff --git a/idea/testData/codeInsight/codeTransformations/branched/ifWhen/ifToWhen/ifWithNegativeRangeTests.kt.after b/idea/testData/codeInsight/codeTransformations/branched/ifWhen/ifToWhen/ifWithNegativeRangeTests.kt.after index 6216fc2f79e..22365e82db6 100644 --- a/idea/testData/codeInsight/codeTransformations/branched/ifWhen/ifToWhen/ifWithNegativeRangeTests.kt.after +++ b/idea/testData/codeInsight/codeTransformations/branched/ifWhen/ifToWhen/ifWithNegativeRangeTests.kt.after @@ -1,8 +1,8 @@ fun test(n: Int): String { - return when { - n !in 0..1000 -> "unknown" - n !in 0..100 -> "big" - n !in 0..10 -> "average" + return when (n) { + !in 0..1000 -> "unknown" + !in 0..100 -> "big" + !in 0..10 -> "average" else -> "small" } } \ No newline at end of file diff --git a/idea/testData/codeInsight/codeTransformations/branched/ifWhen/ifToWhen/ifWithRangeTests.kt.after b/idea/testData/codeInsight/codeTransformations/branched/ifWhen/ifToWhen/ifWithRangeTests.kt.after index f47641c76dc..67f8dd5e022 100644 --- a/idea/testData/codeInsight/codeTransformations/branched/ifWhen/ifToWhen/ifWithRangeTests.kt.after +++ b/idea/testData/codeInsight/codeTransformations/branched/ifWhen/ifToWhen/ifWithRangeTests.kt.after @@ -1,8 +1,8 @@ fun test(n: Int): String { - return when { - n in 0..10 -> "small" - n in 10..100 -> "average" - n in 100..1000 -> "big" + return when (n) { + in 0..10 -> "small" + in 10..100 -> "average" + in 100..1000 -> "big" else -> "unknown" } } \ No newline at end of file diff --git a/idea/testData/codeInsight/codeTransformations/branched/ifWhen/ifToWhen/ifWithRangeTestsAndMultiConditions.kt.after b/idea/testData/codeInsight/codeTransformations/branched/ifWhen/ifToWhen/ifWithRangeTestsAndMultiConditions.kt.after index aa84b8524a0..88b38a37492 100644 --- a/idea/testData/codeInsight/codeTransformations/branched/ifWhen/ifToWhen/ifWithRangeTestsAndMultiConditions.kt.after +++ b/idea/testData/codeInsight/codeTransformations/branched/ifWhen/ifToWhen/ifWithRangeTestsAndMultiConditions.kt.after @@ -1,8 +1,8 @@ fun test(n: Int): String { - return when { - n in 0..5, n in 5..10 -> "small" - n in 10..50, n in 50..100 -> "average" - n in 100..500, n in 500..1000 -> "big" + return when (n) { + in 0..5, in 5..10 -> "small" + in 10..50, in 50..100 -> "average" + in 100..500, in 500..1000 -> "big" else -> "unknown" } } \ No newline at end of file diff --git a/idea/testData/codeInsight/codeTransformations/branched/ifWhen/ifToWhen/ifWithRangeTestsAndUnparenthesizedMultiConditions.kt.after b/idea/testData/codeInsight/codeTransformations/branched/ifWhen/ifToWhen/ifWithRangeTestsAndUnparenthesizedMultiConditions.kt.after index aa84b8524a0..88b38a37492 100644 --- a/idea/testData/codeInsight/codeTransformations/branched/ifWhen/ifToWhen/ifWithRangeTestsAndUnparenthesizedMultiConditions.kt.after +++ b/idea/testData/codeInsight/codeTransformations/branched/ifWhen/ifToWhen/ifWithRangeTestsAndUnparenthesizedMultiConditions.kt.after @@ -1,8 +1,8 @@ fun test(n: Int): String { - return when { - n in 0..5, n in 5..10 -> "small" - n in 10..50, n in 50..100 -> "average" - n in 100..500, n in 500..1000 -> "big" + return when (n) { + in 0..5, in 5..10 -> "small" + in 10..50, in 50..100 -> "average" + in 100..500, in 500..1000 -> "big" else -> "unknown" } } \ No newline at end of file diff --git a/idea/testData/codeInsight/codeTransformations/branched/ifWhen/ifToWhen/whenWithMultipleConditionTypes.kt.after b/idea/testData/codeInsight/codeTransformations/branched/ifWhen/ifToWhen/whenWithMultipleConditionTypes.kt.after index 6babe750cc6..ea4d863fb5d 100644 --- a/idea/testData/codeInsight/codeTransformations/branched/ifWhen/ifToWhen/whenWithMultipleConditionTypes.kt.after +++ b/idea/testData/codeInsight/codeTransformations/branched/ifWhen/ifToWhen/whenWithMultipleConditionTypes.kt.after @@ -1,12 +1,12 @@ fun test(n: Int): String { - return when { - n !is Int -> "???" - n in 0..10 -> "small" - n in 10..100 -> "average" - n in 100..1000 -> "big" - n == 1000000 -> "million" - n !in -100..-10 -> "good" - n is Int -> "unknown" + return when (n) { + !is Int -> "???" + in 0..10 -> "small" + in 10..100 -> "average" + in 100..1000 -> "big" + 1000000 -> "million" + !in -100..-10 -> "good" + is Int -> "unknown" else -> "unknown" } } \ No newline at end of file From 9442f96b87677a5d84194f965f1574cb45c601e6 Mon Sep 17 00:00:00 2001 From: Alexey Sedunov Date: Wed, 15 May 2013 18:44:15 +0400 Subject: [PATCH 099/249] Extract getText() method --- .../jetbrains/jet/lang/psi/JetPsiFactory.java | 18 +++++++++--------- .../jet/lang/psi/JetPsiUnparsingUtils.java | 10 +++++----- .../org/jetbrains/jet/lang/psi/JetPsiUtil.java | 6 +++++- .../branchedTransformations/IfWhenUtils.java | 2 +- .../branchedTransformations/WhenUtils.java | 2 +- 5 files changed, 21 insertions(+), 17 deletions(-) diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetPsiFactory.java b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetPsiFactory.java index c349daa3c95..23df1f27e61 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetPsiFactory.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetPsiFactory.java @@ -256,7 +256,7 @@ public class JetPsiFactory { @NotNull public static JetBinaryExpression createBinaryExpression(Project project, @Nullable JetExpression lhs, @NotNull String op, @Nullable JetExpression rhs) { - return createBinaryExpression(project, lhs != null ? lhs.getText() : "", op, rhs != null ? rhs.getText() : ""); + return createBinaryExpression(project, JetPsiUtil.getText(lhs), op, JetPsiUtil.getText(rhs)); } public static JetTypeCodeFragment createTypeCodeFragment(Project project, String text, PsiElement context) { @@ -274,7 +274,7 @@ public class JetPsiFactory { @NotNull public static JetReturnExpression createReturn(Project project, @Nullable JetExpression expression) { - return createReturn(project, expression != null ? expression.getText() : ""); + return createReturn(project, JetPsiUtil.getText(expression)); } @NotNull @@ -316,7 +316,7 @@ public class JetPsiFactory { @NotNull public IfChainBuilder elseBranch(@Nullable JetExpression expression) { - return elseBranch(expression != null ? expression.getText() : ""); + return elseBranch(JetPsiUtil.getText(expression)); } @NotNull @@ -364,7 +364,7 @@ public class JetPsiFactory { @NotNull public WhenBuilder condition(@Nullable JetExpression expression) { - return condition(expression != null ? expression.getText() : ""); + return condition(JetPsiUtil.getText(expression)); } @NotNull @@ -374,7 +374,7 @@ public class JetPsiFactory { @NotNull public WhenBuilder pattern(@Nullable JetTypeReference typeReference, boolean negated) { - return pattern(typeReference != null ? typeReference.getText() : "", negated); + return pattern(JetPsiUtil.getText(typeReference), negated); } @NotNull @@ -384,7 +384,7 @@ public class JetPsiFactory { @NotNull public WhenBuilder range(@Nullable JetExpression argument, boolean negated) { - return range(argument != null ? argument.getText() : "", negated); + return range(JetPsiUtil.getText(argument), negated); } @NotNull @@ -400,7 +400,7 @@ public class JetPsiFactory { @NotNull public WhenBuilder branchExpression(@Nullable JetExpression expression) { - return branchExpression(expression != null ? expression.getText() : ""); + return branchExpression(JetPsiUtil.getText(expression)); } @NotNull @@ -415,7 +415,7 @@ public class JetPsiFactory { @NotNull public WhenBuilder entry(@Nullable JetWhenEntry whenEntry) { - return entry(whenEntry != null ? whenEntry.getText() : ""); + return entry(JetPsiUtil.getText(whenEntry)); } @NotNull @@ -425,7 +425,7 @@ public class JetPsiFactory { @NotNull public WhenBuilder elseEntry(@Nullable JetExpression expression) { - return elseEntry(expression != null ? expression.getText() : ""); + return elseEntry(JetPsiUtil.getText(expression)); } @NotNull diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetPsiUnparsingUtils.java b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetPsiUnparsingUtils.java index ed3b8a7adfe..e3d86c3f0f0 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetPsiUnparsingUtils.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetPsiUnparsingUtils.java @@ -16,6 +16,7 @@ package org.jetbrains.jet.lang.psi; +import com.intellij.psi.PsiElement; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -26,8 +27,8 @@ public class JetPsiUnparsingUtils { @NotNull public static String toIf(@Nullable JetExpression condition, @Nullable JetExpression thenExpression, @Nullable JetExpression elseExpression) { return toIf( - condition != null ? condition.getText() : "", - thenExpression != null ? thenExpression.getText() : "", + JetPsiUtil.getText(condition), + JetPsiUtil.getText(thenExpression), elseExpression != null ? elseExpression.getText() : null ); } @@ -39,7 +40,7 @@ public class JetPsiUnparsingUtils { @NotNull public static String toBinaryExpression(@Nullable JetExpression left, @NotNull String op, @Nullable JetElement right) { - return toBinaryExpression(left != null ? left.getText() : "", op, right != null ? right.getText() : ""); + return toBinaryExpression(JetPsiUtil.getText(left), op, JetPsiUtil.getText(right)); } @NotNull @@ -49,9 +50,8 @@ public class JetPsiUnparsingUtils { @NotNull public static String parenthesizeIfNeeded(@Nullable JetExpression expression) { - if (expression == null) return ""; + String text = JetPsiUtil.getText(expression); - String text = expression.getText(); return (expression instanceof JetParenthesizedExpression || expression instanceof JetConstantExpression || expression instanceof JetSimpleNameExpression) diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetPsiUtil.java b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetPsiUtil.java index cb9fa86166f..865bcc2622d 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetPsiUtil.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetPsiUtil.java @@ -40,7 +40,6 @@ import org.jetbrains.jet.lang.types.expressions.OperatorConventions; import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns; import org.jetbrains.jet.lexer.JetToken; import org.jetbrains.jet.lexer.JetTokens; -import org.jetbrains.jet.util.QualifiedNamesUtil; import java.util.Collection; import java.util.HashSet; @@ -718,4 +717,9 @@ public class JetPsiUtil { return true; } }; + + @NotNull + public static String getText(@Nullable PsiElement element) { + return element != null ? element.getText() : ""; + } } diff --git a/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/IfWhenUtils.java b/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/IfWhenUtils.java index 92d1562ebe6..b0a9ec4aa07 100644 --- a/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/IfWhenUtils.java +++ b/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/IfWhenUtils.java @@ -154,7 +154,7 @@ public class IfWhenUtils { builder.elseBranch(branch); } else { String branchConditionText = combineWhenConditions(entry.getConditions(), whenExpression.getSubjectExpression()); - builder.ifBranch(branchConditionText, branch != null ? branch.getText() : ""); + builder.ifBranch(branchConditionText, JetPsiUtil.getText(branch)); } } diff --git a/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/WhenUtils.java b/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/WhenUtils.java index 5037371dee7..8f97f83b2cf 100644 --- a/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/WhenUtils.java +++ b/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/WhenUtils.java @@ -188,7 +188,7 @@ public class WhenUtils { if (subject != null) { return toBinaryExpression(parenthesizeIfNeeded(subject), "==", parenthesizeIfNeeded(conditionExpression)); } - return conditionExpression != null ? conditionExpression.getText() : ""; + return JetPsiUtil.getText(conditionExpression); } @NotNull From 71e76bc6906205a2e66f7a6b86934b03410cc55e Mon Sep 17 00:00:00 2001 From: Alexey Sedunov Date: Wed, 15 May 2013 18:54:01 +0400 Subject: [PATCH 100/249] Add 'else' check for 'when' expressions --- .../branchedTransformations/BranchedUnfoldingUtils.java | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/BranchedUnfoldingUtils.java b/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/BranchedUnfoldingUtils.java index e45924b8b12..755ce457657 100644 --- a/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/BranchedUnfoldingUtils.java +++ b/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/BranchedUnfoldingUtils.java @@ -42,12 +42,16 @@ public class BranchedUnfoldingUtils { JetExpression rhs = assignment.getRight(); if (rhs instanceof JetIfExpression) return UnfoldableKind.ASSIGNMENT_TO_IF; - if (rhs instanceof JetWhenExpression) return UnfoldableKind.ASSIGNMENT_TO_WHEN; + if (rhs instanceof JetWhenExpression && JetPsiUtil.checkWhenExpressionHasSingleElse((JetWhenExpression) rhs)) { + return UnfoldableKind.ASSIGNMENT_TO_WHEN; + } } else if (root instanceof JetReturnExpression) { JetExpression resultExpr = ((JetReturnExpression)root).getReturnedExpression(); if (resultExpr instanceof JetIfExpression) return UnfoldableKind.RETURN_TO_IF; - if (resultExpr instanceof JetWhenExpression) return UnfoldableKind.RETURN_TO_WHEN; + if (resultExpr instanceof JetWhenExpression && JetPsiUtil.checkWhenExpressionHasSingleElse((JetWhenExpression) resultExpr)) { + return UnfoldableKind.RETURN_TO_WHEN; + } } return null; From d5739bbe7f612821bc5be6b6af13eb1f784dc2ef Mon Sep 17 00:00:00 2001 From: Alexey Sedunov Date: Thu, 16 May 2013 13:57:09 +0400 Subject: [PATCH 101/249] Fix negative quickfix tests which use when --- .../addStarProjections/when/beforeUnqualifiedMapOneArg.kt | 6 ++++++ .../testData/quickfix/when/beforeTwoElseBranchesInWhen.kt | 3 +++ .../jet/plugin/quickfix/QuickFixActionsUtils.java | 8 ++++---- 3 files changed, 13 insertions(+), 4 deletions(-) diff --git a/idea/testData/quickfix/addStarProjections/when/beforeUnqualifiedMapOneArg.kt b/idea/testData/quickfix/addStarProjections/when/beforeUnqualifiedMapOneArg.kt index 42b2681a5ff..c8f90c88840 100644 --- a/idea/testData/quickfix/addStarProjections/when/beforeUnqualifiedMapOneArg.kt +++ b/idea/testData/quickfix/addStarProjections/when/beforeUnqualifiedMapOneArg.kt @@ -1,6 +1,12 @@ // "Add '<*, *>'" "false" // "Add '<*>'" "false" // ERROR: 2 type arguments expected +// ACTION: Disable 'Eliminate Argument of 'when'' +// ACTION: Disable 'Replace 'when' with 'if'' +// ACTION: Edit intention settings +// ACTION: Edit intention settings +// ACTION: Eliminate argument of 'when' +// ACTION: Replace 'when' with 'if' public fun foo(a: Any) { when (a) { is Map -> {} diff --git a/idea/testData/quickfix/when/beforeTwoElseBranchesInWhen.kt b/idea/testData/quickfix/when/beforeTwoElseBranchesInWhen.kt index ddf036a0336..de076791f12 100644 --- a/idea/testData/quickfix/when/beforeTwoElseBranchesInWhen.kt +++ b/idea/testData/quickfix/when/beforeTwoElseBranchesInWhen.kt @@ -3,6 +3,9 @@ // ERROR: 'else' entry must be the last one in a when-expression // ERROR: Unreachable code // ERROR: Unreachable code +// ACTION: Disable 'Eliminate Argument of 'when'' +// ACTION: Edit intention settings +// ACTION: Eliminate argument of 'when' package foo fun foo() { diff --git a/idea/tests/org/jetbrains/jet/plugin/quickfix/QuickFixActionsUtils.java b/idea/tests/org/jetbrains/jet/plugin/quickfix/QuickFixActionsUtils.java index 4943d86c013..e51a122bf24 100644 --- a/idea/tests/org/jetbrains/jet/plugin/quickfix/QuickFixActionsUtils.java +++ b/idea/tests/org/jetbrains/jet/plugin/quickfix/QuickFixActionsUtils.java @@ -19,8 +19,8 @@ package org.jetbrains.jet.plugin.quickfix; import com.google.common.base.Function; import com.google.common.base.Predicate; import com.google.common.collect.Collections2; +import com.google.common.collect.Lists; import com.google.common.collect.Ordering; -import com.google.common.collect.Sets; import com.intellij.codeInsight.intention.IntentionAction; import com.intellij.testFramework.UsefulTestCase; import org.jetbrains.annotations.Nullable; @@ -73,16 +73,16 @@ public class QuickFixActionsUtils { public static void checkAvailableActionsAreExpected(JetFile file, Collection availableActions) { List validActions = Ordering.natural().sortedCopy( - Sets.newHashSet(InTextDirectivesUtils.findLinesWithPrefixesRemoved(file.getText(), "// ACTION:"))); + Lists.newArrayList(InTextDirectivesUtils.findLinesWithPrefixesRemoved(file.getText(), "// ACTION:"))); Collection actualActions = Ordering.natural().sortedCopy( - Collections2.transform(availableActions, new Function() { + Lists.newArrayList(Collections2.transform(availableActions, new Function() { @Override public String apply(@Nullable IntentionAction input) { assert input != null; return input.getText(); } - })); + }))); UsefulTestCase.assertOrderedEquals("Some unexpected actions available at current position: %s. Use // ACTION: directive", actualActions, validActions); From b2bb581127dea24acbbad36962c70802ccfbd6a6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Sapalski?= Date: Mon, 6 May 2013 10:16:43 +0200 Subject: [PATCH 102/249] Quickfix for MIXING_NAMED_AND_POSITIONED_ARGUMENTS. --- .../jetbrains/jet/lang/psi/JetPsiFactory.java | 9 + .../jetbrains/jet/plugin/JetBundle.properties | 7 +- .../plugin/quickfix/AddNameToArgumentFix.java | 198 ++++++++++++++++++ .../jet/plugin/quickfix/QuickFixes.java | 2 + .../afterMixedNamedAndPositionalArguments.kt | 6 + ...dNamedAndPositionalArgumentsConstructor.kt | 6 + ...ixedNamedAndPositionalArgumentsMultiple.kt | 6 + ...MixedNamedAndPositionalArgumentsSubtype.kt | 8 + ...xedNamedAndPositionalArgumentsUsedNamed.kt | 6 + ...medAndPositionalArgumentsUsedPositional.kt | 6 + .../beforeMixedNamedAndPositionalArguments.kt | 6 + ...dNamedAndPositionalArgumentsConstructor.kt | 6 + ...ixedNamedAndPositionalArgumentsMultiple.kt | 6 + ...MixedNamedAndPositionalArgumentsSubtype.kt | 8 + ...xedNamedAndPositionalArgumentsUsedNamed.kt | 6 + ...medAndPositionalArgumentsUsedPositional.kt | 6 + .../quickfix/QuickFixTestGenerated.java | 30 +++ 17 files changed, 321 insertions(+), 1 deletion(-) create mode 100644 idea/src/org/jetbrains/jet/plugin/quickfix/AddNameToArgumentFix.java create mode 100644 idea/testData/quickfix/checkArguments/afterMixedNamedAndPositionalArguments.kt create mode 100644 idea/testData/quickfix/checkArguments/afterMixedNamedAndPositionalArgumentsConstructor.kt create mode 100644 idea/testData/quickfix/checkArguments/afterMixedNamedAndPositionalArgumentsMultiple.kt create mode 100644 idea/testData/quickfix/checkArguments/afterMixedNamedAndPositionalArgumentsSubtype.kt create mode 100644 idea/testData/quickfix/checkArguments/afterMixedNamedAndPositionalArgumentsUsedNamed.kt create mode 100644 idea/testData/quickfix/checkArguments/afterMixedNamedAndPositionalArgumentsUsedPositional.kt create mode 100644 idea/testData/quickfix/checkArguments/beforeMixedNamedAndPositionalArguments.kt create mode 100644 idea/testData/quickfix/checkArguments/beforeMixedNamedAndPositionalArgumentsConstructor.kt create mode 100644 idea/testData/quickfix/checkArguments/beforeMixedNamedAndPositionalArgumentsMultiple.kt create mode 100644 idea/testData/quickfix/checkArguments/beforeMixedNamedAndPositionalArgumentsSubtype.kt create mode 100644 idea/testData/quickfix/checkArguments/beforeMixedNamedAndPositionalArgumentsUsedNamed.kt create mode 100644 idea/testData/quickfix/checkArguments/beforeMixedNamedAndPositionalArgumentsUsedPositional.kt diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetPsiFactory.java b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetPsiFactory.java index 23df1f27e61..cfb5dfd6f59 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetPsiFactory.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetPsiFactory.java @@ -283,6 +283,15 @@ public class JetPsiFactory { return (JetIfExpression) createExpression(project, JetPsiUnparsingUtils.toIf(condition, thenExpr, elseExpr)); } + @NotNull + public static JetValueArgument createArgumentWithName( + @NotNull Project project, + @NotNull String name, + @NotNull JetExpression argumentExpression + ) { + return createCallArguments(project, "(" + name + " = " + argumentExpression.getText() + ")").getArguments().get(0); + } + public static class IfChainBuilder { private final StringBuilder sb = new StringBuilder(); private boolean first = true; diff --git a/idea/src/org/jetbrains/jet/plugin/JetBundle.properties b/idea/src/org/jetbrains/jet/plugin/JetBundle.properties index c56c934fe75..0ac4c6666ce 100644 --- a/idea/src/org/jetbrains/jet/plugin/JetBundle.properties +++ b/idea/src/org/jetbrains/jet/plugin/JetBundle.properties @@ -196,4 +196,9 @@ change.function.signature.family=Change function signature change.function.signature.chooser.title=Choose signature change.function.signature.action=Change function signature remove.unnecessary.parentheses=Remove unnecessary parentheses -remove.unnecessary.parentheses.family=Remove Unnecessary Parentheses \ No newline at end of file +remove.unnecessary.parentheses.family=Remove Unnecessary Parentheses +add.name.to.argument.family=Add Name to Argument +add.name.to.argument.single=Add name to argument\: ''{0}'' +add.name.to.argument.multiple=Add name to argument... +add.name.to.argument.action=Add name to argument... +add.name.to.parameter.name.chooser.title=Choose parameter name diff --git a/idea/src/org/jetbrains/jet/plugin/quickfix/AddNameToArgumentFix.java b/idea/src/org/jetbrains/jet/plugin/quickfix/AddNameToArgumentFix.java new file mode 100644 index 00000000000..cc0f03947f3 --- /dev/null +++ b/idea/src/org/jetbrains/jet/plugin/quickfix/AddNameToArgumentFix.java @@ -0,0 +1,198 @@ +/* + * Copyright 2010-2013 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.jetbrains.jet.plugin.quickfix; + +import com.google.common.collect.Lists; +import com.google.common.collect.Sets; +import com.intellij.codeInsight.intention.IntentionAction; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.command.CommandProcessor; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.ui.popup.JBPopupFactory; +import com.intellij.openapi.ui.popup.ListPopupStep; +import com.intellij.openapi.ui.popup.PopupStep; +import com.intellij.openapi.ui.popup.util.BaseListPopupStep; +import com.intellij.psi.PsiDocumentManager; +import com.intellij.psi.util.PsiTreeUtil; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import org.jetbrains.jet.lang.descriptors.CallableDescriptor; +import org.jetbrains.jet.lang.descriptors.ValueParameterDescriptor; +import org.jetbrains.jet.lang.diagnostics.Diagnostic; +import org.jetbrains.jet.lang.psi.*; +import org.jetbrains.jet.lang.resolve.BindingContext; +import org.jetbrains.jet.lang.resolve.calls.model.ResolvedCall; +import org.jetbrains.jet.lang.types.JetType; +import org.jetbrains.jet.lang.types.checker.JetTypeChecker; +import org.jetbrains.jet.plugin.JetBundle; +import org.jetbrains.jet.plugin.JetIcons; +import org.jetbrains.jet.plugin.project.WholeProjectAnalyzerFacade; + +import javax.swing.*; +import java.util.Collections; +import java.util.List; +import java.util.Set; + +public class AddNameToArgumentFix extends JetIntentionAction { + + @NotNull + private final List possibleNames; + + public AddNameToArgumentFix(@NotNull JetValueArgument argument, @NotNull List possibleNames) { + super(argument); + this.possibleNames = possibleNames; + } + + @NotNull + private static List generatePossibleNames(@NotNull JetValueArgument argument) { + JetCallElement callElement = PsiTreeUtil.getParentOfType(argument, JetCallElement.class); + assert callElement != null : "The argument has to be inside a function or constructor call"; + + JetExpression callee = callElement.getCalleeExpression(); + if (!(callee instanceof JetReferenceExpression)) return Collections.emptyList(); + + BindingContext context = WholeProjectAnalyzerFacade.analyzeProjectWithCacheOnAFile((JetFile) argument.getContainingFile()).getBindingContext(); + ResolvedCall resolvedCall = context.get(BindingContext.RESOLVED_CALL, (JetReferenceExpression) callee); + if (resolvedCall == null) return Collections.emptyList(); + + CallableDescriptor callableDescriptor = resolvedCall.getResultingDescriptor(); + JetType type = context.get(BindingContext.EXPRESSION_TYPE, argument.getArgumentExpression()); + Set usedParameters = getUsedParameters(callElement, callableDescriptor); + List names = Lists.newArrayList(); + for (ValueParameterDescriptor parameter: callableDescriptor.getValueParameters()) { + String name = parameter.getName().getName(); + if (usedParameters.contains(name)) continue; + if (type == null || JetTypeChecker.INSTANCE.isSubtypeOf(type, parameter.getType())) { + names.add(name); + } + } + return names; + } + + @NotNull + private static Set getUsedParameters(@NotNull JetCallElement callElement, @NotNull CallableDescriptor callableDescriptor) { + Set usedParameters = Sets.newHashSet(); + boolean isPositionalArgument = true; + int idx = 0; + for (ValueArgument argument : callElement.getValueArguments()) { + if (argument.isNamed()) { + JetValueArgumentName name = argument.getArgumentName(); + assert name != null : "Named argument's name cannot be null"; + usedParameters.add(name.getText()); + isPositionalArgument = false; + } + else if (isPositionalArgument) { + ValueParameterDescriptor parameter = callableDescriptor.getValueParameters().get(idx); + usedParameters.add(parameter.getName().getName()); + idx++; + } + } + return usedParameters; + } + + @Override + protected void invoke(@NotNull Project project, Editor editor, JetFile file) { + if (possibleNames.size() == 1 || editor == null || !editor.getComponent().isShowing()) { + addName(project, element, possibleNames.get(0)); + } + else { + chooseNameAndAdd(project, editor); + } + } + + private void chooseNameAndAdd(@NotNull Project project, Editor editor) { + JBPopupFactory.getInstance().createListPopup(getNamePopup(project)).showInBestPositionFor(editor); + } + + private ListPopupStep getNamePopup(final @NotNull Project project) { + return new BaseListPopupStep( + JetBundle.message("add.name.to.parameter.name.chooser.title"), possibleNames) { + @Override + public PopupStep onChosen(String selectedName, boolean finalChoice) { + if (finalChoice) { + addName(project, element, selectedName); + } + return FINAL_CHOICE; + } + + @Override + public Icon getIconFor(String name) { + return JetIcons.PARAMETER; + } + + @NotNull + @Override + public String getTextFor(String name) { + return getParsedArgumentWithName(name, element).getText(); + } + }; + } + + private static void addName(@NotNull Project project, final @NotNull JetValueArgument argument, final @NotNull String name) { + PsiDocumentManager.getInstance(project).commitAllDocuments(); + + CommandProcessor.getInstance().executeCommand(project, new Runnable() { + @Override + public void run() { + ApplicationManager.getApplication().runWriteAction(new Runnable() { + @Override + public void run() { + JetValueArgument newArgument = getParsedArgumentWithName(name, argument); + argument.replace(newArgument); + } + }); + } + }, JetBundle.message("add.name.to.argument.action"), null); + } + + @NotNull + private static JetValueArgument getParsedArgumentWithName(@NotNull String name, @NotNull JetValueArgument argument) { + JetExpression argumentExpression = argument.getArgumentExpression(); + assert argumentExpression != null : "Argument should be already parsed."; + return JetPsiFactory.createArgumentWithName(argument.getProject(), name, argumentExpression); + } + + @NotNull + @Override + public String getText() { + if (possibleNames.size() == 1) { + return JetBundle.message("add.name.to.argument.single", getParsedArgumentWithName(possibleNames.get(0), element).getText()); + } else { + return JetBundle.message("add.name.to.argument.multiple"); + } + } + + @NotNull + @Override + public String getFamilyName() { + return JetBundle.message("add.name.to.argument.family"); + } + @NotNull + public static JetIntentionActionFactory createFactory() { + return new JetIntentionActionFactory() { + @Nullable + @Override + public IntentionAction createAction(Diagnostic diagnostic) { + JetValueArgument argument = QuickFixUtil.getParentElementOfType(diagnostic, JetValueArgument.class); + if (argument == null) return null; + List possibleNames = generatePossibleNames(argument); + return possibleNames.isEmpty() ? null : new AddNameToArgumentFix(argument, possibleNames); + } + }; + } +} diff --git a/idea/src/org/jetbrains/jet/plugin/quickfix/QuickFixes.java b/idea/src/org/jetbrains/jet/plugin/quickfix/QuickFixes.java index 756b883bfee..9369f5b330b 100644 --- a/idea/src/org/jetbrains/jet/plugin/quickfix/QuickFixes.java +++ b/idea/src/org/jetbrains/jet/plugin/quickfix/QuickFixes.java @@ -85,6 +85,8 @@ public class QuickFixes { factories.put(NON_VARARG_SPREAD, RemovePsiElementSimpleFix.createRemoveSpreadFactory()); + factories.put(MIXING_NAMED_AND_POSITIONED_ARGUMENTS, AddNameToArgumentFix.createFactory()); + factories.put(NON_MEMBER_FUNCTION_NO_BODY, addFunctionBodyFactory); factories.put(NOTHING_TO_OVERRIDE, RemoveModifierFix.createRemoveModifierFromListOwnerFactory(OVERRIDE_KEYWORD)); diff --git a/idea/testData/quickfix/checkArguments/afterMixedNamedAndPositionalArguments.kt b/idea/testData/quickfix/checkArguments/afterMixedNamedAndPositionalArguments.kt new file mode 100644 index 00000000000..a6c98c01470 --- /dev/null +++ b/idea/testData/quickfix/checkArguments/afterMixedNamedAndPositionalArguments.kt @@ -0,0 +1,6 @@ +// "Add name to argument: 'b = "FOO"'" "true" +fun f(a: Int, b: String) {} + +fun g() { + f(a = 10, b = "FOO") +} \ No newline at end of file diff --git a/idea/testData/quickfix/checkArguments/afterMixedNamedAndPositionalArgumentsConstructor.kt b/idea/testData/quickfix/checkArguments/afterMixedNamedAndPositionalArgumentsConstructor.kt new file mode 100644 index 00000000000..fca2a83f77f --- /dev/null +++ b/idea/testData/quickfix/checkArguments/afterMixedNamedAndPositionalArgumentsConstructor.kt @@ -0,0 +1,6 @@ +// "Add name to argument: 'b = "FOO"'" "true" +class A(a: Int, b: String) {} + +fun f() { + A(a = 1, b = "FOO") +} \ No newline at end of file diff --git a/idea/testData/quickfix/checkArguments/afterMixedNamedAndPositionalArgumentsMultiple.kt b/idea/testData/quickfix/checkArguments/afterMixedNamedAndPositionalArgumentsMultiple.kt new file mode 100644 index 00000000000..9ee83810f46 --- /dev/null +++ b/idea/testData/quickfix/checkArguments/afterMixedNamedAndPositionalArgumentsMultiple.kt @@ -0,0 +1,6 @@ +// "Add name to argument..." "true" +fun f(a: Int, b: String = "b", c: String = "c") {} + +fun g() { + f(a = 10, b = "FOO") +} \ No newline at end of file diff --git a/idea/testData/quickfix/checkArguments/afterMixedNamedAndPositionalArgumentsSubtype.kt b/idea/testData/quickfix/checkArguments/afterMixedNamedAndPositionalArgumentsSubtype.kt new file mode 100644 index 00000000000..8c19cc0867d --- /dev/null +++ b/idea/testData/quickfix/checkArguments/afterMixedNamedAndPositionalArgumentsSubtype.kt @@ -0,0 +1,8 @@ +// "Add name to argument: 'b = B()'" "true" +open class A {} +open class B : A() {} + +fun f(a: Int, b: A) {} +fun g() { + f(a=1, b = B()) +} \ No newline at end of file diff --git a/idea/testData/quickfix/checkArguments/afterMixedNamedAndPositionalArgumentsUsedNamed.kt b/idea/testData/quickfix/checkArguments/afterMixedNamedAndPositionalArgumentsUsedNamed.kt new file mode 100644 index 00000000000..993b836aef6 --- /dev/null +++ b/idea/testData/quickfix/checkArguments/afterMixedNamedAndPositionalArgumentsUsedNamed.kt @@ -0,0 +1,6 @@ +// "Add name to argument: 'b = "FOO"'" "true" +fun f(a: String, b: String) {} + +fun g() { + f(a = "BAR", b = "FOO") +} \ No newline at end of file diff --git a/idea/testData/quickfix/checkArguments/afterMixedNamedAndPositionalArgumentsUsedPositional.kt b/idea/testData/quickfix/checkArguments/afterMixedNamedAndPositionalArgumentsUsedPositional.kt new file mode 100644 index 00000000000..077ee955ac4 --- /dev/null +++ b/idea/testData/quickfix/checkArguments/afterMixedNamedAndPositionalArgumentsUsedPositional.kt @@ -0,0 +1,6 @@ +// "Add name to argument: 'b = "FOO"'" "true" +fun f(a: String, x: Int, b: String) {} + +fun g() { + f("BAR", x = 10, b = "FOO") +} \ No newline at end of file diff --git a/idea/testData/quickfix/checkArguments/beforeMixedNamedAndPositionalArguments.kt b/idea/testData/quickfix/checkArguments/beforeMixedNamedAndPositionalArguments.kt new file mode 100644 index 00000000000..7d8310d29e7 --- /dev/null +++ b/idea/testData/quickfix/checkArguments/beforeMixedNamedAndPositionalArguments.kt @@ -0,0 +1,6 @@ +// "Add name to argument: 'b = "FOO"'" "true" +fun f(a: Int, b: String) {} + +fun g() { + f(a = 10, "FOO") +} \ No newline at end of file diff --git a/idea/testData/quickfix/checkArguments/beforeMixedNamedAndPositionalArgumentsConstructor.kt b/idea/testData/quickfix/checkArguments/beforeMixedNamedAndPositionalArgumentsConstructor.kt new file mode 100644 index 00000000000..3e6ccdbe349 --- /dev/null +++ b/idea/testData/quickfix/checkArguments/beforeMixedNamedAndPositionalArgumentsConstructor.kt @@ -0,0 +1,6 @@ +// "Add name to argument: 'b = "FOO"'" "true" +class A(a: Int, b: String) {} + +fun f() { + A(a = 1, "FOO") +} \ No newline at end of file diff --git a/idea/testData/quickfix/checkArguments/beforeMixedNamedAndPositionalArgumentsMultiple.kt b/idea/testData/quickfix/checkArguments/beforeMixedNamedAndPositionalArgumentsMultiple.kt new file mode 100644 index 00000000000..16e2f905cc8 --- /dev/null +++ b/idea/testData/quickfix/checkArguments/beforeMixedNamedAndPositionalArgumentsMultiple.kt @@ -0,0 +1,6 @@ +// "Add name to argument..." "true" +fun f(a: Int, b: String = "b", c: String = "c") {} + +fun g() { + f(a = 10, "FOO") +} \ No newline at end of file diff --git a/idea/testData/quickfix/checkArguments/beforeMixedNamedAndPositionalArgumentsSubtype.kt b/idea/testData/quickfix/checkArguments/beforeMixedNamedAndPositionalArgumentsSubtype.kt new file mode 100644 index 00000000000..8ff0c9b38d4 --- /dev/null +++ b/idea/testData/quickfix/checkArguments/beforeMixedNamedAndPositionalArgumentsSubtype.kt @@ -0,0 +1,8 @@ +// "Add name to argument: 'b = B()'" "true" +open class A {} +open class B : A() {} + +fun f(a: Int, b: A) {} +fun g() { + f(a=1, B()) +} \ No newline at end of file diff --git a/idea/testData/quickfix/checkArguments/beforeMixedNamedAndPositionalArgumentsUsedNamed.kt b/idea/testData/quickfix/checkArguments/beforeMixedNamedAndPositionalArgumentsUsedNamed.kt new file mode 100644 index 00000000000..7460c8eb891 --- /dev/null +++ b/idea/testData/quickfix/checkArguments/beforeMixedNamedAndPositionalArgumentsUsedNamed.kt @@ -0,0 +1,6 @@ +// "Add name to argument: 'b = "FOO"'" "true" +fun f(a: String, b: String) {} + +fun g() { + f(a = "BAR", "FOO") +} \ No newline at end of file diff --git a/idea/testData/quickfix/checkArguments/beforeMixedNamedAndPositionalArgumentsUsedPositional.kt b/idea/testData/quickfix/checkArguments/beforeMixedNamedAndPositionalArgumentsUsedPositional.kt new file mode 100644 index 00000000000..d984c15088c --- /dev/null +++ b/idea/testData/quickfix/checkArguments/beforeMixedNamedAndPositionalArgumentsUsedPositional.kt @@ -0,0 +1,6 @@ +// "Add name to argument: 'b = "FOO"'" "true" +fun f(a: String, x: Int, b: String) {} + +fun g() { + f("BAR", x = 10, "FOO") +} \ No newline at end of file diff --git a/idea/tests/org/jetbrains/jet/plugin/quickfix/QuickFixTestGenerated.java b/idea/tests/org/jetbrains/jet/plugin/quickfix/QuickFixTestGenerated.java index 9b32c411512..d35d22f475b 100644 --- a/idea/tests/org/jetbrains/jet/plugin/quickfix/QuickFixTestGenerated.java +++ b/idea/tests/org/jetbrains/jet/plugin/quickfix/QuickFixTestGenerated.java @@ -422,6 +422,36 @@ public class QuickFixTestGenerated extends AbstractQuickFixTest { JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.GenerateTests", new File("idea/testData/quickfix/checkArguments"), Pattern.compile("^before(\\w+)\\.kt$"), true); } + @TestMetadata("beforeMixedNamedAndPositionalArguments.kt") + public void testMixedNamedAndPositionalArguments() throws Exception { + doTest("idea/testData/quickfix/checkArguments/beforeMixedNamedAndPositionalArguments.kt"); + } + + @TestMetadata("beforeMixedNamedAndPositionalArgumentsConstructor.kt") + public void testMixedNamedAndPositionalArgumentsConstructor() throws Exception { + doTest("idea/testData/quickfix/checkArguments/beforeMixedNamedAndPositionalArgumentsConstructor.kt"); + } + + @TestMetadata("beforeMixedNamedAndPositionalArgumentsMultiple.kt") + public void testMixedNamedAndPositionalArgumentsMultiple() throws Exception { + doTest("idea/testData/quickfix/checkArguments/beforeMixedNamedAndPositionalArgumentsMultiple.kt"); + } + + @TestMetadata("beforeMixedNamedAndPositionalArgumentsSubtype.kt") + public void testMixedNamedAndPositionalArgumentsSubtype() throws Exception { + doTest("idea/testData/quickfix/checkArguments/beforeMixedNamedAndPositionalArgumentsSubtype.kt"); + } + + @TestMetadata("beforeMixedNamedAndPositionalArgumentsUsedNamed.kt") + public void testMixedNamedAndPositionalArgumentsUsedNamed() throws Exception { + doTest("idea/testData/quickfix/checkArguments/beforeMixedNamedAndPositionalArgumentsUsedNamed.kt"); + } + + @TestMetadata("beforeMixedNamedAndPositionalArgumentsUsedPositional.kt") + public void testMixedNamedAndPositionalArgumentsUsedPositional() throws Exception { + doTest("idea/testData/quickfix/checkArguments/beforeMixedNamedAndPositionalArgumentsUsedPositional.kt"); + } + @TestMetadata("beforeNonVarargSpread.kt") public void testNonVarargSpread() throws Exception { doTest("idea/testData/quickfix/checkArguments/beforeNonVarargSpread.kt"); From aac7f84c2522bea1b7515031ec9ca03f32ff10f4 Mon Sep 17 00:00:00 2001 From: Nikolay Krasko Date: Mon, 13 May 2013 16:21:19 +0400 Subject: [PATCH 103/249] Fix absence of implemented/overridden markers on overridden functions --- .../highlighter/JetLineMarkerProvider.java | 11 +++++------ .../codeInsight/lineMarker/OverrideFunction.kt | 16 ++++++++++++++++ .../OverrideImplementLineMarkerTest.java | 4 ++++ 3 files changed, 25 insertions(+), 6 deletions(-) create mode 100644 idea/testData/codeInsight/lineMarker/OverrideFunction.kt diff --git a/idea/src/org/jetbrains/jet/plugin/highlighter/JetLineMarkerProvider.java b/idea/src/org/jetbrains/jet/plugin/highlighter/JetLineMarkerProvider.java index a6e84447bdf..25577f783f3 100644 --- a/idea/src/org/jetbrains/jet/plugin/highlighter/JetLineMarkerProvider.java +++ b/idea/src/org/jetbrains/jet/plugin/highlighter/JetLineMarkerProvider.java @@ -34,6 +34,7 @@ import com.intellij.openapi.project.DumbService; import com.intellij.openapi.ui.popup.JBPopup; import com.intellij.openapi.ui.popup.JBPopupFactory; import com.intellij.openapi.util.Pair; +import com.intellij.openapi.util.text.StringUtil; import com.intellij.psi.CommonClassNames; import com.intellij.psi.PsiClass; import com.intellij.psi.PsiElement; @@ -255,15 +256,12 @@ public class JetLineMarkerProvider implements LineMarkerProvider { builder.append(DescriptorRenderer.HTML.render(descriptor)); int overrideCount = overriddenMembers.size(); if (overrideCount >= 1) { - builder.append("\n").append(implementsOrOverrides).append("\n"); + builder.append("
").append(implementsOrOverrides).append("
"); builder.append(DescriptorRenderer.HTML.render(overriddenMembers.iterator().next())); } if (overrideCount > 1) { - int count = overrideCount - 1; - builder.append("\nand ").append(count).append(" other ").append(memberKind); - if (count > 1) { - builder.append("s"); - } + int otherCount = overrideCount - 1; + builder.append("
and ").append(otherCount).append(" other ").append(StringUtil.pluralize(memberKind, otherCount)); } return builder.toString(); @@ -318,6 +316,7 @@ public class JetLineMarkerProvider implements LineMarkerProvider { // Not all open or abstract declarations are actually overridable, but this is heuristic return declaration.hasModifier(JetTokens.ABSTRACT_KEYWORD) || declaration.hasModifier(JetTokens.OPEN_KEYWORD) || + declaration.hasModifier(JetTokens.OVERRIDE_KEYWORD) || ((JetClass) parent.getParent()).isTrait(); } diff --git a/idea/testData/codeInsight/lineMarker/OverrideFunction.kt b/idea/testData/codeInsight/lineMarker/OverrideFunction.kt new file mode 100644 index 00000000000..ee4a54cac32 --- /dev/null +++ b/idea/testData/codeInsight/lineMarker/OverrideFunction.kt @@ -0,0 +1,16 @@ +open class A { + open fun a(){ + } +} + +open class B:A(){ + override fun a(){ + } +} + +class C:B(){ + override fun a(){ + } +} \ No newline at end of file diff --git a/idea/tests/org/jetbrains/jet/plugin/codeInsight/OverrideImplementLineMarkerTest.java b/idea/tests/org/jetbrains/jet/plugin/codeInsight/OverrideImplementLineMarkerTest.java index 2b52ed5f21d..1d5c0fe2bde 100644 --- a/idea/tests/org/jetbrains/jet/plugin/codeInsight/OverrideImplementLineMarkerTest.java +++ b/idea/tests/org/jetbrains/jet/plugin/codeInsight/OverrideImplementLineMarkerTest.java @@ -42,6 +42,10 @@ public class OverrideImplementLineMarkerTest extends LightCodeInsightFixtureTest doTest(); } + public void testOverrideFunction() throws Throwable { + doTest(); + } + private void doTest() { try { myFixture.configureByFile(getTestName(false) + ".kt"); From 8752b417e594fcbaf446e35dc373b2fe106e128c Mon Sep 17 00:00:00 2001 From: Nikolay Krasko Date: Fri, 26 Apr 2013 18:37:20 +0400 Subject: [PATCH 104/249] Refactoring: extract methods --- .../search/KotlinDefinitionsSearcher.java | 44 +++++++++++-------- 1 file changed, 26 insertions(+), 18 deletions(-) diff --git a/idea/src/org/jetbrains/jet/plugin/search/KotlinDefinitionsSearcher.java b/idea/src/org/jetbrains/jet/plugin/search/KotlinDefinitionsSearcher.java index ecbd25dd5e1..6b3d2837d87 100644 --- a/idea/src/org/jetbrains/jet/plugin/search/KotlinDefinitionsSearcher.java +++ b/idea/src/org/jetbrains/jet/plugin/search/KotlinDefinitionsSearcher.java @@ -33,30 +33,38 @@ import org.jetbrains.jet.lang.psi.JetNamedFunction; public class KotlinDefinitionsSearcher extends QueryExecutorBase { @Override - public void processQuery(@NotNull final PsiElement queryParameters, @NotNull Processor consumer) { + public void processQuery(@NotNull PsiElement queryParameters, @NotNull Processor consumer) { if (queryParameters instanceof JetClass) { - PsiClass psiClass = ApplicationManager.getApplication().runReadAction(new Computable() { - @Override - public PsiClass compute() { - return LightClassUtil.getPsiClass((JetClass) queryParameters); - } - }); - if (psiClass != null) { - ContainerUtil.process(ClassInheritorsSearch.search(psiClass, true), consumer); - } + processClassImplementations((JetClass) queryParameters, consumer); } if (queryParameters instanceof JetNamedFunction) { - PsiMethod psiMethod = ApplicationManager.getApplication().runReadAction(new Computable() { - @Override - public PsiMethod compute() { - return LightClassUtil.getLightClassMethod((JetNamedFunction) queryParameters); - } - }); + processFunctionImplementations((JetNamedFunction) queryParameters, consumer); + } + } - if (psiMethod != null) { - ContainerUtil.process(MethodImplementationsSearch.getMethodImplementations(psiMethod), consumer); + private static void processClassImplementations(final JetClass queryParameters, Processor consumer) { + PsiClass psiClass = ApplicationManager.getApplication().runReadAction(new Computable() { + @Override + public PsiClass compute() { + return LightClassUtil.getPsiClass(queryParameters); } + }); + if (psiClass != null) { + ContainerUtil.process(ClassInheritorsSearch.search(psiClass, true), consumer); + } + } + + private static void processFunctionImplementations(final JetNamedFunction queryParameters, Processor consumer) { + PsiMethod psiMethod = ApplicationManager.getApplication().runReadAction(new Computable() { + @Override + public PsiMethod compute() { + return LightClassUtil.getLightClassMethod(queryParameters); + } + }); + + if (psiMethod != null) { + ContainerUtil.process(MethodImplementationsSearch.getMethodImplementations(psiMethod), consumer); } } } From cef1bb2aba352e97baaf04c75b22bc89f64d47ad Mon Sep 17 00:00:00 2001 From: Nikolay Krasko Date: Wed, 8 May 2013 12:31:00 +0400 Subject: [PATCH 105/249] Add test for wrapping function without body --- idea/testData/javaFacade/wrapFunInClassWithoutBody.kt | 5 +++++ .../jetbrains/jet/plugin/javaFacade/JetJavaFacadeTest.java | 4 ++++ 2 files changed, 9 insertions(+) create mode 100644 idea/testData/javaFacade/wrapFunInClassWithoutBody.kt diff --git a/idea/testData/javaFacade/wrapFunInClassWithoutBody.kt b/idea/testData/javaFacade/wrapFunInClassWithoutBody.kt new file mode 100644 index 00000000000..4fc3ec14070 --- /dev/null +++ b/idea/testData/javaFacade/wrapFunInClassWithoutBody.kt @@ -0,0 +1,5 @@ +package some + +open class Hello { + open fun hello() = "DoSomething" +} \ No newline at end of file diff --git a/idea/tests/org/jetbrains/jet/plugin/javaFacade/JetJavaFacadeTest.java b/idea/tests/org/jetbrains/jet/plugin/javaFacade/JetJavaFacadeTest.java index fbdae321873..2b91d146ee7 100644 --- a/idea/tests/org/jetbrains/jet/plugin/javaFacade/JetJavaFacadeTest.java +++ b/idea/tests/org/jetbrains/jet/plugin/javaFacade/JetJavaFacadeTest.java @@ -51,6 +51,10 @@ public class JetJavaFacadeTest extends LightCodeInsightFixtureTestCase { doTestWrapMethod(false); } + public void testWrapFunInClassWithoutBody() { + doTestWrapMethod(true); + } + public void testWrapFunInClassObject() { doTestWrapMethod(true); } From d97ab295886151496e604204bb9de3e20e9db2a7 Mon Sep 17 00:00:00 2001 From: Nikolay Krasko Date: Thu, 16 May 2013 19:08:06 +0400 Subject: [PATCH 106/249] Add test for wrapping function with default parameters --- idea/testData/javaFacade/wrapTopLevelFunWithDefaultParams.kt | 3 +++ .../jetbrains/jet/plugin/javaFacade/JetJavaFacadeTest.java | 4 ++++ 2 files changed, 7 insertions(+) create mode 100644 idea/testData/javaFacade/wrapTopLevelFunWithDefaultParams.kt diff --git a/idea/testData/javaFacade/wrapTopLevelFunWithDefaultParams.kt b/idea/testData/javaFacade/wrapTopLevelFunWithDefaultParams.kt new file mode 100644 index 00000000000..dec6cd76068 --- /dev/null +++ b/idea/testData/javaFacade/wrapTopLevelFunWithDefaultParams.kt @@ -0,0 +1,3 @@ +fun test(some: Int = 12) { + println(some) +} \ No newline at end of file diff --git a/idea/tests/org/jetbrains/jet/plugin/javaFacade/JetJavaFacadeTest.java b/idea/tests/org/jetbrains/jet/plugin/javaFacade/JetJavaFacadeTest.java index 2b91d146ee7..29d19e723a7 100644 --- a/idea/tests/org/jetbrains/jet/plugin/javaFacade/JetJavaFacadeTest.java +++ b/idea/tests/org/jetbrains/jet/plugin/javaFacade/JetJavaFacadeTest.java @@ -95,6 +95,10 @@ public class JetJavaFacadeTest extends LightCodeInsightFixtureTestCase { doTestWrapClass(); } + public void testWrapTopLevelFunWithDefaultParams() { + doTestWrapMethod(true); + } + public void testEa38770() { myFixture.configureByFile(getTestName(true) + ".kt"); From 312bd6f828ad0664ad2176771a6769f9f3b6e6a6 Mon Sep 17 00:00:00 2001 From: Nikolay Krasko Date: Thu, 16 May 2013 19:07:53 +0400 Subject: [PATCH 107/249] Get PsiMethod wrappers for properties and property accessors --- .../jetbrains/jet/asJava/LightClassUtil.java | 180 ++++++++++++++---- .../javaFacade/wrapValTopLevelProperty.kt | 1 + .../javaFacade/wrapVarPropertyInClass.kt | 3 + .../javaFacade/wrapVarPropertyInLocalClass.kt | 5 + .../wrapVarPropertyWithAccessorsInTrait.kt | 5 + .../javaFacade/wrapVarTopLevelAccessor.kt | 3 + .../javaFacade/wrapVarTopLevelProperty.kt | 1 + .../plugin/javaFacade/JetJavaFacadeTest.java | 74 ++++++- 8 files changed, 225 insertions(+), 47 deletions(-) create mode 100644 idea/testData/javaFacade/wrapValTopLevelProperty.kt create mode 100644 idea/testData/javaFacade/wrapVarPropertyInClass.kt create mode 100644 idea/testData/javaFacade/wrapVarPropertyInLocalClass.kt create mode 100644 idea/testData/javaFacade/wrapVarPropertyWithAccessorsInTrait.kt create mode 100644 idea/testData/javaFacade/wrapVarTopLevelAccessor.kt create mode 100644 idea/testData/javaFacade/wrapVarTopLevelProperty.kt diff --git a/compiler/jet.as.java.psi/src/org/jetbrains/jet/asJava/LightClassUtil.java b/compiler/jet.as.java.psi/src/org/jetbrains/jet/asJava/LightClassUtil.java index 686b92d5cc9..04104a33439 100644 --- a/compiler/jet.as.java.psi/src/org/jetbrains/jet/asJava/LightClassUtil.java +++ b/compiler/jet.as.java.psi/src/org/jetbrains/jet/asJava/LightClassUtil.java @@ -31,10 +31,13 @@ import com.intellij.psi.search.GlobalSearchScope; import com.intellij.psi.stubs.PsiFileStub; import com.intellij.psi.stubs.StubElement; import com.intellij.psi.util.PsiTreeUtil; +import com.intellij.util.SmartList; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.jet.codegen.binding.PsiCodegenPredictor; import org.jetbrains.jet.lang.psi.*; +import org.jetbrains.jet.lang.resolve.java.JetClsMethod; +import org.jetbrains.jet.lang.resolve.java.JvmAbi; import org.jetbrains.jet.lang.resolve.java.JvmClassName; import org.jetbrains.jet.lang.resolve.name.FqName; import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns; @@ -42,6 +45,7 @@ import org.jetbrains.jet.utils.KotlinVfsUtil; import java.net.MalformedURLException; import java.net.URL; +import java.util.*; public class LightClassUtil { private static final Logger LOG = Logger.getInstance(LightClassUtil.class); @@ -116,42 +120,70 @@ public class LightClassUtil { return LightClassGenerationSupport.getInstance(classOrObject.getProject()).getPsiClass(classOrObject); } + @Nullable + public static PsiMethod getLightClassAccessorMethod(@NotNull JetPropertyAccessor accessor) { + return getPsiMethodWrapper(accessor); + } + + @NotNull + public static PropertyAccessorsPsiMethods getLightClassPropertyMethods(@NotNull JetProperty property) { + JetPropertyAccessor getter = property.getGetter(); + JetPropertyAccessor setter = property.getSetter(); + + PsiMethod getterWrapper = getter != null ? getLightClassAccessorMethod(getter) : null; + PsiMethod setterWrapper = setter != null ? getLightClassAccessorMethod(setter) : null; + + if (getterWrapper == null || setterWrapper == null) { + List wrappers = getPsiMethodWrappers(property, true); + assert wrappers.size() <= 2 : "Maximum two wrappers are expected to be generated for property"; + + for (PsiMethod wrapper : wrappers) { + if (wrapper.getName().startsWith(JvmAbi.SETTER_PREFIX)) { + assert setterWrapper == null : String.format( + "Setter accessor isn't expected to be reassigned (old: %s, new: %s)", setterWrapper, wrapper); + + setterWrapper = wrapper; + } + else { + assert getterWrapper == null : String.format( + "Getter accessor isn't expected to be reassigned (old: %s, new: %s)", getterWrapper, wrapper); + + getterWrapper = wrapper; + } + } + } + + return new PropertyAccessorsPsiMethods(getterWrapper, setterWrapper); + } + @Nullable public static PsiMethod getLightClassMethod(@NotNull JetNamedFunction function) { - //noinspection unchecked - if (PsiTreeUtil.getParentOfType(function, JetFunction.class, JetProperty.class) != null) { - // Don't genClassOrObject method wrappers for internal declarations. Their classes are not generated during calcStub - // with ClassBuilderMode.SIGNATURES mode, and this produces "Class not found exception" in getDelegate() - return null; + return getPsiMethodWrapper(function); + } + + @Nullable + private static PsiMethod getPsiMethodWrapper(@NotNull JetDeclaration declaration) { + List wrappers = getPsiMethodWrappers(declaration, false); + return !wrappers.isEmpty() ? wrappers.get(0) : null; + } + + @NotNull + private static List getPsiMethodWrappers(@NotNull JetDeclaration declaration, boolean collectAll) { + PsiClass psiClass = getWrappingClass(declaration); + if (psiClass == null) { + return Collections.emptyList(); } - Project project = function.getProject(); - - PsiElement parent = function.getParent(); - PsiClass psiClass; - if (parent == function.getContainingFile()) { - // top-level function - JvmClassName jvmClassName = PsiCodegenPredictor.getPredefinedJvmClassName((JetFile) parent, true); - if (jvmClassName == null) return null; - - String fqName = jvmClassName.getFqName().getFqName(); - psiClass = JavaElementFinder.getInstance(project).findClass(fqName, GlobalSearchScope.allScope(project)); - } - else { - if (!(parent instanceof JetClassBody)) return null; - assert parent.getParent() instanceof JetClassOrObject; - - // function in a class - JetClassOrObject classOrObject = (JetClassOrObject) parent.getParent(); - psiClass = getPsiClass(classOrObject); - } - - if (psiClass == null) return null; - + List methods = new SmartList(); for (PsiMethod method : psiClass.getMethods()) { try { - if (method instanceof PsiCompiledElement && ((PsiCompiledElement) method).getMirror() == function) { - return method; + if (method instanceof JetClsMethod) { + if (method instanceof PsiCompiledElement && ((PsiCompiledElement) method).getMirror() == declaration) { + methods.add(method); + if (!collectAll) { + return methods; + } + } } } catch (ProcessCanceledException e) { @@ -159,24 +191,94 @@ public class LightClassUtil { } catch (Throwable e) { throw new IllegalStateException( - "Error while wrapping function " + function.getName() + + "Error while wrapping declaration " + declaration.getName() + "Context\n:" + String.format("=== In file ===\n" + - "%s\n" + - "===On element===\n" + - "%s\n" + - "===WrappedElement===\n" + - "%s\n", - function.getContainingFile().getText(), - function.getText(), - method.toString()), + "%s\n" + + "=== On element ===\n" + + "%s\n" + + "=== WrappedElement ===\n" + + "%s\n", + declaration.getContainingFile().getText(), + declaration.getText(), + method.toString()), e ); } } + return methods; + } + + @Nullable + private static PsiClass getWrappingClass(@NotNull JetDeclaration declaration) { + if (declaration instanceof JetPropertyAccessor) { + PsiElement propertyParent = declaration.getParent(); + assert propertyParent instanceof JetProperty : "JetProperty is expected to be parent of accessor"; + + declaration = (JetProperty) propertyParent; + } + + //noinspection unchecked + if (PsiTreeUtil.getParentOfType(declaration, JetFunction.class, JetProperty.class) != null) { + // Can't get wrappers for internal declarations. Their classes are not generated during calcStub + // with ClassBuilderMode.SIGNATURES mode, and this produces "Class not found exception" in getDelegate() + return null; + } + + PsiElement parent = declaration.getParent(); + + if (parent instanceof JetFile) { + // top-level declaration + JvmClassName jvmName = PsiCodegenPredictor.getPredefinedJvmClassName((JetFile) parent, true); + if (jvmName != null) { + Project project = declaration.getProject(); + + String fqName = jvmName.getFqName().getFqName(); + return JavaElementFinder.getInstance(project).findClass(fqName, GlobalSearchScope.allScope(project)); + } + } + else if (parent instanceof JetClassBody) { + assert parent.getParent() instanceof JetClassOrObject; + return getPsiClass((JetClassOrObject) parent.getParent()); + } + return null; } + public static class PropertyAccessorsPsiMethods implements Iterable { + private final PsiMethod getter; + private final PsiMethod setter; + private final Collection accessors = new ArrayList(2); + + PropertyAccessorsPsiMethods(@Nullable PsiMethod getter, @Nullable PsiMethod setter) { + this.getter = getter; + if (getter != null) { + accessors.add(getter); + } + + this.setter = setter; + if (setter != null) { + accessors.add(setter); + } + } + + @Nullable + public PsiMethod getGetter() { + return getter; + } + + @Nullable + public PsiMethod getSetter() { + return setter; + } + + @NotNull + @Override + public Iterator iterator() { + return accessors.iterator(); + } + } + private LightClassUtil() {} } diff --git a/idea/testData/javaFacade/wrapValTopLevelProperty.kt b/idea/testData/javaFacade/wrapValTopLevelProperty.kt new file mode 100644 index 00000000000..5d903b0a451 --- /dev/null +++ b/idea/testData/javaFacade/wrapValTopLevelProperty.kt @@ -0,0 +1 @@ +val test: Int? = null \ No newline at end of file diff --git a/idea/testData/javaFacade/wrapVarPropertyInClass.kt b/idea/testData/javaFacade/wrapVarPropertyInClass.kt new file mode 100644 index 00000000000..8aaf0e814fe --- /dev/null +++ b/idea/testData/javaFacade/wrapVarPropertyInClass.kt @@ -0,0 +1,3 @@ +class Test { + var test = "Test" +} \ No newline at end of file diff --git a/idea/testData/javaFacade/wrapVarPropertyInLocalClass.kt b/idea/testData/javaFacade/wrapVarPropertyInLocalClass.kt new file mode 100644 index 00000000000..e89a96f78cf --- /dev/null +++ b/idea/testData/javaFacade/wrapVarPropertyInLocalClass.kt @@ -0,0 +1,5 @@ +fun test() { + class Test { + var someProperty = "No wrapper is expected" + } +} \ No newline at end of file diff --git a/idea/testData/javaFacade/wrapVarPropertyWithAccessorsInTrait.kt b/idea/testData/javaFacade/wrapVarPropertyWithAccessorsInTrait.kt new file mode 100644 index 00000000000..9b324ad7dc7 --- /dev/null +++ b/idea/testData/javaFacade/wrapVarPropertyWithAccessorsInTrait.kt @@ -0,0 +1,5 @@ +trait Hello { + var some: String + get() = "Hi" + set(value) {} +} \ No newline at end of file diff --git a/idea/testData/javaFacade/wrapVarTopLevelAccessor.kt b/idea/testData/javaFacade/wrapVarTopLevelAccessor.kt new file mode 100644 index 00000000000..f8ae61889b9 --- /dev/null +++ b/idea/testData/javaFacade/wrapVarTopLevelAccessor.kt @@ -0,0 +1,3 @@ +var some: String + get() = "Hi" + set(value) {} diff --git a/idea/testData/javaFacade/wrapVarTopLevelProperty.kt b/idea/testData/javaFacade/wrapVarTopLevelProperty.kt new file mode 100644 index 00000000000..c242b701c67 --- /dev/null +++ b/idea/testData/javaFacade/wrapVarTopLevelProperty.kt @@ -0,0 +1 @@ +var test: Int? = null \ No newline at end of file diff --git a/idea/tests/org/jetbrains/jet/plugin/javaFacade/JetJavaFacadeTest.java b/idea/tests/org/jetbrains/jet/plugin/javaFacade/JetJavaFacadeTest.java index 29d19e723a7..8f444c4fa6e 100644 --- a/idea/tests/org/jetbrains/jet/plugin/javaFacade/JetJavaFacadeTest.java +++ b/idea/tests/org/jetbrains/jet/plugin/javaFacade/JetJavaFacadeTest.java @@ -24,8 +24,7 @@ import com.intellij.testFramework.fixtures.LightCodeInsightFixtureTestCase; import org.jetbrains.annotations.NotNull; import org.jetbrains.jet.asJava.KotlinLightClass; import org.jetbrains.jet.asJava.LightClassUtil; -import org.jetbrains.jet.lang.psi.JetClass; -import org.jetbrains.jet.lang.psi.JetNamedFunction; +import org.jetbrains.jet.lang.psi.*; import org.jetbrains.jet.lang.resolve.java.JvmAbi; import org.jetbrains.jet.plugin.JetLightProjectDescriptor; import org.jetbrains.jet.plugin.PluginTestCaseBase; @@ -99,6 +98,30 @@ public class JetJavaFacadeTest extends LightCodeInsightFixtureTestCase { doTestWrapMethod(true); } + public void testWrapValTopLevelProperty() { + doTestWrapProperty(true, false); + } + + public void testWrapVarPropertyInClass() { + doTestWrapProperty(true, true); + } + + public void testWrapVarPropertyWithAccessorsInTrait() { + doTestWrapProperty(true, true); + } + + public void testWrapVarTopLevelProperty() { + doTestWrapProperty(true, true); + } + + public void testWrapVarPropertyInLocalClass() { + doTestWrapProperty(false, false); + } + + public void testWrapVarTopLevelAccessor() { + doTestWrapPropertyAccessor(true); + } + public void testEa38770() { myFixture.configureByFile(getTestName(true) + ".kt"); @@ -166,6 +189,37 @@ public class JetJavaFacadeTest extends LightCodeInsightFixtureTestCase { } private void doTestWrapMethod(boolean shouldBeWrapped) { + JetNamedFunction jetFunction = getPreparedElement(JetNamedFunction.class); + + // Should not fail! + PsiMethod psiMethod = LightClassUtil.getLightClassMethod(jetFunction); + + checkDeclarationMethodWrapped(shouldBeWrapped, jetFunction, psiMethod); + } + + private void doTestWrapProperty(boolean shouldWrapGetter, boolean shouldWrapSetter) { + JetProperty jetProperty = getPreparedElement(JetProperty.class); + + // Should not fail! + LightClassUtil.PropertyAccessorsPsiMethods propertyAccessors = LightClassUtil.getLightClassPropertyMethods(jetProperty); + + JetPropertyAccessor getter = jetProperty.getGetter(); + JetPropertyAccessor setter = jetProperty.getSetter(); + + checkDeclarationMethodWrapped(shouldWrapGetter, getter != null ? getter : jetProperty, propertyAccessors.getGetter()); + checkDeclarationMethodWrapped(shouldWrapSetter, setter != null ? setter : jetProperty, propertyAccessors.getSetter()); + } + + private void doTestWrapPropertyAccessor(boolean shouldWrapAccessor) { + JetPropertyAccessor jetPropertyAccessor = getPreparedElement(JetPropertyAccessor.class); + + // Should not fail! + PsiMethod propertyAccessors = LightClassUtil.getLightClassAccessorMethod(jetPropertyAccessor); + checkDeclarationMethodWrapped(shouldWrapAccessor, jetPropertyAccessor, propertyAccessors); + } + + @NotNull + private T getPreparedElement(Class elementClass) { myFixture.configureByFile(getTestName(true) + ".kt"); int offset = myFixture.getEditor().getCaretModel().getOffset(); @@ -173,16 +227,20 @@ public class JetJavaFacadeTest extends LightCodeInsightFixtureTestCase { assertNotNull("Caret should be set for tested file", elementAt); - JetNamedFunction jetFunction = PsiTreeUtil.getParentOfType(elementAt, JetNamedFunction.class); - assertNotNull("Caret should be placed to function definition", jetFunction); + T caretElement = PsiTreeUtil.getParentOfType(elementAt, elementClass); + assertNotNull( + String.format("Caret should be placed to element of type: %s, but was at element '%s' of type %s", + elementClass, elementAt, elementAt.getClass()), + caretElement); - // Should not fail! - PsiMethod psiMethod = LightClassUtil.getLightClassMethod(jetFunction); + return caretElement; + } + private static void checkDeclarationMethodWrapped(boolean shouldBeWrapped, JetDeclaration declaration, PsiMethod psiMethod) { if (shouldBeWrapped) { - assertNotNull(String.format("Failed to wrap jetFunction '%s' to method", jetFunction.getText()), psiMethod); + assertNotNull(String.format("Failed to wrap declaration '%s' to method", declaration.getText()), psiMethod); assertInstanceOf(psiMethod, PsiCompiledElement.class); - assertEquals("Invalid original element for generated method", ((PsiCompiledElement) psiMethod).getMirror(), jetFunction); + assertEquals("Invalid original element for generated method", ((PsiCompiledElement) psiMethod).getMirror(), declaration); } else { assertNull("There should be no wrapper for given method", psiMethod); From 5cc49f55f36e5fd78d763a9b927cba91e99fbeec Mon Sep 17 00:00:00 2001 From: Nikolay Krasko Date: Fri, 26 Apr 2013 18:38:43 +0400 Subject: [PATCH 108/249] KT-3542 Can't navigate to property implementation #KT-3542 Fixed --- .../search/KotlinDefinitionsSearcher.java | 33 +++++++++++++++++++ .../PropertyOverriddenNavigation.kt | 17 ++++++++++ .../ImplementVarInJava.java | 11 +++++++ .../ImplementVarInJava/ImplementVarInJava.kt | 8 +++++ .../JetGotoImplementationMultifileTest.java | 4 +++ .../navigation/JetGotoImplementationTest.java | 4 +++ 6 files changed, 77 insertions(+) create mode 100644 idea/testData/navigation/implementations/PropertyOverriddenNavigation.kt create mode 100644 idea/testData/navigation/implementations/multifile/ImplementVarInJava/ImplementVarInJava.java create mode 100644 idea/testData/navigation/implementations/multifile/ImplementVarInJava/ImplementVarInJava.kt diff --git a/idea/src/org/jetbrains/jet/plugin/search/KotlinDefinitionsSearcher.java b/idea/src/org/jetbrains/jet/plugin/search/KotlinDefinitionsSearcher.java index 6b3d2837d87..950032e1fbe 100644 --- a/idea/src/org/jetbrains/jet/plugin/search/KotlinDefinitionsSearcher.java +++ b/idea/src/org/jetbrains/jet/plugin/search/KotlinDefinitionsSearcher.java @@ -21,6 +21,7 @@ import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.application.QueryExecutorBase; import com.intellij.openapi.util.Computable; import com.intellij.psi.PsiClass; +import com.intellij.psi.PsiCompiledElement; import com.intellij.psi.PsiElement; import com.intellij.psi.PsiMethod; import com.intellij.psi.search.searches.ClassInheritorsSearch; @@ -30,6 +31,8 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.jet.asJava.LightClassUtil; import org.jetbrains.jet.lang.psi.JetClass; import org.jetbrains.jet.lang.psi.JetNamedFunction; +import org.jetbrains.jet.lang.psi.JetProperty; +import org.jetbrains.jet.lang.psi.JetPropertyAccessor; public class KotlinDefinitionsSearcher extends QueryExecutorBase { @Override @@ -41,6 +44,10 @@ public class KotlinDefinitionsSearcher extends QueryExecutorBase consumer) { @@ -67,4 +74,30 @@ public class KotlinDefinitionsSearcher extends QueryExecutorBase consumer) { + LightClassUtil.PropertyAccessorsPsiMethods accessorsPsiMethods = ApplicationManager.getApplication().runReadAction( + new Computable() { + @Override + public LightClassUtil.PropertyAccessorsPsiMethods compute() { + return LightClassUtil.getLightClassPropertyMethods(property); + } + }); + + for (PsiMethod method : accessorsPsiMethods) { + PsiMethod[] implementations = MethodImplementationsSearch.getMethodImplementations(method); + for (PsiMethod implementation : implementations) { + PsiElement mirrorElement = implementation instanceof PsiCompiledElement ? ((PsiCompiledElement) implementation).getMirror() : null; + if (mirrorElement instanceof JetProperty) { + consumer.process(mirrorElement); + } + else if (mirrorElement instanceof JetPropertyAccessor && mirrorElement.getParent() instanceof JetProperty) { + consumer.process(mirrorElement.getParent()); + } + else { + consumer.process(implementation); + } + } + } + } } diff --git a/idea/testData/navigation/implementations/PropertyOverriddenNavigation.kt b/idea/testData/navigation/implementations/PropertyOverriddenNavigation.kt new file mode 100644 index 00000000000..31ed7520492 --- /dev/null +++ b/idea/testData/navigation/implementations/PropertyOverriddenNavigation.kt @@ -0,0 +1,17 @@ +package testing + +open class Base { + open var test = 12 +} + +open class SubBase: Base() { + override var test = 12 +} + +class SubSubBase: SubBase() { + override var test = 12 +} + + +// REF: (testing.SubBase).test +// REF: (testing.SubSubBase).test \ No newline at end of file diff --git a/idea/testData/navigation/implementations/multifile/ImplementVarInJava/ImplementVarInJava.java b/idea/testData/navigation/implementations/multifile/ImplementVarInJava/ImplementVarInJava.java new file mode 100644 index 00000000000..9cec2ab5d00 --- /dev/null +++ b/idea/testData/navigation/implementations/multifile/ImplementVarInJava/ImplementVarInJava.java @@ -0,0 +1,11 @@ +package testing.jj; + +public class JavaBase extends testing.kt.KotlinBase { + @Override + public String getSome() { + } + + @Override + public void setSome(String someValue) { + } +} \ No newline at end of file diff --git a/idea/testData/navigation/implementations/multifile/ImplementVarInJava/ImplementVarInJava.kt b/idea/testData/navigation/implementations/multifile/ImplementVarInJava/ImplementVarInJava.kt new file mode 100644 index 00000000000..c1d0b9b8540 --- /dev/null +++ b/idea/testData/navigation/implementations/multifile/ImplementVarInJava/ImplementVarInJava.kt @@ -0,0 +1,8 @@ +package testing.kt + +open class KotlinBase { + open var some = "Test" +} + +// REF: (in testing.jj.JavaBase).getSome() +// REF: (in testing.jj.JavaBase).setSome(String) \ No newline at end of file diff --git a/idea/tests/org/jetbrains/jet/plugin/navigation/JetGotoImplementationMultifileTest.java b/idea/tests/org/jetbrains/jet/plugin/navigation/JetGotoImplementationMultifileTest.java index ed6d73c4299..22fc50b54cf 100644 --- a/idea/tests/org/jetbrains/jet/plugin/navigation/JetGotoImplementationMultifileTest.java +++ b/idea/tests/org/jetbrains/jet/plugin/navigation/JetGotoImplementationMultifileTest.java @@ -39,6 +39,10 @@ public class JetGotoImplementationMultifileTest extends CodeInsightTestCase { doKotlinJavaTest(); } + public void testImplementVarInJava() throws Exception { + doKotlinJavaTest(); + } + private void doKotlinJavaTest() throws Exception { doMultifileTest(getTestName(false) + ".kt", getTestName(false) + ".java"); } diff --git a/idea/tests/org/jetbrains/jet/plugin/navigation/JetGotoImplementationTest.java b/idea/tests/org/jetbrains/jet/plugin/navigation/JetGotoImplementationTest.java index a863e867bbd..27e2f18ef46 100644 --- a/idea/tests/org/jetbrains/jet/plugin/navigation/JetGotoImplementationTest.java +++ b/idea/tests/org/jetbrains/jet/plugin/navigation/JetGotoImplementationTest.java @@ -37,6 +37,10 @@ public class JetGotoImplementationTest extends LightCodeInsightTestCase { doTest(); } + public void testPropertyOverriddenNavigation() { + doTest(); + } + @NotNull @Override protected String getTestDataPath() { From 0a2ca39f88e50522bdcfbeee3c3ce2e65ec1c44d Mon Sep 17 00:00:00 2001 From: Nikolay Krasko Date: Tue, 14 May 2013 01:09:51 +0400 Subject: [PATCH 109/249] Search implementations for properties from constructor parameters --- .../jetbrains/jet/asJava/LightClassUtil.java | 60 ++++++++++++------- .../search/KotlinDefinitionsSearcher.java | 32 ++++++++-- .../javaFacade/wrapConstructorField.kt | 1 + .../javaFacade/wrapConstructorParameter.kt | 1 + .../javaFacade/wrapFunctionParameter.kt | 1 + .../plugin/javaFacade/JetJavaFacadeTest.java | 22 +++++++ 6 files changed, 91 insertions(+), 26 deletions(-) create mode 100644 idea/testData/javaFacade/wrapConstructorField.kt create mode 100644 idea/testData/javaFacade/wrapConstructorParameter.kt create mode 100644 idea/testData/javaFacade/wrapFunctionParameter.kt diff --git a/compiler/jet.as.java.psi/src/org/jetbrains/jet/asJava/LightClassUtil.java b/compiler/jet.as.java.psi/src/org/jetbrains/jet/asJava/LightClassUtil.java index 04104a33439..7ef41f7d4c3 100644 --- a/compiler/jet.as.java.psi/src/org/jetbrains/jet/asJava/LightClassUtil.java +++ b/compiler/jet.as.java.psi/src/org/jetbrains/jet/asJava/LightClassUtil.java @@ -133,27 +133,11 @@ public class LightClassUtil { PsiMethod getterWrapper = getter != null ? getLightClassAccessorMethod(getter) : null; PsiMethod setterWrapper = setter != null ? getLightClassAccessorMethod(setter) : null; - if (getterWrapper == null || setterWrapper == null) { - List wrappers = getPsiMethodWrappers(property, true); - assert wrappers.size() <= 2 : "Maximum two wrappers are expected to be generated for property"; + return extractPropertyAccessors(property, getterWrapper, setterWrapper); + } - for (PsiMethod wrapper : wrappers) { - if (wrapper.getName().startsWith(JvmAbi.SETTER_PREFIX)) { - assert setterWrapper == null : String.format( - "Setter accessor isn't expected to be reassigned (old: %s, new: %s)", setterWrapper, wrapper); - - setterWrapper = wrapper; - } - else { - assert getterWrapper == null : String.format( - "Getter accessor isn't expected to be reassigned (old: %s, new: %s)", getterWrapper, wrapper); - - getterWrapper = wrapper; - } - } - } - - return new PropertyAccessorsPsiMethods(getterWrapper, setterWrapper); + public static PropertyAccessorsPsiMethods getLightClassPropertyMethods(@NotNull JetParameter parameter) { + return extractPropertyAccessors(parameter, null, null); } @Nullable @@ -212,6 +196,10 @@ public class LightClassUtil { @Nullable private static PsiClass getWrappingClass(@NotNull JetDeclaration declaration) { + if (declaration instanceof JetParameter && declaration.getParent().getParent() instanceof JetClass) { + return getPsiClass((JetClassOrObject) declaration.getParent().getParent()); + } + if (declaration instanceof JetPropertyAccessor) { PsiElement propertyParent = declaration.getParent(); assert propertyParent instanceof JetProperty : "JetProperty is expected to be parent of accessor"; @@ -246,6 +234,38 @@ public class LightClassUtil { return null; } + private static PropertyAccessorsPsiMethods extractPropertyAccessors( + @NotNull JetDeclaration jetDeclaration, + @Nullable PsiMethod specialGetter, @Nullable PsiMethod specialSetter) + { + PsiMethod getterWrapper = specialGetter; + PsiMethod setterWrapper = specialSetter; + + if (getterWrapper == null || setterWrapper == null) { + // If some getter or setter isn't found yet try to get it from wrappers for general declaration + + List wrappers = getPsiMethodWrappers(jetDeclaration, true); + assert wrappers.size() <= 2 : "Maximum two wrappers are expected to be generated for declaration: " + jetDeclaration.getText(); + + for (PsiMethod wrapper : wrappers) { + if (wrapper.getName().startsWith(JvmAbi.SETTER_PREFIX)) { + assert setterWrapper == null : String.format( + "Setter accessor isn't expected to be reassigned (old: %s, new: %s)", setterWrapper, wrapper); + + setterWrapper = wrapper; + } + else { + assert getterWrapper == null : String.format( + "Getter accessor isn't expected to be reassigned (old: %s, new: %s)", getterWrapper, wrapper); + + getterWrapper = wrapper; + } + } + } + + return new PropertyAccessorsPsiMethods(getterWrapper, setterWrapper); + } + public static class PropertyAccessorsPsiMethods implements Iterable { private final PsiMethod getter; private final PsiMethod setter; diff --git a/idea/src/org/jetbrains/jet/plugin/search/KotlinDefinitionsSearcher.java b/idea/src/org/jetbrains/jet/plugin/search/KotlinDefinitionsSearcher.java index 950032e1fbe..89980b7611d 100644 --- a/idea/src/org/jetbrains/jet/plugin/search/KotlinDefinitionsSearcher.java +++ b/idea/src/org/jetbrains/jet/plugin/search/KotlinDefinitionsSearcher.java @@ -29,10 +29,7 @@ import com.intellij.util.Processor; import com.intellij.util.containers.ContainerUtil; import org.jetbrains.annotations.NotNull; import org.jetbrains.jet.asJava.LightClassUtil; -import org.jetbrains.jet.lang.psi.JetClass; -import org.jetbrains.jet.lang.psi.JetNamedFunction; -import org.jetbrains.jet.lang.psi.JetProperty; -import org.jetbrains.jet.lang.psi.JetPropertyAccessor; +import org.jetbrains.jet.lang.psi.*; public class KotlinDefinitionsSearcher extends QueryExecutorBase { @Override @@ -48,6 +45,13 @@ public class KotlinDefinitionsSearcher extends QueryExecutorBase consumer) { @@ -75,6 +79,18 @@ public class KotlinDefinitionsSearcher extends QueryExecutorBase consumer) { + LightClassUtil.PropertyAccessorsPsiMethods accessorsPsiMethods = ApplicationManager.getApplication().runReadAction( + new Computable() { + @Override + public LightClassUtil.PropertyAccessorsPsiMethods compute() { + return LightClassUtil.getLightClassPropertyMethods(parameter); + } + }); + + processPropertyImplementationsMethods(accessorsPsiMethods, consumer); + } + private static void processPropertyImplementations(@NotNull final JetProperty property, @NotNull Processor consumer) { LightClassUtil.PropertyAccessorsPsiMethods accessorsPsiMethods = ApplicationManager.getApplication().runReadAction( new Computable() { @@ -84,11 +100,15 @@ public class KotlinDefinitionsSearcher extends QueryExecutorBase consumer) { + for (PsiMethod method : accessors) { PsiMethod[] implementations = MethodImplementationsSearch.getMethodImplementations(method); for (PsiMethod implementation : implementations) { PsiElement mirrorElement = implementation instanceof PsiCompiledElement ? ((PsiCompiledElement) implementation).getMirror() : null; - if (mirrorElement instanceof JetProperty) { + if (mirrorElement instanceof JetProperty || mirrorElement instanceof JetParameter) { consumer.process(mirrorElement); } else if (mirrorElement instanceof JetPropertyAccessor && mirrorElement.getParent() instanceof JetProperty) { diff --git a/idea/testData/javaFacade/wrapConstructorField.kt b/idea/testData/javaFacade/wrapConstructorField.kt new file mode 100644 index 00000000000..37419fc3881 --- /dev/null +++ b/idea/testData/javaFacade/wrapConstructorField.kt @@ -0,0 +1 @@ +class Test(var field: Int) \ No newline at end of file diff --git a/idea/testData/javaFacade/wrapConstructorParameter.kt b/idea/testData/javaFacade/wrapConstructorParameter.kt new file mode 100644 index 00000000000..87fcd86a1f0 --- /dev/null +++ b/idea/testData/javaFacade/wrapConstructorParameter.kt @@ -0,0 +1 @@ +class Test(var field: Int, parameter: Int) \ No newline at end of file diff --git a/idea/testData/javaFacade/wrapFunctionParameter.kt b/idea/testData/javaFacade/wrapFunctionParameter.kt new file mode 100644 index 00000000000..68f96dab810 --- /dev/null +++ b/idea/testData/javaFacade/wrapFunctionParameter.kt @@ -0,0 +1 @@ +fun testFun(parameter: Int) = 0 \ No newline at end of file diff --git a/idea/tests/org/jetbrains/jet/plugin/javaFacade/JetJavaFacadeTest.java b/idea/tests/org/jetbrains/jet/plugin/javaFacade/JetJavaFacadeTest.java index 8f444c4fa6e..a43fd97d429 100644 --- a/idea/tests/org/jetbrains/jet/plugin/javaFacade/JetJavaFacadeTest.java +++ b/idea/tests/org/jetbrains/jet/plugin/javaFacade/JetJavaFacadeTest.java @@ -122,6 +122,18 @@ public class JetJavaFacadeTest extends LightCodeInsightFixtureTestCase { doTestWrapPropertyAccessor(true); } + public void testWrapConstructorField() { + doTestWrapParameter(true, true); + } + + public void testWrapConstructorParameter() { + doTestWrapParameter(false, false); + } + + public void testWrapFunctionParameter() { + doTestWrapParameter(false, false); + } + public void testEa38770() { myFixture.configureByFile(getTestName(true) + ".kt"); @@ -197,6 +209,16 @@ public class JetJavaFacadeTest extends LightCodeInsightFixtureTestCase { checkDeclarationMethodWrapped(shouldBeWrapped, jetFunction, psiMethod); } + private void doTestWrapParameter(boolean shouldWrapGetter, boolean shouldWrapSetter) { + JetParameter jetParameter = getPreparedElement(JetParameter.class); + + // Should not fail! + LightClassUtil.PropertyAccessorsPsiMethods propertyAccessors = LightClassUtil.getLightClassPropertyMethods(jetParameter); + + checkDeclarationMethodWrapped(shouldWrapGetter, jetParameter, propertyAccessors.getGetter()); + checkDeclarationMethodWrapped(shouldWrapSetter, jetParameter, propertyAccessors.getSetter()); + } + private void doTestWrapProperty(boolean shouldWrapGetter, boolean shouldWrapSetter) { JetProperty jetProperty = getPreparedElement(JetProperty.class); From 3c087965f108a44bbffc92f6a999f1e64d85e619 Mon Sep 17 00:00:00 2001 From: Nikolay Krasko Date: Wed, 8 May 2013 18:15:55 +0400 Subject: [PATCH 110/249] Add presentation renderer for field declared in constructor --- .../jetbrains/jet/lang/psi/JetParameter.java | 7 ++++- .../jetbrains/jet/lang/psi/JetPsiUtil.java | 7 ++++- idea/src/META-INF/plugin.xml | 2 ++ .../presentation/JetParameterPresenter.java | 28 +++++++++++++++++++ ...ConstructorPropertyOverriddenNavigation.kt | 12 ++++++++ .../navigation/JetGotoImplementationTest.java | 4 +++ 6 files changed, 58 insertions(+), 2 deletions(-) create mode 100644 idea/src/org/jetbrains/jet/plugin/presentation/JetParameterPresenter.java create mode 100644 idea/testData/navigation/implementations/ConstructorPropertyOverriddenNavigation.kt diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetParameter.java b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetParameter.java index 58ed3e5bf89..296ef03e3f4 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetParameter.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetParameter.java @@ -17,6 +17,8 @@ package org.jetbrains.jet.lang.psi; import com.intellij.lang.ASTNode; +import com.intellij.navigation.ItemPresentation; +import com.intellij.navigation.ItemPresentationProviders; import com.intellij.psi.stubs.IStubElementType; import com.intellij.util.ArrayFactory; import org.jetbrains.annotations.NotNull; @@ -107,5 +109,8 @@ public class JetParameter extends JetNamedDeclarationStub { return getNode().findChildByType(JetTokens.VAR_KEYWORD); } - + @Override + public ItemPresentation getPresentation() { + return ItemPresentationProviders.getItemPresentation(this); + } } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetPsiUtil.java b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetPsiUtil.java index 865bcc2622d..3228d0f9e32 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetPsiUtil.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetPsiUtil.java @@ -196,11 +196,16 @@ public class JetPsiUtil { else if (parent instanceof JetNamedFunction || parent instanceof JetClass) { firstPart = getFQName((JetNamedDeclaration) parent); } + else if (namedDeclaration instanceof JetParameter) { + if (((JetParameter) namedDeclaration).getValOrVarNode() != null && parent != null && parent.getParent() instanceof JetClassOrObject) { + firstPart = getFQName((JetClassOrObject) parent.getParent()); + } + } else if (parent instanceof JetObjectDeclaration) { if (parent.getParent() instanceof JetClassObject) { JetClassOrObject classOrObject = PsiTreeUtil.getParentOfType(parent, JetClassOrObject.class); if (classOrObject != null) { - firstPart = getFQName((JetNamedDeclaration) classOrObject); + firstPart = getFQName(classOrObject); } } else { diff --git a/idea/src/META-INF/plugin.xml b/idea/src/META-INF/plugin.xml index a942b5d6e55..f1e7fd11e46 100644 --- a/idea/src/META-INF/plugin.xml +++ b/idea/src/META-INF/plugin.xml @@ -219,6 +219,8 @@ forClass="org.jetbrains.jet.lang.psi.JetClass"/> + diff --git a/idea/src/org/jetbrains/jet/plugin/presentation/JetParameterPresenter.java b/idea/src/org/jetbrains/jet/plugin/presentation/JetParameterPresenter.java new file mode 100644 index 00000000000..54b34f3be1a --- /dev/null +++ b/idea/src/org/jetbrains/jet/plugin/presentation/JetParameterPresenter.java @@ -0,0 +1,28 @@ +/* + * Copyright 2010-2013 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.jetbrains.jet.plugin.presentation; + +import com.intellij.navigation.ItemPresentation; +import com.intellij.navigation.ItemPresentationProvider; +import org.jetbrains.jet.lang.psi.JetParameter; + +public class JetParameterPresenter implements ItemPresentationProvider { + @Override + public ItemPresentation getPresentation(JetParameter item) { + return new JetDefaultNamedDeclarationPresentation(item); + } +} diff --git a/idea/testData/navigation/implementations/ConstructorPropertyOverriddenNavigation.kt b/idea/testData/navigation/implementations/ConstructorPropertyOverriddenNavigation.kt new file mode 100644 index 00000000000..a7b04f331b2 --- /dev/null +++ b/idea/testData/navigation/implementations/ConstructorPropertyOverriddenNavigation.kt @@ -0,0 +1,12 @@ +package testing + +open class Test(open var some: Int) + +class OtherTestInConstructor(override var some: Int): Test(some) + +class OtherTestInBody(some: Int, other: String): Test(some) { + override var some: Int = some +} + +// REF: (testing.OtherTestInConstructor).some +// REF: (testing.OtherTestInBody).some \ No newline at end of file diff --git a/idea/tests/org/jetbrains/jet/plugin/navigation/JetGotoImplementationTest.java b/idea/tests/org/jetbrains/jet/plugin/navigation/JetGotoImplementationTest.java index 27e2f18ef46..dd81a32003a 100644 --- a/idea/tests/org/jetbrains/jet/plugin/navigation/JetGotoImplementationTest.java +++ b/idea/tests/org/jetbrains/jet/plugin/navigation/JetGotoImplementationTest.java @@ -41,6 +41,10 @@ public class JetGotoImplementationTest extends LightCodeInsightTestCase { doTest(); } + public void testConstructorPropertyOverriddenNavigation() { + doTest(); + } + @NotNull @Override protected String getTestDataPath() { From 9bb2d90bcaf13101a7833616b6f8042cbdc7a976 Mon Sep 17 00:00:00 2001 From: Nikolay Krasko Date: Mon, 6 May 2013 15:58:14 +0400 Subject: [PATCH 111/249] Go to implementation line markers for properties --- .../jetbrains/jet/plugin/JetBundle.properties | 8 + .../highlighter/JetLineMarkerProvider.java | 226 ++++++++++++++---- .../search/KotlinDefinitionsSearcher.java | 2 +- .../lineMarker/PropertyOverride.kt | 7 + .../OverrideImplementLineMarkerTest.java | 4 + 5 files changed, 201 insertions(+), 46 deletions(-) create mode 100644 idea/testData/codeInsight/lineMarker/PropertyOverride.kt diff --git a/idea/src/org/jetbrains/jet/plugin/JetBundle.properties b/idea/src/org/jetbrains/jet/plugin/JetBundle.properties index 0ac4c6666ce..868da4e6b67 100644 --- a/idea/src/org/jetbrains/jet/plugin/JetBundle.properties +++ b/idea/src/org/jetbrains/jet/plugin/JetBundle.properties @@ -202,3 +202,11 @@ add.name.to.argument.single=Add name to argument\: ''{0}'' add.name.to.argument.multiple=Add name to argument... add.name.to.argument.action=Add name to argument... add.name.to.parameter.name.chooser.title=Choose parameter name + +property.is.implemented.too.many=Has implementations +property.is.overridden.too.many=Is overridden in subclasses +property.is.implemented.header=Is implemented in
+property.is.overridden.header=Is overridden in
+ +navigation.title.overriding.property=Choose Implementation of {0} +navigation.findUsages.title.overriding.property=Overriding properties of {0} \ No newline at end of file diff --git a/idea/src/org/jetbrains/jet/plugin/highlighter/JetLineMarkerProvider.java b/idea/src/org/jetbrains/jet/plugin/highlighter/JetLineMarkerProvider.java index 25577f783f3..667bff4566a 100644 --- a/idea/src/org/jetbrains/jet/plugin/highlighter/JetLineMarkerProvider.java +++ b/idea/src/org/jetbrains/jet/plugin/highlighter/JetLineMarkerProvider.java @@ -16,18 +16,20 @@ package org.jetbrains.jet.plugin.highlighter; -import com.google.common.collect.Lists; -import com.google.common.collect.Maps; -import com.google.common.collect.Sets; +import com.google.common.collect.*; import com.intellij.codeHighlighting.Pass; import com.intellij.codeInsight.daemon.GutterIconNavigationHandler; import com.intellij.codeInsight.daemon.LineMarkerInfo; import com.intellij.codeInsight.daemon.LineMarkerProvider; +import com.intellij.codeInsight.daemon.impl.GutterIconTooltipHelper; import com.intellij.codeInsight.daemon.impl.LineMarkerNavigator; import com.intellij.codeInsight.daemon.impl.MarkerType; +import com.intellij.codeInsight.daemon.impl.PsiElementListNavigator; import com.intellij.codeInsight.hint.HintUtil; import com.intellij.codeInsight.navigation.NavigationUtil; import com.intellij.icons.AllIcons; +import com.intellij.ide.util.DefaultPsiElementCellRenderer; +import com.intellij.ide.util.PsiClassListCellRenderer; import com.intellij.openapi.editor.markup.GutterIconRenderer; import com.intellij.openapi.progress.ProgressManager; import com.intellij.openapi.project.DumbService; @@ -35,19 +37,17 @@ import com.intellij.openapi.ui.popup.JBPopup; import com.intellij.openapi.ui.popup.JBPopupFactory; import com.intellij.openapi.util.Pair; import com.intellij.openapi.util.text.StringUtil; -import com.intellij.psi.CommonClassNames; -import com.intellij.psi.PsiClass; -import com.intellij.psi.PsiElement; -import com.intellij.psi.PsiMethod; +import com.intellij.psi.*; +import com.intellij.psi.search.PsiElementProcessor; +import com.intellij.psi.search.PsiElementProcessorAdapter; import com.intellij.psi.search.searches.AllOverridingMethodsSearch; import com.intellij.psi.search.searches.ClassInheritorsSearch; +import com.intellij.psi.search.searches.OverridingMethodsSearch; import com.intellij.psi.util.PsiUtilCore; import com.intellij.ui.awt.RelativePoint; -import com.intellij.util.Function; -import com.intellij.util.NullableFunction; -import com.intellij.util.Processor; -import com.intellij.util.PsiNavigateUtil; +import com.intellij.util.*; import gnu.trove.THashSet; +import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.jet.asJava.LightClassUtil; @@ -58,16 +58,15 @@ import org.jetbrains.jet.lang.psi.*; import org.jetbrains.jet.lang.resolve.BindingContext; import org.jetbrains.jet.lang.resolve.BindingContextUtils; import org.jetbrains.jet.lexer.JetTokens; +import org.jetbrains.jet.plugin.JetBundle; import org.jetbrains.jet.plugin.codeInsight.JetFunctionPsiElementCellRenderer; import org.jetbrains.jet.plugin.project.WholeProjectAnalyzerFacade; +import org.jetbrains.jet.plugin.search.KotlinDefinitionsSearcher; import org.jetbrains.jet.renderer.DescriptorRenderer; import javax.swing.*; import java.awt.event.MouseEvent; -import java.util.Collection; -import java.util.List; -import java.util.Map; -import java.util.Set; +import java.util.*; public class JetLineMarkerProvider implements LineMarkerProvider { public static final Icon OVERRIDING_MARK = AllIcons.Gutter.OverridingMethod; @@ -115,6 +114,98 @@ public class JetLineMarkerProvider implements LineMarkerProvider { } ); + private static final MarkerType OVERRIDDEN_PROPERTY = new MarkerType( + new NullableFunction() { + @Override + public String fun(@Nullable PsiElement element) { + if (element == null) return null; + + assert element.getParent() instanceof JetProperty : "This tooltip provider should be placed only on identifies in properties"; + JetProperty property = (JetProperty) element.getParent(); + + PsiElementProcessor.CollectElementsWithLimit processor = new PsiElementProcessor.CollectElementsWithLimit(5); + Processor consumer = new AdapterProcessor( + new CommonProcessors.UniqueProcessor(new PsiElementProcessorAdapter(processor)), + new Function() { + @Override + public PsiClass fun(PsiMethod method) { + return method.getContainingClass(); + } + }); + + for (PsiMethod method : LightClassUtil.getLightClassPropertyMethods(property)) { + if (!processor.isOverflow()) { + OverridingMethodsSearch.search(method, true).forEach(consumer); + } + } + + boolean isImplemented = isImplemented(property); + if (processor.isOverflow()) { + return isImplemented ? + JetBundle.message("property.is.implemented.too.many") : + JetBundle.message("property.is.overridden.too.many"); + } + + List collectedClasses = Lists.newArrayList(processor.getCollection()); + if (collectedClasses.isEmpty()) return null; + + Collections.sort(collectedClasses, new PsiClassListCellRenderer().getComparator()); + + String start = isImplemented ? + JetBundle.message("property.is.implemented.header") : + JetBundle.message("property.is.overridden.header"); + + @NonNls String pattern = "    {0}"; + return GutterIconTooltipHelper.composeText(collectedClasses, start, pattern); + } + }, + + new LineMarkerNavigator() { + @Override + public void browse(@Nullable MouseEvent e, @Nullable PsiElement element) { + if (element == null) return; + + assert element.getParent() instanceof JetProperty : "This marker navigator should be placed only on identifies in properties"; + JetProperty property = (JetProperty) element.getParent(); + + if (DumbService.isDumb(element.getProject())) { + DumbService.getInstance(element.getProject()).showDumbModeNotification("Navigation to overriding classes is not possible during index update"); + return; + } + + final LightClassUtil.PropertyAccessorsPsiMethods psiPropertyMethods = + LightClassUtil.getLightClassPropertyMethods((JetProperty) element.getParent()); + + final CommonProcessors.CollectUniquesProcessor elementProcessor = new CommonProcessors.CollectUniquesProcessor(); + Runnable jetPsiMethodProcessor = new Runnable() { + @Override + public void run() { + KotlinDefinitionsSearcher.processPropertyImplementationsMethods(psiPropertyMethods, elementProcessor); + } + }; + + if (!ProgressManager.getInstance().runProcessWithProgressSynchronously( + jetPsiMethodProcessor, + MarkerType.SEARCHING_FOR_OVERRIDING_METHODS, true, + element.getProject(), + e != null ? (JComponent) e.getComponent() : null)) { + return; + } + + DefaultPsiElementCellRenderer renderer = new DefaultPsiElementCellRenderer(); + List elements = Ordering.from(renderer.getComparator()).sortedCopy(elementProcessor.getResults()); + + NavigatablePsiElement[] navigatableElements = Iterables.toArray( + Iterables.filter(elements, NavigatablePsiElement.class), NavigatablePsiElement.class); + + PsiElementListNavigator.openTargets(e, navigatableElements, + JetBundle.message("navigation.title.overriding.property", property.getName()), + JetBundle.message("navigation.findUsages.title.overriding.property", property.getName()), + renderer); + } + } + ); + @Nullable private static PsiClass getPsiClass(@Nullable PsiElement element) { if (element == null) return null; @@ -274,6 +365,7 @@ public class JetLineMarkerProvider implements LineMarkerProvider { } Set functions = Sets.newHashSet(); + Set properties = Sets.newHashSet(); for (PsiElement element : elements) { if (element instanceof JetClass) { @@ -283,9 +375,14 @@ public class JetLineMarkerProvider implements LineMarkerProvider { if (element instanceof JetNamedFunction) { functions.add((JetNamedFunction) element); } + + if (element instanceof JetProperty) { + properties.add((JetProperty) element); + } } collectOverridingAccessors(functions, result); + collectOverridingPropertiesAccessors(properties, result); } private static void collectInheritingClasses(JetClass element, Collection result) { @@ -334,8 +431,38 @@ public class JetLineMarkerProvider implements LineMarkerProvider { return false; } + private static void collectOverridingPropertiesAccessors(Collection properties, Collection result) { + Map mappingToJava = Maps.newHashMap(); + for (JetProperty property : properties) { + if (isOverridableHeuristic(property)) { + LightClassUtil.PropertyAccessorsPsiMethods accessorsPsiMethods = LightClassUtil.getLightClassPropertyMethods(property); + for (PsiMethod psiMethod : accessorsPsiMethods) { + mappingToJava.put(psiMethod, property); + } + } + } + + Set classes = collectContainingClasses(mappingToJava.keySet()); + + for (JetProperty property : getOverriddenDeclarations(mappingToJava, classes)) { + ProgressManager.checkCanceled(); + + PsiElement anchor = property.getNameIdentifier(); + if (anchor == null) anchor = property; + + LineMarkerInfo info = new LineMarkerInfo( + anchor, anchor.getTextOffset(), + isImplemented(property) ? IMPLEMENTED_MARK : OVERRIDDEN_MARK, + Pass.UPDATE_OVERRIDEN_MARKERS, + OVERRIDDEN_PROPERTY.getTooltip(), OVERRIDDEN_PROPERTY.getNavigationHandler(), + GutterIconRenderer.Alignment.RIGHT); + + result.add(info); + } + } + private static void collectOverridingAccessors(Collection functions, Collection result) { - final Map mappingToJava = Maps.newHashMap(); + Map mappingToJava = Maps.newHashMap(); for (JetNamedFunction function : functions) { if (isOverridableHeuristic(function)) { PsiMethod method = LightClassUtil.getLightClassMethod(function); @@ -345,36 +472,9 @@ public class JetLineMarkerProvider implements LineMarkerProvider { } } - Set classes = new THashSet(); - for (PsiMethod method : mappingToJava.keySet()) { - ProgressManager.checkCanceled(); - PsiClass parentClass = method.getContainingClass(); - if (parentClass != null && !CommonClassNames.JAVA_LANG_OBJECT.equals(parentClass.getQualifiedName())) { - classes.add(parentClass); - } - } + Set classes = collectContainingClasses(mappingToJava.keySet()); - final Set overridden = Sets.newHashSet(); - for (PsiClass aClass : classes) { - AllOverridingMethodsSearch.search(aClass).forEach(new Processor>() { - @Override - public boolean process(Pair pair) { - ProgressManager.checkCanceled(); - - PsiMethod superMethod = pair.getFirst(); - - JetNamedFunction function = mappingToJava.get(superMethod); - if (function != null) { - mappingToJava.remove(superMethod); - overridden.add(function); - } - - return !mappingToJava.isEmpty(); - } - }); - } - - for (JetNamedFunction function : overridden) { + for (JetNamedFunction function : getOverriddenDeclarations(mappingToJava, classes)) { ProgressManager.checkCanceled(); PsiElement anchor = function.getNameIdentifier(); @@ -390,4 +490,40 @@ public class JetLineMarkerProvider implements LineMarkerProvider { result.add(info); } } + + private static Set collectContainingClasses(Collection methods) { + Set classes = new THashSet(); + for (PsiMethod method : methods) { + ProgressManager.checkCanceled(); + PsiClass parentClass = method.getContainingClass(); + if (parentClass != null && !CommonClassNames.JAVA_LANG_OBJECT.equals(parentClass.getQualifiedName())) { + classes.add(parentClass); + } + } + return classes; + } + + private static Set getOverriddenDeclarations(final Map mappingToJava, Set classes) { + final Set overridden = Sets.newHashSet(); + for (PsiClass aClass : classes) { + AllOverridingMethodsSearch.search(aClass).forEach(new Processor>() { + @Override + public boolean process(Pair pair) { + ProgressManager.checkCanceled(); + + PsiMethod superMethod = pair.getFirst(); + + T declaration = mappingToJava.get(superMethod); + if (declaration != null) { + mappingToJava.remove(superMethod); + overridden.add(declaration); + } + + return !mappingToJava.isEmpty(); + } + }); + } + + return overridden; + } } diff --git a/idea/src/org/jetbrains/jet/plugin/search/KotlinDefinitionsSearcher.java b/idea/src/org/jetbrains/jet/plugin/search/KotlinDefinitionsSearcher.java index 89980b7611d..bbceb76d7ca 100644 --- a/idea/src/org/jetbrains/jet/plugin/search/KotlinDefinitionsSearcher.java +++ b/idea/src/org/jetbrains/jet/plugin/search/KotlinDefinitionsSearcher.java @@ -103,7 +103,7 @@ public class KotlinDefinitionsSearcher extends QueryExecutorBase consumer) { + public static void processPropertyImplementationsMethods(LightClassUtil.PropertyAccessorsPsiMethods accessors, @NotNull Processor consumer) { for (PsiMethod method : accessors) { PsiMethod[] implementations = MethodImplementationsSearch.getMethodImplementations(method); for (PsiMethod implementation : implementations) { diff --git a/idea/testData/codeInsight/lineMarker/PropertyOverride.kt b/idea/testData/codeInsight/lineMarker/PropertyOverride.kt new file mode 100644 index 00000000000..1c3507c2823 --- /dev/null +++ b/idea/testData/codeInsight/lineMarker/PropertyOverride.kt @@ -0,0 +1,7 @@ +open class Base { + open var writable: Int = 12 +} + +class SubBase: Base() { + override var writable: Int = 42 +} \ No newline at end of file diff --git a/idea/tests/org/jetbrains/jet/plugin/codeInsight/OverrideImplementLineMarkerTest.java b/idea/tests/org/jetbrains/jet/plugin/codeInsight/OverrideImplementLineMarkerTest.java index 1d5c0fe2bde..0e7db67e78d 100644 --- a/idea/tests/org/jetbrains/jet/plugin/codeInsight/OverrideImplementLineMarkerTest.java +++ b/idea/tests/org/jetbrains/jet/plugin/codeInsight/OverrideImplementLineMarkerTest.java @@ -46,6 +46,10 @@ public class OverrideImplementLineMarkerTest extends LightCodeInsightFixtureTest doTest(); } + public void testPropertyOverride() throws Throwable { + doTest(); + } + private void doTest() { try { myFixture.configureByFile(getTestName(false) + ".kt"); From 11a10673803fd9c09549bca91b8f78b3d4727420 Mon Sep 17 00:00:00 2001 From: Nikolay Krasko Date: Tue, 14 May 2013 17:12:58 +0400 Subject: [PATCH 112/249] Workaround assert when java function overrides kotlin property accessor #KT-3621 Open --- .../java/kotlinSignature/SignaturesPropagationData.java | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/kotlinSignature/SignaturesPropagationData.java b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/kotlinSignature/SignaturesPropagationData.java index 264c5c67d69..62b5993f9f3 100644 --- a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/kotlinSignature/SignaturesPropagationData.java +++ b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/kotlinSignature/SignaturesPropagationData.java @@ -242,9 +242,10 @@ public class SignaturesPropagationData { continue; } - assert superFun instanceof FunctionDescriptor : superFun.getClass().getName(); - - superFunctions.add(substituteSuperFunction(superclassToSupertype, (FunctionDescriptor) superFun)); + // TODO: Add propagation for other kotlin descriptors (KT-3621) + if (superFun instanceof FunctionDescriptor) { + superFunctions.add(substituteSuperFunction(superclassToSupertype, (FunctionDescriptor) superFun)); + } } // sorting for diagnostic stability From 3a2a932e2f395064ca858f2d42c578368e74db67 Mon Sep 17 00:00:00 2001 From: Nikolay Krasko Date: Thu, 16 May 2013 18:44:58 +0400 Subject: [PATCH 113/249] Add utility method for getting class from constructor parameter --- .../org/jetbrains/jet/lang/psi/JetPsiUtil.java | 17 +++++++++++++++-- .../jetbrains/jet/asJava/LightClassUtil.java | 7 +++++-- .../jetbrains/jet/plugin/JetIconProvider.java | 8 +++----- .../search/KotlinDefinitionsSearcher.java | 2 +- 4 files changed, 24 insertions(+), 10 deletions(-) diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetPsiUtil.java b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetPsiUtil.java index 3228d0f9e32..d54ddbe6179 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetPsiUtil.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetPsiUtil.java @@ -197,8 +197,9 @@ public class JetPsiUtil { firstPart = getFQName((JetNamedDeclaration) parent); } else if (namedDeclaration instanceof JetParameter) { - if (((JetParameter) namedDeclaration).getValOrVarNode() != null && parent != null && parent.getParent() instanceof JetClassOrObject) { - firstPart = getFQName((JetClassOrObject) parent.getParent()); + JetClass constructorClass = getClassIfParameterIsProperty((JetParameter) namedDeclaration); + if (constructorClass != null) { + firstPart = getFQName(constructorClass); } } else if (parent instanceof JetObjectDeclaration) { @@ -574,6 +575,18 @@ public class JetPsiUtil { } } + @Nullable + public static JetClass getClassIfParameterIsProperty(@NotNull JetParameter jetParameter) { + if (jetParameter.getValOrVarNode() != null) { + PsiElement parent = jetParameter.getParent(); + if (parent instanceof JetParameterList && parent.getParent() instanceof JetClass) { + return (JetClass) parent.getParent(); + } + } + + return null; + } + @Nullable private static IElementType getOperation(@NotNull JetExpression expression) { if (expression instanceof JetQualifiedExpression) { diff --git a/compiler/jet.as.java.psi/src/org/jetbrains/jet/asJava/LightClassUtil.java b/compiler/jet.as.java.psi/src/org/jetbrains/jet/asJava/LightClassUtil.java index 7ef41f7d4c3..6fd300653e8 100644 --- a/compiler/jet.as.java.psi/src/org/jetbrains/jet/asJava/LightClassUtil.java +++ b/compiler/jet.as.java.psi/src/org/jetbrains/jet/asJava/LightClassUtil.java @@ -196,8 +196,11 @@ public class LightClassUtil { @Nullable private static PsiClass getWrappingClass(@NotNull JetDeclaration declaration) { - if (declaration instanceof JetParameter && declaration.getParent().getParent() instanceof JetClass) { - return getPsiClass((JetClassOrObject) declaration.getParent().getParent()); + if (declaration instanceof JetParameter) { + JetClass constructorClass = JetPsiUtil.getClassIfParameterIsProperty((JetParameter) declaration); + if (constructorClass != null) { + return getPsiClass(constructorClass); + } } if (declaration instanceof JetPropertyAccessor) { diff --git a/idea/src/org/jetbrains/jet/plugin/JetIconProvider.java b/idea/src/org/jetbrains/jet/plugin/JetIconProvider.java index 4b5efb62853..a1268443475 100644 --- a/idea/src/org/jetbrains/jet/plugin/JetIconProvider.java +++ b/idea/src/org/jetbrains/jet/plugin/JetIconProvider.java @@ -143,12 +143,10 @@ public class JetIconProvider extends IconProvider { } if (psiElement instanceof JetParameter) { JetParameter parameter = (JetParameter) psiElement; - if (parameter.getValOrVarNode() != null) { - JetParameterList parameterList = PsiTreeUtil.getParentOfType(psiElement, JetParameterList.class); - if (parameterList != null && parameterList.getParent() instanceof JetClass) { - return parameter.isMutable() ? JetIcons.FIELD_VAR : JetIcons.FIELD_VAL; - } + if (JetPsiUtil.getClassIfParameterIsProperty(parameter) != null) { + return parameter.isMutable() ? JetIcons.FIELD_VAR : JetIcons.FIELD_VAL; } + return JetIcons.PARAMETER; } if (psiElement instanceof JetProperty) { diff --git a/idea/src/org/jetbrains/jet/plugin/search/KotlinDefinitionsSearcher.java b/idea/src/org/jetbrains/jet/plugin/search/KotlinDefinitionsSearcher.java index bbceb76d7ca..534be277f50 100644 --- a/idea/src/org/jetbrains/jet/plugin/search/KotlinDefinitionsSearcher.java +++ b/idea/src/org/jetbrains/jet/plugin/search/KotlinDefinitionsSearcher.java @@ -48,7 +48,7 @@ public class KotlinDefinitionsSearcher extends QueryExecutorBase Date: Mon, 20 May 2013 13:23:46 +0400 Subject: [PATCH 114/249] Using JetClsMethod interface to recognize method compiled from kotlin --- .../src/org/jetbrains/jet/asJava/LightClassUtil.java | 11 ++++------- .../jet/plugin/search/KotlinDefinitionsSearcher.java | 4 ++-- 2 files changed, 6 insertions(+), 9 deletions(-) diff --git a/compiler/jet.as.java.psi/src/org/jetbrains/jet/asJava/LightClassUtil.java b/compiler/jet.as.java.psi/src/org/jetbrains/jet/asJava/LightClassUtil.java index 6fd300653e8..374a13bb3e5 100644 --- a/compiler/jet.as.java.psi/src/org/jetbrains/jet/asJava/LightClassUtil.java +++ b/compiler/jet.as.java.psi/src/org/jetbrains/jet/asJava/LightClassUtil.java @@ -23,7 +23,6 @@ import com.intellij.openapi.util.Comparing; import com.intellij.openapi.util.SystemInfo; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.psi.PsiClass; -import com.intellij.psi.PsiCompiledElement; import com.intellij.psi.PsiElement; import com.intellij.psi.PsiMethod; import com.intellij.psi.impl.java.stubs.PsiClassStub; @@ -161,12 +160,10 @@ public class LightClassUtil { List methods = new SmartList(); for (PsiMethod method : psiClass.getMethods()) { try { - if (method instanceof JetClsMethod) { - if (method instanceof PsiCompiledElement && ((PsiCompiledElement) method).getMirror() == declaration) { - methods.add(method); - if (!collectAll) { - return methods; - } + if (method instanceof JetClsMethod && ((JetClsMethod) method).getOrigin() == declaration) { + methods.add(method); + if (!collectAll) { + return methods; } } } diff --git a/idea/src/org/jetbrains/jet/plugin/search/KotlinDefinitionsSearcher.java b/idea/src/org/jetbrains/jet/plugin/search/KotlinDefinitionsSearcher.java index 534be277f50..6d0cdb48c18 100644 --- a/idea/src/org/jetbrains/jet/plugin/search/KotlinDefinitionsSearcher.java +++ b/idea/src/org/jetbrains/jet/plugin/search/KotlinDefinitionsSearcher.java @@ -21,7 +21,6 @@ import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.application.QueryExecutorBase; import com.intellij.openapi.util.Computable; import com.intellij.psi.PsiClass; -import com.intellij.psi.PsiCompiledElement; import com.intellij.psi.PsiElement; import com.intellij.psi.PsiMethod; import com.intellij.psi.search.searches.ClassInheritorsSearch; @@ -30,6 +29,7 @@ import com.intellij.util.containers.ContainerUtil; import org.jetbrains.annotations.NotNull; import org.jetbrains.jet.asJava.LightClassUtil; import org.jetbrains.jet.lang.psi.*; +import org.jetbrains.jet.lang.resolve.java.JetClsMethod; public class KotlinDefinitionsSearcher extends QueryExecutorBase { @Override @@ -107,7 +107,7 @@ public class KotlinDefinitionsSearcher extends QueryExecutorBase Date: Mon, 20 May 2013 17:02:38 +0400 Subject: [PATCH 115/249] KT-3575, KT-2297 Inserting pair for "${": use JetPairMatcher instead of KotlinTypeHandler #KT-3575 fixed --- .../org/jetbrains/jet/plugin/JetPairMatcher.java | 3 ++- .../jet/plugin/editor/KotlinTypedHandler.java | 14 -------------- .../org/jetbrains/jet/editor/TypedHandlerTest.java | 6 ++++++ 3 files changed, 8 insertions(+), 15 deletions(-) diff --git a/idea/src/org/jetbrains/jet/plugin/JetPairMatcher.java b/idea/src/org/jetbrains/jet/plugin/JetPairMatcher.java index 5646c25cac2..a97fdee0200 100644 --- a/idea/src/org/jetbrains/jet/plugin/JetPairMatcher.java +++ b/idea/src/org/jetbrains/jet/plugin/JetPairMatcher.java @@ -39,7 +39,8 @@ public class JetPairMatcher implements PairedBraceMatcher { @Override public boolean isPairedBracesAllowedBeforeType(@NotNull IElementType lbraceType, @Nullable IElementType contextType) { - return JetTokens.WHITE_SPACE_OR_COMMENT_BIT_SET.contains(contextType) + return lbraceType.equals(JetTokens.LONG_TEMPLATE_ENTRY_START) + || JetTokens.WHITE_SPACE_OR_COMMENT_BIT_SET.contains(contextType) || contextType == JetTokens.SEMICOLON || contextType == JetTokens.COMMA || contextType == JetTokens.RPAR diff --git a/idea/src/org/jetbrains/jet/plugin/editor/KotlinTypedHandler.java b/idea/src/org/jetbrains/jet/plugin/editor/KotlinTypedHandler.java index baedb696788..b35d929710d 100644 --- a/idea/src/org/jetbrains/jet/plugin/editor/KotlinTypedHandler.java +++ b/idea/src/org/jetbrains/jet/plugin/editor/KotlinTypedHandler.java @@ -57,20 +57,6 @@ public class KotlinTypedHandler extends TypedHandlerDelegate { JetLtGtTypingUtils.handleJetAutoCloseLT(editor); return Result.STOP; } - - if (!(file instanceof JetFile) || !CodeInsightSettings.getInstance().AUTOINSERT_PAIR_BRACKET) { - return Result.CONTINUE; - } - if (c == '{') { - PsiDocumentManager.getInstance(project).commitAllDocuments(); - int offset = editor.getCaretModel().getOffset(); - PsiElement previousElement = file.findElementAt(offset - 1); - if (previousElement instanceof LeafPsiElement - && ((LeafPsiElement) previousElement).getElementType() == JetTokens.LONG_TEMPLATE_ENTRY_START) { - editor.getDocument().insertString(offset, "}"); - } - return Result.STOP; - } return Result.CONTINUE; } } diff --git a/idea/tests/org/jetbrains/jet/editor/TypedHandlerTest.java b/idea/tests/org/jetbrains/jet/editor/TypedHandlerTest.java index 78a78adffbf..5ac75e43c72 100644 --- a/idea/tests/org/jetbrains/jet/editor/TypedHandlerTest.java +++ b/idea/tests/org/jetbrains/jet/editor/TypedHandlerTest.java @@ -26,6 +26,12 @@ public class TypedHandlerTest extends LightCodeInsightTestCase { checkResultByText("val x = \"${}\""); } + public void testKT3575() throws Exception { + configureFromFileText("a.kt", "val x = \"$]\""); + EditorTestUtil.performTypingAction(getEditor(), '{'); + checkResultByText("val x = \"${}]\""); + } + public void testTypeLtInFunDeclaration() throws Exception { doLtGtTest("fun "); } From e98ee752bf4dae5e780d12e42c5562c1130b8825 Mon Sep 17 00:00:00 2001 From: Nikolay Krasko Date: Wed, 15 May 2013 16:03:03 +0400 Subject: [PATCH 116/249] Base class for jet light fixture to execute runPostStartupActivities() in more fixture tests --- .../JetLightCodeInsightFixtureTestCase.java | 38 +++++++++++++++++ .../OverrideImplementLineMarkerTest.java | 7 ++-- .../plugin/javaFacade/JetJavaFacadeTest.java | 27 ++++++++---- .../plugin/navigation/JetGotoSymbolTest.java | 41 ++++--------------- 4 files changed, 67 insertions(+), 46 deletions(-) create mode 100644 idea/tests/org/jetbrains/jet/plugin/JetLightCodeInsightFixtureTestCase.java diff --git a/idea/tests/org/jetbrains/jet/plugin/JetLightCodeInsightFixtureTestCase.java b/idea/tests/org/jetbrains/jet/plugin/JetLightCodeInsightFixtureTestCase.java new file mode 100644 index 00000000000..0bd5ce32473 --- /dev/null +++ b/idea/tests/org/jetbrains/jet/plugin/JetLightCodeInsightFixtureTestCase.java @@ -0,0 +1,38 @@ +/* + * Copyright 2010-2013 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.jetbrains.jet.plugin; + +import com.intellij.ide.startup.impl.StartupManagerImpl; +import com.intellij.openapi.startup.StartupManager; +import com.intellij.testFramework.fixtures.LightCodeInsightFixtureTestCase; + +public abstract class JetLightCodeInsightFixtureTestCase extends LightCodeInsightFixtureTestCase { + @Override + protected void setUp() throws Exception { + super.setUp(); + ((StartupManagerImpl) StartupManager.getInstance(getProject())).runPostStartupActivities(); + } + + @Override + protected void tearDown() throws Exception { + super.tearDown(); + } + + protected String fileName() { + return getTestName(false) + ".kt"; + } +} diff --git a/idea/tests/org/jetbrains/jet/plugin/codeInsight/OverrideImplementLineMarkerTest.java b/idea/tests/org/jetbrains/jet/plugin/codeInsight/OverrideImplementLineMarkerTest.java index 0e7db67e78d..c81b6d7ca84 100644 --- a/idea/tests/org/jetbrains/jet/plugin/codeInsight/OverrideImplementLineMarkerTest.java +++ b/idea/tests/org/jetbrains/jet/plugin/codeInsight/OverrideImplementLineMarkerTest.java @@ -22,13 +22,12 @@ import com.intellij.openapi.editor.Document; import com.intellij.openapi.project.Project; import com.intellij.psi.PsiDocumentManager; import com.intellij.testFramework.ExpectedHighlightingData; -import com.intellij.testFramework.fixtures.LightCodeInsightFixtureTestCase; +import org.jetbrains.jet.plugin.JetLightCodeInsightFixtureTestCase; import org.jetbrains.jet.plugin.PluginTestCaseBase; import java.util.List; -public class OverrideImplementLineMarkerTest extends LightCodeInsightFixtureTestCase { - +public class OverrideImplementLineMarkerTest extends JetLightCodeInsightFixtureTestCase { @Override protected String getBasePath() { return PluginTestCaseBase.TEST_DATA_PROJECT_RELATIVE + "/codeInsight/lineMarker"; @@ -52,7 +51,7 @@ public class OverrideImplementLineMarkerTest extends LightCodeInsightFixtureTest private void doTest() { try { - myFixture.configureByFile(getTestName(false) + ".kt"); + myFixture.configureByFile(fileName()); Project project = myFixture.getProject(); Document document = myFixture.getEditor().getDocument(); diff --git a/idea/tests/org/jetbrains/jet/plugin/javaFacade/JetJavaFacadeTest.java b/idea/tests/org/jetbrains/jet/plugin/javaFacade/JetJavaFacadeTest.java index a43fd97d429..a49ce9969dc 100644 --- a/idea/tests/org/jetbrains/jet/plugin/javaFacade/JetJavaFacadeTest.java +++ b/idea/tests/org/jetbrains/jet/plugin/javaFacade/JetJavaFacadeTest.java @@ -20,16 +20,16 @@ import com.intellij.psi.*; import com.intellij.psi.search.GlobalSearchScope; import com.intellij.psi.util.PsiTreeUtil; import com.intellij.testFramework.LightProjectDescriptor; -import com.intellij.testFramework.fixtures.LightCodeInsightFixtureTestCase; import org.jetbrains.annotations.NotNull; import org.jetbrains.jet.asJava.KotlinLightClass; import org.jetbrains.jet.asJava.LightClassUtil; import org.jetbrains.jet.lang.psi.*; import org.jetbrains.jet.lang.resolve.java.JvmAbi; +import org.jetbrains.jet.plugin.JetLightCodeInsightFixtureTestCase; import org.jetbrains.jet.plugin.JetLightProjectDescriptor; import org.jetbrains.jet.plugin.PluginTestCaseBase; -public class JetJavaFacadeTest extends LightCodeInsightFixtureTestCase { +public class JetJavaFacadeTest extends JetLightCodeInsightFixtureTestCase { @NotNull @Override protected LightProjectDescriptor getProjectDescriptor() { @@ -39,7 +39,11 @@ public class JetJavaFacadeTest extends LightCodeInsightFixtureTestCase { @Override public void setUp() throws Exception { super.setUp(); - myFixture.setTestDataPath(PluginTestCaseBase.getTestDataPathBase() + "/javaFacade"); + } + + @Override + protected String getTestDataPath() { + return PluginTestCaseBase.getTestDataPathBase() + "/javaFacade"; } public void testDoNotWrapFunFromLocalClass() { @@ -135,7 +139,7 @@ public class JetJavaFacadeTest extends LightCodeInsightFixtureTestCase { } public void testEa38770() { - myFixture.configureByFile(getTestName(true) + ".kt"); + myFixture.configureByFile(fileName()); PsiReference reference = myFixture.getFile().findReferenceAt(myFixture.getCaretOffset()); assertNotNull(reference); @@ -148,7 +152,7 @@ public class JetJavaFacadeTest extends LightCodeInsightFixtureTestCase { } public void testInnerClass() throws Exception { - myFixture.configureByFile(getTestName(true) + ".kt"); + myFixture.configureByFile(fileName()); JavaPsiFacade facade = myFixture.getJavaFacade(); PsiClass mirrorClass = facade.findClass("foo.Outer.Inner", GlobalSearchScope.allScope(getProject())); @@ -160,7 +164,7 @@ public class JetJavaFacadeTest extends LightCodeInsightFixtureTestCase { } public void testClassObject() throws Exception { - myFixture.configureByFile(getTestName(true) + ".kt"); + myFixture.configureByFile(fileName()); JavaPsiFacade facade = myFixture.getJavaFacade(); PsiClass theClass = facade.findClass("foo.TheClass", GlobalSearchScope.allScope(getProject())); @@ -188,7 +192,7 @@ public class JetJavaFacadeTest extends LightCodeInsightFixtureTestCase { } public void testLightClassIsNotCreatedForBuiltins() throws Exception { - myFixture.configureByFile(getTestName(true) + ".kt"); + myFixture.configureByFile(fileName()); PsiReference reference = myFixture.getFile().findReferenceAt(myFixture.getCaretOffset()); assert reference != null; @@ -242,7 +246,7 @@ public class JetJavaFacadeTest extends LightCodeInsightFixtureTestCase { @NotNull private T getPreparedElement(Class elementClass) { - myFixture.configureByFile(getTestName(true) + ".kt"); + myFixture.configureByFile(fileName()); int offset = myFixture.getEditor().getCaretModel().getOffset(); PsiElement elementAt = myFixture.getFile().findElementAt(offset); @@ -270,7 +274,7 @@ public class JetJavaFacadeTest extends LightCodeInsightFixtureTestCase { } private void doTestWrapClass() { - myFixture.configureByFile(getTestName(true) + ".kt"); + myFixture.configureByFile(fileName()); int offset = myFixture.getEditor().getCaretModel().getOffset(); PsiElement elementAt = myFixture.getFile().findElementAt(offset); @@ -289,4 +293,9 @@ public class JetJavaFacadeTest extends LightCodeInsightFixtureTestCase { // No exception/error should happen here lightClass.getDelegate(); } + + @Override + protected String fileName() { + return getTestName(true) + ".kt"; + } } diff --git a/idea/tests/org/jetbrains/jet/plugin/navigation/JetGotoSymbolTest.java b/idea/tests/org/jetbrains/jet/plugin/navigation/JetGotoSymbolTest.java index e956bb575ee..f754eb0ea05 100644 --- a/idea/tests/org/jetbrains/jet/plugin/navigation/JetGotoSymbolTest.java +++ b/idea/tests/org/jetbrains/jet/plugin/navigation/JetGotoSymbolTest.java @@ -16,40 +16,12 @@ package org.jetbrains.jet.plugin.navigation; -import com.intellij.openapi.module.Module; -import com.intellij.openapi.module.ModuleType; -import com.intellij.openapi.module.StdModuleTypes; -import com.intellij.openapi.projectRoots.Sdk; -import com.intellij.openapi.roots.ContentEntry; -import com.intellij.openapi.roots.ModifiableRootModel; -import com.intellij.testFramework.LightProjectDescriptor; -import com.intellij.testFramework.fixtures.LightCodeInsightFixtureTestCase; -import org.jetbrains.annotations.NotNull; +import org.jetbrains.jet.plugin.JetLightCodeInsightFixtureTestCase; import org.jetbrains.jet.plugin.PluginTestCaseBase; import java.io.File; -public class JetGotoSymbolTest extends LightCodeInsightFixtureTestCase { - @NotNull - @Override - protected LightProjectDescriptor getProjectDescriptor() { - return new LightProjectDescriptor() { - @Override - public ModuleType getModuleType() { - return StdModuleTypes.JAVA; - } - - @Override - public Sdk getSdk() { - return PluginTestCaseBase.jdkFromIdeaHome(); - } - - @Override - public void configureModule(Module module, ModifiableRootModel model, ContentEntry contentEntry) { - } - }; - } - +public class JetGotoSymbolTest extends JetLightCodeInsightFixtureTestCase { public void testProperties() { doTest(); } @@ -64,9 +36,12 @@ public class JetGotoSymbolTest extends LightCodeInsightFixtureTestCase { } protected void doTest() { - String fileName = getTestName(true) + ".kt"; - myFixture.configureByFile(fileName); - + myFixture.configureByFile(fileName()); NavigationTestUtils.assertGotoSymbol(getProject(), myFixture.getEditor()); } + + @Override + protected String fileName() { + return getTestName(true) + ".kt"; + } } From f33792a567c59e36fbb62407c26a868c0f522d3b Mon Sep 17 00:00:00 2001 From: Nikolay Krasko Date: Mon, 20 May 2013 16:28:04 +0400 Subject: [PATCH 117/249] Configure project descriptor with directives Implement optimize import test with redesigned class --- .../jetbrains/jet/InTextDirectivesUtils.java | 4 ++ .../editor/optimizeImports/UnusedImports.kt | 4 +- .../optimizeImports/UnusedImports_after.kt | 4 +- .../JetLightCodeInsightFixtureTestCase.java | 26 +++++++++- .../importOptimizer/OptimizeImportsTest.java | 49 +++---------------- 5 files changed, 41 insertions(+), 46 deletions(-) diff --git a/compiler/tests/org/jetbrains/jet/InTextDirectivesUtils.java b/compiler/tests/org/jetbrains/jet/InTextDirectivesUtils.java index d91eb0cec1e..714bb8004ef 100644 --- a/compiler/tests/org/jetbrains/jet/InTextDirectivesUtils.java +++ b/compiler/tests/org/jetbrains/jet/InTextDirectivesUtils.java @@ -64,6 +64,10 @@ public final class InTextDirectivesUtils { return result; } + public static boolean isDirectiveDefined(String fileText, String directive) { + return !findListWithPrefixes(fileText, directive).isEmpty(); + } + @Nullable public static String findStringWithPrefixes(String fileText, String... prefixes) { List strings = findListWithPrefixes(fileText, prefixes); diff --git a/idea/testData/editor/optimizeImports/UnusedImports.kt b/idea/testData/editor/optimizeImports/UnusedImports.kt index 349e61ee9f2..a454695a3fa 100644 --- a/idea/testData/editor/optimizeImports/UnusedImports.kt +++ b/idea/testData/editor/optimizeImports/UnusedImports.kt @@ -17,4 +17,6 @@ class Action { measureTimeMillis({ println(HashMap().size()) }) val test : ArrayList? = null } -} \ No newline at end of file +} + +// RUNTIME \ No newline at end of file diff --git a/idea/testData/editor/optimizeImports/UnusedImports_after.kt b/idea/testData/editor/optimizeImports/UnusedImports_after.kt index fe7a544c7e8..a5377f45aa7 100644 --- a/idea/testData/editor/optimizeImports/UnusedImports_after.kt +++ b/idea/testData/editor/optimizeImports/UnusedImports_after.kt @@ -11,4 +11,6 @@ class Action { measureTimeMillis({ println(HashMap().size()) }) val test : ArrayList? = null } -} \ No newline at end of file +} + +// RUNTIME \ No newline at end of file diff --git a/idea/tests/org/jetbrains/jet/plugin/JetLightCodeInsightFixtureTestCase.java b/idea/tests/org/jetbrains/jet/plugin/JetLightCodeInsightFixtureTestCase.java index 0bd5ce32473..985f7d91651 100644 --- a/idea/tests/org/jetbrains/jet/plugin/JetLightCodeInsightFixtureTestCase.java +++ b/idea/tests/org/jetbrains/jet/plugin/JetLightCodeInsightFixtureTestCase.java @@ -18,21 +18,43 @@ package org.jetbrains.jet.plugin; import com.intellij.ide.startup.impl.StartupManagerImpl; import com.intellij.openapi.startup.StartupManager; +import com.intellij.openapi.util.io.FileUtil; +import com.intellij.testFramework.LightProjectDescriptor; import com.intellij.testFramework.fixtures.LightCodeInsightFixtureTestCase; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.jet.InTextDirectivesUtils; + +import java.io.File; public abstract class JetLightCodeInsightFixtureTestCase extends LightCodeInsightFixtureTestCase { + LightProjectDescriptor projectDescriptor = null; + @Override protected void setUp() throws Exception { + String fileText = FileUtil.loadFile(new File(getTestDataPath(), fileName())); + if (InTextDirectivesUtils.isDirectiveDefined(fileText, "RUNTIME")) { + projectDescriptor = JetWithJdkAndRuntimeLightProjectDescriptor.INSTANCE; + } + else { + projectDescriptor = JetLightProjectDescriptor.INSTANCE; + } + super.setUp(); + ((StartupManagerImpl) StartupManager.getInstance(getProject())).runPostStartupActivities(); } @Override protected void tearDown() throws Exception { super.tearDown(); + projectDescriptor = null; } - protected String fileName() { - return getTestName(false) + ".kt"; + @NotNull + @Override + protected LightProjectDescriptor getProjectDescriptor() { + return projectDescriptor; } + + protected abstract String fileName(); } diff --git a/idea/tests/org/jetbrains/jet/plugin/importOptimizer/OptimizeImportsTest.java b/idea/tests/org/jetbrains/jet/plugin/importOptimizer/OptimizeImportsTest.java index 3ee8ca7396e..b422671bc34 100644 --- a/idea/tests/org/jetbrains/jet/plugin/importOptimizer/OptimizeImportsTest.java +++ b/idea/tests/org/jetbrains/jet/plugin/importOptimizer/OptimizeImportsTest.java @@ -16,27 +16,15 @@ package org.jetbrains.jet.plugin.importOptimizer; -import com.intellij.ide.startup.impl.StartupManagerImpl; import com.intellij.openapi.command.CommandProcessor; import com.intellij.openapi.command.UndoConfirmationPolicy; -import com.intellij.openapi.projectRoots.JavaSdk; -import com.intellij.openapi.projectRoots.Sdk; -import com.intellij.openapi.startup.StartupManager; -import com.intellij.testFramework.LightCodeInsightTestCase; -import org.apache.commons.lang.SystemUtils; +import org.jetbrains.jet.plugin.JetLightCodeInsightFixtureTestCase; import org.jetbrains.jet.plugin.PluginTestCaseBase; import org.jetbrains.jet.plugin.editor.importOptimizer.JetImportOptimizer; -import org.jetbrains.jet.testing.ConfigLibraryUtil; import java.io.File; -public class OptimizeImportsTest extends LightCodeInsightTestCase { - @Override - protected void setUp() throws Exception { - super.setUp(); - ((StartupManagerImpl) StartupManager.getInstance(getProject())).runPostStartupActivities(); - } - +public class OptimizeImportsTest extends JetLightCodeInsightFixtureTestCase { public void testAlreadyOptimized() throws Exception { doTest(); } @@ -54,7 +42,7 @@ public class OptimizeImportsTest extends LightCodeInsightTestCase { } public void testUnusedImports() throws Exception { - doTestWithKotlinRuntime(); + doTest(); } public void testWithAliases() throws Exception { @@ -86,23 +74,9 @@ public class OptimizeImportsTest extends LightCodeInsightTestCase { } public void doTest() throws Exception { - configureByFile(fileName()); + myFixture.configureByFile(fileName()); invokeFormatFile(); - checkResultByFile(null, checkFileName(), true); - } - - public void doTestWithKotlinRuntime() { - try { - ConfigLibraryUtil.configureKotlinRuntime(getModule(), getFullJavaJDK()); - - configureByFile(fileName()); - invokeFormatFile(); - - checkResultByFile(null, checkFileName(), false); - } - finally { - ConfigLibraryUtil.unConfigureKotlinRuntime(getModule(), getProjectJDK()); - } + myFixture.checkResultByFile(checkFileName(), false); } @Override @@ -112,14 +86,6 @@ public class OptimizeImportsTest extends LightCodeInsightTestCase { } @Override - protected Sdk getProjectJDK() { - return PluginTestCaseBase.jdkFromIdeaHome(); - } - - protected static Sdk getFullJavaJDK() { - return JavaSdk.getInstance().createJdk("JDK", SystemUtils.getJavaHome().getAbsolutePath()); - } - public String fileName() { return getTestName(false) + ".kt"; } @@ -128,9 +94,8 @@ public class OptimizeImportsTest extends LightCodeInsightTestCase { return getTestName(false) + "_after.kt"; } - private static void invokeFormatFile() { - CommandProcessor.getInstance().executeCommand( - getProject(), new JetImportOptimizer().processFile(getFile()), + private void invokeFormatFile() { + CommandProcessor.getInstance().executeCommand(myFixture.getProject(), new JetImportOptimizer().processFile(myFixture.getFile()), "Optimize Imports", null, UndoConfirmationPolicy.DO_NOT_REQUEST_CONFIRMATION); } } From ddb7b54eee4a43c3f033e2ebade06d366ce4d3f6 Mon Sep 17 00:00:00 2001 From: Nikolay Krasko Date: Wed, 15 May 2013 14:03:17 +0400 Subject: [PATCH 118/249] KT-3620 Don't auto-import js.* and remove in `optimize imports` KT-3620 Fixed --- .../jet/util/QualifiedNamesUtil.java | 10 +++++ .../plugin/quickfix/ImportInsertHelper.java | 34 +++++++-------- .../handlers/DoNotInsertDefaultJsImports.kt | 6 +++ .../DoNotInsertDefaultJsImports.kt.after | 6 +++ .../optimizeImports/DefaultJsImports.kt | 8 ++++ .../optimizeImports/DefaultJsImports_after.kt | 6 +++ .../handlers/CompletionHandlerTest.java | 42 ++++++------------- .../JetLightCodeInsightFixtureTestCase.java | 7 +++- .../importOptimizer/OptimizeImportsTest.java | 9 ++-- 9 files changed, 76 insertions(+), 52 deletions(-) create mode 100644 idea/testData/completion/handlers/DoNotInsertDefaultJsImports.kt create mode 100644 idea/testData/completion/handlers/DoNotInsertDefaultJsImports.kt.after create mode 100644 idea/testData/editor/optimizeImports/DefaultJsImports.kt create mode 100644 idea/testData/editor/optimizeImports/DefaultJsImports_after.kt diff --git a/compiler/frontend/src/org/jetbrains/jet/util/QualifiedNamesUtil.java b/compiler/frontend/src/org/jetbrains/jet/util/QualifiedNamesUtil.java index be00e670556..85384187dc5 100644 --- a/compiler/frontend/src/org/jetbrains/jet/util/QualifiedNamesUtil.java +++ b/compiler/frontend/src/org/jetbrains/jet/util/QualifiedNamesUtil.java @@ -143,6 +143,16 @@ public final class QualifiedNamesUtil { return isImported(alreadyImported, newImport.fqnPart()); } + public static boolean isImported(@NotNull Iterable imports, @NotNull ImportPath newImport) { + for (ImportPath alreadyImported : imports) { + if (isImported(alreadyImported, newImport)) { + return true; + } + } + + return false; + } + public static boolean isValidJavaFqName(@Nullable String qualifiedName) { if (qualifiedName == null) return false; diff --git a/idea/src/org/jetbrains/jet/plugin/quickfix/ImportInsertHelper.java b/idea/src/org/jetbrains/jet/plugin/quickfix/ImportInsertHelper.java index d78f4cbfca3..7f0e9c84c4a 100644 --- a/idea/src/org/jetbrains/jet/plugin/quickfix/ImportInsertHelper.java +++ b/idea/src/org/jetbrains/jet/plugin/quickfix/ImportInsertHelper.java @@ -37,9 +37,11 @@ import org.jetbrains.jet.lang.types.ErrorUtils; import org.jetbrains.jet.lang.types.JetType; import org.jetbrains.jet.lang.types.TypeUtils; import org.jetbrains.jet.plugin.JetPluginUtil; +import org.jetbrains.jet.plugin.framework.KotlinFrameworkDetector; import org.jetbrains.jet.plugin.project.AnalyzerFacadeWithCache; import org.jetbrains.jet.plugin.references.JetPsiReference; import org.jetbrains.jet.util.QualifiedNamesUtil; +import org.jetbrains.k2js.analyze.JsConfiguration; import java.util.List; @@ -145,7 +147,7 @@ public class ImportInsertHelper { /** * Check that import is useless. */ - private static boolean isImportedByDefault(@NotNull ImportPath importPath, @NotNull FqName filePackageFqn) { + private static boolean isImportedByDefault(@NotNull ImportPath importPath, @NotNull JetFile jetFile) { if (importPath.fqnPart().isRoot()) { return true; } @@ -157,33 +159,31 @@ public class ImportInsertHelper { } // There's no need to import a declaration from the package of current file - if (filePackageFqn.equals(importPath.fqnPart().parent())) { + if (JetPsiUtil.getFQName(jetFile).equals(importPath.fqnPart().parent())) { return true; } } if (isImportedWithKotlinDefault(importPath)) return true; - if (isImportedWithJavaDefault(importPath)) return true; - return false; + if (KotlinFrameworkDetector.isJsKotlinModule(jetFile)) { + return isImportedWithJsDefault(importPath); + } + else { + return isImportedWithJavaDefault(importPath); + } } public static boolean isImportedWithJavaDefault(ImportPath importPath) { - for (ImportPath defaultJavaImport : JavaBridgeConfiguration.DEFAULT_JAVA_IMPORTS) { - if (QualifiedNamesUtil.isImported(defaultJavaImport, importPath)) { - return true; - } - } - return false; + return QualifiedNamesUtil.isImported(JavaBridgeConfiguration.DEFAULT_JAVA_IMPORTS, importPath); + } + + public static boolean isImportedWithJsDefault(ImportPath importPath) { + return QualifiedNamesUtil.isImported(JsConfiguration.DEFAULT_IMPORT_PATHS, importPath); } public static boolean isImportedWithKotlinDefault(ImportPath importPath) { - for (ImportPath defaultJetImport : DefaultModuleConfiguration.DEFAULT_JET_IMPORTS) { - if (QualifiedNamesUtil.isImported(defaultJetImport, importPath)) { - return true; - } - } - return false; + return QualifiedNamesUtil.isImported(DefaultModuleConfiguration.DEFAULT_JET_IMPORTS, importPath); } public static boolean doNeedImport(@NotNull ImportPath importPath, @NotNull JetFile file) { @@ -196,7 +196,7 @@ public class ImportInsertHelper { importPath = new ImportPath(withoutJavaRoot, importPath.isAllUnder(), importPath.getAlias()); } - if (isImportedByDefault(importPath, JetPsiUtil.getFQName(file))) { + if (isImportedByDefault(importPath, file)) { return false; } diff --git a/idea/testData/completion/handlers/DoNotInsertDefaultJsImports.kt b/idea/testData/completion/handlers/DoNotInsertDefaultJsImports.kt new file mode 100644 index 00000000000..f3346bb9f4a --- /dev/null +++ b/idea/testData/completion/handlers/DoNotInsertDefaultJsImports.kt @@ -0,0 +1,6 @@ +fun main(args: Array) { + println +} + +// For KT-3620: Don't auto-import js.* and remove in `optimize imports` +// JS \ No newline at end of file diff --git a/idea/testData/completion/handlers/DoNotInsertDefaultJsImports.kt.after b/idea/testData/completion/handlers/DoNotInsertDefaultJsImports.kt.after new file mode 100644 index 00000000000..b0281749b13 --- /dev/null +++ b/idea/testData/completion/handlers/DoNotInsertDefaultJsImports.kt.after @@ -0,0 +1,6 @@ +fun main(args: Array) { + println() +} + +// For KT-3620: Don't auto-import js.* and remove in `optimize imports` +// JS \ No newline at end of file diff --git a/idea/testData/editor/optimizeImports/DefaultJsImports.kt b/idea/testData/editor/optimizeImports/DefaultJsImports.kt new file mode 100644 index 00000000000..a6644787327 --- /dev/null +++ b/idea/testData/editor/optimizeImports/DefaultJsImports.kt @@ -0,0 +1,8 @@ +import js.Json + +fun main(args: Array) { + val a: Json? = null +} + +// For KT-3620 Don't auto-import js.* and remove in `optimize imports` +// JS \ No newline at end of file diff --git a/idea/testData/editor/optimizeImports/DefaultJsImports_after.kt b/idea/testData/editor/optimizeImports/DefaultJsImports_after.kt new file mode 100644 index 00000000000..d522ff63a54 --- /dev/null +++ b/idea/testData/editor/optimizeImports/DefaultJsImports_after.kt @@ -0,0 +1,6 @@ +fun main(args: Array) { + val a: Json? = null +} + +// For KT-3620 Don't auto-import js.* and remove in `optimize imports` +// JS \ No newline at end of file diff --git a/idea/tests/org/jetbrains/jet/completion/handlers/CompletionHandlerTest.java b/idea/tests/org/jetbrains/jet/completion/handlers/CompletionHandlerTest.java index 89b59e22f95..eb35e457f24 100644 --- a/idea/tests/org/jetbrains/jet/completion/handlers/CompletionHandlerTest.java +++ b/idea/tests/org/jetbrains/jet/completion/handlers/CompletionHandlerTest.java @@ -22,35 +22,19 @@ import com.intellij.codeInsight.lookup.LookupElementPresentation; import com.intellij.codeInsight.lookup.LookupEvent; import com.intellij.codeInsight.lookup.LookupManager; import com.intellij.codeInsight.lookup.impl.LookupImpl; -import com.intellij.ide.startup.impl.StartupManagerImpl; import com.intellij.openapi.command.WriteCommandAction; -import com.intellij.openapi.startup.StartupManager; import com.intellij.psi.codeStyle.CodeStyleSettings; import com.intellij.psi.codeStyle.CodeStyleSettingsManager; -import com.intellij.testFramework.LightProjectDescriptor; -import com.intellij.testFramework.fixtures.LightCodeInsightFixtureTestCase; import junit.framework.Assert; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import org.jetbrains.jet.plugin.JetLightProjectDescriptor; +import org.jetbrains.jet.plugin.JetLightCodeInsightFixtureTestCase; import org.jetbrains.jet.plugin.PluginTestCaseBase; import org.jetbrains.jet.plugin.formatter.JetCodeStyleSettings; import java.io.File; -public class CompletionHandlerTest extends LightCodeInsightFixtureTestCase { - @Override - protected void setUp() throws Exception { - super.setUp(); - ((StartupManagerImpl) StartupManager.getInstance(getProject())).runPostStartupActivities(); - } - - @NotNull - @Override - protected LightProjectDescriptor getProjectDescriptor() { - return JetLightProjectDescriptor.INSTANCE; - } - +public class CompletionHandlerTest extends JetLightCodeInsightFixtureTestCase { public void testClassCompletionImport() { doTest(CompletionType.BASIC, 2, "SortedSet", null, '\n'); } @@ -59,6 +43,10 @@ public class CompletionHandlerTest extends LightCodeInsightFixtureTestCase { doTest(); } + public void testDoNotInsertDefaultJsImports() { + doTest(); + } + public void testDoNotInsertImportIfResolvedIntoJavaConstructor() { doTest(); } @@ -88,9 +76,9 @@ public class CompletionHandlerTest extends LightCodeInsightFixtureTestCase { } public void testSingleBrackets() { - myFixture.configureByFile(getBeforeFileName()); + myFixture.configureByFile(fileName()); myFixture.type('('); - myFixture.checkResultByFile(getAfterFileName()); + myFixture.checkResultByFile(afterFileName()); } public void testExistingSingleBrackets() { @@ -106,9 +94,9 @@ public class CompletionHandlerTest extends LightCodeInsightFixtureTestCase { } public void testInsertFunctionWithBothParentheses() { - myFixture.configureByFile(getBeforeFileName()); + myFixture.configureByFile(fileName()); myFixture.type("test()"); - myFixture.checkResultByFile(getAfterFileName()); + myFixture.checkResultByFile(afterFileName()); } public void testInsertImportOnTab() { @@ -144,7 +132,7 @@ public class CompletionHandlerTest extends LightCodeInsightFixtureTestCase { } public void doTest(CompletionType type, int time, @Nullable String lookupString, @Nullable String tailText, char completionChar) { - myFixture.configureByFile(getBeforeFileName()); + myFixture.configureByFile(fileName()); if (lookupString != null || tailText != null) { myFixture.complete(type, time); @@ -158,7 +146,7 @@ public class CompletionHandlerTest extends LightCodeInsightFixtureTestCase { forceCompleteFirst(type, time); } - myFixture.checkResultByFile(getAfterFileName()); + myFixture.checkResultByFile(afterFileName()); } @Nullable @@ -203,11 +191,7 @@ public class CompletionHandlerTest extends LightCodeInsightFixtureTestCase { return foundElement; } - protected String getBeforeFileName() { - return getTestName(false) + ".kt"; - } - - protected String getAfterFileName() { + protected String afterFileName() { return getTestName(false) + ".kt.after"; } diff --git a/idea/tests/org/jetbrains/jet/plugin/JetLightCodeInsightFixtureTestCase.java b/idea/tests/org/jetbrains/jet/plugin/JetLightCodeInsightFixtureTestCase.java index 985f7d91651..ae4309512ae 100644 --- a/idea/tests/org/jetbrains/jet/plugin/JetLightCodeInsightFixtureTestCase.java +++ b/idea/tests/org/jetbrains/jet/plugin/JetLightCodeInsightFixtureTestCase.java @@ -35,6 +35,9 @@ public abstract class JetLightCodeInsightFixtureTestCase extends LightCodeInsigh if (InTextDirectivesUtils.isDirectiveDefined(fileText, "RUNTIME")) { projectDescriptor = JetWithJdkAndRuntimeLightProjectDescriptor.INSTANCE; } + else if (InTextDirectivesUtils.isDirectiveDefined(fileText, "JS")) { + projectDescriptor = JetStdJSProjectDescriptor.INSTANCE; + } else { projectDescriptor = JetLightProjectDescriptor.INSTANCE; } @@ -56,5 +59,7 @@ public abstract class JetLightCodeInsightFixtureTestCase extends LightCodeInsigh return projectDescriptor; } - protected abstract String fileName(); + protected String fileName() { + return getTestName(false) + ".kt"; + } } diff --git a/idea/tests/org/jetbrains/jet/plugin/importOptimizer/OptimizeImportsTest.java b/idea/tests/org/jetbrains/jet/plugin/importOptimizer/OptimizeImportsTest.java index b422671bc34..a84def047b5 100644 --- a/idea/tests/org/jetbrains/jet/plugin/importOptimizer/OptimizeImportsTest.java +++ b/idea/tests/org/jetbrains/jet/plugin/importOptimizer/OptimizeImportsTest.java @@ -29,6 +29,10 @@ public class OptimizeImportsTest extends JetLightCodeInsightFixtureTestCase { doTest(); } + public void testDefaultJsImports() throws Exception { + doTest(); + } + public void testRemoveImportsIfGeneral() throws Exception { doTest(); } @@ -85,11 +89,6 @@ public class OptimizeImportsTest extends JetLightCodeInsightFixtureTestCase { File.separator; } - @Override - public String fileName() { - return getTestName(false) + ".kt"; - } - public String checkFileName() { return getTestName(false) + "_after.kt"; } From 5ca4df3d1d78924d3ee9d005559ce11246957b26 Mon Sep 17 00:00:00 2001 From: Nikolay Krasko Date: Wed, 15 May 2013 15:27:09 +0400 Subject: [PATCH 119/249] KT-3618 Missing space in error message "inconstructor" #KT-3618 Fixed --- .../org/jetbrains/jet/lang/diagnostics/rendering/Renderers.java | 2 +- idea/testData/diagnosticMessage/conflictingSubstitutions1.html | 2 +- idea/testData/diagnosticMessage/conflictingSubstitutions2.html | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/diagnostics/rendering/Renderers.java b/compiler/frontend/src/org/jetbrains/jet/lang/diagnostics/rendering/Renderers.java index fd0ba9018a0..42bc78af206 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/diagnostics/rendering/Renderers.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/diagnostics/rendering/Renderers.java @@ -184,7 +184,7 @@ public class Renderers { result.text(newText() .normal("Cannot infer type parameter ") .strong(firstConflictingParameter.getName()) - .normal(" in")); + .normal(" in ")); //String type = strong(firstConflictingParameter.getName()); TableRenderer table = newTable(); result.table(table); diff --git a/idea/testData/diagnosticMessage/conflictingSubstitutions1.html b/idea/testData/diagnosticMessage/conflictingSubstitutions1.html index 0e8a5072ff5..150ce8e0434 100644 --- a/idea/testData/diagnosticMessage/conflictingSubstitutions1.html +++ b/idea/testData/diagnosticMessage/conflictingSubstitutions1.html @@ -2,7 +2,7 @@ Type inference failed: Cannot infer type parameter T - in + in
diff --git a/idea/testData/diagnosticMessage/conflictingSubstitutions2.html b/idea/testData/diagnosticMessage/conflictingSubstitutions2.html index 61c7f6a3491..08c46d628b7 100644 --- a/idea/testData/diagnosticMessage/conflictingSubstitutions2.html +++ b/idea/testData/diagnosticMessage/conflictingSubstitutions2.html @@ -2,7 +2,7 @@ Type inference failed: Cannot infer type parameter T - in
+ in
From 1bf06f7c02e7dc7bc68824926bd7f4174b780986 Mon Sep 17 00:00:00 2001 From: chocolateboy Date: Wed, 8 May 2013 05:10:19 +0100 Subject: [PATCH 120/249] make the preloader's required profiler argument (time|notime) an optional switch: -pp fixes for broken Windows batch files --- compiler/cli/bin/kotlinc-js | 9 +++++++-- compiler/cli/bin/kotlinc-js.bat | 26 ++++++++++++++++++++++---- compiler/cli/bin/kotlinc-jvm | 9 +++++++-- compiler/cli/bin/kotlinc-jvm.bat | 26 ++++++++++++++++++++++---- 4 files changed, 58 insertions(+), 12 deletions(-) diff --git a/compiler/cli/bin/kotlinc-js b/compiler/cli/bin/kotlinc-js index cc2129bf160..9a73260e964 100755 --- a/compiler/cli/bin/kotlinc-js +++ b/compiler/cli/bin/kotlinc-js @@ -2,7 +2,7 @@ # ############################################################################## # Copyright 2002-2011, LAMP/EPFL -# Copyright 2011, JetBrains +# Copyright 2011-2013, JetBrains # # This is free software; see the distribution for copying conditions. # There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A @@ -45,6 +45,7 @@ fi # -D options will be available as system properties. declare -a java_args declare -a kotlin_args +profile_preloader="notime" while [ $# -gt 0 ]; do case "$1" in @@ -62,6 +63,10 @@ while [ $# -gt 0 ]; do kotlin_args=("${kotlin_args[@]}" "$1") shift ;; + -pp) + profile_preloader="time" + shift + ;; *) kotlin_args=("${kotlin_args[@]}" "$1") shift @@ -82,4 +87,4 @@ CPSELECT="-cp " $JAVA_OPTS \ "${java_args[@]}" \ ${CPSELECT}"${KOTLIN_HOME}/lib/kotlin-preloader.jar" \ - org.jetbrains.jet.preloading.Preloader "${KOTLIN_HOME}/lib/kotlin-compiler.jar" org.jetbrains.jet.cli.js.K2JSCompiler 4096 "$@" + org.jetbrains.jet.preloading.Preloader "${KOTLIN_HOME}/lib/kotlin-compiler.jar" org.jetbrains.jet.cli.js.K2JSCompiler 4096 $profile_preloader "$@" diff --git a/compiler/cli/bin/kotlinc-js.bat b/compiler/cli/bin/kotlinc-js.bat index fef3bb6bcc2..4ef29f47720 100644 --- a/compiler/cli/bin/kotlinc-js.bat +++ b/compiler/cli/bin/kotlinc-js.bat @@ -2,13 +2,17 @@ rem based on scalac.bat from the Scala distribution rem ########################################################################## rem # Copyright 2002-2011, LAMP/EPFL -rem # Copyright 2011, JetBrains +rem # Copyright 2011-2013, JetBrains rem # rem # This is free software; see the distribution for copying conditions. rem # There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A rem # PARTICULAR PURPOSE. rem ########################################################################## +rem We adopt the following conventions: +rem - System/user environment variables start with a letter +rem - Local batch variables start with an underscore ('_') + @setlocal call :set_home @@ -18,12 +22,26 @@ if not "%JAVA_HOME%"=="" ( if "%_JAVACMD%"=="" set _JAVACMD=java +set _PROFILE_PRELOADER=notime +rem re: E%1 &c., see http://www.riedquat.de/blog/2011-11-27-01#w9aab1c45 +if E%1==E-pp ( + shift + set _PROFILE_PRELOADER=time +) + rem We use the value of the JAVA_OPTS environment variable if defined set _JAVA_OPTS=-Xmx256M -Xms32M -noverify -"%_JAVACMD%" %_JAVA_OPTS% -cp "%_KOTLIN_HOME%\lib\kotlin-preloader.jar" ^ - org.jetbrains.jet.preloading.Preloader "${KOTLIN_HOME}/lib/kotlin-compiler.jar" ^ - org.jetbrains.jet.cli.jvm.K2JVMCompiler 4096 org.jetbrains.jet.cli.js.K2JSCompiler %* +rem re: %1 %2 &c., see http://www.riedquat.de/blog/2011-11-27-01#w9aab1c60 +if "%_PROFILE_PRELOADER%"=="time" ( + "%_JAVACMD%" %_JAVA_OPTS% -cp "%_KOTLIN_HOME%\lib\kotlin-preloader.jar" ^ + org.jetbrains.jet.preloading.Preloader "%_KOTLIN_HOME%\lib\kotlin-compiler.jar" ^ + org.jetbrains.jet.cli.js.K2JSCompiler 4096 %_PROFILE_PRELOADER% %1 %2 %3 %4 %5 %6 %7 %8 %9 +) else ( + "%_JAVACMD%" %_JAVA_OPTS% -cp "%_KOTLIN_HOME%\lib\kotlin-preloader.jar" ^ + org.jetbrains.jet.preloading.Preloader "%_KOTLIN_HOME%\lib\kotlin-compiler.jar" ^ + org.jetbrains.jet.cli.js.K2JSCompiler 4096 %_PROFILE_PRELOADER% %* +) goto end rem ########################################################################## diff --git a/compiler/cli/bin/kotlinc-jvm b/compiler/cli/bin/kotlinc-jvm index c837ecb6cb5..70b7a826def 100755 --- a/compiler/cli/bin/kotlinc-jvm +++ b/compiler/cli/bin/kotlinc-jvm @@ -2,7 +2,7 @@ # ############################################################################## # Copyright 2002-2011, LAMP/EPFL -# Copyright 2011, JetBrains +# Copyright 2011-2013, JetBrains # # This is free software; see the distribution for copying conditions. # There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A @@ -45,6 +45,7 @@ fi # -D options will be available as system properties. declare -a java_args declare -a kotlin_args +profile_preloader="notime" while [ $# -gt 0 ]; do case "$1" in @@ -62,6 +63,10 @@ while [ $# -gt 0 ]; do kotlin_args=("${kotlin_args[@]}" "$1") shift ;; + -pp) + profile_preloader="time" + shift + ;; *) kotlin_args=("${kotlin_args[@]}" "$1") shift @@ -82,4 +87,4 @@ CPSELECT="-cp " $JAVA_OPTS \ "${java_args[@]}" \ ${CPSELECT}"${KOTLIN_HOME}/lib/kotlin-preloader.jar" \ - org.jetbrains.jet.preloading.Preloader "${KOTLIN_HOME}/lib/kotlin-compiler.jar" org.jetbrains.jet.cli.jvm.K2JVMCompiler 4096 "$@" + org.jetbrains.jet.preloading.Preloader "${KOTLIN_HOME}/lib/kotlin-compiler.jar" org.jetbrains.jet.cli.jvm.K2JVMCompiler 4096 $profile_preloader "$@" diff --git a/compiler/cli/bin/kotlinc-jvm.bat b/compiler/cli/bin/kotlinc-jvm.bat index 3949f6f5797..b9a35548557 100644 --- a/compiler/cli/bin/kotlinc-jvm.bat +++ b/compiler/cli/bin/kotlinc-jvm.bat @@ -2,13 +2,17 @@ rem based on scalac.bat from the Scala distribution rem ########################################################################## rem # Copyright 2002-2011, LAMP/EPFL -rem # Copyright 2011, JetBrains +rem # Copyright 2011-2013, JetBrains rem # rem # This is free software; see the distribution for copying conditions. rem # There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A rem # PARTICULAR PURPOSE. rem ########################################################################## +rem We adopt the following conventions: +rem - System/user environment variables start with a letter +rem - Local batch variables start with an underscore ('_') + @setlocal call :set_home @@ -18,12 +22,26 @@ if not "%JAVA_HOME%"=="" ( if "%_JAVACMD%"=="" set _JAVACMD=java +set _PROFILE_PRELOADER=notime +rem re: E%1 &c., see http://www.riedquat.de/blog/2011-11-27-01#w9aab1c45 +if E%1==E-pp ( + shift + set _PROFILE_PRELOADER=time +) + rem We use the value of the JAVA_OPTS environment variable if defined set _JAVA_OPTS=-Xmx256M -Xms32M -noverify -"%_JAVACMD%" %_JAVA_OPTS% -cp "%_KOTLIN_HOME%\lib\kotlin-preloader.jar" ^ - org.jetbrains.jet.preloading.Preloader "${KOTLIN_HOME}/lib/kotlin-compiler.jar" ^ - org.jetbrains.jet.cli.jvm.K2JVMCompiler 4096 org.jetbrains.jet.cli.jvm.K2JVMCompiler %* +rem re: %1 %2 &c., see http://www.riedquat.de/blog/2011-11-27-01#w9aab1c60 +if "%_PROFILE_PRELOADER%"=="time" ( + "%_JAVACMD%" %_JAVA_OPTS% -cp "%_KOTLIN_HOME%\lib\kotlin-preloader.jar" ^ + org.jetbrains.jet.preloading.Preloader "%_KOTLIN_HOME%\lib\kotlin-compiler.jar" ^ + org.jetbrains.jet.cli.jvm.K2JVMCompiler 4096 %_PROFILE_PRELOADER% %1 %2 %3 %4 %5 %6 %7 %8 %9 +) else ( + "%_JAVACMD%" %_JAVA_OPTS% -cp "%_KOTLIN_HOME%\lib\kotlin-preloader.jar" ^ + org.jetbrains.jet.preloading.Preloader "%_KOTLIN_HOME%\lib\kotlin-compiler.jar" ^ + org.jetbrains.jet.cli.jvm.K2JVMCompiler 4096 %_PROFILE_PRELOADER% %* +) goto end rem ########################################################################## From a5f1a8b3f8a2ca81bd25562bb2d9e2506ffaec71 Mon Sep 17 00:00:00 2001 From: "Natalia.Ukhorskaya" Date: Mon, 20 May 2013 12:13:42 +0400 Subject: [PATCH 121/249] TypeCastException when casting null to T with nullable upper-bound #KT-3637 Fixed --- .../jet/codegen/ExpressionCodegen.java | 2 +- .../boxWithStdlib/casts/asWithGeneric.kt | 21 +++++++++++++++++++ ...lackBoxWithStdlibCodegenTestGenerated.java | 16 +++++++++++++- 3 files changed, 37 insertions(+), 2 deletions(-) create mode 100644 compiler/testData/codegen/boxWithStdlib/casts/asWithGeneric.kt diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java index 19f0dc3f072..093ac725a21 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java @@ -3513,7 +3513,7 @@ The "returned" value of try expression with no finally is either the last expres value.put(boxType(value.type), v); if (opToken != JetTokens.AS_SAFE) { - if (!rightType.isNullable()) { + if (!CodegenUtil.isNullableType(rightType)) { v.dup(); Label nonnull = new Label(); v.ifnonnull(nonnull); diff --git a/compiler/testData/codegen/boxWithStdlib/casts/asWithGeneric.kt b/compiler/testData/codegen/boxWithStdlib/casts/asWithGeneric.kt new file mode 100644 index 00000000000..aed0bdf83d2 --- /dev/null +++ b/compiler/testData/codegen/boxWithStdlib/casts/asWithGeneric.kt @@ -0,0 +1,21 @@ +fun test1() = null as T +fun test2(): T { + val a : Any? = null + return a as T +} + +fun test3() = null as T + +fun box(): String { + if (test1() != null) return "fail: test1" + if (test2() != null) return "fail: test2" + var result3 = "fail" + try { + test3() + } + catch(e: TypeCastException) { + result3 = "OK" + } + if (result3 != "OK") return "fail: test3" + return "OK" +} diff --git a/compiler/tests/org/jetbrains/jet/codegen/generated/BlackBoxWithStdlibCodegenTestGenerated.java b/compiler/tests/org/jetbrains/jet/codegen/generated/BlackBoxWithStdlibCodegenTestGenerated.java index 2d014884dc9..6543439e5eb 100644 --- a/compiler/tests/org/jetbrains/jet/codegen/generated/BlackBoxWithStdlibCodegenTestGenerated.java +++ b/compiler/tests/org/jetbrains/jet/codegen/generated/BlackBoxWithStdlibCodegenTestGenerated.java @@ -31,12 +31,25 @@ import org.jetbrains.jet.codegen.generated.AbstractBlackBoxCodegenTest; /** This class is generated by {@link org.jetbrains.jet.generators.tests.GenerateTests}. DO NOT MODIFY MANUALLY */ @SuppressWarnings("all") @TestMetadata("compiler/testData/codegen/boxWithStdlib") -@InnerTestClasses({BlackBoxWithStdlibCodegenTestGenerated.DataClasses.class, BlackBoxWithStdlibCodegenTestGenerated.FullJdk.class, BlackBoxWithStdlibCodegenTestGenerated.JdkAnnotations.class, BlackBoxWithStdlibCodegenTestGenerated.Ranges.class, BlackBoxWithStdlibCodegenTestGenerated.Regressions.class, BlackBoxWithStdlibCodegenTestGenerated.Strings.class}) +@InnerTestClasses({BlackBoxWithStdlibCodegenTestGenerated.Casts.class, BlackBoxWithStdlibCodegenTestGenerated.DataClasses.class, BlackBoxWithStdlibCodegenTestGenerated.FullJdk.class, BlackBoxWithStdlibCodegenTestGenerated.JdkAnnotations.class, BlackBoxWithStdlibCodegenTestGenerated.Ranges.class, BlackBoxWithStdlibCodegenTestGenerated.Regressions.class, BlackBoxWithStdlibCodegenTestGenerated.Strings.class}) public class BlackBoxWithStdlibCodegenTestGenerated extends AbstractBlackBoxCodegenTest { public void testAllFilesPresentInBoxWithStdlib() throws Exception { JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.GenerateTests", new File("compiler/testData/codegen/boxWithStdlib"), Pattern.compile("^(.+)\\.kt$"), true); } + @TestMetadata("compiler/testData/codegen/boxWithStdlib/casts") + public static class Casts extends AbstractBlackBoxCodegenTest { + public void testAllFilesPresentInCasts() throws Exception { + JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.GenerateTests", new File("compiler/testData/codegen/boxWithStdlib/casts"), Pattern.compile("^(.+)\\.kt$"), true); + } + + @TestMetadata("asWithGeneric.kt") + public void testAsWithGeneric() throws Exception { + doTestWithStdlib("compiler/testData/codegen/boxWithStdlib/casts/asWithGeneric.kt"); + } + + } + @TestMetadata("compiler/testData/codegen/boxWithStdlib/dataClasses") @InnerTestClasses({DataClasses.Copy.class, DataClasses.Equals.class, DataClasses.Hashcode.class, DataClasses.Tostring.class}) public static class DataClasses extends AbstractBlackBoxCodegenTest { @@ -749,6 +762,7 @@ public class BlackBoxWithStdlibCodegenTestGenerated extends AbstractBlackBoxCode public static Test suite() { TestSuite suite = new TestSuite("BlackBoxWithStdlibCodegenTestGenerated"); suite.addTestSuite(BlackBoxWithStdlibCodegenTestGenerated.class); + suite.addTestSuite(Casts.class); suite.addTest(DataClasses.innerSuite()); suite.addTestSuite(FullJdk.class); suite.addTestSuite(JdkAnnotations.class); From 97c33b02ab322b99df2f21e1f07a405224aaa5ad Mon Sep 17 00:00:00 2001 From: "Natalia.Ukhorskaya" Date: Mon, 20 May 2013 13:10:35 +0400 Subject: [PATCH 122/249] Add library classes for delegated properties --- .../src/kotlin/properties/Properties.kt | 7 +- .../properties/delegation/Delegation.kt | 118 +++++++++ .../properties/delegation/lazy/LazyValues.kt | 75 ++++++ .../properties/delegation/DelegationTest.kt | 64 +++++ .../delegation/MapDelegationTest.kt | 224 ++++++++++++++++++ .../delegation/lazy/LazyValuesTest.kt | 143 +++++++++++ 6 files changed, 629 insertions(+), 2 deletions(-) create mode 100644 libraries/stdlib/src/kotlin/properties/delegation/Delegation.kt create mode 100644 libraries/stdlib/src/kotlin/properties/delegation/lazy/LazyValues.kt create mode 100644 libraries/stdlib/test/properties/delegation/DelegationTest.kt create mode 100644 libraries/stdlib/test/properties/delegation/MapDelegationTest.kt create mode 100644 libraries/stdlib/test/properties/delegation/lazy/LazyValuesTest.kt diff --git a/libraries/stdlib/src/kotlin/properties/Properties.kt b/libraries/stdlib/src/kotlin/properties/Properties.kt index 6c5aa09312f..e045c5993c6 100644 --- a/libraries/stdlib/src/kotlin/properties/Properties.kt +++ b/libraries/stdlib/src/kotlin/properties/Properties.kt @@ -1,9 +1,8 @@ package kotlin.properties -import kotlin.* -import kotlin.util.* import java.util.HashMap import java.util.ArrayList +import kotlin.properties.delegation.ObservableProperty public class ChangeEvent(val source: Any, val name: String, val oldValue: Any?, val newValue: Any?) { var propogationId: Any? = null @@ -66,6 +65,10 @@ public abstract class ChangeSupport { } } + protected fun property(init: T): ObservableProperty { + return ObservableProperty(init) { name, oldValue, newValue -> changeProperty(name, oldValue, newValue) } + } + public fun onPropertyChange(fn: (ChangeEvent) -> Unit) { // TODO //addChangeListener(DelegateChangeListener(fn)) diff --git a/libraries/stdlib/src/kotlin/properties/delegation/Delegation.kt b/libraries/stdlib/src/kotlin/properties/delegation/Delegation.kt new file mode 100644 index 00000000000..fe4dbb05a6d --- /dev/null +++ b/libraries/stdlib/src/kotlin/properties/delegation/Delegation.kt @@ -0,0 +1,118 @@ +package kotlin.properties.delegation + +import kotlin.properties.ChangeSupport + +public class NotNullVar { + private var value: T? = null + + public fun get(thisRef: Any?, desc: PropertyMetadata): T { + return value ?: throw IllegalStateException("Property ${desc.name} should be initialized before get") + } + + public fun set(thisRef: Any?, desc: PropertyMetadata, value: T) { + this.value = value + } +} + +public class SynchronizedVar(private val initValue: T, private val lock: Any) { + private var value: T = initValue + + public fun get(thisRef: Any?, desc: PropertyMetadata): T { + return synchronized(lock) { value } + } + + public fun set(thisRef: Any?, desc: PropertyMetadata, newValue: T) { + synchronized(lock) { + value = newValue + } + } +} + +class ObservableProperty(initialValue: T, val changeSupport: (name: String, oldValue: T, newValue: T) -> Unit) { + private var value = initialValue + + public fun get(thisRef: Any?, desc: PropertyMetadata): T { + return value + } + + public fun set(thisRef: Any?, desc: PropertyMetadata, newValue: T) { + changeSupport(desc.name, value, newValue) + value = newValue + } +} + +public class KeyMissingException(message: String): RuntimeException(message) + +public abstract class MapVal { + public abstract fun getMap(thisRef: T): Map<*, *> + public abstract fun getKey(desc: PropertyMetadata): Any? + + public open fun getDefaultValue(desc: PropertyMetadata, key: Any?): V { + throw KeyMissingException("Key $key is missing") + } + + public fun get(thisRef: T, desc: PropertyMetadata): V { + val key = getKey(desc) + val map = getMap(thisRef) + if (!map.containsKey(key)) { + return getDefaultValue(desc, key) + } + return map[key] as V + } +} + +public abstract class MapVar: MapVal() { + + public fun set(thisRef: T, desc: PropertyMetadata, newValue: V) { + val map = getMap(thisRef) as MutableMap + map[getKey(desc)] = newValue + } +} + +public fun Map.readOnlyProperty(default: (() -> V)? = null): MapVal { + return object: MapVal() { + override fun getMap(thisRef: Any?) = this@readOnlyProperty + override fun getKey(desc: PropertyMetadata) = desc.name + override fun getDefaultValue(desc: PropertyMetadata, key: Any?) = if (default == null) super.getDefaultValue(desc, key) else default() + } +} + +public fun Map<*, *>.readOnlyProperty(default: (() -> V)? = null, key: Any?): MapVal { + return object: MapVal() { + override fun getMap(thisRef: Any?) = this@readOnlyProperty + override fun getKey(desc: PropertyMetadata) = key + override fun getDefaultValue(desc: PropertyMetadata, key: Any?) = if (default == null) super.getDefaultValue(desc, key) else default() + } +} + +public fun Map<*, *>.readOnlyProperty(default: (() -> V)? = null, key: (desc: PropertyMetadata) -> Any?): MapVal { + return object: MapVal() { + override fun getMap(thisRef: Any?) = this@readOnlyProperty + override fun getKey(desc: PropertyMetadata) = key(desc) + override fun getDefaultValue(desc: PropertyMetadata, key: Any?) = if (default == null) super.getDefaultValue(desc, key) else default() + } +} + +public fun MutableMap.property(default: (() -> V)? = null): MapVar { + return object: MapVar() { + override fun getMap(thisRef: Any?) = this@property + override fun getKey(desc: PropertyMetadata) = desc.name + override fun getDefaultValue(desc: PropertyMetadata, key: Any?) = if (default == null) super.getDefaultValue(desc, key) else default() + } +} + +public fun MutableMap<*, *>.property(default: (() -> V)? = null, key: Any?): MapVar { + return object: MapVar() { + override fun getMap(thisRef: Any?) = this@property + override fun getKey(desc: PropertyMetadata) = key + override fun getDefaultValue(desc: PropertyMetadata, key: Any?) = if (default == null) super.getDefaultValue(desc, key) else default() + } +} + +public fun MutableMap<*, *>.property(default: (() -> V)? = null, key: (desc: PropertyMetadata) -> Any?): MapVar { + return object: MapVar() { + override fun getMap(thisRef: Any?) = this@property + override fun getKey(desc: PropertyMetadata) = key(desc) + override fun getDefaultValue(desc: PropertyMetadata, key: Any?) = if (default == null) super.getDefaultValue(desc, key) else default() + } +} \ No newline at end of file diff --git a/libraries/stdlib/src/kotlin/properties/delegation/lazy/LazyValues.kt b/libraries/stdlib/src/kotlin/properties/delegation/lazy/LazyValues.kt new file mode 100644 index 00000000000..2d0767446d3 --- /dev/null +++ b/libraries/stdlib/src/kotlin/properties/delegation/lazy/LazyValues.kt @@ -0,0 +1,75 @@ +package kotlin.properties.delegation.lazy + +private val NULL_VALUE: Any = Any() + +private fun escape(value: T): Any { + return if (value == null) NULL_VALUE else value +} + +private fun unescape(value: Any): T? { + return if (value == NULL_VALUE) null else value as T +} + +public open class LazyVal(initializer: () -> T): NullableLazyVal(initializer) { + override fun get(thisRef: Any?, desc: PropertyMetadata): T { + return super.get(thisRef, desc)!! + } +} + +public open class NullableLazyVal(private val initializer: () -> T?) { + private var value: Any? = null + + public open fun get(thisRef: Any?, desc: PropertyMetadata): T? { + if (value == null) { + value = escape(initializer()) + } + return unescape(value!!) + } +} + +public open class VolatileLazyVal(initializer: () -> T): VolatileNullableLazyVal(initializer) { + override fun get(thisRef: Any?, desc: PropertyMetadata): T { + return super.get(thisRef, desc)!! + } +} + +public open class VolatileNullableLazyVal(private val initializer: () -> T?) { + private volatile var value: Any? = null + + public open fun get(thisRef: Any?, desc: PropertyMetadata): T? { + if (value == null) { + value = escape(initializer()) + } + return unescape(value!!) + } +} + +public open class AtomicLazyVal(lock: Any? = null, initializer: () -> T): AtomicNullableLazyVal(lock, initializer) { + override fun get(thisRef: Any?, desc: PropertyMetadata): T { + return super.get(thisRef, desc)!! + } +} + +public open class AtomicNullableLazyVal(lock: Any? = null, private val initializer: () -> T?) { + private val lock = lock ?: this + private volatile var value: Any? = null + + public open fun get(thisRef: Any?, desc: PropertyMetadata): T? { + val _v1 = value + if (_v1 != null) { + return unescape(_v1) + } + + return synchronized(lock) { + val _v2 = value + if (_v2 != null) { + unescape(_v2) + } + else { + val typedValue = initializer() + value = escape(typedValue) + typedValue + } + } + } +} \ No newline at end of file diff --git a/libraries/stdlib/test/properties/delegation/DelegationTest.kt b/libraries/stdlib/test/properties/delegation/DelegationTest.kt new file mode 100644 index 00000000000..cceeeaf6af1 --- /dev/null +++ b/libraries/stdlib/test/properties/delegation/DelegationTest.kt @@ -0,0 +1,64 @@ +package test.properties.delegation + +import junit.framework.TestCase +import kotlin.test.* +import kotlin.properties.* +import kotlin.properties.delegation.* +import kotlin.properties.delegation.lazy.* + +trait WithBox { + fun box(): String +} + +abstract class DelegationTestBase: TestCase() { + fun doTest(klass: WithBox) { + assertEquals("OK", klass.box()) + } +} + +class DelegationTest(): DelegationTestBase() { + fun testNotNullVar() { + doTest(TestNotNullVar("a", "b")) + } + + fun testObservableProperty() { + doTest(TestObservableProperty()) + } +} + +public class TestNotNullVar(val a1: String, val b1: T): WithBox { + var a: String by NotNullVar() + var b by NotNullVar() + + override fun box(): String { + a = a1 + b = b1 + if (a != "a") return "fail: a shouuld be a, but was $a" + if (b != "b") return "fail: b should be b, but was $b" + return "OK" + } +} + +class TestObservableProperty: WithBox, ChangeSupport() { + + var b by property(init = 2) + var c by property(3) + + override fun box(): String { + var result = false + addChangeListener("b", object: ChangeListener { + public override fun onPropertyChange(event: ChangeEvent) { + result = true + } + }) + addChangeListener("c", object: ChangeListener { + public override fun onPropertyChange(event: ChangeEvent) { + result = false + } + }) + b = 4 + if (b != 4) return "fail: b != 4" + if (!result) return "fail: result should be true" + return "OK" + } +} \ No newline at end of file diff --git a/libraries/stdlib/test/properties/delegation/MapDelegationTest.kt b/libraries/stdlib/test/properties/delegation/MapDelegationTest.kt new file mode 100644 index 00000000000..9bc21c81c20 --- /dev/null +++ b/libraries/stdlib/test/properties/delegation/MapDelegationTest.kt @@ -0,0 +1,224 @@ +package test.properties.delegation + +import java.util.HashMap +import kotlin.properties.delegation.* + +class MapDelegationTest(): DelegationTestBase() { + + fun testMapPropertyString() { + doTest(TestMapPropertyString()) + } + + fun testMapValWithDifferentTypes() { + doTest(TestMapValWithDifferentTypes()) + } + + fun testMapVarWithDifferentTypes() { + doTest(TestMapVarWithDifferentTypes()) + } + + fun testNullableKey() { + doTest(TestNullableKey()) + } + + fun testMapPropertyKey() { + doTest(TestMapPropertyKey()) + } + + fun testMapPropertyFunction() { + doTest(TestMapPropertyFunction()) + } + + fun testMapPropertyCustom() { + doTest(TestMapPropertyCustom()) + } + + fun testMapValWithDefault() { + doTest(TestMapValWithDefault()) + } + + fun testMapVarWithDefault() { + doTest(TestMapVarWithDefault()) + } + + fun testMapPropertyCustomWithDefault() { + doTest(TestMapPropertyCustomWithDefault()) + } +} + +class TestMapValWithDifferentTypes(): WithBox { + val map = hashMapOf("a" to "a", "b" to 1, "c" to A(1), "d" to null) + val a by map.readOnlyProperty() + val b by map.readOnlyProperty() + val c by map.readOnlyProperty() + val d by map.readOnlyProperty() + + override fun box(): String { + if (a != "a") return "fail at 'a'" + if (b != 1) return "fail at 'b'" + if (c != A(1)) return "fail at 'c'" + if (d != null) return "fail at 'd'" + return "OK" + } + + data class A(val a: Int) +} + +class TestMapVarWithDifferentTypes(): WithBox { + val map: HashMap = hashMapOf("a" to "a", "b" to 1, "c" to A(1), "d" to "d") + var a by map.property() + var b by map.property() + var c by map.property() + var d by map.property() + + override fun box(): String { + a = "aa" + b = 11 + c = A(11) + d = null + if (a != "aa") return "fail at 'a'" + if (b != 11) return "fail at 'b'" + if (c != A(11)) return "fail at 'c'" + if (d != null) return "fail at 'd'" + return "OK" + } + + data class A(val a: Int) +} + +class TestNullableKey: WithBox { + val map = hashMapOf(null to "null") + var a by map.property { desc -> null } + + override fun box(): String { + if (a != "null") return "fail at 'a'" + a = "foo" + if (a != "foo") return "fail at 'a' after set" + return "OK" + } +} + +class TestMapPropertyString(): WithBox { + val map = hashMapOf("a" to "a", "b" to "b", "c" to "c") + val a by map.readOnlyProperty() + var b by map.property() + val c by map.property() + + override fun box(): String { + b = "newB" + if (a != "a") return "fail at 'a'" + if (b != "newB") return "fail at 'b'" + if (c != "c") return "fail at 'c'" + return "OK" + } +} + +class TestMapValWithDefault(): WithBox { + val map = hashMapOf() + val a by map.readOnlyProperty(default = { "aDefault" }) + val b by map.readOnlyProperty(default = { "bDefault" }, key = "b") + val c by map.readOnlyProperty(default = { "cDefault" }, key = { desc -> desc.name }) + + override fun box(): String { + if (a != "aDefault") return "fail at 'a'" + if (b != "bDefault") return "fail at 'b'" + if (c != "cDefault") return "fail at 'c'" + return "OK" + } +} + +class TestMapVarWithDefault(): WithBox { + val map = hashMapOf() + var a by map.property(default = { "aDefault" }) + var b by map.property(default = { "bDefault" }, key = "b") + var c by map.property(default = { "cDefault" }, key = { desc -> desc.name }) + + override fun box(): String { + if (a != "aDefault") return "fail at 'a'" + if (b != "bDefault") return "fail at 'b'" + if (c != "cDefault") return "fail at 'c'" + a = "a" + b = "b" + c = "c" + if (a != "a") return "fail at 'a' after set" + if (b != "b") return "fail at 'b' after set" + if (c != "c") return "fail at 'c' after set" + return "OK" + } +} + +class TestMapPropertyKey(): WithBox { + val map = hashMapOf("a" to "a", "b" to "b") + val a by map.readOnlyProperty(key = "a") + var b by map.property(key = "b") + + override fun box(): String { + b = "c" + if (a != "a") return "fail at 'a'" + if (b != "c") return "fail at 'b'" + return "OK" + } +} + +class TestMapPropertyFunction(): WithBox { + val map = hashMapOf("aDesc" to "a", "bDesc" to "b") + val a by map.readOnlyProperty { desc -> "${desc.name}Desc" } + var b by map.property { desc -> "${desc.name}Desc" } + + override fun box(): String { + b = "c" + if (a != "a") return "fail at 'a'" + if (b != "c") return "fail at 'b' after set" + return "OK" + } +} + +val mapVal = object : MapVal() { + override fun getMap(thisRef: TestMapPropertyCustom) = thisRef.map + override fun getKey(desc: PropertyMetadata) = "${desc.name}Desc" +} +val mapVar = object : MapVar() { + override fun getMap(thisRef: TestMapPropertyCustom) = thisRef.map + override fun getKey(desc: PropertyMetadata) = "${desc.name}Desc" +} + +class TestMapPropertyCustom(): WithBox { + val map = hashMapOf("aDesc" to "a", "bDesc" to "b") + val a by mapVal + var b by mapVar + + override fun box(): String { + b = "newB" + if (a != "a") return "fail at 'a'" + if (b != "newB") return "fail at 'b' after set" + return "OK" + } +} + +val mapValWithDefault = object : MapVal() { + override fun getMap(thisRef: TestMapPropertyCustomWithDefault) = thisRef.map + override fun getKey(desc: PropertyMetadata) = desc.name + + override fun getDefaultValue(desc: PropertyMetadata, key: Any?) = "default" +} + +val mapVarWithDefault = object : MapVar() { + override fun getMap(thisRef: TestMapPropertyCustomWithDefault) = thisRef.map + override fun getKey(desc: PropertyMetadata) = desc.name + + override fun getDefaultValue(desc: PropertyMetadata, key: Any?) = "default" +} + +class TestMapPropertyCustomWithDefault(): WithBox { + val map = hashMapOf() + val a by mapValWithDefault + var b by mapVarWithDefault + + override fun box(): String { + if (a != "default") return "fail at 'a'" + if (b != "default") return "fail at 'b'" + b = "c" + if (b != "c") return "fail at 'b' after set" + return "OK" + } +} \ No newline at end of file diff --git a/libraries/stdlib/test/properties/delegation/lazy/LazyValuesTest.kt b/libraries/stdlib/test/properties/delegation/lazy/LazyValuesTest.kt new file mode 100644 index 00000000000..6a3a4cac847 --- /dev/null +++ b/libraries/stdlib/test/properties/delegation/lazy/LazyValuesTest.kt @@ -0,0 +1,143 @@ +package test.properties.delegation.lazy + +import kotlin.properties.delegation.lazy.* +import test.properties.delegation.WithBox +import test.properties.delegation.DelegationTestBase + +class LazyValuesTest(): DelegationTestBase() { + + fun testLazyVal() { + doTest(TestLazyVal()) + } + + fun testNullableLazyVal() { + doTest(TestNullableLazyVal()) + } + + fun testAtomicNullableLazyVal() { + doTest(TestAtomicNullableLazyVal()) + } + + fun testAtomicLazyVal() { + doTest(TestAtomicLazyVal()) + } + + fun testVolatileNullableLazyVal() { + doTest(TestVolatileNullableLazyVal()) + } + + fun testVolatileLazyVal() { + doTest(TestVolatileLazyVal()) + } +} + +class TestLazyVal: WithBox { + var result = 0 + val a by LazyVal { + ++result + } + + override fun box(): String { + a + if (a != 1) return "fail: initializer should be invoked only once" + return "OK" + } +} + +class TestNullableLazyVal: WithBox { + var resultA = 0 + var resultB = 0 + + val a: Int? by NullableLazyVal { resultA++; null} + val b by NullableLazyVal { foo() } + + override fun box(): String { + a + b + + if (a != null) return "fail: a should be null" + if (b != null) return "fail: a should be null" + if (resultA != 1) return "fail: initializer for a should be invoked only once" + if (resultB != 1) return "fail: initializer for b should be invoked only once" + return "OK" + } + + fun foo(): String? { + resultB++ + return null + } +} + +class TestAtomicLazyVal: WithBox { + var result = 0 + val a by AtomicLazyVal { + ++result + } + + override fun box(): String { + a + if (a != 1) return "fail: initializer should be invoked only once" + return "OK" + } +} + +class TestVolatileNullableLazyVal: WithBox { + var resultA = 0 + var resultB = 0 + + val a: Int? by VolatileNullableLazyVal { resultA++; null} + val b by VolatileNullableLazyVal { foo() } + + override fun box(): String { + a + b + + if (a != null) return "fail: a should be null" + if (b != null) return "fail: a should be null" + if (resultA != 1) return "fail: initializer for a should be invoked only once" + if (resultB != 1) return "fail: initializer for b should be invoked only once" + return "OK" + } + + fun foo(): String? { + resultB++ + return null + } +} + +class TestVolatileLazyVal: WithBox { + var result = 0 + val a by VolatileLazyVal { + ++result + } + + override fun box(): String { + a + if (a != 1) return "fail: initializer should be invoked only once" + return "OK" + } +} + +class TestAtomicNullableLazyVal: WithBox { + var resultA = 0 + var resultB = 0 + + val a: Int? by AtomicNullableLazyVal { resultA++; null} + val b by AtomicNullableLazyVal { foo() } + + override fun box(): String { + a + b + + if (a != null) return "fail: a should be null" + if (b != null) return "fail: a should be null" + if (resultA != 1) return "fail: initializer for a should be invoked only once" + if (resultB != 1) return "fail: initializer for b should be invoked only once" + return "OK" + } + + fun foo(): String? { + resultB++ + return null + } +} From a2b82095dae43057e11827045be3618704a7b4e6 Mon Sep 17 00:00:00 2001 From: Andrey Breslav Date: Tue, 21 May 2013 13:01:31 +0400 Subject: [PATCH 123/249] Using the version of ASM that has debug information in it No more need for extra ASM jars (analysis and util) --- .idea/artifacts/KotlinPlugin.xml | 1 - .idea/libraries/asm.xml | 2 +- .idea/libraries/asm_addons.xml | 12 ------------ build.xml | 4 +--- compiler/backend/backend.iml | 1 - compiler/cli/cli.iml | 1 - compiler/tests/compiler-tests.iml | 1 - update_dependencies.xml | 27 +++++++++++++-------------- 8 files changed, 15 insertions(+), 34 deletions(-) delete mode 100644 .idea/libraries/asm_addons.xml diff --git a/.idea/artifacts/KotlinPlugin.xml b/.idea/artifacts/KotlinPlugin.xml index 778180015dc..41a47a34c35 100644 --- a/.idea/artifacts/KotlinPlugin.xml +++ b/.idea/artifacts/KotlinPlugin.xml @@ -4,7 +4,6 @@ - diff --git a/.idea/libraries/asm.xml b/.idea/libraries/asm.xml index 8968222f967..13003cfe5f2 100644 --- a/.idea/libraries/asm.xml +++ b/.idea/libraries/asm.xml @@ -1,7 +1,7 @@ - + diff --git a/.idea/libraries/asm_addons.xml b/.idea/libraries/asm_addons.xml deleted file mode 100644 index 7488a22044c..00000000000 --- a/.idea/libraries/asm_addons.xml +++ /dev/null @@ -1,12 +0,0 @@ - - - - - - - - - - - - \ No newline at end of file diff --git a/build.xml b/build.xml index 632c0352eb8..182b6655096 100644 --- a/build.xml +++ b/build.xml @@ -18,7 +18,6 @@ - @@ -276,8 +275,7 @@ - - + diff --git a/compiler/backend/backend.iml b/compiler/backend/backend.iml index 9dd4449bbb4..e1b68dd0487 100644 --- a/compiler/backend/backend.iml +++ b/compiler/backend/backend.iml @@ -9,7 +9,6 @@ - diff --git a/compiler/cli/cli.iml b/compiler/cli/cli.iml index 3fc055ccfc9..f67af7c8ec3 100644 --- a/compiler/cli/cli.iml +++ b/compiler/cli/cli.iml @@ -13,7 +13,6 @@ - diff --git a/compiler/tests/compiler-tests.iml b/compiler/tests/compiler-tests.iml index da889f38b4b..c29422b9f46 100644 --- a/compiler/tests/compiler-tests.iml +++ b/compiler/tests/compiler-tests.iml @@ -14,7 +14,6 @@ - diff --git a/update_dependencies.xml b/update_dependencies.xml index 3fc8c81ac46..b3fe11a630b 100644 --- a/update_dependencies.xml +++ b/update_dependencies.xml @@ -123,28 +123,20 @@ - - - + - - - - - - - - + + - + @@ -194,7 +186,7 @@ - + @@ -227,7 +219,8 @@ - + + @@ -239,6 +232,12 @@ --> + + + From 4c9174d49b5fe0a6ced10870c870dcdb4d902169 Mon Sep 17 00:00:00 2001 From: "Natalia.Ukhorskaya" Date: Tue, 21 May 2013 14:20:41 +0400 Subject: [PATCH 124/249] Don't create stubs for properties in delegate expression --- .../psi/stubs/elements/JetStubElementType.java | 15 +++++++++++---- .../jetbrains/jet/plugin/stubs/JetStubsTest.java | 6 ++++++ 2 files changed, 17 insertions(+), 4 deletions(-) diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/psi/stubs/elements/JetStubElementType.java b/compiler/frontend/src/org/jetbrains/jet/lang/psi/stubs/elements/JetStubElementType.java index 434e812fe69..4cddb31a310 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/psi/stubs/elements/JetStubElementType.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/psi/stubs/elements/JetStubElementType.java @@ -23,10 +23,7 @@ import com.intellij.psi.stubs.StubElement; import com.intellij.psi.util.PsiTreeUtil; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; -import org.jetbrains.jet.lang.psi.JetBlockExpression; -import org.jetbrains.jet.lang.psi.JetExpression; -import org.jetbrains.jet.lang.psi.JetFunctionLiteral; -import org.jetbrains.jet.lang.psi.JetWithExpressionInitializer; +import org.jetbrains.jet.lang.psi.*; import org.jetbrains.jet.plugin.JetLanguage; public abstract class JetStubElementType extends IStubElementType { @@ -67,6 +64,16 @@ public abstract class JetStubElementType Date: Tue, 21 May 2013 16:26:40 +0400 Subject: [PATCH 125/249] KT-3575, KT-2297 Inserting pair for "${": reverting to use KotlinTypeHandler (with disabling JetPairMatcher for this case) --- .../org/jetbrains/jet/plugin/JetPairMatcher.java | 8 ++++++-- .../jet/plugin/editor/KotlinTypedHandler.java | 14 ++++++++++++++ .../org/jetbrains/jet/editor/TypedHandlerTest.java | 12 ++++++++++++ 3 files changed, 32 insertions(+), 2 deletions(-) diff --git a/idea/src/org/jetbrains/jet/plugin/JetPairMatcher.java b/idea/src/org/jetbrains/jet/plugin/JetPairMatcher.java index a97fdee0200..9bf05aa432b 100644 --- a/idea/src/org/jetbrains/jet/plugin/JetPairMatcher.java +++ b/idea/src/org/jetbrains/jet/plugin/JetPairMatcher.java @@ -39,8 +39,12 @@ public class JetPairMatcher implements PairedBraceMatcher { @Override public boolean isPairedBracesAllowedBeforeType(@NotNull IElementType lbraceType, @Nullable IElementType contextType) { - return lbraceType.equals(JetTokens.LONG_TEMPLATE_ENTRY_START) - || JetTokens.WHITE_SPACE_OR_COMMENT_BIT_SET.contains(contextType) + if (lbraceType.equals(JetTokens.LONG_TEMPLATE_ENTRY_START)) { + // KotlinTypedHandler insert paired brace in this case + return false; + } + + return JetTokens.WHITE_SPACE_OR_COMMENT_BIT_SET.contains(contextType) || contextType == JetTokens.SEMICOLON || contextType == JetTokens.COMMA || contextType == JetTokens.RPAR diff --git a/idea/src/org/jetbrains/jet/plugin/editor/KotlinTypedHandler.java b/idea/src/org/jetbrains/jet/plugin/editor/KotlinTypedHandler.java index b35d929710d..baedb696788 100644 --- a/idea/src/org/jetbrains/jet/plugin/editor/KotlinTypedHandler.java +++ b/idea/src/org/jetbrains/jet/plugin/editor/KotlinTypedHandler.java @@ -57,6 +57,20 @@ public class KotlinTypedHandler extends TypedHandlerDelegate { JetLtGtTypingUtils.handleJetAutoCloseLT(editor); return Result.STOP; } + + if (!(file instanceof JetFile) || !CodeInsightSettings.getInstance().AUTOINSERT_PAIR_BRACKET) { + return Result.CONTINUE; + } + if (c == '{') { + PsiDocumentManager.getInstance(project).commitAllDocuments(); + int offset = editor.getCaretModel().getOffset(); + PsiElement previousElement = file.findElementAt(offset - 1); + if (previousElement instanceof LeafPsiElement + && ((LeafPsiElement) previousElement).getElementType() == JetTokens.LONG_TEMPLATE_ENTRY_START) { + editor.getDocument().insertString(offset, "}"); + } + return Result.STOP; + } return Result.CONTINUE; } } diff --git a/idea/tests/org/jetbrains/jet/editor/TypedHandlerTest.java b/idea/tests/org/jetbrains/jet/editor/TypedHandlerTest.java index 5ac75e43c72..998a88535cf 100644 --- a/idea/tests/org/jetbrains/jet/editor/TypedHandlerTest.java +++ b/idea/tests/org/jetbrains/jet/editor/TypedHandlerTest.java @@ -26,6 +26,18 @@ public class TypedHandlerTest extends LightCodeInsightTestCase { checkResultByText("val x = \"${}\""); } + public void testTypeStringTemplateStartWithCloseBraceAfter() throws Exception { + configureFromFileText("a.kt", "fun foo() { \"$\" }"); + EditorTestUtil.performTypingAction(getEditor(), '{'); + checkResultByText("fun foo() { \"${}\" }"); + } + + public void testTypeStringTemplateStartBeforeString() throws Exception { + configureFromFileText("a.kt", "fun foo() { \"$something\" }"); + EditorTestUtil.performTypingAction(getEditor(), '{'); + checkResultByText("fun foo() { \"${}something\" }"); + } + public void testKT3575() throws Exception { configureFromFileText("a.kt", "val x = \"$]\""); EditorTestUtil.performTypingAction(getEditor(), '{'); From 86d60aea9fbef7a40546cb1f12f12deb3df93b31 Mon Sep 17 00:00:00 2001 From: Evgeny Gerashchenko Date: Wed, 8 May 2013 16:12:13 +0400 Subject: [PATCH 126/249] Minor. Replaced for with for each. --- .../jet/lang/descriptors/impl/FunctionDescriptorUtil.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/impl/FunctionDescriptorUtil.java b/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/impl/FunctionDescriptorUtil.java index 1384d15a7b6..9959f4e9ba7 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/impl/FunctionDescriptorUtil.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/impl/FunctionDescriptorUtil.java @@ -71,8 +71,7 @@ public class FunctionDescriptorUtil { public static List getSubstitutedValueParameters(FunctionDescriptor substitutedDescriptor, @NotNull FunctionDescriptor functionDescriptor, @NotNull TypeSubstitutor substitutor) { List result = new ArrayList(); List unsubstitutedValueParameters = functionDescriptor.getValueParameters(); - for (int i = 0, unsubstitutedValueParametersSize = unsubstitutedValueParameters.size(); i < unsubstitutedValueParametersSize; i++) { - ValueParameterDescriptor unsubstitutedValueParameter = unsubstitutedValueParameters.get(i); + for (ValueParameterDescriptor unsubstitutedValueParameter : unsubstitutedValueParameters) { // TODO : Lazy? JetType substitutedType = substitutor.substitute(unsubstitutedValueParameter.getType(), Variance.IN_VARIANCE); JetType varargElementType = unsubstitutedValueParameter.getVarargElementType(); From 6f7d42185f559c82beb07f6741c38275c7aea7be Mon Sep 17 00:00:00 2001 From: Evgeny Gerashchenko Date: Fri, 17 May 2013 19:14:36 +0400 Subject: [PATCH 127/249] Added dependency class resolver -> function resolver. --- .../di/InjectorForJavaDescriptorResolver.java | 49 ++++++++++--------- .../di/InjectorForJavaSemanticServices.java | 49 ++++++++++--------- .../di/InjectorForTopDownAnalyzerForJvm.java | 49 ++++++++++--------- .../java/resolver/JavaClassResolver.java | 7 ++- 4 files changed, 81 insertions(+), 73 deletions(-) diff --git a/compiler/frontend.java/src/org/jetbrains/jet/di/InjectorForJavaDescriptorResolver.java b/compiler/frontend.java/src/org/jetbrains/jet/di/InjectorForJavaDescriptorResolver.java index 0af9b9e9d41..abca44baa87 100644 --- a/compiler/frontend.java/src/org/jetbrains/jet/di/InjectorForJavaDescriptorResolver.java +++ b/compiler/frontend.java/src/org/jetbrains/jet/di/InjectorForJavaDescriptorResolver.java @@ -30,11 +30,11 @@ import org.jetbrains.jet.lang.resolve.java.resolver.JavaAnnotationResolver; import org.jetbrains.jet.lang.resolve.java.resolver.JavaCompileTimeConstResolver; import org.jetbrains.jet.lang.resolve.java.resolver.JavaClassObjectResolver; import org.jetbrains.jet.lang.resolve.java.resolver.JavaSupertypeResolver; -import org.jetbrains.jet.lang.resolve.java.resolver.JavaNamespaceResolver; -import org.jetbrains.jet.lang.resolve.java.resolver.JavaSignatureResolver; -import org.jetbrains.jet.lang.resolve.java.resolver.JavaConstructorResolver; -import org.jetbrains.jet.lang.resolve.java.resolver.JavaValueParameterResolver; import org.jetbrains.jet.lang.resolve.java.resolver.JavaFunctionResolver; +import org.jetbrains.jet.lang.resolve.java.resolver.JavaValueParameterResolver; +import org.jetbrains.jet.lang.resolve.java.resolver.JavaSignatureResolver; +import org.jetbrains.jet.lang.resolve.java.resolver.JavaNamespaceResolver; +import org.jetbrains.jet.lang.resolve.java.resolver.JavaConstructorResolver; import org.jetbrains.jet.lang.resolve.java.resolver.JavaInnerClassResolver; import org.jetbrains.jet.lang.resolve.java.resolver.JavaPropertyResolver; import org.jetbrains.annotations.NotNull; @@ -57,11 +57,11 @@ public class InjectorForJavaDescriptorResolver { private JavaCompileTimeConstResolver javaCompileTimeConstResolver; private JavaClassObjectResolver javaClassObjectResolver; private JavaSupertypeResolver javaSupertypeResolver; - private JavaNamespaceResolver javaNamespaceResolver; - private JavaSignatureResolver javaSignatureResolver; - private JavaConstructorResolver javaConstructorResolver; - private JavaValueParameterResolver javaValueParameterResolver; private JavaFunctionResolver javaFunctionResolver; + private JavaValueParameterResolver javaValueParameterResolver; + private JavaSignatureResolver javaSignatureResolver; + private JavaNamespaceResolver javaNamespaceResolver; + private JavaConstructorResolver javaConstructorResolver; private JavaInnerClassResolver javaInnerClassResolver; private JavaPropertyResolver javaPropertyResolver; @@ -84,11 +84,11 @@ public class InjectorForJavaDescriptorResolver { this.javaCompileTimeConstResolver = new JavaCompileTimeConstResolver(); this.javaClassObjectResolver = new JavaClassObjectResolver(); this.javaSupertypeResolver = new JavaSupertypeResolver(); - this.javaNamespaceResolver = new JavaNamespaceResolver(); - this.javaSignatureResolver = new JavaSignatureResolver(); - this.javaConstructorResolver = new JavaConstructorResolver(); - this.javaValueParameterResolver = new JavaValueParameterResolver(); this.javaFunctionResolver = new JavaFunctionResolver(); + this.javaValueParameterResolver = new JavaValueParameterResolver(); + this.javaSignatureResolver = new JavaSignatureResolver(); + this.javaNamespaceResolver = new JavaNamespaceResolver(); + this.javaConstructorResolver = new JavaConstructorResolver(); this.javaInnerClassResolver = new JavaInnerClassResolver(); this.javaPropertyResolver = new JavaPropertyResolver(); @@ -114,6 +114,7 @@ public class InjectorForJavaDescriptorResolver { javaClassResolver.setAnnotationResolver(javaAnnotationResolver); javaClassResolver.setClassObjectResolver(javaClassObjectResolver); + javaClassResolver.setFunctionResolver(javaFunctionResolver); javaClassResolver.setNamespaceResolver(javaNamespaceResolver); javaClassResolver.setPsiClassFinder(psiClassFinder); javaClassResolver.setSemanticServices(javaSemanticServices); @@ -136,24 +137,24 @@ public class InjectorForJavaDescriptorResolver { javaSupertypeResolver.setTrace(bindingTrace); javaSupertypeResolver.setTypeTransformer(javaTypeTransformer); - javaNamespaceResolver.setJavaSemanticServices(javaSemanticServices); - javaNamespaceResolver.setPsiClassFinder(psiClassFinder); - javaNamespaceResolver.setTrace(bindingTrace); - - javaSignatureResolver.setJavaSemanticServices(javaSemanticServices); - - javaConstructorResolver.setTrace(bindingTrace); - javaConstructorResolver.setTypeTransformer(javaTypeTransformer); - javaConstructorResolver.setValueParameterResolver(javaValueParameterResolver); - - javaValueParameterResolver.setTypeTransformer(javaTypeTransformer); - javaFunctionResolver.setAnnotationResolver(javaAnnotationResolver); javaFunctionResolver.setParameterResolver(javaValueParameterResolver); javaFunctionResolver.setSignatureResolver(javaSignatureResolver); javaFunctionResolver.setTrace(bindingTrace); javaFunctionResolver.setTypeTransformer(javaTypeTransformer); + javaValueParameterResolver.setTypeTransformer(javaTypeTransformer); + + javaSignatureResolver.setJavaSemanticServices(javaSemanticServices); + + javaNamespaceResolver.setJavaSemanticServices(javaSemanticServices); + javaNamespaceResolver.setPsiClassFinder(psiClassFinder); + javaNamespaceResolver.setTrace(bindingTrace); + + javaConstructorResolver.setTrace(bindingTrace); + javaConstructorResolver.setTypeTransformer(javaTypeTransformer); + javaConstructorResolver.setValueParameterResolver(javaValueParameterResolver); + javaInnerClassResolver.setClassResolver(javaClassResolver); javaPropertyResolver.setAnnotationResolver(javaAnnotationResolver); diff --git a/compiler/frontend.java/src/org/jetbrains/jet/di/InjectorForJavaSemanticServices.java b/compiler/frontend.java/src/org/jetbrains/jet/di/InjectorForJavaSemanticServices.java index 50e3e0780df..809bf1da9af 100644 --- a/compiler/frontend.java/src/org/jetbrains/jet/di/InjectorForJavaSemanticServices.java +++ b/compiler/frontend.java/src/org/jetbrains/jet/di/InjectorForJavaSemanticServices.java @@ -30,11 +30,11 @@ import org.jetbrains.jet.lang.resolve.java.resolver.JavaAnnotationResolver; import org.jetbrains.jet.lang.resolve.java.resolver.JavaCompileTimeConstResolver; import org.jetbrains.jet.lang.resolve.java.resolver.JavaClassObjectResolver; import org.jetbrains.jet.lang.resolve.java.resolver.JavaSupertypeResolver; -import org.jetbrains.jet.lang.resolve.java.resolver.JavaNamespaceResolver; -import org.jetbrains.jet.lang.resolve.java.resolver.JavaSignatureResolver; -import org.jetbrains.jet.lang.resolve.java.resolver.JavaConstructorResolver; -import org.jetbrains.jet.lang.resolve.java.resolver.JavaValueParameterResolver; import org.jetbrains.jet.lang.resolve.java.resolver.JavaFunctionResolver; +import org.jetbrains.jet.lang.resolve.java.resolver.JavaValueParameterResolver; +import org.jetbrains.jet.lang.resolve.java.resolver.JavaSignatureResolver; +import org.jetbrains.jet.lang.resolve.java.resolver.JavaNamespaceResolver; +import org.jetbrains.jet.lang.resolve.java.resolver.JavaConstructorResolver; import org.jetbrains.jet.lang.resolve.java.resolver.JavaInnerClassResolver; import org.jetbrains.jet.lang.resolve.java.resolver.JavaPropertyResolver; import org.jetbrains.annotations.NotNull; @@ -57,11 +57,11 @@ public class InjectorForJavaSemanticServices { private JavaCompileTimeConstResolver javaCompileTimeConstResolver; private JavaClassObjectResolver javaClassObjectResolver; private JavaSupertypeResolver javaSupertypeResolver; - private JavaNamespaceResolver javaNamespaceResolver; - private JavaSignatureResolver javaSignatureResolver; - private JavaConstructorResolver javaConstructorResolver; - private JavaValueParameterResolver javaValueParameterResolver; private JavaFunctionResolver javaFunctionResolver; + private JavaValueParameterResolver javaValueParameterResolver; + private JavaSignatureResolver javaSignatureResolver; + private JavaNamespaceResolver javaNamespaceResolver; + private JavaConstructorResolver javaConstructorResolver; private JavaInnerClassResolver javaInnerClassResolver; private JavaPropertyResolver javaPropertyResolver; @@ -82,11 +82,11 @@ public class InjectorForJavaSemanticServices { this.javaCompileTimeConstResolver = new JavaCompileTimeConstResolver(); this.javaClassObjectResolver = new JavaClassObjectResolver(); this.javaSupertypeResolver = new JavaSupertypeResolver(); - this.javaNamespaceResolver = new JavaNamespaceResolver(); - this.javaSignatureResolver = new JavaSignatureResolver(); - this.javaConstructorResolver = new JavaConstructorResolver(); - this.javaValueParameterResolver = new JavaValueParameterResolver(); this.javaFunctionResolver = new JavaFunctionResolver(); + this.javaValueParameterResolver = new JavaValueParameterResolver(); + this.javaSignatureResolver = new JavaSignatureResolver(); + this.javaNamespaceResolver = new JavaNamespaceResolver(); + this.javaConstructorResolver = new JavaConstructorResolver(); this.javaInnerClassResolver = new JavaInnerClassResolver(); this.javaPropertyResolver = new JavaPropertyResolver(); @@ -114,6 +114,7 @@ public class InjectorForJavaSemanticServices { javaClassResolver.setAnnotationResolver(javaAnnotationResolver); javaClassResolver.setClassObjectResolver(javaClassObjectResolver); + javaClassResolver.setFunctionResolver(javaFunctionResolver); javaClassResolver.setNamespaceResolver(javaNamespaceResolver); javaClassResolver.setPsiClassFinder(psiClassFinder); javaClassResolver.setSemanticServices(javaSemanticServices); @@ -136,24 +137,24 @@ public class InjectorForJavaSemanticServices { javaSupertypeResolver.setTrace(bindingTrace); javaSupertypeResolver.setTypeTransformer(javaTypeTransformer); - javaNamespaceResolver.setJavaSemanticServices(javaSemanticServices); - javaNamespaceResolver.setPsiClassFinder(psiClassFinder); - javaNamespaceResolver.setTrace(bindingTrace); - - javaSignatureResolver.setJavaSemanticServices(javaSemanticServices); - - javaConstructorResolver.setTrace(bindingTrace); - javaConstructorResolver.setTypeTransformer(javaTypeTransformer); - javaConstructorResolver.setValueParameterResolver(javaValueParameterResolver); - - javaValueParameterResolver.setTypeTransformer(javaTypeTransformer); - javaFunctionResolver.setAnnotationResolver(javaAnnotationResolver); javaFunctionResolver.setParameterResolver(javaValueParameterResolver); javaFunctionResolver.setSignatureResolver(javaSignatureResolver); javaFunctionResolver.setTrace(bindingTrace); javaFunctionResolver.setTypeTransformer(javaTypeTransformer); + javaValueParameterResolver.setTypeTransformer(javaTypeTransformer); + + javaSignatureResolver.setJavaSemanticServices(javaSemanticServices); + + javaNamespaceResolver.setJavaSemanticServices(javaSemanticServices); + javaNamespaceResolver.setPsiClassFinder(psiClassFinder); + javaNamespaceResolver.setTrace(bindingTrace); + + javaConstructorResolver.setTrace(bindingTrace); + javaConstructorResolver.setTypeTransformer(javaTypeTransformer); + javaConstructorResolver.setValueParameterResolver(javaValueParameterResolver); + javaInnerClassResolver.setClassResolver(javaClassResolver); javaPropertyResolver.setAnnotationResolver(javaAnnotationResolver); diff --git a/compiler/frontend.java/src/org/jetbrains/jet/di/InjectorForTopDownAnalyzerForJvm.java b/compiler/frontend.java/src/org/jetbrains/jet/di/InjectorForTopDownAnalyzerForJvm.java index 653d2ef6547..f39ccfdc0bc 100644 --- a/compiler/frontend.java/src/org/jetbrains/jet/di/InjectorForTopDownAnalyzerForJvm.java +++ b/compiler/frontend.java/src/org/jetbrains/jet/di/InjectorForTopDownAnalyzerForJvm.java @@ -54,11 +54,11 @@ import org.jetbrains.jet.lang.resolve.java.resolver.JavaAnnotationResolver; import org.jetbrains.jet.lang.resolve.java.resolver.JavaCompileTimeConstResolver; import org.jetbrains.jet.lang.resolve.java.resolver.JavaClassObjectResolver; import org.jetbrains.jet.lang.resolve.java.resolver.JavaSupertypeResolver; -import org.jetbrains.jet.lang.resolve.java.resolver.JavaNamespaceResolver; -import org.jetbrains.jet.lang.resolve.java.resolver.JavaSignatureResolver; -import org.jetbrains.jet.lang.resolve.java.resolver.JavaConstructorResolver; -import org.jetbrains.jet.lang.resolve.java.resolver.JavaValueParameterResolver; import org.jetbrains.jet.lang.resolve.java.resolver.JavaFunctionResolver; +import org.jetbrains.jet.lang.resolve.java.resolver.JavaValueParameterResolver; +import org.jetbrains.jet.lang.resolve.java.resolver.JavaSignatureResolver; +import org.jetbrains.jet.lang.resolve.java.resolver.JavaNamespaceResolver; +import org.jetbrains.jet.lang.resolve.java.resolver.JavaConstructorResolver; import org.jetbrains.jet.lang.resolve.java.resolver.JavaInnerClassResolver; import org.jetbrains.jet.lang.resolve.java.resolver.JavaPropertyResolver; import org.jetbrains.annotations.NotNull; @@ -105,11 +105,11 @@ public class InjectorForTopDownAnalyzerForJvm implements InjectorForTopDownAnaly private JavaCompileTimeConstResolver javaCompileTimeConstResolver; private JavaClassObjectResolver javaClassObjectResolver; private JavaSupertypeResolver javaSupertypeResolver; - private JavaNamespaceResolver javaNamespaceResolver; - private JavaSignatureResolver javaSignatureResolver; - private JavaConstructorResolver javaConstructorResolver; - private JavaValueParameterResolver javaValueParameterResolver; private JavaFunctionResolver javaFunctionResolver; + private JavaValueParameterResolver javaValueParameterResolver; + private JavaSignatureResolver javaSignatureResolver; + private JavaNamespaceResolver javaNamespaceResolver; + private JavaConstructorResolver javaConstructorResolver; private JavaInnerClassResolver javaInnerClassResolver; private JavaPropertyResolver javaPropertyResolver; @@ -157,11 +157,11 @@ public class InjectorForTopDownAnalyzerForJvm implements InjectorForTopDownAnaly this.javaCompileTimeConstResolver = new JavaCompileTimeConstResolver(); this.javaClassObjectResolver = new JavaClassObjectResolver(); this.javaSupertypeResolver = new JavaSupertypeResolver(); - this.javaNamespaceResolver = new JavaNamespaceResolver(); - this.javaSignatureResolver = new JavaSignatureResolver(); - this.javaConstructorResolver = new JavaConstructorResolver(); - this.javaValueParameterResolver = new JavaValueParameterResolver(); this.javaFunctionResolver = new JavaFunctionResolver(); + this.javaValueParameterResolver = new JavaValueParameterResolver(); + this.javaSignatureResolver = new JavaSignatureResolver(); + this.javaNamespaceResolver = new JavaNamespaceResolver(); + this.javaConstructorResolver = new JavaConstructorResolver(); this.javaInnerClassResolver = new JavaInnerClassResolver(); this.javaPropertyResolver = new JavaPropertyResolver(); @@ -287,6 +287,7 @@ public class InjectorForTopDownAnalyzerForJvm implements InjectorForTopDownAnaly javaClassResolver.setAnnotationResolver(javaAnnotationResolver); javaClassResolver.setClassObjectResolver(javaClassObjectResolver); + javaClassResolver.setFunctionResolver(javaFunctionResolver); javaClassResolver.setNamespaceResolver(javaNamespaceResolver); javaClassResolver.setPsiClassFinder(psiClassFinder); javaClassResolver.setSemanticServices(javaSemanticServices); @@ -309,24 +310,24 @@ public class InjectorForTopDownAnalyzerForJvm implements InjectorForTopDownAnaly javaSupertypeResolver.setTrace(bindingTrace); javaSupertypeResolver.setTypeTransformer(javaTypeTransformer); - javaNamespaceResolver.setJavaSemanticServices(javaSemanticServices); - javaNamespaceResolver.setPsiClassFinder(psiClassFinder); - javaNamespaceResolver.setTrace(bindingTrace); - - javaSignatureResolver.setJavaSemanticServices(javaSemanticServices); - - javaConstructorResolver.setTrace(bindingTrace); - javaConstructorResolver.setTypeTransformer(javaTypeTransformer); - javaConstructorResolver.setValueParameterResolver(javaValueParameterResolver); - - javaValueParameterResolver.setTypeTransformer(javaTypeTransformer); - javaFunctionResolver.setAnnotationResolver(javaAnnotationResolver); javaFunctionResolver.setParameterResolver(javaValueParameterResolver); javaFunctionResolver.setSignatureResolver(javaSignatureResolver); javaFunctionResolver.setTrace(bindingTrace); javaFunctionResolver.setTypeTransformer(javaTypeTransformer); + javaValueParameterResolver.setTypeTransformer(javaTypeTransformer); + + javaSignatureResolver.setJavaSemanticServices(javaSemanticServices); + + javaNamespaceResolver.setJavaSemanticServices(javaSemanticServices); + javaNamespaceResolver.setPsiClassFinder(psiClassFinder); + javaNamespaceResolver.setTrace(bindingTrace); + + javaConstructorResolver.setTrace(bindingTrace); + javaConstructorResolver.setTypeTransformer(javaTypeTransformer); + javaConstructorResolver.setValueParameterResolver(javaValueParameterResolver); + javaInnerClassResolver.setClassResolver(javaClassResolver); javaPropertyResolver.setAnnotationResolver(javaAnnotationResolver); diff --git a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/resolver/JavaClassResolver.java b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/resolver/JavaClassResolver.java index 2d0dcf5c172..5e2032d01fc 100644 --- a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/resolver/JavaClassResolver.java +++ b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/resolver/JavaClassResolver.java @@ -33,7 +33,6 @@ import org.jetbrains.jet.lang.resolve.java.*; import org.jetbrains.jet.lang.resolve.java.descriptor.ClassDescriptorFromJvmBytecode; import org.jetbrains.jet.lang.resolve.java.kt.JetClassAnnotation; import org.jetbrains.jet.lang.resolve.java.provider.ClassPsiDeclarationProvider; -import org.jetbrains.jet.lang.resolve.java.provider.MembersCache; import org.jetbrains.jet.lang.resolve.java.scope.JavaClassNonStaticMembersScope; import org.jetbrains.jet.lang.resolve.java.wrapper.PsiClassWrapper; import org.jetbrains.jet.lang.resolve.name.FqName; @@ -80,6 +79,7 @@ public final class JavaClassResolver { private JavaNamespaceResolver namespaceResolver; private JavaClassObjectResolver classObjectResolver; private JavaSupertypeResolver supertypesResolver; + private JavaFunctionResolver functionResolver; public JavaClassResolver() { } @@ -124,6 +124,11 @@ public final class JavaClassResolver { this.supertypesResolver = supertypesResolver; } + @Inject + public void setFunctionResolver(JavaFunctionResolver functionResolver) { + this.functionResolver = functionResolver; + } + @Nullable public ClassDescriptor resolveClass(@NotNull FqName qualifiedName, @NotNull DescriptorSearchRule searchRule) { PostponedTasks postponedTasks = new PostponedTasks(); From 5fc7c885bb121c38f278af9f500fc49599bc3dca Mon Sep 17 00:00:00 2001 From: Evgeny Gerashchenko Date: Fri, 17 May 2013 20:54:36 +0400 Subject: [PATCH 128/249] KT-3577 Stack overflow when resolving SAM adapter (from completion, show parameters, etc) #KT-3577 --- .../ClassDescriptorFromJvmBytecode.java | 16 ++-- .../resolve/java/provider/MembersCache.java | 24 ++++-- .../resolver/JavaClassObjectResolver.java | 4 +- .../java/resolver/JavaClassResolver.java | 13 +++- .../java/resolver/JavaFunctionResolver.java | 27 ++++--- .../java/sam/SingleAbstractMethodUtils.java | 76 +++++++++++++++---- .../adapter/DeepSamLoop.java | 12 +++ .../adapter/DeepSamLoop.txt | 19 +++++ .../adapter/SelfAsParameter.java | 5 ++ .../adapter/SelfAsParameter.txt | 8 ++ .../jvm/compiler/LoadJavaTestGenerated.java | 10 +++ 11 files changed, 174 insertions(+), 40 deletions(-) create mode 100644 compiler/testData/loadJava/compiledJava/singleAbstractMethod/adapter/DeepSamLoop.java create mode 100644 compiler/testData/loadJava/compiledJava/singleAbstractMethod/adapter/DeepSamLoop.txt create mode 100644 compiler/testData/loadJava/compiledJava/singleAbstractMethod/adapter/SelfAsParameter.java create mode 100644 compiler/testData/loadJava/compiledJava/singleAbstractMethod/adapter/SelfAsParameter.txt diff --git a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/descriptor/ClassDescriptorFromJvmBytecode.java b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/descriptor/ClassDescriptorFromJvmBytecode.java index e2e95710cb7..25e3dcfc48e 100644 --- a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/descriptor/ClassDescriptorFromJvmBytecode.java +++ b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/descriptor/ClassDescriptorFromJvmBytecode.java @@ -23,6 +23,7 @@ import org.jetbrains.jet.lang.descriptors.ConstructorDescriptor; import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor; import org.jetbrains.jet.lang.descriptors.impl.MutableClassDescriptorLite; import org.jetbrains.jet.lang.resolve.java.scope.JavaClassNonStaticMembersScope; +import org.jetbrains.jet.lang.types.JetType; import java.util.Collection; @@ -30,18 +31,16 @@ import java.util.Collection; * @see org.jetbrains.jet.lang.resolve.lazy.descriptors.LazyClassDescriptor */ public class ClassDescriptorFromJvmBytecode extends MutableClassDescriptorLite { - private final boolean isSamInterface; + private JetType functionTypeForSamInterface; private JavaClassNonStaticMembersScope scopeForConstructorResolve; public ClassDescriptorFromJvmBytecode( @NotNull DeclarationDescriptor containingDeclaration, @NotNull ClassKind kind, - boolean isInner, - boolean isSamInterface + boolean isInner ) { super(containingDeclaration, kind, isInner); - this.isSamInterface = isSamInterface; } @@ -62,7 +61,12 @@ public class ClassDescriptorFromJvmBytecode extends MutableClassDescriptorLite { this.scopeForConstructorResolve = scopeForConstructorResolve; } - public boolean isSamInterface() { - return isSamInterface; + @Nullable + public JetType getFunctionTypeForSamInterface() { + return functionTypeForSamInterface; + } + + public void setFunctionTypeForSamInterface(@NotNull JetType functionTypeForSamInterface) { + this.functionTypeForSamInterface = functionTypeForSamInterface; } } diff --git a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/provider/MembersCache.java b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/provider/MembersCache.java index f5b6fa5777b..5c305bcfcee 100644 --- a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/provider/MembersCache.java +++ b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/provider/MembersCache.java @@ -18,6 +18,7 @@ package org.jetbrains.jet.lang.resolve.java.provider; import com.google.common.collect.HashMultimap; import com.google.common.collect.ImmutableSet; +import com.google.common.collect.Lists; import com.google.common.collect.Multimap; import com.intellij.psi.*; import com.intellij.psi.util.PsiFormatUtil; @@ -402,28 +403,37 @@ public final class MembersCache { } public static boolean isSamInterface(@NotNull PsiClass psiClass) { + return getSamInterfaceMethod(psiClass) != null; + } + + // Returns null if not SAM interface + @Nullable + public static PsiMethod getSamInterfaceMethod(@NotNull PsiClass psiClass) { + if (psiClass.hasModifierProperty(PsiModifier.PRIVATE)) { // TODO hacky + return null; + } if (DescriptorResolverUtils.isKotlinClass(psiClass)) { - return false; + return null; } String qualifiedName = psiClass.getQualifiedName(); if (qualifiedName == null || qualifiedName.startsWith(KotlinBuiltIns.BUILT_INS_PACKAGE_FQ_NAME.getFqName() + ".")) { - return false; + return null; } if (!psiClass.isInterface() || psiClass.isAnnotationType()) { - return false; + return null; } - int foundAbstractMethods = 0; + List methods = Lists.newArrayList(); for (PsiMethod method : psiClass.getAllMethods()) { if (!isObjectMethod(method) && method.hasModifierProperty(PsiModifier.ABSTRACT)) { - foundAbstractMethods++; + methods.add(method); if (method.hasTypeParameters()) { - return false; + return null; } } } - return foundAbstractMethods == 1; + return methods.size() == 1 ? methods.get(0) : null; } private static abstract class RunOnce implements Runnable { diff --git a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/resolver/JavaClassObjectResolver.java b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/resolver/JavaClassObjectResolver.java index 2a9c3c3f286..50cac772c7b 100644 --- a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/resolver/JavaClassObjectResolver.java +++ b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/resolver/JavaClassObjectResolver.java @@ -100,7 +100,7 @@ public final class JavaClassObjectResolver { FqName fqName = new FqName(qualifiedName); ClassPsiDeclarationProvider classObjectData = semanticServices.getPsiDeclarationProviderFactory().createBinaryClassData(classObjectPsiClass); ClassDescriptorFromJvmBytecode classObjectDescriptor - = new ClassDescriptorFromJvmBytecode(containing, ClassKind.CLASS_OBJECT, false, false); + = new ClassDescriptorFromJvmBytecode(containing, ClassKind.CLASS_OBJECT, false); classObjectDescriptor.setSupertypes(supertypesResolver.getSupertypes(classObjectDescriptor, new PsiClassWrapper(classObjectPsiClass), classObjectData, @@ -129,7 +129,7 @@ public final class JavaClassObjectResolver { ) { FqNameUnsafe fqName = DescriptorResolverUtils.getFqNameForClassObject(psiClass); ClassDescriptorFromJvmBytecode classObjectDescriptor = - new ClassDescriptorFromJvmBytecode(containing, ClassKind.CLASS_OBJECT, false, false); + new ClassDescriptorFromJvmBytecode(containing, ClassKind.CLASS_OBJECT, false); ClassPsiDeclarationProvider data = semanticServices.getPsiDeclarationProviderFactory().createSyntheticClassObjectClassData(psiClass); setUpClassObjectDescriptor(classObjectDescriptor, containing, fqName, data, getClassObjectName(containing.getName().getName())); return classObjectDescriptor; diff --git a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/resolver/JavaClassResolver.java b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/resolver/JavaClassResolver.java index 5e2032d01fc..edb7177da25 100644 --- a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/resolver/JavaClassResolver.java +++ b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/resolver/JavaClassResolver.java @@ -20,6 +20,7 @@ import com.google.common.collect.Lists; import com.google.common.collect.Sets; import com.intellij.openapi.util.text.StringUtil; import com.intellij.psi.PsiClass; +import com.intellij.psi.PsiMethod; import com.intellij.psi.PsiModifier; import gnu.trove.THashMap; import gnu.trove.TObjectHashingStrategy; @@ -33,8 +34,11 @@ import org.jetbrains.jet.lang.resolve.java.*; import org.jetbrains.jet.lang.resolve.java.descriptor.ClassDescriptorFromJvmBytecode; import org.jetbrains.jet.lang.resolve.java.kt.JetClassAnnotation; import org.jetbrains.jet.lang.resolve.java.provider.ClassPsiDeclarationProvider; +import org.jetbrains.jet.lang.resolve.java.provider.MembersCache; +import org.jetbrains.jet.lang.resolve.java.sam.SingleAbstractMethodUtils; import org.jetbrains.jet.lang.resolve.java.scope.JavaClassNonStaticMembersScope; import org.jetbrains.jet.lang.resolve.java.wrapper.PsiClassWrapper; +import org.jetbrains.jet.lang.resolve.java.wrapper.PsiMethodWrapper; import org.jetbrains.jet.lang.resolve.name.FqName; import org.jetbrains.jet.lang.resolve.name.FqNameBase; import org.jetbrains.jet.lang.resolve.name.FqNameUnsafe; @@ -234,7 +238,7 @@ public final class JavaClassResolver { ClassKind kind = getClassKind(psiClass, jetClassAnnotation); ClassPsiDeclarationProvider classData = semanticServices.getPsiDeclarationProviderFactory().createBinaryClassData(psiClass); ClassDescriptorFromJvmBytecode classDescriptor = new ClassDescriptorFromJvmBytecode( - containingDeclaration, kind, isInnerClass(psiClass), MembersCache.isSamInterface(psiClass)); + containingDeclaration, kind, isInnerClass(psiClass)); cache(javaClassToKotlinFqName(fqName), classDescriptor); classDescriptor.setName(Name.identifier(psiClass.getName())); @@ -269,6 +273,13 @@ public final class JavaClassResolver { trace.record(BindingContext.CLASS, psiClass, classDescriptor); + PsiMethod samInterfaceMethod = MembersCache.getSamInterfaceMethod(psiClass); + if (samInterfaceMethod != null) { + SimpleFunctionDescriptor abstractMethod = functionResolver.resolveFunctionMutely( + psiClass, new PsiMethodWrapper(samInterfaceMethod), classDescriptor); + classDescriptor.setFunctionTypeForSamInterface(SingleAbstractMethodUtils.getFunctionTypeForAbstractMethod(abstractMethod)); + } + return classDescriptor; } diff --git a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/resolver/JavaFunctionResolver.java b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/resolver/JavaFunctionResolver.java index 01f84197a25..8d2e5dd7a40 100644 --- a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/resolver/JavaFunctionResolver.java +++ b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/resolver/JavaFunctionResolver.java @@ -34,10 +34,7 @@ import org.jetbrains.jet.lang.resolve.java.*; import org.jetbrains.jet.lang.resolve.java.kotlinSignature.AlternativeMethodSignatureData; import org.jetbrains.jet.lang.resolve.java.kotlinSignature.SignaturesPropagationData; import org.jetbrains.jet.lang.resolve.java.kt.DescriptorKindUtils; -import org.jetbrains.jet.lang.resolve.java.provider.ClassPsiDeclarationProvider; -import org.jetbrains.jet.lang.resolve.java.provider.NamedMembers; -import org.jetbrains.jet.lang.resolve.java.provider.PackagePsiDeclarationProvider; -import org.jetbrains.jet.lang.resolve.java.provider.PsiDeclarationProvider; +import org.jetbrains.jet.lang.resolve.java.provider.*; import org.jetbrains.jet.lang.resolve.java.sam.SingleAbstractMethodUtils; import org.jetbrains.jet.lang.resolve.java.wrapper.PsiMethodWrapper; import org.jetbrains.jet.lang.resolve.name.Name; @@ -93,10 +90,18 @@ public final class JavaFunctionResolver { this.annotationResolver = annotationResolver; } + @Nullable + SimpleFunctionDescriptor resolveFunctionMutely( + @NotNull PsiClass psiClass, PsiMethodWrapper method, + @NotNull ClassOrNamespaceDescriptor ownerDescriptor + ) { + return resolveMethodToFunctionDescriptor(psiClass, method, DeclarationOrigin.JAVA, ownerDescriptor, false); + } + @Nullable private SimpleFunctionDescriptor resolveMethodToFunctionDescriptor( @NotNull PsiClass psiClass, PsiMethodWrapper method, - @NotNull PsiDeclarationProvider scopeData, @NotNull ClassOrNamespaceDescriptor ownerDescriptor + @NotNull DeclarationOrigin declarationOrigin, @NotNull ClassOrNamespaceDescriptor ownerDescriptor, boolean record ) { if (!DescriptorResolverUtils.isCorrectOwnerForEnumMember(ownerDescriptor, method.getPsiMember())) { return null; @@ -114,7 +119,7 @@ public final class JavaFunctionResolver { PsiMethod psiMethod = method.getPsiMethod(); PsiClass containingClass = psiMethod.getContainingClass(); - if (scopeData.getDeclarationOrigin() == KOTLIN) { + if (declarationOrigin == KOTLIN) { // TODO: unless maybe class explicitly extends Object assert containingClass != null; String ownerClassName = containingClass.getQualifiedName(); @@ -189,11 +194,11 @@ public final class JavaFunctionResolver { /*isInline = */ false ); - if (functionDescriptorImpl.getKind() == CallableMemberDescriptor.Kind.DECLARATION) { + if (functionDescriptorImpl.getKind() == CallableMemberDescriptor.Kind.DECLARATION && record) { BindingContextUtils.recordFunctionDeclarationToDescriptor(trace, psiMethod, functionDescriptorImpl); } - if (scopeData.getDeclarationOrigin() == JAVA) { + if (declarationOrigin == JAVA && record) { trace.record(BindingContext.IS_DECLARED_IN_JAVA, functionDescriptorImpl); } @@ -208,7 +213,9 @@ public final class JavaFunctionResolver { checkFunctionsOverrideCorrectly(method, superFunctions, functionDescriptorImpl); } else { - trace.record(BindingContext.LOAD_FROM_JAVA_SIGNATURE_ERRORS, functionDescriptorImpl, signatureErrors); + if (record) { + trace.record(BindingContext.LOAD_FROM_JAVA_SIGNATURE_ERRORS, functionDescriptorImpl, signatureErrors); + } } } @@ -267,7 +274,7 @@ public final class JavaFunctionResolver { Set functionsFromCurrent = Sets.newHashSet(); for (PsiMethodWrapper method : namedMembers.getMethods()) { - SimpleFunctionDescriptor function = resolveMethodToFunctionDescriptor(psiClass, method, scopeData, owner); + SimpleFunctionDescriptor function = resolveMethodToFunctionDescriptor(psiClass, method, scopeData.getDeclarationOrigin(), owner, true); if (function != null) { functionsFromCurrent.add(function); diff --git a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/sam/SingleAbstractMethodUtils.java b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/sam/SingleAbstractMethodUtils.java index 76aa59c2aaf..bc89a2d42e0 100644 --- a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/sam/SingleAbstractMethodUtils.java +++ b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/sam/SingleAbstractMethodUtils.java @@ -27,10 +27,7 @@ import org.jetbrains.jet.lang.descriptors.impl.ValueParameterDescriptorImpl; import org.jetbrains.jet.lang.resolve.java.descriptor.ClassDescriptorFromJvmBytecode; import org.jetbrains.jet.lang.resolve.java.kotlinSignature.SignaturesUtil; import org.jetbrains.jet.lang.resolve.name.Name; -import org.jetbrains.jet.lang.types.JetType; -import org.jetbrains.jet.lang.types.TypeSubstitutor; -import org.jetbrains.jet.lang.types.TypeUtils; -import org.jetbrains.jet.lang.types.Variance; +import org.jetbrains.jet.lang.types.*; import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns; import java.util.Arrays; @@ -38,7 +35,10 @@ import java.util.Collections; import java.util.List; import java.util.Map; +import static org.jetbrains.jet.lang.types.Variance.INVARIANT; + public class SingleAbstractMethodUtils { + @NotNull private static List getAbstractMembers(@NotNull JetType type) { List abstractMembers = Lists.newArrayList(); @@ -52,18 +52,67 @@ public class SingleAbstractMethodUtils { return abstractMembers; } - @NotNull + // TODO maybe do this in substitutor? + private static JetType fixProjections(@NotNull JetType functionType) { + //removes redundant projection kinds and detects conflicts + + List arguments = Lists.newArrayList(); + for (TypeParameterDescriptor typeParameter : functionType.getConstructor().getParameters()) { + Variance variance = typeParameter.getVariance(); + TypeProjection argument = functionType.getArguments().get(typeParameter.getIndex()); + Variance kind = argument.getProjectionKind(); + if (kind != INVARIANT && variance != INVARIANT) { + if (kind == variance) { + arguments.add(new TypeProjection(argument.getType())); + } + else { + return null; + } + } + else { + arguments.add(argument); + } + } + ClassifierDescriptor classifier = functionType.getConstructor().getDeclarationDescriptor(); + assert classifier instanceof ClassDescriptor : "Not class: " + classifier; + return new JetTypeImpl( + functionType.getAnnotations(), + functionType.getConstructor(), + functionType.isNullable(), + arguments, + ((ClassDescriptor) classifier).getMemberScope(arguments) + ); + } + + @Nullable private static JetType getFunctionTypeForSamType(@NotNull JetType samType) { - FunctionDescriptor function = getAbstractMethodOfSamType(samType); + // e.g. samType == Comparator? + + ClassifierDescriptor classifier = samType.getConstructor().getDeclarationDescriptor(); + if (classifier instanceof ClassDescriptorFromJvmBytecode) { + // Function2 + JetType functionTypeDefault = ((ClassDescriptorFromJvmBytecode) classifier).getFunctionTypeForSamInterface(); + + if (functionTypeDefault != null) { + // Function2? + JetType substitute = TypeSubstitutor.create(samType).substitute(functionTypeDefault, Variance.INVARIANT); + + return substitute == null ? null : fixProjections(TypeUtils.makeNullableAsSpecified(substitute, samType.isNullable())); + } + } + return null; + } + + @NotNull + public static JetType getFunctionTypeForAbstractMethod(@NotNull FunctionDescriptor function) { JetType returnType = function.getReturnType(); assert returnType != null : "function is not initialized: " + function; List parameterTypes = Lists.newArrayList(); for (ValueParameterDescriptor parameter : function.getValueParameters()) { parameterTypes.add(parameter.getType()); } - JetType functionType = KotlinBuiltIns.getInstance() - .getFunctionType(Collections.emptyList(), null, parameterTypes, returnType); - return TypeUtils.makeNullableAsSpecified(functionType, samType.isNullable()); + return KotlinBuiltIns.getInstance().getFunctionType( + Collections.emptyList(), null, parameterTypes, returnType); } private static boolean isSamInterface(@NotNull ClassDescriptor klass) { @@ -98,6 +147,7 @@ public class SingleAbstractMethodUtils { TypeParameters typeParameters = recreateAndInitializeTypeParameters(samInterface.getTypeConstructor().getParameters(), result); JetType parameterTypeUnsubstituted = getFunctionTypeForSamType(samInterface.getDefaultType()); + assert parameterTypeUnsubstituted != null : "couldn't get function type for SAM type" + samInterface.getDefaultType(); JetType parameterType = typeParameters.substitutor.substitute(parameterTypeUnsubstituted, Variance.IN_VARIANCE); assert parameterType != null : "couldn't substitute type: " + parameterType + ", substitutor = " + typeParameters.substitutor; ValueParameterDescriptor parameter = new ValueParameterDescriptorImpl( @@ -121,10 +171,7 @@ public class SingleAbstractMethodUtils { } public static boolean isSamType(@NotNull JetType type) { - ClassifierDescriptor classifier = type.getConstructor().getDeclarationDescriptor(); - return classifier instanceof ClassDescriptorFromJvmBytecode && - ((ClassDescriptorFromJvmBytecode) classifier).isSamInterface() && - getAbstractMembers(type).size() == 1; // Comparator<*> is not a SAM type, because substituted compare() method doesn't exist + return getFunctionTypeForSamType(type) != null; } public static boolean isSamAdapterNecessary(@NotNull SimpleFunctionDescriptor fun) { @@ -155,7 +202,8 @@ public class SingleAbstractMethodUtils { List valueParameters = Lists.newArrayList(); for (ValueParameterDescriptor originalParam : original.getValueParameters()) { JetType originalType = originalParam.getType(); - JetType newTypeUnsubstituted = isSamType(originalType) ? getFunctionTypeForSamType(originalType) : originalType; + JetType functionType = getFunctionTypeForSamType(originalType); + JetType newTypeUnsubstituted = functionType != null ? functionType : originalType; JetType newType = typeParameters.substitutor.substitute(newTypeUnsubstituted, Variance.IN_VARIANCE); assert newType != null : "couldn't substitute type: " + newTypeUnsubstituted + ", substitutor = " + typeParameters.substitutor; diff --git a/compiler/testData/loadJava/compiledJava/singleAbstractMethod/adapter/DeepSamLoop.java b/compiler/testData/loadJava/compiledJava/singleAbstractMethod/adapter/DeepSamLoop.java new file mode 100644 index 00000000000..25835b936cd --- /dev/null +++ b/compiler/testData/loadJava/compiledJava/singleAbstractMethod/adapter/DeepSamLoop.java @@ -0,0 +1,12 @@ +package test; + +public interface DeepSamLoop { + + interface Foo { + void foo(Bar p); + } + + interface Bar { + void foo(Foo p); + } +} diff --git a/compiler/testData/loadJava/compiledJava/singleAbstractMethod/adapter/DeepSamLoop.txt b/compiler/testData/loadJava/compiledJava/singleAbstractMethod/adapter/DeepSamLoop.txt new file mode 100644 index 00000000000..d558ccd28f4 --- /dev/null +++ b/compiler/testData/loadJava/compiledJava/singleAbstractMethod/adapter/DeepSamLoop.txt @@ -0,0 +1,19 @@ +package test + +public trait DeepSamLoop : java.lang.Object { + + public trait Bar : java.lang.Object { + public abstract /*synthesized*/ fun foo(/*0*/ p0: ((test.DeepSamLoop.Bar?) -> jet.Unit)?): jet.Unit + public abstract fun foo(/*0*/ p0: test.DeepSamLoop.Foo?): jet.Unit + } + + public trait Foo : java.lang.Object { + public abstract /*synthesized*/ fun foo(/*0*/ p0: ((test.DeepSamLoop.Foo?) -> jet.Unit)?): jet.Unit + public abstract fun foo(/*0*/ p0: test.DeepSamLoop.Bar?): jet.Unit + } +} + +package DeepSamLoop { + public /*synthesized*/ fun Bar(/*0*/ function: (test.DeepSamLoop.Foo?) -> jet.Unit): test.DeepSamLoop.Bar + public /*synthesized*/ fun Foo(/*0*/ function: (test.DeepSamLoop.Bar?) -> jet.Unit): test.DeepSamLoop.Foo +} diff --git a/compiler/testData/loadJava/compiledJava/singleAbstractMethod/adapter/SelfAsParameter.java b/compiler/testData/loadJava/compiledJava/singleAbstractMethod/adapter/SelfAsParameter.java new file mode 100644 index 00000000000..f24f93f9114 --- /dev/null +++ b/compiler/testData/loadJava/compiledJava/singleAbstractMethod/adapter/SelfAsParameter.java @@ -0,0 +1,5 @@ +package test; + +public interface SelfAsParameter { + void foo(SelfAsParameter p); +} diff --git a/compiler/testData/loadJava/compiledJava/singleAbstractMethod/adapter/SelfAsParameter.txt b/compiler/testData/loadJava/compiledJava/singleAbstractMethod/adapter/SelfAsParameter.txt new file mode 100644 index 00000000000..d579c380a55 --- /dev/null +++ b/compiler/testData/loadJava/compiledJava/singleAbstractMethod/adapter/SelfAsParameter.txt @@ -0,0 +1,8 @@ +package test + +public /*synthesized*/ fun SelfAsParameter(/*0*/ function: (test.SelfAsParameter?) -> jet.Unit): test.SelfAsParameter + +public trait SelfAsParameter : java.lang.Object { + public abstract /*synthesized*/ fun foo(/*0*/ p0: ((test.SelfAsParameter?) -> jet.Unit)?): jet.Unit + public abstract fun foo(/*0*/ p0: test.SelfAsParameter?): jet.Unit +} diff --git a/compiler/tests/org/jetbrains/jet/jvm/compiler/LoadJavaTestGenerated.java b/compiler/tests/org/jetbrains/jet/jvm/compiler/LoadJavaTestGenerated.java index faf788d6631..6506c2d5255 100644 --- a/compiler/tests/org/jetbrains/jet/jvm/compiler/LoadJavaTestGenerated.java +++ b/compiler/tests/org/jetbrains/jet/jvm/compiler/LoadJavaTestGenerated.java @@ -1229,11 +1229,21 @@ public class LoadJavaTestGenerated extends AbstractLoadJavaTest { doTestCompiledJava("compiler/testData/loadJava/compiledJava/singleAbstractMethod/adapter/Basic.java"); } + @TestMetadata("DeepSamLoop.java") + public void testDeepSamLoop() throws Exception { + doTestCompiledJava("compiler/testData/loadJava/compiledJava/singleAbstractMethod/adapter/DeepSamLoop.java"); + } + @TestMetadata("NonTrivialFunctionType.java") public void testNonTrivialFunctionType() throws Exception { doTestCompiledJava("compiler/testData/loadJava/compiledJava/singleAbstractMethod/adapter/NonTrivialFunctionType.java"); } + @TestMetadata("SelfAsParameter.java") + public void testSelfAsParameter() throws Exception { + doTestCompiledJava("compiler/testData/loadJava/compiledJava/singleAbstractMethod/adapter/SelfAsParameter.java"); + } + @TestMetadata("SeveralSamParameters.java") public void testSeveralSamParameters() throws Exception { doTestCompiledJava("compiler/testData/loadJava/compiledJava/singleAbstractMethod/adapter/SeveralSamParameters.java"); From 12485c0ef5f08b6fdd219d7af20c466053be5f5b Mon Sep 17 00:00:00 2001 From: Evgeny Gerashchenko Date: Tue, 21 May 2013 13:14:28 +0400 Subject: [PATCH 129/249] Test for KT-3331 RuntimeException in frontend-java at TypeVariableResolverFromTypeDescriptors.getTypeVariable() #KT-3331 obsolete --- .../loadKotlin/class/InheritSubstitutedMethod.kt | 10 ++++++++++ .../loadKotlin/class/InheritSubstitutedMethod.txt | 12 ++++++++++++ .../compiler/LoadCompiledKotlinTestGenerated.java | 5 +++++ 3 files changed, 27 insertions(+) create mode 100644 compiler/testData/loadKotlin/class/InheritSubstitutedMethod.kt create mode 100644 compiler/testData/loadKotlin/class/InheritSubstitutedMethod.txt diff --git a/compiler/testData/loadKotlin/class/InheritSubstitutedMethod.kt b/compiler/testData/loadKotlin/class/InheritSubstitutedMethod.kt new file mode 100644 index 00000000000..c8e64d4e0e0 --- /dev/null +++ b/compiler/testData/loadKotlin/class/InheritSubstitutedMethod.kt @@ -0,0 +1,10 @@ +package test + +public trait A { + fun bar(): T + fun foo(): T = bar() +} + +public class B : A { + override fun bar() = "" +} diff --git a/compiler/testData/loadKotlin/class/InheritSubstitutedMethod.txt b/compiler/testData/loadKotlin/class/InheritSubstitutedMethod.txt new file mode 100644 index 00000000000..f8220df53ad --- /dev/null +++ b/compiler/testData/loadKotlin/class/InheritSubstitutedMethod.txt @@ -0,0 +1,12 @@ +package test + +public trait A { + internal abstract fun bar(): T + internal open fun foo(): T +} + +public final class B : test.A { + /*primary*/ public constructor B() + internal open override /*1*/ fun bar(): jet.String + internal open override /*1*/ /*fake_override*/ fun foo(): jet.String +} diff --git a/compiler/tests/org/jetbrains/jet/jvm/compiler/LoadCompiledKotlinTestGenerated.java b/compiler/tests/org/jetbrains/jet/jvm/compiler/LoadCompiledKotlinTestGenerated.java index 5c32db7fb29..89e993dc3e8 100644 --- a/compiler/tests/org/jetbrains/jet/jvm/compiler/LoadCompiledKotlinTestGenerated.java +++ b/compiler/tests/org/jetbrains/jet/jvm/compiler/LoadCompiledKotlinTestGenerated.java @@ -128,6 +128,11 @@ public class LoadCompiledKotlinTestGenerated extends AbstractLoadCompiledKotlinT doTestWithAccessors("compiler/testData/loadKotlin/class/InheritClassWithParam.kt"); } + @TestMetadata("InheritSubstitutedMethod.kt") + public void testInheritSubstitutedMethod() throws Exception { + doTestWithAccessors("compiler/testData/loadKotlin/class/InheritSubstitutedMethod.kt"); + } + @TestMetadata("InheritTraitWithParam.kt") public void testInheritTraitWithParam() throws Exception { doTestWithAccessors("compiler/testData/loadKotlin/class/InheritTraitWithParam.kt"); From fb416418f0c2f1bd84a40c4ce574dd0599183875 Mon Sep 17 00:00:00 2001 From: Evgeny Gerashchenko Date: Tue, 21 May 2013 14:19:56 +0400 Subject: [PATCH 130/249] Minor. Fixed assertion message. --- .../jet/lang/resolve/java/sam/SingleAbstractMethodUtils.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/sam/SingleAbstractMethodUtils.java b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/sam/SingleAbstractMethodUtils.java index bc89a2d42e0..dc8c30aa1e0 100644 --- a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/sam/SingleAbstractMethodUtils.java +++ b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/sam/SingleAbstractMethodUtils.java @@ -147,7 +147,7 @@ public class SingleAbstractMethodUtils { TypeParameters typeParameters = recreateAndInitializeTypeParameters(samInterface.getTypeConstructor().getParameters(), result); JetType parameterTypeUnsubstituted = getFunctionTypeForSamType(samInterface.getDefaultType()); - assert parameterTypeUnsubstituted != null : "couldn't get function type for SAM type" + samInterface.getDefaultType(); + assert parameterTypeUnsubstituted != null : "couldn't get function type for SAM type " + samInterface.getDefaultType(); JetType parameterType = typeParameters.substitutor.substitute(parameterTypeUnsubstituted, Variance.IN_VARIANCE); assert parameterType != null : "couldn't substitute type: " + parameterType + ", substitutor = " + typeParameters.substitutor; ValueParameterDescriptor parameter = new ValueParameterDescriptorImpl( From de6d5a4a96f3757e8eed6d116b637712a100ebd5 Mon Sep 17 00:00:00 2001 From: Evgeny Gerashchenko Date: Tue, 21 May 2013 16:37:24 +0400 Subject: [PATCH 131/249] Fixed loading SAM interfaces when they inherit abstract methods. --- .../resolve/java/provider/MembersCache.java | 3 -- .../java/resolver/JavaClassResolver.java | 34 +++++++++++++++++-- .../java/resolver/JavaFunctionResolver.java | 6 ++-- .../java/sam/SingleAbstractMethodUtils.java | 2 +- .../SubstitutedSamInterface.java | 6 ++++ .../SubstitutedSamInterface.txt | 7 ++++ ...stitutedSamInterfaceSubclassOfBuiltin.java | 4 +++ ...bstitutedSamInterfaceSubclassOfBuiltin.txt | 7 ++++ .../jvm/compiler/LoadJavaTestGenerated.java | 10 ++++++ ...esolveNamespaceComparingTestGenerated.java | 5 +++ 10 files changed, 76 insertions(+), 8 deletions(-) create mode 100644 compiler/testData/loadJava/compiledJava/singleAbstractMethod/SubstitutedSamInterface.java create mode 100644 compiler/testData/loadJava/compiledJava/singleAbstractMethod/SubstitutedSamInterface.txt create mode 100644 compiler/testData/loadJava/compiledJava/singleAbstractMethod/SubstitutedSamInterfaceSubclassOfBuiltin.java create mode 100644 compiler/testData/loadJava/compiledJava/singleAbstractMethod/SubstitutedSamInterfaceSubclassOfBuiltin.txt diff --git a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/provider/MembersCache.java b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/provider/MembersCache.java index 5c305bcfcee..1b3eaa095d8 100644 --- a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/provider/MembersCache.java +++ b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/provider/MembersCache.java @@ -409,9 +409,6 @@ public final class MembersCache { // Returns null if not SAM interface @Nullable public static PsiMethod getSamInterfaceMethod(@NotNull PsiClass psiClass) { - if (psiClass.hasModifierProperty(PsiModifier.PRIVATE)) { // TODO hacky - return null; - } if (DescriptorResolverUtils.isKotlinClass(psiClass)) { return null; } diff --git a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/resolver/JavaClassResolver.java b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/resolver/JavaClassResolver.java index edb7177da25..980ad38d540 100644 --- a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/resolver/JavaClassResolver.java +++ b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/resolver/JavaClassResolver.java @@ -44,6 +44,8 @@ import org.jetbrains.jet.lang.resolve.name.FqNameBase; import org.jetbrains.jet.lang.resolve.name.FqNameUnsafe; import org.jetbrains.jet.lang.resolve.name.Name; import org.jetbrains.jet.lang.types.JetType; +import org.jetbrains.jet.lang.types.TypeSubstitutor; +import org.jetbrains.jet.lang.types.TypeUtils; import javax.inject.Inject; import java.util.ArrayList; @@ -275,14 +277,42 @@ public final class JavaClassResolver { PsiMethod samInterfaceMethod = MembersCache.getSamInterfaceMethod(psiClass); if (samInterfaceMethod != null) { - SimpleFunctionDescriptor abstractMethod = functionResolver.resolveFunctionMutely( - psiClass, new PsiMethodWrapper(samInterfaceMethod), classDescriptor); + SimpleFunctionDescriptor abstractMethod = resolveFunctionOfSamInterface(psiClass, samInterfaceMethod, classDescriptor); classDescriptor.setFunctionTypeForSamInterface(SingleAbstractMethodUtils.getFunctionTypeForAbstractMethod(abstractMethod)); } return classDescriptor; } + @NotNull + private SimpleFunctionDescriptor resolveFunctionOfSamInterface( + @NotNull PsiClass psiClass, + @NotNull PsiMethod samInterfaceMethod, + @NotNull ClassDescriptorFromJvmBytecode samInterface + ) { + PsiClass methodContainer = samInterfaceMethod.getContainingClass(); + assert methodContainer != null : "method container is null for " + methodContainer; + String containerQualifiedName = methodContainer.getQualifiedName(); + assert containerQualifiedName != null : "qualified name is null for " + psiClass; + + if (DescriptorUtils.getFQName(samInterface).getFqName().equals(containerQualifiedName)) { + SimpleFunctionDescriptor abstractMethod = + functionResolver.resolveFunctionMutely(new PsiMethodWrapper(samInterfaceMethod), samInterface); + assert abstractMethod != null : "couldn't resolve method " + samInterfaceMethod; + return abstractMethod; + } + else { + Set supertypes = TypeUtils.getAllSupertypes(samInterface.getDefaultType()); + for (JetType supertype : supertypes) { + List abstractMembers = SingleAbstractMethodUtils.getAbstractMembers(supertype); + if (!abstractMembers.isEmpty()) { + return (SimpleFunctionDescriptor) abstractMembers.get(0); + } + } + throw new IllegalStateException("Couldn't find abstract method in supertypes " + supertypes); + } + } + private void cache(@NotNull FqNameBase fqName, @Nullable ClassDescriptor classDescriptor) { if (classDescriptor == null) { cacheNegativeValue(fqName); diff --git a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/resolver/JavaFunctionResolver.java b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/resolver/JavaFunctionResolver.java index 8d2e5dd7a40..5a6ca428aaf 100644 --- a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/resolver/JavaFunctionResolver.java +++ b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/resolver/JavaFunctionResolver.java @@ -92,10 +92,12 @@ public final class JavaFunctionResolver { @Nullable SimpleFunctionDescriptor resolveFunctionMutely( - @NotNull PsiClass psiClass, PsiMethodWrapper method, + @NotNull PsiMethodWrapper method, @NotNull ClassOrNamespaceDescriptor ownerDescriptor ) { - return resolveMethodToFunctionDescriptor(psiClass, method, DeclarationOrigin.JAVA, ownerDescriptor, false); + PsiClass containingClass = method.getPsiMethod().getContainingClass(); + assert containingClass != null : "containing class is null for " + method; + return resolveMethodToFunctionDescriptor(containingClass, method, DeclarationOrigin.JAVA, ownerDescriptor, false); } @Nullable diff --git a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/sam/SingleAbstractMethodUtils.java b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/sam/SingleAbstractMethodUtils.java index dc8c30aa1e0..791161d5abc 100644 --- a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/sam/SingleAbstractMethodUtils.java +++ b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/sam/SingleAbstractMethodUtils.java @@ -40,7 +40,7 @@ import static org.jetbrains.jet.lang.types.Variance.INVARIANT; public class SingleAbstractMethodUtils { @NotNull - private static List getAbstractMembers(@NotNull JetType type) { + public static List getAbstractMembers(@NotNull JetType type) { List abstractMembers = Lists.newArrayList(); for (DeclarationDescriptor member : type.getMemberScope().getAllDescriptors()) { if (member instanceof CallableMemberDescriptor && diff --git a/compiler/testData/loadJava/compiledJava/singleAbstractMethod/SubstitutedSamInterface.java b/compiler/testData/loadJava/compiledJava/singleAbstractMethod/SubstitutedSamInterface.java new file mode 100644 index 00000000000..0585609ad95 --- /dev/null +++ b/compiler/testData/loadJava/compiledJava/singleAbstractMethod/SubstitutedSamInterface.java @@ -0,0 +1,6 @@ +package test; + +import java.util.Comparator; + +public interface SubstitutedSamInterface extends Comparator { +} diff --git a/compiler/testData/loadJava/compiledJava/singleAbstractMethod/SubstitutedSamInterface.txt b/compiler/testData/loadJava/compiledJava/singleAbstractMethod/SubstitutedSamInterface.txt new file mode 100644 index 00000000000..d292208116a --- /dev/null +++ b/compiler/testData/loadJava/compiledJava/singleAbstractMethod/SubstitutedSamInterface.txt @@ -0,0 +1,7 @@ +package test + +public /*synthesized*/ fun SubstitutedSamInterface(/*0*/ function: (jet.String?, jet.String?) -> jet.Int): test.SubstitutedSamInterface + +public trait SubstitutedSamInterface : java.util.Comparator { + public abstract override /*1*/ /*fake_override*/ fun compare(/*0*/ p0: jet.String?, /*1*/ p1: jet.String?): jet.Int +} diff --git a/compiler/testData/loadJava/compiledJava/singleAbstractMethod/SubstitutedSamInterfaceSubclassOfBuiltin.java b/compiler/testData/loadJava/compiledJava/singleAbstractMethod/SubstitutedSamInterfaceSubclassOfBuiltin.java new file mode 100644 index 00000000000..f60d884bf46 --- /dev/null +++ b/compiler/testData/loadJava/compiledJava/singleAbstractMethod/SubstitutedSamInterfaceSubclassOfBuiltin.java @@ -0,0 +1,4 @@ +package test; + +public interface SubstitutedSamInterfaceSubclassOfBuiltin extends Comparable { +} diff --git a/compiler/testData/loadJava/compiledJava/singleAbstractMethod/SubstitutedSamInterfaceSubclassOfBuiltin.txt b/compiler/testData/loadJava/compiledJava/singleAbstractMethod/SubstitutedSamInterfaceSubclassOfBuiltin.txt new file mode 100644 index 00000000000..cd1b36fa97e --- /dev/null +++ b/compiler/testData/loadJava/compiledJava/singleAbstractMethod/SubstitutedSamInterfaceSubclassOfBuiltin.txt @@ -0,0 +1,7 @@ +package test + +public /*synthesized*/ fun SubstitutedSamInterfaceSubclassOfBuiltin(/*0*/ function: (test.SubstitutedSamInterfaceSubclassOfBuiltin) -> jet.Int): test.SubstitutedSamInterfaceSubclassOfBuiltin + +public trait SubstitutedSamInterfaceSubclassOfBuiltin : jet.Comparable { + public abstract override /*1*/ /*fake_override*/ fun compareTo(/*0*/ other: test.SubstitutedSamInterfaceSubclassOfBuiltin): jet.Int +} diff --git a/compiler/tests/org/jetbrains/jet/jvm/compiler/LoadJavaTestGenerated.java b/compiler/tests/org/jetbrains/jet/jvm/compiler/LoadJavaTestGenerated.java index 6506c2d5255..5d88070a54a 100644 --- a/compiler/tests/org/jetbrains/jet/jvm/compiler/LoadJavaTestGenerated.java +++ b/compiler/tests/org/jetbrains/jet/jvm/compiler/LoadJavaTestGenerated.java @@ -1218,6 +1218,16 @@ public class LoadJavaTestGenerated extends AbstractLoadJavaTest { doTestCompiledJava("compiler/testData/loadJava/compiledJava/singleAbstractMethod/Runnable.java"); } + @TestMetadata("SubstitutedSamInterface.java") + public void testSubstitutedSamInterface() throws Exception { + doTestCompiledJava("compiler/testData/loadJava/compiledJava/singleAbstractMethod/SubstitutedSamInterface.java"); + } + + @TestMetadata("SubstitutedSamInterfaceSubclassOfBuiltin.java") + public void testSubstitutedSamInterfaceSubclassOfBuiltin() throws Exception { + doTestCompiledJava("compiler/testData/loadJava/compiledJava/singleAbstractMethod/SubstitutedSamInterfaceSubclassOfBuiltin.java"); + } + @TestMetadata("compiler/testData/loadJava/compiledJava/singleAbstractMethod/adapter") public static class Adapter extends AbstractLoadJavaTest { public void testAllFilesPresentInAdapter() throws Exception { diff --git a/compiler/tests/org/jetbrains/jet/lang/resolve/lazy/LazyResolveNamespaceComparingTestGenerated.java b/compiler/tests/org/jetbrains/jet/lang/resolve/lazy/LazyResolveNamespaceComparingTestGenerated.java index 4c683e969e2..b2bcdbb32bf 100644 --- a/compiler/tests/org/jetbrains/jet/lang/resolve/lazy/LazyResolveNamespaceComparingTestGenerated.java +++ b/compiler/tests/org/jetbrains/jet/lang/resolve/lazy/LazyResolveNamespaceComparingTestGenerated.java @@ -130,6 +130,11 @@ public class LazyResolveNamespaceComparingTestGenerated extends AbstractLazyReso doTestCheckingPrimaryConstructorsAndAccessors("compiler/testData/loadKotlin/class/InheritClassWithParam.kt"); } + @TestMetadata("InheritSubstitutedMethod.kt") + public void testInheritSubstitutedMethod() throws Exception { + doTestCheckingPrimaryConstructorsAndAccessors("compiler/testData/loadKotlin/class/InheritSubstitutedMethod.kt"); + } + @TestMetadata("InheritTraitWithParam.kt") public void testInheritTraitWithParam() throws Exception { doTestCheckingPrimaryConstructorsAndAccessors("compiler/testData/loadKotlin/class/InheritTraitWithParam.kt"); From 43b9a9d434a638aeaaa058f772efd3db5617cfd2 Mon Sep 17 00:00:00 2001 From: Evgeny Gerashchenko Date: Tue, 21 May 2013 17:56:04 +0400 Subject: [PATCH 132/249] Renamed Name.getName() and FqName.getFqName() to asString() --- .../jet/codegen/AnnotationCodegen.java | 6 +-- .../org/jetbrains/jet/codegen/AsmUtil.java | 6 +-- .../jetbrains/jet/codegen/ClosureCodegen.java | 8 ++-- .../jet/codegen/ExpressionCodegen.java | 16 +++---- .../org/jetbrains/jet/codegen/FieldInfo.java | 2 +- .../jet/codegen/FunctionCodegen.java | 6 +-- .../codegen/ImplementationBodyCodegen.java | 12 ++--- .../jet/codegen/PropertyCodegen.java | 10 ++-- .../jet/codegen/RangeCodegenUtil.java | 2 +- .../org/jetbrains/jet/codegen/StackValue.java | 2 +- .../binding/CodegenAnnotatingVisitor.java | 4 +- .../codegen/binding/PsiCodegenPredictor.java | 10 ++-- .../codegen/intrinsics/IntrinsicMethods.java | 2 +- .../jet/codegen/intrinsics/StaticField.java | 2 +- .../signature/BothSignatureWriter.java | 4 +- .../jet/codegen/state/JetTypeMapper.java | 8 ++-- .../messages/AnalyzerWithCompilerReport.java | 2 +- .../jvm/compiler/CompileEnvironmentUtil.java | 2 +- .../jet/cli/jvm/repl/ReplInterpreter.java | 2 +- .../resolve/java/DescriptorResolverUtils.java | 2 +- .../resolve/java/JavaToKotlinClassMap.java | 4 +- .../resolve/java/JavaTypeTransformer.java | 6 +-- .../java/JetTypeJetSignatureReader.java | 2 +- .../jet/lang/resolve/java/JvmAbi.java | 4 +- .../jet/lang/resolve/java/JvmClassName.java | 4 +- .../resolve/java/KotlinToJavaTypesMap.java | 2 +- .../lang/resolve/java/PackageClassUtils.java | 2 +- .../lang/resolve/java/PsiClassFinderImpl.java | 6 +-- ...peVariableResolverFromTypeDescriptors.java | 2 +- .../SignaturesPropagationData.java | 2 +- .../TypeTransformingVisitor.java | 6 +-- .../resolve/java/kt/JetClassAnnotation.java | 2 +- .../java/kt/JetClassObjectAnnotation.java | 2 +- .../java/kt/JetConstructorAnnotation.java | 2 +- .../resolve/java/kt/JetMethodAnnotation.java | 2 +- .../java/kt/JetPackageClassAnnotation.java | 2 +- .../java/kt/JetTypeParameterAnnotation.java | 2 +- .../java/kt/JetValueParameterAnnotation.java | 2 +- .../java/kt/KotlinSignatureAnnotation.java | 2 +- .../resolve/java/provider/MembersCache.java | 2 +- .../java/resolver/JavaAnnotationResolver.java | 2 +- .../resolver/JavaClassObjectResolver.java | 2 +- .../java/resolver/JavaClassResolver.java | 7 ++- .../java/resolver/JavaFunctionResolver.java | 4 +- .../java/resolver/JavaPropertyResolver.java | 2 +- .../resolver/JavaValueParameterResolver.java | 2 +- .../descriptors/impl/ClassDescriptorImpl.java | 2 +- .../impl/MutableClassDescriptorLite.java | 2 +- .../impl/TypeParameterDescriptorImpl.java | 2 +- .../lang/diagnostics/rendering/Renderers.java | 4 +- .../org/jetbrains/jet/lang/psi/JetClass.java | 2 +- .../jetbrains/jet/lang/psi/JetPsiFactory.java | 2 +- .../jetbrains/jet/lang/psi/JetPsiUtil.java | 4 +- .../elements/JetAnnotationElementType.java | 2 +- .../stubs/elements/JetClassElementType.java | 4 +- .../jet/lang/resolve/AnnotationResolver.java | 4 +- .../jet/lang/resolve/DeclarationResolver.java | 4 +- .../jet/lang/resolve/DeclarationsChecker.java | 2 +- .../jet/lang/resolve/DescriptorUtils.java | 8 ++-- .../jet/lang/resolve/ImportPath.java | 4 +- .../jet/lang/resolve/OverloadResolver.java | 6 +-- .../jet/lang/resolve/OverrideResolver.java | 4 +- .../TraceBasedRedeclarationHandler.java | 2 +- .../jet/lang/resolve/TypeResolver.java | 2 +- .../jet/lang/resolve/calls/CallResolver.java | 3 +- .../calls/tasks/TracingStrategyImpl.java | 2 +- .../descriptors/LazyClassMemberScope.java | 2 +- .../jet/lang/resolve/name/FqName.java | 6 +-- .../jet/lang/resolve/name/FqNameBase.java | 4 +- .../jet/lang/resolve/name/FqNameUnsafe.java | 14 +++--- .../jetbrains/jet/lang/resolve/name/Name.java | 4 +- .../resolve/scopes/WritableScopeImpl.java | 4 +- .../BasicExpressionTypingVisitor.java | 4 +- .../ControlStructureTypingVisitor.java | 2 +- .../expressions/DelegatedPropertyUtils.java | 4 +- .../expressions/ExpressionTypingUtils.java | 4 +- .../jet/lang/types/lang/KotlinBuiltIns.java | 8 ++-- .../jet/util/QualifiedNamesUtil.java | 12 ++--- .../jetbrains/jet/asJava/JetLightPackage.java | 2 +- .../asJava/KotlinJavaFileStubProvider.java | 4 +- ...otlinLightClassForExplicitDeclaration.java | 10 ++-- .../asJava/KotlinLightClassForPackage.java | 4 +- .../jetbrains/jet/asJava/LightClassUtil.java | 4 +- .../tests/org/jetbrains/jet/FqNameTest.java | 46 +++++++++---------- .../jet/codegen/CodegenTestCase.java | 2 +- .../AbstractBlackBoxCodegenTest.java | 2 +- .../AbstractLoadCompiledKotlinTest.java | 2 +- .../jvm/compiler/ExpectedLoadErrorsUtil.java | 3 +- .../IdeaJdkAnnotationsReflectedTest.java | 4 +- .../jet/jvm/compiler/JvmClassNameTest.java | 4 +- .../jet/test/util/NamespaceComparator.java | 2 +- .../jvm/GenerateJavaToKotlinMethodMap.java | 4 +- .../jetbrains/jet/plugin/JetPluginUtil.java | 4 +- .../plugin/actions/JetAddImportAction.java | 4 +- .../caches/JetGotoClassContributor.java | 2 +- .../jet/plugin/caches/JetShortNamesCache.java | 14 +++--- .../IDELightClassGenerationSupport.java | 14 +++--- .../ReferenceToClassesShortening.java | 2 +- .../ktSignature/KotlinSignatureUtil.java | 2 +- .../completion/DescriptorLookupConverter.java | 4 +- .../importOptimizer/JetImportOptimizer.java | 2 +- .../DeprecatedAnnotationVisitor.java | 2 +- .../jet/plugin/highlighter/IdeRenderers.java | 2 +- .../libraries/JetSourceNavigationHelper.java | 8 ++-- .../jet/plugin/libraries/MemberMatching.java | 4 +- .../quickfix/AddFunctionParametersFix.java | 6 +-- .../plugin/quickfix/AddNameToArgumentFix.java | 4 +- .../jet/plugin/quickfix/AutoImportFix.java | 2 +- .../quickfix/ChangeFunctionReturnTypeFix.java | 5 +- .../plugin/quickfix/ImportInsertHelper.java | 4 +- .../quickfix/MakeOverriddenMemberOpenFix.java | 2 +- .../quickfix/MapPlatformClassToKotlinFix.java | 4 +- .../quickfix/RemoveFunctionParametersFix.java | 2 +- ...meParameterToMatchOverriddenMethodFix.java | 4 +- .../plugin/refactoring/JetNameSuggester.java | 4 +- .../refactoring/JetNameValidatorImpl.java | 2 +- .../changeSignature/JetChangeInfo.java | 2 +- .../JetFunctionPlatformDescriptorImpl.java | 6 +-- .../run/JetRunConfigurationProducer.java | 6 +-- .../KotlinAnnotatedElementsSearcher.java | 2 +- .../KotlinDirectInheritorsSearcher.java | 2 +- .../JetStructureViewElement.java | 4 +- .../stubindex/StubIndexServiceImpl.java | 10 ++-- .../versions/KotlinRuntimeLibraryUtil.java | 2 +- .../codeInsight/OverrideImplementTest.java | 2 +- .../NavigateToStdlibSourceRegressionTest.java | 4 +- .../BuiltInsReferenceResolverTest.java | 2 +- .../jet/j2k/visitors/TypeVisitor.java | 2 +- .../k2js/translate/context/Namer.java | 2 +- .../k2js/translate/context/StaticContext.java | 10 ++-- .../translate/context/TranslationContext.java | 2 +- .../expression/StringTemplateTranslator.java | 4 +- .../foreach/ArrayForTranslator.java | 4 +- .../foreach/RangeForTranslator.java | 2 +- .../initializer/InitializerUtils.java | 4 +- .../PrimitiveBinaryOperationFIF.java | 4 +- .../factories/PrimitiveUnaryOperationFIF.java | 2 +- .../functions/patterns/NamePredicate.java | 2 +- .../translate/reference/CallTranslator.java | 2 +- .../translate/utils/AnnotationsUtils.java | 2 +- 140 files changed, 294 insertions(+), 304 deletions(-) diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/AnnotationCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/AnnotationCodegen.java index 87fb2949e3c..b8ac58e8cc4 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/AnnotationCodegen.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/AnnotationCodegen.java @@ -115,7 +115,7 @@ public abstract class AnnotationCodegen { } Name keyName = entry.getKey().getName(); - genAnnotationValueArgument(annotationVisitor, valueArgument, keyName.getName()); + genAnnotationValueArgument(annotationVisitor, valueArgument, keyName.asString()); } } @@ -152,7 +152,7 @@ public abstract class AnnotationCodegen { if (call != null) { if (call.getResultingDescriptor() instanceof PropertyDescriptor) { PropertyDescriptor descriptor = (PropertyDescriptor) call.getResultingDescriptor(); - annotationVisitor.visitEnum(keyName, typeMapper.mapType(descriptor).getDescriptor(), descriptor.getName().getName()); + annotationVisitor.visitEnum(keyName, typeMapper.mapType(descriptor).getDescriptor(), descriptor.getName().asString()); return; } } @@ -168,7 +168,7 @@ public abstract class AnnotationCodegen { if (annotations != null) { for (AnnotationDescriptor annotation : annotations) { //noinspection ConstantConditions - if ("Intrinsic".equals(annotation.getType().getConstructor().getDeclarationDescriptor().getName().getName())) { + if ("Intrinsic".equals(annotation.getType().getConstructor().getDeclarationDescriptor().getName().asString())) { value = (String) annotation.getAllValueArguments().values().iterator().next().getValue(); break; } diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/AsmUtil.java b/compiler/backend/src/org/jetbrains/jet/codegen/AsmUtil.java index 4596c51c4c5..76d717a323b 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/AsmUtil.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/AsmUtil.java @@ -505,7 +505,7 @@ public class AsmUtil { Type asmType = state.getTypeMapper().mapReturnType(type); if (asmType.getSort() == Type.OBJECT || asmType.getSort() == Type.ARRAY) { v.load(index, asmType); - v.visitLdcInsn(descriptor.getName().getName()); + v.visitLdcInsn(descriptor.getName().asString()); v.invokestatic("jet/runtime/Intrinsics", "checkParameterIsNotNull", "(Ljava/lang/Object;Ljava/lang/String;)V"); } } @@ -546,8 +546,8 @@ public class AsmUtil { Type asmType = state.getTypeMapper().mapReturnType(type); if (asmType.getSort() == Type.OBJECT || asmType.getSort() == Type.ARRAY) { v.dup(); - v.visitLdcInsn(descriptor.getContainingDeclaration().getName().getName()); - v.visitLdcInsn(descriptor.getName().getName()); + v.visitLdcInsn(descriptor.getContainingDeclaration().getName().asString()); + v.visitLdcInsn(descriptor.getName().asString()); v.invokestatic("jet/runtime/Intrinsics", assertMethodToCall, "(Ljava/lang/Object;Ljava/lang/String;Ljava/lang/String;)V"); } } diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/ClosureCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/ClosureCodegen.java index d53c617333b..ea860a0a78c 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/ClosureCodegen.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/ClosureCodegen.java @@ -178,7 +178,7 @@ public class ClosureCodegen extends GenerationStateAware { return; } - MethodVisitor mv = cv.newMethod(fun, ACC_PUBLIC | ACC_BRIDGE, interfaceFunction.getName().getName(), + MethodVisitor mv = cv.newMethod(fun, ACC_PUBLIC | ACC_BRIDGE, interfaceFunction.getName().asString(), bridge.getDescriptor(), null, ArrayUtil.EMPTY_STRING_ARRAY); if (state.getClassBuilderMode() == ClassBuilderMode.STUBS) { genStubCode(mv); @@ -203,7 +203,7 @@ public class ClosureCodegen extends GenerationStateAware { count++; } - iv.invokevirtual(name.getInternalName(), interfaceFunction.getName().getName(), delegate.getDescriptor()); + iv.invokevirtual(name.getInternalName(), interfaceFunction.getName().asString(), delegate.getDescriptor()); StackValue.onStack(delegate.getReturnType()).put(bridge.getReturnType(), iv); iv.areturn(bridge.getReturnType()); @@ -268,11 +268,11 @@ public class ClosureCodegen extends GenerationStateAware { Type type = sharedVarType != null ? sharedVarType : typeMapper.mapType((VariableDescriptor) descriptor); - args.add(FieldInfo.createForHiddenField(ownerType, type, "$" + descriptor.getName().getName())); + args.add(FieldInfo.createForHiddenField(ownerType, type, "$" + descriptor.getName().asString())); } else if (isLocalNamedFun(descriptor)) { JvmClassName className = classNameForAnonymousClass(bindingContext, (FunctionDescriptor) descriptor); - args.add(FieldInfo.createForHiddenField(ownerType, className.getAsmType(), "$" + descriptor.getName().getName())); + args.add(FieldInfo.createForHiddenField(ownerType, className.getAsmType(), "$" + descriptor.getName().asString())); } else if (descriptor instanceof FunctionDescriptor) { assert captureReceiver != null; diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java index 093ac725a21..adb1cf703f6 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java @@ -560,7 +560,7 @@ public class ExpressionCodegen extends JetVisitor implem @Override public void run() { myFrameMap.leave(parameterDescriptor); - v.visitLocalVariable(parameterDescriptor.getName().getName(), + v.visitLocalVariable(parameterDescriptor.getName().asString(), asmTypeForParameter.getDescriptor(), null, bodyStart, bodyEnd, loopParameterVar); @@ -601,7 +601,7 @@ public class ExpressionCodegen extends JetVisitor implem @Override public void run() { myFrameMap.leave(componentDescriptor); - v.visitLocalVariable(componentDescriptor.getName().getName(), + v.visitLocalVariable(componentDescriptor.getName().asString(), componentAsmType.getDescriptor(), null, bodyStart, bodyEnd, componentVarIndex); @@ -1414,7 +1414,7 @@ public class ExpressionCodegen extends JetVisitor implem v.store(index, OBJECT_TYPE); } } - v.visitLocalVariable(variableDescriptor.getName().getName(), type.getDescriptor(), null, scopeStart, blockEnd, + v.visitLocalVariable(variableDescriptor.getName().asString(), type.getDescriptor(), null, scopeStart, blockEnd, index); return null; } @@ -1628,7 +1628,7 @@ public class ExpressionCodegen extends JetVisitor implem ClassDescriptor containing = (ClassDescriptor) variableDescriptor.getContainingDeclaration().getContainingDeclaration(); assert containing != null; Type type = typeMapper.mapType(containing); - return StackValue.field(type, JvmClassName.byType(type), variableDescriptor.getName().getName(), true); + return StackValue.field(type, JvmClassName.byType(type), variableDescriptor.getName().asString(), true); } else { return StackValue.singleton(objectClassDescriptor, typeMapper); @@ -2924,7 +2924,7 @@ public class ExpressionCodegen extends JetVisitor implem else { DeclarationDescriptor cls = op.getContainingDeclaration(); CallableMethod callableMethod = (CallableMethod) callable; - if (isPrimitiveNumberClassDescriptor(cls) || !(op.getName().getName().equals("inc") || op.getName().getName().equals("dec"))) { + if (isPrimitiveNumberClassDescriptor(cls) || !(op.getName().asString().equals("inc") || op.getName().asString().equals("dec"))) { return invokeOperation(expression, (FunctionDescriptor) op, callableMethod); } else { @@ -2981,14 +2981,14 @@ public class ExpressionCodegen extends JetVisitor implem if (op instanceof FunctionDescriptor) { Type asmType = expressionType(expression); DeclarationDescriptor cls = op.getContainingDeclaration(); - if (op.getName().getName().equals("inc") || op.getName().getName().equals("dec")) { + if (op.getName().asString().equals("inc") || op.getName().asString().equals("dec")) { if (isPrimitiveNumberClassDescriptor(cls)) { receiver.put(receiver.type, v); JetExpression operand = expression.getBaseExpression(); if (operand instanceof JetReferenceExpression) { int index = indexOfLocal((JetReferenceExpression) operand); if (index >= 0 && isIntPrimitive(asmType)) { - int increment = op.getName().getName().equals("inc") ? 1 : -1; + int increment = op.getName().asString().equals("inc") ? 1 : -1; return StackValue.postIncrement(index, increment); } } @@ -3053,7 +3053,7 @@ public class ExpressionCodegen extends JetVisitor implem } private void generateIncrement(DeclarationDescriptor op, Type asmType, JetExpression operand, StackValue receiver) { - int increment = op.getName().getName().equals("inc") ? 1 : -1; + int increment = op.getName().asString().equals("inc") ? 1 : -1; if (operand instanceof JetReferenceExpression) { int index = indexOfLocal((JetReferenceExpression) operand); if (index >= 0 && isIntPrimitive(asmType)) { diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/FieldInfo.java b/compiler/backend/src/org/jetbrains/jet/codegen/FieldInfo.java index 47371252938..6cafb4a834c 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/FieldInfo.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/FieldInfo.java @@ -41,7 +41,7 @@ public class FieldInfo { Type ownerType = typeMapper.mapType(ownerDescriptor.getDefaultType()); String fieldName = kind == ClassKind.ENUM_ENTRY - ? fieldClassDescriptor.getName().getName() + ? fieldClassDescriptor.getName().asString() : fieldClassDescriptor.getKind() == ClassKind.CLASS_OBJECT ? JvmAbi.CLASS_OBJECT_FIELD : JvmAbi.INSTANCE_FIELD; return new FieldInfo(ownerType, fieldType, fieldName, true); } diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/FunctionCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/FunctionCodegen.java index 5c99197b3c6..ccbff63900f 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/FunctionCodegen.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/FunctionCodegen.java @@ -200,7 +200,7 @@ public class FunctionCodegen extends GenerationStateAware { List parameters = functionDescriptor.getValueParameters(); List result = new ArrayList(parameters.size()); for (ValueParameterDescriptor parameter : parameters) { - result.add(parameter.getName().getName()); + result.add(parameter.getName().asString()); } return result; } @@ -244,7 +244,7 @@ public class FunctionCodegen extends GenerationStateAware { if (kind == JvmMethodParameterKind.VALUE) { ValueParameterDescriptor parameter = valueParameters.next(); Label divideLabel = labelsForSharedVars.get(parameter.getName()); - parameterName = parameter.getName().getName(); + parameterName = parameter.getName().asString(); if (divideLabel != null) { mv.visitLocalVariable(parameterName, type.getDescriptor(), null, methodBegin, divideLabel, shift); @@ -377,7 +377,7 @@ public class FunctionCodegen extends GenerationStateAware { ValueParameterDescriptor parameterDescriptor = null; if (kind == JvmMethodParameterKind.VALUE) { parameterDescriptor = valueParameters.next(); - parameterName = parameterDescriptor.getName().getName(); + parameterName = parameterDescriptor.getName().asString(); } else if (kind == JvmMethodParameterKind.ENUM_NAME || kind == JvmMethodParameterKind.ENUM_ORDINAL) { //we shouldn't generate annotations for invisible in runtime parameters otherwise we get bad RuntimeInvisibleParameterAnnotations error in javac continue; diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/ImplementationBodyCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/ImplementationBodyCodegen.java index cba0dfea6d1..785d3a0913e 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/ImplementationBodyCodegen.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/ImplementationBodyCodegen.java @@ -297,7 +297,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { innerClassInternalName = outerClassInternalName + JvmAbi.CLASS_OBJECT_SUFFIX; } else { - innerName = innerClass.getName().isSpecial() ? null : innerClass.getName().getName(); + innerName = innerClass.getName().isSpecial() ? null : innerClass.getName().asString(); innerClassInternalName = getInternalNameForImpl(innerClass); } @@ -620,11 +620,11 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { boolean first = true; for (PropertyDescriptor propertyDescriptor : properties) { if (first) { - iv.aconst(descriptor.getName() + "(" + propertyDescriptor.getName().getName()+"="); + iv.aconst(descriptor.getName() + "(" + propertyDescriptor.getName().asString()+"="); first = false; } else { - iv.aconst(", " + propertyDescriptor.getName().getName()+"="); + iv.aconst(", " + propertyDescriptor.getName().asString()+"="); } genInvokeAppendMethod(iv, JAVA_STRING_TYPE); @@ -821,7 +821,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { Type[] argTypes = method.getArgumentTypes(); String owner = typeMapper.getOwner(original, OwnerKind.IMPLEMENTATION, isCallInsideSameModuleAsDeclared(original, context)).getInternalName(); - MethodVisitor mv = v.newMethod(null, ACC_SYNTHETIC | ACC_STATIC, bridge.getName().getName(), + MethodVisitor mv = v.newMethod(null, ACC_SYNTHETIC | ACC_STATIC, bridge.getName().asString(), method.getDescriptor(), null, null); if (state.getClassBuilderMode() == ClassBuilderMode.STUBS) { genStubCode(mv); @@ -1015,7 +1015,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { Type type = typeMapper.mapType(descriptor); iv.load(0, classAsmType); iv.load(codegen.myFrameMap.getIndex(descriptor), type); - iv.putfield(classAsmType.getInternalName(), descriptor.getName().getName(), type.getDescriptor()); + iv.putfield(classAsmType.getInternalName(), descriptor.getName().asString(), type.getDescriptor()); } curParam++; } @@ -1097,7 +1097,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { Boolean.TRUE.equals(bindingContext.get(BindingContext.BACKING_FIELD_REQUIRED, propertyDescriptor))) { // final property with backing field field = StackValue.field(typeMapper.mapType(propertyDescriptor.getType()), classname, - propertyDescriptor.getName().getName(), false); + propertyDescriptor.getName().asString(), false); } else { iv.load(0, classType); diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/PropertyCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/PropertyCodegen.java index 10a7bee673e..34c71c9655b 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/PropertyCodegen.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/PropertyCodegen.java @@ -148,7 +148,7 @@ public class PropertyCodegen extends GenerationStateAware { modifiers |= ACC_VOLATILE; } Type type = typeMapper.mapType(propertyDescriptor); - return v.newField(p, modifiers, propertyDescriptor.getName().getName(), type.getDescriptor(), null, value); + return v.newField(p, modifiers, propertyDescriptor.getName().asString(), type.getDescriptor(), null, value); } private void generateGetter(JetNamedDeclaration p, PropertyDescriptor propertyDescriptor, JetPropertyAccessor getter) { @@ -248,7 +248,7 @@ public class PropertyCodegen extends GenerationStateAware { iv.visitFieldInsn( kind == OwnerKind.NAMESPACE ? GETSTATIC : GETFIELD, typeMapper.getOwner(propertyDescriptor, kind, isCallInsideSameModuleAsDeclared(propertyDescriptor, context)).getInternalName(), - propertyDescriptor.getName().getName(), + propertyDescriptor.getName().asString(), type.getDescriptor()); iv.areturn(type); } @@ -265,7 +265,7 @@ public class PropertyCodegen extends GenerationStateAware { iv.load(paramCode, type); iv.visitFieldInsn(kind == OwnerKind.NAMESPACE ? PUTSTATIC : PUTFIELD, typeMapper.getOwner(propertyDescriptor, kind, isCallInsideSameModuleAsDeclared(propertyDescriptor, context)).getInternalName(), - propertyDescriptor.getName().getName(), + propertyDescriptor.getName().asString(), type.getDescriptor()); iv.visitInsn(RETURN); @@ -336,11 +336,11 @@ public class PropertyCodegen extends GenerationStateAware { } public static String getterName(Name propertyName) { - return JvmAbi.GETTER_PREFIX + StringUtil.capitalizeWithJavaBeanConvention(propertyName.getName()); + return JvmAbi.GETTER_PREFIX + StringUtil.capitalizeWithJavaBeanConvention(propertyName.asString()); } public static String setterName(Name propertyName) { - return JvmAbi.SETTER_PREFIX + StringUtil.capitalizeWithJavaBeanConvention(propertyName.getName()); + return JvmAbi.SETTER_PREFIX + StringUtil.capitalizeWithJavaBeanConvention(propertyName.asString()); } public void genDelegate(PropertyDescriptor delegate, PropertyDescriptor overridden, StackValue field) { diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/RangeCodegenUtil.java b/compiler/backend/src/org/jetbrains/jet/codegen/RangeCodegenUtil.java index 17f5409bc3e..ebb6ad902e0 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/RangeCodegenUtil.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/RangeCodegenUtil.java @@ -112,7 +112,7 @@ public class RangeCodegenUtil { } public static boolean isOptimizableRangeTo(CallableDescriptor rangeTo) { - if ("rangeTo".equals(rangeTo.getName().getName())) { + if ("rangeTo".equals(rangeTo.getName().asString())) { if (isPrimitiveNumberClassDescriptor(rangeTo.getContainingDeclaration())) { return true; } diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/StackValue.java b/compiler/backend/src/org/jetbrains/jet/codegen/StackValue.java index 3fcaae8c1ff..b7f8d673b7d 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/StackValue.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/StackValue.java @@ -913,7 +913,7 @@ public abstract class StackValue { } private String getPropertyName() { - return isDelegated ? JvmAbi.getPropertyDelegateName(descriptor.getName()) : descriptor.getName().getName(); + return isDelegated ? JvmAbi.getPropertyDelegateName(descriptor.getName()) : descriptor.getName().asString(); } } diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/binding/CodegenAnnotatingVisitor.java b/compiler/backend/src/org/jetbrains/jet/codegen/binding/CodegenAnnotatingVisitor.java index 05f737656ab..b91bf08e7d7 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/binding/CodegenAnnotatingVisitor.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/binding/CodegenAnnotatingVisitor.java @@ -227,7 +227,7 @@ class CodegenAnnotatingVisitor extends JetVisitorVoid { private String getName(ClassDescriptor classDescriptor) { String base = peekFromStack(nameStack); return DescriptorUtils.isTopLevelDeclaration(classDescriptor) ? base.isEmpty() ? classDescriptor.getName() - .getName() : base + '/' + classDescriptor.getName() : base + '$' + classDescriptor.getName(); + .asString() : base + '/' + classDescriptor.getName() : base + '$' + classDescriptor.getName(); } @Override @@ -350,7 +350,7 @@ class CodegenAnnotatingVisitor extends JetVisitorVoid { DeclarationDescriptor containingDeclaration = descriptor.getContainingDeclaration(); String peek = peekFromStack(nameStack); - String name = descriptor.getName().getName(); + String name = descriptor.getName().asString(); if (containingDeclaration instanceof ClassDescriptor) { return peek + '$' + name; } diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/binding/PsiCodegenPredictor.java b/compiler/backend/src/org/jetbrains/jet/codegen/binding/PsiCodegenPredictor.java index 4946194d635..b3affd8f237 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/binding/PsiCodegenPredictor.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/binding/PsiCodegenPredictor.java @@ -116,7 +116,7 @@ public final class PsiCodegenPredictor { if (declaration instanceof JetNamedFunction) { if (parentDeclaration == null) { JvmClassName packageClass = addPackageClass(parentClassName); - return JvmClassName.byInternalName(packageClass.getInternalName() + "$" + name.getName()); + return JvmClassName.byInternalName(packageClass.getInternalName() + "$" + name.asString()); } if (!(parentDeclaration instanceof JetClass || parentDeclaration instanceof JetObjectDeclaration)) { @@ -128,16 +128,16 @@ public final class PsiCodegenPredictor { // NOTE: looks like a bug - for class in getter of top level property class name will be $propertyName$ClassName but not // namespace$propertyName$ClassName if (declaration instanceof JetProperty) { - return JvmClassName.byInternalName(parentClassName.getInternalName() + "$" + name.getName()); + return JvmClassName.byInternalName(parentClassName.getInternalName() + "$" + name.asString()); } if (fqName.isRoot()) { - return JvmClassName.byInternalName(name.getName()); + return JvmClassName.byInternalName(name.asString()); } return JvmClassName.byInternalName(parentDeclaration == null ? - parentClassName.getInternalName() + "/" + name.getName() : - parentClassName.getInternalName() + "$" + name.getName()); + parentClassName.getInternalName() + "/" + name.asString() : + parentClassName.getInternalName() + "$" + name.asString()); } return null; 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 d82fa7073c0..69b4a44be93 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/IntrinsicMethods.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/IntrinsicMethods.java @@ -241,7 +241,7 @@ public class IntrinsicMethods { for (AnnotationDescriptor annotation : annotations) { ClassifierDescriptor classifierDescriptor = annotation.getType().getConstructor().getDeclarationDescriptor(); assert classifierDescriptor != null; - if ("Intrinsic".equals(classifierDescriptor.getName().getName())) { + if ("Intrinsic".equals(classifierDescriptor.getName().asString())) { String value = (String) annotation.getAllValueArguments().values().iterator().next().getValue(); intrinsicMethod = namedMethods.get(value); if (intrinsicMethod != null) { diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/StaticField.java b/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/StaticField.java index 6339aeaaf21..034e0ba3f85 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/StaticField.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/StaticField.java @@ -51,7 +51,7 @@ public class StaticField implements IntrinsicMethod { StackValue receiver, @NotNull GenerationState state ) { - v.getstatic(JvmClassName.byFqNameWithoutInnerClasses(ownerClass).getInternalName(), propertyName.getName(), expectedType.getDescriptor()); + v.getstatic(JvmClassName.byFqNameWithoutInnerClasses(ownerClass).getInternalName(), propertyName.asString(), expectedType.getDescriptor()); return StackValue.onStack(expectedType); } } diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/signature/BothSignatureWriter.java b/compiler/backend/src/org/jetbrains/jet/codegen/signature/BothSignatureWriter.java index bf733044928..de3de631c4e 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/signature/BothSignatureWriter.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/signature/BothSignatureWriter.java @@ -272,8 +272,8 @@ public class BothSignatureWriter { } public void writeTypeVariable(Name name, boolean nullable, Type asmType) { - signatureVisitor().visitTypeVariable(name.getName()); - jetSignatureWriter.visitTypeVariable(name.getName(), nullable); + signatureVisitor().visitTypeVariable(name.asString()); + jetSignatureWriter.visitTypeVariable(name.asString(), nullable); generic = true; writeAsmType0(asmType); } diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/state/JetTypeMapper.java b/compiler/backend/src/org/jetbrains/jet/codegen/state/JetTypeMapper.java index 6b2e915f340..d9606affaf0 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/state/JetTypeMapper.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/state/JetTypeMapper.java @@ -578,7 +578,7 @@ public class JetTypeMapper extends BindingTraceAware { @NotNull public JvmMethodSignature mapSignature(@NotNull FunctionDescriptor f, boolean needGenericSignature, @NotNull OwnerKind kind) { - String name = f.getName().getName(); + String name = f.getName().asString(); if (f instanceof PropertyAccessorDescriptor) { boolean isGetter = f instanceof PropertyGetterDescriptor; name = getPropertyAccessorName(((PropertyAccessorDescriptor) f).getCorrespondingProperty(), isGetter); @@ -588,7 +588,7 @@ public class JetTypeMapper extends BindingTraceAware { @NotNull public JvmMethodSignature mapSignature(@NotNull Name functionName, @NotNull FunctionDescriptor f) { - return mapSignature(functionName.getName(), f, false, OwnerKind.IMPLEMENTATION); + return mapSignature(functionName.asString(), f, false, OwnerKind.IMPLEMENTATION); } @NotNull @@ -675,7 +675,7 @@ public class JetTypeMapper extends BindingTraceAware { } private void writeFormalTypeParameter(TypeParameterDescriptor typeParameterDescriptor, BothSignatureWriter signatureVisitor) { - signatureVisitor.writeFormalTypeParameter(typeParameterDescriptor.getName().getName(), typeParameterDescriptor.getVariance(), + signatureVisitor.writeFormalTypeParameter(typeParameterDescriptor.getName().asString(), typeParameterDescriptor.getVariance(), typeParameterDescriptor.isReified()); classBound: @@ -730,7 +730,7 @@ public class JetTypeMapper extends BindingTraceAware { DeclarationDescriptor parentDescriptor = descriptor.getContainingDeclaration(); boolean isAnnotation = parentDescriptor instanceof ClassDescriptor && ((ClassDescriptor) parentDescriptor).getKind() == ClassKind.ANNOTATION_CLASS; - return isAnnotation ? descriptor.getName().getName() : + return isAnnotation ? descriptor.getName().asString() : isGetter ? PropertyCodegen.getterName(descriptor.getName()) : PropertyCodegen.setterName(descriptor.getName()); } diff --git a/compiler/cli/src/org/jetbrains/jet/cli/common/messages/AnalyzerWithCompilerReport.java b/compiler/cli/src/org/jetbrains/jet/cli/common/messages/AnalyzerWithCompilerReport.java index 444d44fed95..6e6092088cd 100644 --- a/compiler/cli/src/org/jetbrains/jet/cli/common/messages/AnalyzerWithCompilerReport.java +++ b/compiler/cli/src/org/jetbrains/jet/cli/common/messages/AnalyzerWithCompilerReport.java @@ -109,7 +109,7 @@ public final class AnalyzerWithCompilerReport { if (!incompletes.isEmpty()) { StringBuilder message = new StringBuilder("The following classes have incomplete hierarchies:\n"); for (ClassDescriptor incomplete : incompletes) { - String fqName = DescriptorUtils.getFQName(incomplete).getFqName(); + String fqName = DescriptorUtils.getFQName(incomplete).asString(); message.append(" ").append(fqName).append("\n"); } messageCollectorWrapper.report(CompilerMessageSeverity.ERROR, message.toString(), CompilerMessageLocation.NO_LOCATION); diff --git a/compiler/cli/src/org/jetbrains/jet/cli/jvm/compiler/CompileEnvironmentUtil.java b/compiler/cli/src/org/jetbrains/jet/cli/jvm/compiler/CompileEnvironmentUtil.java index 48f3f83464d..e8ccfee3774 100644 --- a/compiler/cli/src/org/jetbrains/jet/cli/jvm/compiler/CompileEnvironmentUtil.java +++ b/compiler/cli/src/org/jetbrains/jet/cli/jvm/compiler/CompileEnvironmentUtil.java @@ -203,7 +203,7 @@ public class CompileEnvironmentUtil { mainAttributes.putValue("Manifest-Version", "1.0"); mainAttributes.putValue("Created-By", "JetBrains Kotlin"); if (mainClass != null) { - mainAttributes.putValue("Main-Class", mainClass.getFqName()); + mainAttributes.putValue("Main-Class", mainClass.asString()); } JarOutputStream stream = new JarOutputStream(fos, manifest); for (String file : factory.files()) { diff --git a/compiler/cli/src/org/jetbrains/jet/cli/jvm/repl/ReplInterpreter.java b/compiler/cli/src/org/jetbrains/jet/cli/jvm/repl/ReplInterpreter.java index cbade7676cc..89eae3219e7 100644 --- a/compiler/cli/src/org/jetbrains/jet/cli/jvm/repl/ReplInterpreter.java +++ b/compiler/cli/src/org/jetbrains/jet/cli/jvm/repl/ReplInterpreter.java @@ -236,7 +236,7 @@ public class ReplInterpreter { } try { - Class scriptClass = classLoader.loadClass(scriptClassName.getFqName().getFqName()); + Class scriptClass = classLoader.loadClass(scriptClassName.getFqName().asString()); Class[] constructorParams = new Class[earlierLines.size()]; Object[] constructorArgs = new Object[earlierLines.size()]; diff --git a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/DescriptorResolverUtils.java b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/DescriptorResolverUtils.java index 0fca6080224..c81e4fad3bb 100644 --- a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/DescriptorResolverUtils.java +++ b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/DescriptorResolverUtils.java @@ -140,7 +140,7 @@ public final class DescriptorResolverUtils { public static FqNameUnsafe getFqNameForClassObject(@NotNull PsiClass psiClass) { String psiClassQualifiedName = psiClass.getQualifiedName(); assert psiClassQualifiedName != null : "Reading java class with no qualified name"; - return new FqNameUnsafe(psiClassQualifiedName + "." + getClassObjectName(psiClass.getName()).getName()); + return new FqNameUnsafe(psiClassQualifiedName + "." + getClassObjectName(psiClass.getName()).asString()); } @NotNull diff --git a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaToKotlinClassMap.java b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaToKotlinClassMap.java index ef9da4ac6ab..5de6852d9a6 100644 --- a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaToKotlinClassMap.java +++ b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaToKotlinClassMap.java @@ -65,7 +65,7 @@ public class JavaToKotlinClassMap extends JavaToKotlinClassMapBuilder implements PrimitiveType primitiveType = jvmPrimitiveType.getPrimitiveType(); primitiveTypesMap.put(jvmPrimitiveType.getName(), KotlinBuiltIns.getInstance().getPrimitiveJetType(primitiveType)); primitiveTypesMap.put("[" + jvmPrimitiveType.getName(), KotlinBuiltIns.getInstance().getPrimitiveArrayJetType(primitiveType)); - primitiveTypesMap.put(jvmPrimitiveType.getWrapper().getFqName().getFqName(), KotlinBuiltIns.getInstance().getNullablePrimitiveJetType( + primitiveTypesMap.put(jvmPrimitiveType.getWrapper().getFqName().asString(), KotlinBuiltIns.getInstance().getNullablePrimitiveJetType( primitiveType)); } primitiveTypesMap.put("void", KotlinBuiltIns.getInstance().getUnitType()); @@ -91,7 +91,7 @@ public class JavaToKotlinClassMap extends JavaToKotlinClassMapBuilder implements @Nullable public AnnotationDescriptor mapToAnnotationClass(@NotNull FqName fqName) { ClassDescriptor classDescriptor = classDescriptorMap.get(fqName); - if (classDescriptor != null && fqName.getFqName().equals(CommonClassNames.JAVA_LANG_DEPRECATED)) { + if (classDescriptor != null && fqName.asString().equals(CommonClassNames.JAVA_LANG_DEPRECATED)) { return DescriptorResolverUtils.getAnnotationDescriptorForJavaLangDeprecated(classDescriptor); } return null; diff --git a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaTypeTransformer.java b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaTypeTransformer.java index 5c30676b45a..3e7255de471 100644 --- a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaTypeTransformer.java +++ b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaTypeTransformer.java @@ -184,7 +184,7 @@ public class JavaTypeTransformer { " in " + classType.getPresentableText() + "\n PsiClass: \n" + psiClass.getText()); for (TypeParameterDescriptor parameter : parameters) { - arguments.add(new TypeProjection(ErrorUtils.createErrorType(parameter.getName().getName()))); + arguments.add(new TypeProjection(ErrorUtils.createErrorType(parameter.getName().asString()))); } } else { @@ -275,10 +275,10 @@ public class JavaTypeTransformer { if (!signatureTypeUsages.contains(originalTypeUsage)) { return originalTypeUsage; } - if (JavaAnnotationResolver.findAnnotationWithExternal(owner, JvmAbi.JETBRAINS_MUTABLE_ANNOTATION.getFqName().getFqName()) != null) { + if (JavaAnnotationResolver.findAnnotationWithExternal(owner, JvmAbi.JETBRAINS_MUTABLE_ANNOTATION.getFqName().asString()) != null) { return TypeUsage.MEMBER_SIGNATURE_COVARIANT; } - if (JavaAnnotationResolver.findAnnotationWithExternal(owner, JvmAbi.JETBRAINS_READONLY_ANNOTATION.getFqName().getFqName()) != null) { + if (JavaAnnotationResolver.findAnnotationWithExternal(owner, JvmAbi.JETBRAINS_READONLY_ANNOTATION.getFqName().asString()) != null) { return TypeUsage.MEMBER_SIGNATURE_CONTRAVARIANT; } return originalTypeUsage; diff --git a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JetTypeJetSignatureReader.java b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JetTypeJetSignatureReader.java index eeb44f1d4b0..f0f02b821c1 100644 --- a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JetTypeJetSignatureReader.java +++ b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JetTypeJetSignatureReader.java @@ -86,7 +86,7 @@ public abstract class JetTypeJetSignatureReader extends JetSignatureExceptionsAd public void visitClassType(String signatureName, boolean nullable, boolean forceReal) { FqName fqName = JvmClassName.bySignatureName(signatureName).getFqName(); - enterClass(resolveClassDescriptorByFqName(fqName, forceReal), fqName.getFqName(), nullable); + enterClass(resolveClassDescriptorByFqName(fqName, forceReal), fqName.asString(), nullable); } private void enterClass(@Nullable ClassDescriptor classDescriptor, @NotNull String className, boolean nullable) { diff --git a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JvmAbi.java b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JvmAbi.java index 087c8a9b6b4..aa592f4dd02 100644 --- a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JvmAbi.java +++ b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JvmAbi.java @@ -17,8 +17,6 @@ package org.jetbrains.jet.lang.resolve.java; import org.jetbrains.annotations.NotNull; -import org.jetbrains.jet.lang.descriptors.ClassDescriptor; -import org.jetbrains.jet.lang.descriptors.ClassKind; import org.jetbrains.jet.lang.resolve.name.FqName; import org.jetbrains.jet.lang.resolve.name.Name; @@ -58,7 +56,7 @@ public class JvmAbi { } public static String getPropertyDelegateName(@NotNull Name name) { - return name.getName() + DELEGATED_PROPERTY_NAME_POSTFIX; + return name.asString() + DELEGATED_PROPERTY_NAME_POSTFIX; } private JvmAbi() { diff --git a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JvmClassName.java b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JvmClassName.java index 4f54eff8e42..4ea57d3534e 100644 --- a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JvmClassName.java +++ b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JvmClassName.java @@ -91,7 +91,7 @@ public class JvmClassName { List innerClassNames = Lists.newArrayList(); while (descriptor.getContainingDeclaration() instanceof ClassDescriptor) { - innerClassNames.add(descriptor.getName().getName()); + innerClassNames.add(descriptor.getName().asString()); descriptor = descriptor.getContainingDeclaration(); assert descriptor != null; } @@ -101,7 +101,7 @@ public class JvmClassName { @NotNull private static String fqNameToInternalName(@NotNull FqName fqName) { - return fqName.getFqName().replace('.', '/'); + return fqName.asString().replace('.', '/'); } @NotNull diff --git a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/KotlinToJavaTypesMap.java b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/KotlinToJavaTypesMap.java index 2b337dc5ef9..b53096d39aa 100644 --- a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/KotlinToJavaTypesMap.java +++ b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/KotlinToJavaTypesMap.java @@ -122,6 +122,6 @@ public class KotlinToJavaTypesMap extends JavaToKotlinClassMapBuilder { public boolean isForceReal(@NotNull JvmClassName className) { return JvmPrimitiveType.getByWrapperClass(className) != null - || mappedTypeNames.contains(className.getFqName().getFqName()); + || mappedTypeNames.contains(className.getFqName().asString()); } } diff --git a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/PackageClassUtils.java b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/PackageClassUtils.java index c2c4e37250c..a268623bc4b 100644 --- a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/PackageClassUtils.java +++ b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/PackageClassUtils.java @@ -32,7 +32,7 @@ public class PackageClassUtils { if (packageFQN.isRoot()) { return DEFAULT_PACKAGE; } - return StringUtil.capitalize(packageFQN.shortName().getName()) + "Package"; + return StringUtil.capitalize(packageFQN.shortName().asString()) + "Package"; } public static FqName getPackageClassFqName(@NotNull FqName packageFQN) { diff --git a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/PsiClassFinderImpl.java b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/PsiClassFinderImpl.java index bee73db55a9..916d71fb48a 100644 --- a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/PsiClassFinderImpl.java +++ b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/PsiClassFinderImpl.java @@ -86,7 +86,7 @@ public class PsiClassFinderImpl implements PsiClassFinder { @Override @Nullable public PsiClass findPsiClass(@NotNull FqName qualifiedName, @NotNull RuntimeClassesHandleMode runtimeClassesHandleMode) { - PsiClass original = javaFacade.findClass(qualifiedName.getFqName(), javaSearchScope); + PsiClass original = javaFacade.findClass(qualifiedName.asString(), javaSearchScope); if (original != null) { String classQualifiedName = original.getQualifiedName(); @@ -106,7 +106,7 @@ public class PsiClassFinderImpl implements PsiClassFinder { if (KotlinBuiltIns.BUILT_INS_PACKAGE_FQ_NAME.equals(qualifiedName.parent())) { PsiAnnotation assertInvisibleAnnotation = JavaAnnotationResolver.findOwnAnnotation( - original, JvmStdlibNames.ASSERT_INVISIBLE_IN_RESOLVER.getFqName().getFqName()); + original, JvmStdlibNames.ASSERT_INVISIBLE_IN_RESOLVER.getFqName().asString()); if (assertInvisibleAnnotation != null) { switch (runtimeClassesHandleMode) { @@ -131,7 +131,7 @@ public class PsiClassFinderImpl implements PsiClassFinder { @Override @Nullable public PsiPackage findPsiPackage(@NotNull FqName qualifiedName) { - return javaFacade.findPackage(qualifiedName.getFqName()); + return javaFacade.findPackage(qualifiedName.asString()); } @NotNull diff --git a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/TypeVariableResolverFromTypeDescriptors.java b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/TypeVariableResolverFromTypeDescriptors.java index 5a28fa68bb5..a8d75fd101b 100644 --- a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/TypeVariableResolverFromTypeDescriptors.java +++ b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/TypeVariableResolverFromTypeDescriptors.java @@ -60,7 +60,7 @@ public class TypeVariableResolverFromTypeDescriptors implements TypeVariableReso @NotNull DeclarationDescriptor owner, @NotNull String context) { for (TypeParameterDescriptor typeParameter : typeParameters) { - if (typeParameter.getName().getName().equals(name)) { + if (typeParameter.getName().asString().equals(name)) { return typeParameter; } } diff --git a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/kotlinSignature/SignaturesPropagationData.java b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/kotlinSignature/SignaturesPropagationData.java index 62b5993f9f3..55b59a76612 100644 --- a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/kotlinSignature/SignaturesPropagationData.java +++ b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/kotlinSignature/SignaturesPropagationData.java @@ -254,7 +254,7 @@ public class SignaturesPropagationData { public int compare(FunctionDescriptor fun1, FunctionDescriptor fun2) { FqNameUnsafe fqName1 = getFQName(fun1.getContainingDeclaration()); FqNameUnsafe fqName2 = getFQName(fun2.getContainingDeclaration()); - return fqName1.getFqName().compareTo(fqName2.getFqName()); + return fqName1.asString().compareTo(fqName2.asString()); } }); return superFunctions; diff --git a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/kotlinSignature/TypeTransformingVisitor.java b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/kotlinSignature/TypeTransformingVisitor.java index 6ab3f537034..c100a35b698 100644 --- a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/kotlinSignature/TypeTransformingVisitor.java +++ b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/kotlinSignature/TypeTransformingVisitor.java @@ -99,14 +99,14 @@ public class TypeTransformingVisitor extends JetVisitor { } private JetType visitCommonType(@NotNull ClassDescriptor classDescriptor, @NotNull JetTypeElement type) { - return visitCommonType(DescriptorUtils.getFQName(classDescriptor).toSafe().getFqName(), type); + return visitCommonType(DescriptorUtils.getFQName(classDescriptor).toSafe().asString(), type); } private JetType visitCommonType(@NotNull String qualifiedName, @NotNull JetTypeElement type) { TypeConstructor originalTypeConstructor = originalType.getConstructor(); ClassifierDescriptor declarationDescriptor = originalTypeConstructor.getDeclarationDescriptor(); assert declarationDescriptor != null; - String fqName = DescriptorUtils.getFQName(declarationDescriptor).toSafe().getFqName(); + String fqName = DescriptorUtils.getFQName(declarationDescriptor).toSafe().asString(); ClassDescriptor classFromLibrary = getAutoTypeAnalogWithinBuiltins(qualifiedName); if (!isSameName(qualifiedName, fqName) && classFromLibrary == null) { throw new AlternativeSignatureMismatchException("Alternative signature type mismatch, expected: %s, actual: %s", qualifiedName, fqName); @@ -212,7 +212,7 @@ public class TypeTransformingVisitor extends JetVisitor { Collection descriptors = JavaToKotlinClassMap.getInstance().mapPlatformClass(JvmClassName.byType(javaAnalog).getFqName()); for (ClassDescriptor descriptor : descriptors) { - String fqName = DescriptorUtils.getFQName(descriptor).getFqName(); + String fqName = DescriptorUtils.getFQName(descriptor).asString(); if (isSameName(qualifiedName, fqName)) { return descriptor; } diff --git a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/kt/JetClassAnnotation.java b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/kt/JetClassAnnotation.java index e7c1f3570cb..39fdb450eba 100644 --- a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/kt/JetClassAnnotation.java +++ b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/kt/JetClassAnnotation.java @@ -54,7 +54,7 @@ public class JetClassAnnotation extends PsiAnnotationWithAbiVersion { @NotNull public static JetClassAnnotation get(PsiClass psiClass) { PsiAnnotation annotation = JavaAnnotationResolver.findOwnAnnotation(psiClass, - JvmStdlibNames.JET_CLASS.getFqName().getFqName()); + JvmStdlibNames.JET_CLASS.getFqName().asString()); return annotation != null ? new JetClassAnnotation(annotation) : NULL_ANNOTATION; } } diff --git a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/kt/JetClassObjectAnnotation.java b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/kt/JetClassObjectAnnotation.java index bbebea1496e..c4a118d957d 100644 --- a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/kt/JetClassObjectAnnotation.java +++ b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/kt/JetClassObjectAnnotation.java @@ -38,7 +38,7 @@ public class JetClassObjectAnnotation extends PsiAnnotationWithAbiVersion { @NotNull public static JetClassObjectAnnotation get(@NotNull PsiClass psiClass) { PsiAnnotation annotation = - JavaAnnotationResolver.findOwnAnnotation(psiClass, JvmStdlibNames.JET_CLASS_OBJECT.getFqName().getFqName()); + JavaAnnotationResolver.findOwnAnnotation(psiClass, JvmStdlibNames.JET_CLASS_OBJECT.getFqName().asString()); return annotation != null ? new JetClassObjectAnnotation(annotation) : NULL_ANNOTATION; } } diff --git a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/kt/JetConstructorAnnotation.java b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/kt/JetConstructorAnnotation.java index 65f8277994a..f83f0c17e0d 100644 --- a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/kt/JetConstructorAnnotation.java +++ b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/kt/JetConstructorAnnotation.java @@ -48,7 +48,7 @@ public class JetConstructorAnnotation extends PsiAnnotationWithFlags { public static JetConstructorAnnotation get(PsiMethod constructor) { PsiAnnotation annotation = - JavaAnnotationResolver.findOwnAnnotation(constructor, JvmStdlibNames.JET_CONSTRUCTOR.getFqName().getFqName()); + JavaAnnotationResolver.findOwnAnnotation(constructor, JvmStdlibNames.JET_CONSTRUCTOR.getFqName().asString()); return annotation != null ? new JetConstructorAnnotation(annotation) : NULL_ANNOTATION; } } diff --git a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/kt/JetMethodAnnotation.java b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/kt/JetMethodAnnotation.java index e1354bd4789..88a3e5066ca 100644 --- a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/kt/JetMethodAnnotation.java +++ b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/kt/JetMethodAnnotation.java @@ -69,7 +69,7 @@ public class JetMethodAnnotation extends PsiAnnotationWithFlags { public static JetMethodAnnotation get(PsiMethod psiMethod) { PsiAnnotation annotation = - JavaAnnotationResolver.findOwnAnnotation(psiMethod, JvmStdlibNames.JET_METHOD.getFqName().getFqName()); + JavaAnnotationResolver.findOwnAnnotation(psiMethod, JvmStdlibNames.JET_METHOD.getFqName().asString()); return annotation != null ? new JetMethodAnnotation(annotation) : NULL_ANNOTATION; } } diff --git a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/kt/JetPackageClassAnnotation.java b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/kt/JetPackageClassAnnotation.java index db7f552fe0d..7ef2fe8d895 100644 --- a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/kt/JetPackageClassAnnotation.java +++ b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/kt/JetPackageClassAnnotation.java @@ -36,7 +36,7 @@ public class JetPackageClassAnnotation extends PsiAnnotationWithAbiVersion { @NotNull public static JetPackageClassAnnotation get(PsiClass psiClass) { PsiAnnotation annotation = JavaAnnotationResolver.findOwnAnnotation(psiClass, - JvmStdlibNames.JET_PACKAGE_CLASS.getFqName().getFqName()); + JvmStdlibNames.JET_PACKAGE_CLASS.getFqName().asString()); return annotation != null ? new JetPackageClassAnnotation(annotation) : NULL_ANNOTATION; } } diff --git a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/kt/JetTypeParameterAnnotation.java b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/kt/JetTypeParameterAnnotation.java index dfee4f4cd85..8d4a5f17758 100644 --- a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/kt/JetTypeParameterAnnotation.java +++ b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/kt/JetTypeParameterAnnotation.java @@ -40,7 +40,7 @@ public class JetTypeParameterAnnotation extends PsiAnnotationWrapper { @NotNull public static JetTypeParameterAnnotation get(@NotNull PsiParameter psiParameter) { PsiAnnotation annotation = - JavaAnnotationResolver.findOwnAnnotation(psiParameter, JvmStdlibNames.JET_TYPE_PARAMETER.getFqName().getFqName()); + JavaAnnotationResolver.findOwnAnnotation(psiParameter, JvmStdlibNames.JET_TYPE_PARAMETER.getFqName().asString()); return annotation != null ? new JetTypeParameterAnnotation(annotation) : NULL_ANNOTATION; } } diff --git a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/kt/JetValueParameterAnnotation.java b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/kt/JetValueParameterAnnotation.java index b03e027d6cf..97b1771d76b 100644 --- a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/kt/JetValueParameterAnnotation.java +++ b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/kt/JetValueParameterAnnotation.java @@ -77,7 +77,7 @@ public class JetValueParameterAnnotation extends PsiAnnotationWrapper { public static JetValueParameterAnnotation get(PsiParameter psiParameter) { PsiAnnotation annotation = - JavaAnnotationResolver.findOwnAnnotation(psiParameter, JvmStdlibNames.JET_VALUE_PARAMETER.getFqName().getFqName()); + JavaAnnotationResolver.findOwnAnnotation(psiParameter, JvmStdlibNames.JET_VALUE_PARAMETER.getFqName().asString()); return annotation != null ? new JetValueParameterAnnotation(annotation) : NULL_ANNOTATION; } } diff --git a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/kt/KotlinSignatureAnnotation.java b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/kt/KotlinSignatureAnnotation.java index fccc0b2e414..e27d70f5b31 100644 --- a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/kt/KotlinSignatureAnnotation.java +++ b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/kt/KotlinSignatureAnnotation.java @@ -50,7 +50,7 @@ public class KotlinSignatureAnnotation extends PsiAnnotationWrapper { @NotNull public static KotlinSignatureAnnotation get(PsiModifierListOwner psiModifierListOwner) { PsiAnnotation annotation = - JavaAnnotationResolver.findAnnotationWithExternal(psiModifierListOwner, JvmStdlibNames.KOTLIN_SIGNATURE.getFqName().getFqName()); + JavaAnnotationResolver.findAnnotationWithExternal(psiModifierListOwner, JvmStdlibNames.KOTLIN_SIGNATURE.getFqName().asString()); return annotation != null ? new KotlinSignatureAnnotation(annotation) : NULL_ANNOTATION; } } diff --git a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/provider/MembersCache.java b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/provider/MembersCache.java index 1b3eaa095d8..7443865b3d0 100644 --- a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/provider/MembersCache.java +++ b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/provider/MembersCache.java @@ -413,7 +413,7 @@ public final class MembersCache { return null; } String qualifiedName = psiClass.getQualifiedName(); - if (qualifiedName == null || qualifiedName.startsWith(KotlinBuiltIns.BUILT_INS_PACKAGE_FQ_NAME.getFqName() + ".")) { + if (qualifiedName == null || qualifiedName.startsWith(KotlinBuiltIns.BUILT_INS_PACKAGE_FQ_NAME.asString() + ".")) { return null; } if (!psiClass.isInterface() || psiClass.isAnnotationType()) { diff --git a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/resolver/JavaAnnotationResolver.java b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/resolver/JavaAnnotationResolver.java index 2e4e1afed45..07e56506faf 100644 --- a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/resolver/JavaAnnotationResolver.java +++ b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/resolver/JavaAnnotationResolver.java @@ -84,7 +84,7 @@ public final class JavaAnnotationResolver { } // Don't process internal jet annotations and jetbrains NotNull annotations - if (qname.startsWith("jet.runtime.typeinfo.") || qname.equals(JvmAbi.JETBRAINS_NOT_NULL_ANNOTATION.getFqName().getFqName())) { + if (qname.startsWith("jet.runtime.typeinfo.") || qname.equals(JvmAbi.JETBRAINS_NOT_NULL_ANNOTATION.getFqName().asString())) { return null; } diff --git a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/resolver/JavaClassObjectResolver.java b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/resolver/JavaClassObjectResolver.java index 50cac772c7b..8bf16a28584 100644 --- a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/resolver/JavaClassObjectResolver.java +++ b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/resolver/JavaClassObjectResolver.java @@ -131,7 +131,7 @@ public final class JavaClassObjectResolver { ClassDescriptorFromJvmBytecode classObjectDescriptor = new ClassDescriptorFromJvmBytecode(containing, ClassKind.CLASS_OBJECT, false); ClassPsiDeclarationProvider data = semanticServices.getPsiDeclarationProviderFactory().createSyntheticClassObjectClassData(psiClass); - setUpClassObjectDescriptor(classObjectDescriptor, containing, fqName, data, getClassObjectName(containing.getName().getName())); + setUpClassObjectDescriptor(classObjectDescriptor, containing, fqName, data, getClassObjectName(containing.getName().asString())); return classObjectDescriptor; } diff --git a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/resolver/JavaClassResolver.java b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/resolver/JavaClassResolver.java index 980ad38d540..f280910e44e 100644 --- a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/resolver/JavaClassResolver.java +++ b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/resolver/JavaClassResolver.java @@ -44,7 +44,6 @@ import org.jetbrains.jet.lang.resolve.name.FqNameBase; import org.jetbrains.jet.lang.resolve.name.FqNameUnsafe; import org.jetbrains.jet.lang.resolve.name.Name; import org.jetbrains.jet.lang.types.JetType; -import org.jetbrains.jet.lang.types.TypeSubstitutor; import org.jetbrains.jet.lang.types.TypeUtils; import javax.inject.Inject; @@ -203,7 +202,7 @@ public final class JavaClassResolver { private static boolean isTraitImplementation(@NotNull FqName qualifiedName) { // TODO: only if -$$TImpl class is created by Kotlin - return qualifiedName.getFqName().endsWith(JvmAbi.TRAIT_IMPL_SUFFIX); + return qualifiedName.asString().endsWith(JvmAbi.TRAIT_IMPL_SUFFIX); } @NotNull @@ -295,7 +294,7 @@ public final class JavaClassResolver { String containerQualifiedName = methodContainer.getQualifiedName(); assert containerQualifiedName != null : "qualified name is null for " + psiClass; - if (DescriptorUtils.getFQName(samInterface).getFqName().equals(containerQualifiedName)) { + if (DescriptorUtils.getFQName(samInterface).asString().equals(containerQualifiedName)) { SimpleFunctionDescriptor abstractMethod = functionResolver.resolveFunctionMutely(new PsiMethodWrapper(samInterfaceMethod), samInterface); assert abstractMethod != null : "couldn't resolve method " + samInterfaceMethod; @@ -378,7 +377,7 @@ public final class JavaClassResolver { private static FqNameUnsafe javaClassToKotlinFqName(@NotNull FqName rawFqName) { List correctedSegments = new ArrayList(); for (Name segment : rawFqName.pathSegments()) { - if (JvmAbi.CLASS_OBJECT_CLASS_NAME.equals(segment.getName())) { + if (JvmAbi.CLASS_OBJECT_CLASS_NAME.equals(segment.asString())) { assert !correctedSegments.isEmpty(); Name previous = correctedSegments.get(correctedSegments.size() - 1); correctedSegments.add(DescriptorUtils.getClassObjectName(previous)); diff --git a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/resolver/JavaFunctionResolver.java b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/resolver/JavaFunctionResolver.java index 5a6ca428aaf..b85f90e7b20 100644 --- a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/resolver/JavaFunctionResolver.java +++ b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/resolver/JavaFunctionResolver.java @@ -125,7 +125,7 @@ public final class JavaFunctionResolver { // TODO: unless maybe class explicitly extends Object assert containingClass != null; String ownerClassName = containingClass.getQualifiedName(); - if (DescriptorResolverUtils.OBJECT_FQ_NAME.getFqName().equals(ownerClassName)) { + if (DescriptorResolverUtils.OBJECT_FQ_NAME.asString().equals(ownerClassName)) { return null; } } @@ -439,7 +439,7 @@ public final class JavaFunctionResolver { transformedType = typeTransformer.transformToType(returnType, typeUsage, typeVariableResolver); } - if (JavaAnnotationResolver.findAnnotationWithExternal(method.getPsiMethod(), JvmAbi.JETBRAINS_NOT_NULL_ANNOTATION.getFqName().getFqName()) != + if (JavaAnnotationResolver.findAnnotationWithExternal(method.getPsiMethod(), JvmAbi.JETBRAINS_NOT_NULL_ANNOTATION.getFqName().asString()) != null) { return TypeUtils.makeNullableAsSpecified(transformedType, false); } diff --git a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/resolver/JavaPropertyResolver.java b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/resolver/JavaPropertyResolver.java index 0d83a6affbc..43bdd800784 100644 --- a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/resolver/JavaPropertyResolver.java +++ b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/resolver/JavaPropertyResolver.java @@ -392,7 +392,7 @@ public final class JavaPropertyResolver { boolean hasNotNullAnnotation = JavaAnnotationResolver.findAnnotationWithExternal( characteristicMember.getType().getPsiNotNullOwner(), - JvmAbi.JETBRAINS_NOT_NULL_ANNOTATION.getFqName().getFqName()) != null; + JvmAbi.JETBRAINS_NOT_NULL_ANNOTATION.getFqName().asString()) != null; if (hasNotNullAnnotation || members.isStaticFinalField()) { propertyType = TypeUtils.makeNotNullable(propertyType); diff --git a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/resolver/JavaValueParameterResolver.java b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/resolver/JavaValueParameterResolver.java index baa581a7593..eb313a72a3a 100644 --- a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/resolver/JavaValueParameterResolver.java +++ b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/resolver/JavaValueParameterResolver.java @@ -90,7 +90,7 @@ public final class JavaValueParameterResolver { else { JetType transformedType; - if (JavaAnnotationResolver.findAnnotationWithExternal(parameter.getPsiParameter(), JvmAbi.JETBRAINS_NOT_NULL_ANNOTATION.getFqName().getFqName()) != + if (JavaAnnotationResolver.findAnnotationWithExternal(parameter.getPsiParameter(), JvmAbi.JETBRAINS_NOT_NULL_ANNOTATION.getFqName().asString()) != null) { transformedType = TypeUtils.makeNullableAsSpecified(outType, false); } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/impl/ClassDescriptorImpl.java b/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/impl/ClassDescriptorImpl.java index 0f8cef9366f..765970371c3 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/impl/ClassDescriptorImpl.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/impl/ClassDescriptorImpl.java @@ -73,7 +73,7 @@ public class ClassDescriptorImpl extends DeclarationDescriptorNonRootImpl implem @Nullable ConstructorDescriptor primaryConstructor, boolean isInner ) { - this.typeConstructor = new TypeConstructorImpl(this, getAnnotations(), sealed, getName().getName(), typeParameters, supertypes); + this.typeConstructor = new TypeConstructorImpl(this, getAnnotations(), sealed, getName().asString(), typeParameters, supertypes); this.memberDeclarations = memberDeclarations; this.constructors = constructors; this.primaryConstructor = primaryConstructor; diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/impl/MutableClassDescriptorLite.java b/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/impl/MutableClassDescriptorLite.java index efc3908a579..cdbcddd9a8e 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/impl/MutableClassDescriptorLite.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/impl/MutableClassDescriptorLite.java @@ -109,7 +109,7 @@ public abstract class MutableClassDescriptorLite extends ClassDescriptorBase { this, Collections.emptyList(), // TODO : pass annotations from the class? !getModality().isOverridable(), - getName().getName(), + getName().asString(), typeParameters, supertypes); } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/impl/TypeParameterDescriptorImpl.java b/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/impl/TypeParameterDescriptorImpl.java index 0785d3f1554..513e5753afd 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/impl/TypeParameterDescriptorImpl.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/impl/TypeParameterDescriptorImpl.java @@ -91,7 +91,7 @@ public class TypeParameterDescriptorImpl extends DeclarationDescriptorNonRootImp this, annotations, false, - name.getName(), + name.asString(), Collections.emptyList(), upperBounds); } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/diagnostics/rendering/Renderers.java b/compiler/frontend/src/org/jetbrains/jet/lang/diagnostics/rendering/Renderers.java index 42bc78af206..189fe0e31e7 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/diagnostics/rendering/Renderers.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/diagnostics/rendering/Renderers.java @@ -64,7 +64,7 @@ public class Renderers { @Override public String render(@NotNull Object element) { if (element instanceof Named) { - return ((Named) element).getName().getName(); + return ((Named) element).getName().asString(); } return element.toString(); } @@ -299,7 +299,7 @@ public class Renderers { StringBuilder sb = new StringBuilder(); int index = 0; for (ClassDescriptor descriptor : descriptors) { - sb.append(DescriptorUtils.getFQName(descriptor).getFqName()); + sb.append(DescriptorUtils.getFQName(descriptor).asString()); index++; if (index <= descriptors.size() - 2) { sb.append(", "); diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetClass.java b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetClass.java index 67454adfe79..3856f9274da 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetClass.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetClass.java @@ -199,7 +199,7 @@ public class JetClass extends JetTypeParameterListOwnerStub imp PsiJetClassStub stub = getStub(); if (stub != null) { FqName fqName = stub.getFqName(); - return fqName == null ? null : fqName.getFqName(); + return fqName == null ? null : fqName.asString(); } List parts = new ArrayList(); diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetPsiFactory.java b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetPsiFactory.java index cfb5dfd6f59..c9f83314700 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetPsiFactory.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetPsiFactory.java @@ -228,7 +228,7 @@ public class JetPsiFactory { Name alias = importPath.getAlias(); if (alias != null) { - importDirectiveBuilder.append(" as ").append(alias.getName()); + importDirectiveBuilder.append(" as ").append(alias.asString()); } JetFile namespace = createFile(project, importDirectiveBuilder.toString()); diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetPsiUtil.java b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetPsiUtil.java index d54ddbe6179..0d02f57ad50 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetPsiUtil.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetPsiUtil.java @@ -408,7 +408,7 @@ public class JetPsiUtil { return false; } - return KotlinBuiltIns.getInstance().getUnit().getName().getName().equals(typeReference.getText()); + return KotlinBuiltIns.getInstance().getUnit().getName().asString().equals(typeReference.getText()); } public static boolean isSafeCall(@NotNull Call call) { @@ -694,7 +694,7 @@ public class JetPsiUtil { public static boolean checkVariableDeclarationInBlock(@NotNull JetBlockExpression block, @NotNull String varName) { for (JetElement element : block.getStatements()) { if (element instanceof JetVariableDeclaration) { - if (((JetVariableDeclaration) element).getNameAsSafeName().getName().equals(varName)) { + if (((JetVariableDeclaration) element).getNameAsSafeName().asString().equals(varName)) { return true; } } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/psi/stubs/elements/JetAnnotationElementType.java b/compiler/frontend/src/org/jetbrains/jet/lang/psi/stubs/elements/JetAnnotationElementType.java index e0e61ca6f1b..a4fb74d67f8 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/psi/stubs/elements/JetAnnotationElementType.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/psi/stubs/elements/JetAnnotationElementType.java @@ -50,7 +50,7 @@ public class JetAnnotationElementType extends JetStubElementType redeclaration : redeclarations) { - trace.report(REDECLARATION.on(redeclaration.getFirst(), redeclaration.getSecond().getName())); + trace.report(REDECLARATION.on(redeclaration.getFirst(), redeclaration.getSecond().asString())); } } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/DeclarationsChecker.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/DeclarationsChecker.java index 8f81456e19e..8e152184462 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/DeclarationsChecker.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/DeclarationsChecker.java @@ -280,7 +280,7 @@ public class DeclarationsChecker { boolean inEnum = classDescriptor.getKind() == ClassKind.ENUM_CLASS; boolean inAbstractClass = classDescriptor.getModality() == Modality.ABSTRACT; if (hasAbstractModifier && !inAbstractClass && !inEnum) { - trace.report(ABSTRACT_FUNCTION_IN_NON_ABSTRACT_CLASS.on(function, functionDescriptor.getName().getName(), classDescriptor)); + trace.report(ABSTRACT_FUNCTION_IN_NON_ABSTRACT_CLASS.on(function, functionDescriptor.getName().asString(), classDescriptor)); } if (hasAbstractModifier && inTrait) { trace.report(ABSTRACT_MODIFIER_IN_TRAIT.on(function)); diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/DescriptorUtils.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/DescriptorUtils.java index 73d15c0171f..5a48b391d44 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/DescriptorUtils.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/DescriptorUtils.java @@ -363,7 +363,7 @@ public class DescriptorUtils { @NotNull public static Name getClassObjectName(@NotNull Name className) { - return getClassObjectName(className.getName()); + return getClassObjectName(className.asString()); } @NotNull @@ -405,7 +405,7 @@ public class DescriptorUtils { String typeSuffix = rendererForTypesIfNecessary == null ? "" : ": " + rendererForTypesIfNecessary.renderType(value.getType(KotlinBuiltIns.getInstance())); - resultList.add(entry.getKey().getName().getName() + " = " + value.toString() + typeSuffix); + resultList.add(entry.getKey().getName().asString() + " = " + value.toString() + typeSuffix); } Collections.sort(resultList); return resultList; @@ -536,14 +536,14 @@ public class DescriptorUtils { public static boolean isEnumValueOfMethod(@NotNull FunctionDescriptor functionDescriptor) { List methodTypeParameters = functionDescriptor.getValueParameters(); JetType nullableString = TypeUtils.makeNullable(KotlinBuiltIns.getInstance().getStringType()); - return "valueOf".equals(functionDescriptor.getName().getName()) + return "valueOf".equals(functionDescriptor.getName().asString()) && methodTypeParameters.size() == 1 && JetTypeChecker.INSTANCE.isSubtypeOf(methodTypeParameters.get(0).getType(), nullableString); } public static boolean isEnumValuesMethod(@NotNull FunctionDescriptor functionDescriptor) { List methodTypeParameters = functionDescriptor.getValueParameters(); - return "values".equals(functionDescriptor.getName().getName()) + return "values".equals(functionDescriptor.getName().asString()) && methodTypeParameters.isEmpty(); } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/ImportPath.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/ImportPath.java index 8a3b2767337..74d44af8791 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/ImportPath.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/ImportPath.java @@ -50,12 +50,12 @@ public final class ImportPath { } public String getPathStr() { - return fqName.getFqName() + (isAllUnder ? ".*" : ""); + return fqName.asString() + (isAllUnder ? ".*" : ""); } @Override public String toString() { - return getPathStr() + (alias != null ? " as " + alias.getName() : ""); + return getPathStr() + (alias != null ? " as " + alias.asString() : ""); } @NotNull diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/OverloadResolver.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/OverloadResolver.java index 77092aee56f..b6fa118fe2d 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/OverloadResolver.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/OverloadResolver.java @@ -75,7 +75,7 @@ public class OverloadResolver { } Key(NamespaceDescriptor namespaceDescriptor, Name name) { - this(DescriptorUtils.getFQName(namespaceDescriptor).getFqName(), name); + this(DescriptorUtils.getFQName(namespaceDescriptor).asString(), name); } public String getNamespace() { @@ -149,7 +149,7 @@ public class OverloadResolver { } if (jetClass instanceof JetObjectDeclaration) { // must be class object - name = classDescriptor.getContainingDeclaration().getName().getName(); + name = classDescriptor.getContainingDeclaration().getName().asString(); return "class object " + name; } // safe @@ -223,7 +223,7 @@ public class OverloadResolver { CallableMemberDescriptor memberDescriptor = redeclaration.getSecond(); JetDeclaration jetDeclaration = redeclaration.getFirst(); if (memberDescriptor instanceof PropertyDescriptor) { - trace.report(Errors.REDECLARATION.on(jetDeclaration, memberDescriptor.getName().getName())); + trace.report(Errors.REDECLARATION.on(jetDeclaration, memberDescriptor.getName().asString())); } else { trace.report(Errors.CONFLICTING_OVERLOADS.on(jetDeclaration, memberDescriptor, functionContainer)); diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/OverrideResolver.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/OverrideResolver.java index ce6fce5853b..e1bca7991dd 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/OverrideResolver.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/OverrideResolver.java @@ -155,7 +155,7 @@ public class OverrideResolver { public void conflict(@NotNull CallableMemberDescriptor fromSuper, @NotNull CallableMemberDescriptor fromCurrent) { JetDeclaration declaration = (JetDeclaration) BindingContextUtils .descriptorToDeclaration(trace.getBindingContext(), fromCurrent); - trace.report(Errors.CONFLICTING_OVERLOADS.on(declaration, fromCurrent, fromCurrent.getContainingDeclaration().getName().getName())); + trace.report(Errors.CONFLICTING_OVERLOADS.on(declaration, fromCurrent, fromCurrent.getContainingDeclaration().getName().asString())); } }); } @@ -586,7 +586,7 @@ public class OverrideResolver { private void checkOverrideForMember(@NotNull final CallableMemberDescriptor declared) { if (declared.getKind() == CallableMemberDescriptor.Kind.SYNTHESIZED) { // TODO: this should be replaced soon by a framework of synthesized member generation tools - if (declared.getName().getName().startsWith(DescriptorResolver.COMPONENT_FUNCTION_NAME_PREFIX)) { + if (declared.getName().asString().startsWith(DescriptorResolver.COMPONENT_FUNCTION_NAME_PREFIX)) { checkOverrideForComponentFunction(declared); } return; diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/TraceBasedRedeclarationHandler.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/TraceBasedRedeclarationHandler.java index 62b7f5f80c8..4d58f1a80b5 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/TraceBasedRedeclarationHandler.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/TraceBasedRedeclarationHandler.java @@ -39,7 +39,7 @@ public class TraceBasedRedeclarationHandler implements RedeclarationHandler { private void report(DeclarationDescriptor descriptor) { PsiElement firstElement = BindingContextUtils.descriptorToDeclaration(trace.getBindingContext(), descriptor); if (firstElement != null) { - trace.report(REDECLARATION.on(firstElement, descriptor.getName().getName())); + trace.report(REDECLARATION.on(firstElement, descriptor.getName().asString())); } else { throw new IllegalStateException("No declaration found for " + descriptor); 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 61f7a61f92c..8c2e1ae7c59 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/TypeResolver.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/TypeResolver.java @@ -342,7 +342,7 @@ public class TypeResolver { assert size != 0 : "No projections possible for a nilary type constructor" + constructor; ClassifierDescriptor declarationDescriptor = constructor.getDeclarationDescriptor(); assert declarationDescriptor != null : "No declaration descriptor for type constructor " + constructor; - String name = declarationDescriptor.getName().getName(); + String name = declarationDescriptor.getName().asString(); return TypeUtils.getTypeNameAndStarProjectionsString(name, size); } 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 cfe2429f578..39bf46044f7 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 @@ -51,7 +51,6 @@ import org.jetbrains.jet.lexer.JetTokens; import javax.inject.Inject; import java.util.Collection; import java.util.Collections; -import java.util.EnumSet; import java.util.List; import static org.jetbrains.jet.lang.descriptors.ReceiverParameterDescriptor.NO_RECEIVER_PARAMETER; @@ -100,7 +99,7 @@ public class CallResolver { Name referencedName = nameExpression.getReferencedNameAsName(); List> callableDescriptorCollectors = Lists.newArrayList(); if (nameExpression.getReferencedNameElementType() == JetTokens.FIELD_IDENTIFIER) { - referencedName = Name.identifier(referencedName.getName().substring(1)); + referencedName = Name.identifier(referencedName.asString().substring(1)); callableDescriptorCollectors.add(CallableDescriptorCollectors.PROPERTIES); } else { diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/tasks/TracingStrategyImpl.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/tasks/TracingStrategyImpl.java index 28a2d4e5ada..07b192aa225 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/tasks/TracingStrategyImpl.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/tasks/TracingStrategyImpl.java @@ -178,7 +178,7 @@ public class TracingStrategyImpl implements TracingStrategy { JetExpression left = binaryExpression.getLeft(); JetExpression right = binaryExpression.getRight(); if (left != null && right != null) { - trace.report(UNSAFE_INFIX_CALL.on(reference, left.getText(), operationString.getName(), right.getText())); + trace.report(UNSAFE_INFIX_CALL.on(reference, left.getText(), operationString.asString(), right.getText())); } } else { diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/lazy/descriptors/LazyClassMemberScope.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/lazy/descriptors/LazyClassMemberScope.java index a8b6be66903..90843cb75ad 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/lazy/descriptors/LazyClassMemberScope.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/lazy/descriptors/LazyClassMemberScope.java @@ -124,7 +124,7 @@ public class LazyClassMemberScope extends AbstractLazyMemberScope { } @NotNull - public String getName() { + public String asString() { return name; } @@ -38,7 +38,7 @@ public final class Name implements Comparable { if (special) { throw new IllegalStateException("not identifier: " + this); } - return getName(); + return asString(); } public boolean isSpecial() { diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/scopes/WritableScopeImpl.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/scopes/WritableScopeImpl.java index 04a2e6e6772..7f1c06745b2 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/scopes/WritableScopeImpl.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/scopes/WritableScopeImpl.java @@ -176,7 +176,7 @@ public class WritableScopeImpl extends WritableScopeWithImports { checkMayWrite(); Map> labelsToDescriptors = getLabelsToDescriptors(); - LabelName name = new LabelName(descriptor.getName().getName()); + LabelName name = new LabelName(descriptor.getName().asString()); List declarationDescriptors = labelsToDescriptors.get(name); if (declarationDescriptors == null) { declarationDescriptors = new ArrayList(); @@ -481,7 +481,7 @@ public class WritableScopeImpl extends WritableScopeWithImports { public PropertyDescriptor getPropertyByFieldReference(@NotNull Name fieldName) { checkMayRead(); - if (!fieldName.getName().startsWith("$")) { + if (!fieldName.asString().startsWith("$")) { throw new IllegalStateException(); } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/BasicExpressionTypingVisitor.java b/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/BasicExpressionTypingVisitor.java index a6bee531df6..98c8207ad23 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/BasicExpressionTypingVisitor.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/BasicExpressionTypingVisitor.java @@ -792,13 +792,13 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor { if (operationType == JetTokens.PLUSPLUS || operationType == JetTokens.MINUSMINUS) { assert returnType != null : "returnType is null for " + resolutionResults.getResultingDescriptor(); if (JetTypeChecker.INSTANCE.isSubtypeOf(returnType, KotlinBuiltIns.getInstance().getUnitType())) { - result = ErrorUtils.createErrorType(KotlinBuiltIns.getInstance().getUnit().getName().getName()); + result = ErrorUtils.createErrorType(KotlinBuiltIns.getInstance().getUnit().getName().asString()); context.trace.report(INC_DEC_SHOULD_NOT_RETURN_UNIT.on(operationSign)); } else { JetType receiverType = receiver.getType(); if (!JetTypeChecker.INSTANCE.isSubtypeOf(returnType, receiverType)) { - context.trace.report(RESULT_TYPE_MISMATCH.on(operationSign, name.getName(), receiverType, returnType)); + context.trace.report(RESULT_TYPE_MISMATCH.on(operationSign, name.asString(), receiverType, returnType)); } else { context.trace.record(BindingContext.VARIABLE_REASSIGNMENT, expression); diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/ControlStructureTypingVisitor.java b/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/ControlStructureTypingVisitor.java index f3c71c4b93d..18f6e7f361e 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/ControlStructureTypingVisitor.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/ControlStructureTypingVisitor.java @@ -339,7 +339,7 @@ public class ControlStructureTypingVisitor extends ExpressionTypingVisitor { VariableDescriptor olderVariable = context.scope.getLocalVariable(variableDescriptor.getName()); if (olderVariable != null && DescriptorUtils.isLocal(context.scope.getContainingDeclaration(), olderVariable)) { PsiElement declaration = BindingContextUtils.descriptorToDeclaration(context.trace.getBindingContext(), variableDescriptor); - context.trace.report(Errors.NAME_SHADOWING.on(declaration, variableDescriptor.getName().getName())); + context.trace.report(Errors.NAME_SHADOWING.on(declaration, variableDescriptor.getName().asString())); } } return variableDescriptor; diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/DelegatedPropertyUtils.java b/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/DelegatedPropertyUtils.java index a80402c2e53..c852ed51ad2 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/DelegatedPropertyUtils.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/DelegatedPropertyUtils.java @@ -136,7 +136,7 @@ public class DelegatedPropertyUtils { List arguments = Lists.newArrayList(); arguments.add(createExpression(project, hasThis ? "this" : "null")); - arguments.add(createExpression(project, KotlinBuiltIns.getInstance().getPropertyMetadataImpl().getName().getName() + "(\"" + propertyDescriptor.getName().getName() + "\")")); + arguments.add(createExpression(project, KotlinBuiltIns.getInstance().getPropertyMetadataImpl().getName().asString() + "(\"" + propertyDescriptor.getName().asString() + "\")")); if (!isGet) { JetReferenceExpression fakeArgument = (JetReferenceExpression) createFakeExpressionOfType(context.expressionTypingServices.getProject(), trace, @@ -148,7 +148,7 @@ public class DelegatedPropertyUtils { } Name functionName = Name.identifier(isGet ? "get" : "set"); - JetReferenceExpression fakeCalleeExpression = createSimpleName(project, functionName.getName()); + JetReferenceExpression fakeCalleeExpression = createSimpleName(project, functionName.asString()); ExpressionReceiver receiver = new ExpressionReceiver(delegateExpression, delegateType); call = CallMaker.makeCallWithExpressions(fakeCalleeExpression, receiver, null, fakeCalleeExpression, arguments, Call.CallType.DEFAULT); diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/ExpressionTypingUtils.java b/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/ExpressionTypingUtils.java index 1e1d6e9f60d..6cd8259c5fb 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/ExpressionTypingUtils.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/ExpressionTypingUtils.java @@ -237,7 +237,7 @@ public class ExpressionTypingUtils { @NotNull JetScope scope, @NotNull ModuleDescriptor module ) { - JetImportDirective importDirective = JetPsiFactory.createImportDirective(project, callableFQN.getFqName()); + JetImportDirective importDirective = JetPsiFactory.createImportDirective(project, callableFQN.asString()); Collection declarationDescriptors = new QualifiedExpressionResolver() .analyseImportReference(importDirective, scope, new BindingTraceContext(), module); @@ -436,7 +436,7 @@ public class ExpressionTypingUtils { if (oldDescriptor != null && DescriptorUtils.isLocal(variableDescriptor.getContainingDeclaration(), oldDescriptor)) { PsiElement declaration = BindingContextUtils.descriptorToDeclaration(context.trace.getBindingContext(), variableDescriptor); if (declaration != null) { - context.trace.report(Errors.NAME_SHADOWING.on(declaration, variableDescriptor.getName().getName())); + context.trace.report(Errors.NAME_SHADOWING.on(declaration, variableDescriptor.getName().asString())); } } } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/types/lang/KotlinBuiltIns.java b/compiler/frontend/src/org/jetbrains/jet/lang/types/lang/KotlinBuiltIns.java index 3057b763e8f..fa9cd738836 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/types/lang/KotlinBuiltIns.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/types/lang/KotlinBuiltIns.java @@ -263,9 +263,9 @@ public class KotlinBuiltIns { } private void makePrimitive(PrimitiveType primitiveType) { - ClassDescriptor theClass = getBuiltInClassByName(primitiveType.getTypeName().getName()); + ClassDescriptor theClass = getBuiltInClassByName(primitiveType.getTypeName().asString()); JetType type = new JetTypeImpl(theClass); - ClassDescriptor arrayClass = getBuiltInClassByName(primitiveType.getArrayTypeName().getName()); + ClassDescriptor arrayClass = getBuiltInClassByName(primitiveType.getArrayTypeName().asString()); JetType arrayType = new JetTypeImpl(arrayClass); primitiveTypeToClass.put(primitiveType, theClass); @@ -335,7 +335,7 @@ public class KotlinBuiltIns { @NotNull public ClassDescriptor getPrimitiveClassDescriptor(@NotNull PrimitiveType type) { - return getBuiltInClassByName(type.getTypeName().getName()); + return getBuiltInClassByName(type.getTypeName().asString()); } @NotNull @@ -398,7 +398,7 @@ public class KotlinBuiltIns { @NotNull public ClassDescriptor getPrimitiveArrayClassDescriptor(@NotNull PrimitiveType type) { - return getBuiltInClassByName(type.getArrayTypeName().getName()); + return getBuiltInClassByName(type.getArrayTypeName().asString()); } @NotNull diff --git a/compiler/frontend/src/org/jetbrains/jet/util/QualifiedNamesUtil.java b/compiler/frontend/src/org/jetbrains/jet/util/QualifiedNamesUtil.java index 85384187dc5..9f78eb1dde8 100644 --- a/compiler/frontend/src/org/jetbrains/jet/util/QualifiedNamesUtil.java +++ b/compiler/frontend/src/org/jetbrains/jet/util/QualifiedNamesUtil.java @@ -39,8 +39,8 @@ public final class QualifiedNamesUtil { return true; } - String subpackageNameStr = subpackageName.getFqName(); - String packageNameStr = packageName.getFqName(); + String subpackageNameStr = subpackageName.asString(); + String packageNameStr = packageName.asString(); return (subpackageNameStr.startsWith(packageNameStr) && subpackageNameStr.charAt(packageNameStr.length()) == '.'); } @@ -54,7 +54,7 @@ public final class QualifiedNamesUtil { } public static boolean isOneSegmentFQN(@NotNull FqName fqn) { - return isOneSegmentFQN(fqn.getFqName()); + return isOneSegmentFQN(fqn.asString()); } @NotNull @@ -74,7 +74,7 @@ public final class QualifiedNamesUtil { return FqName.ROOT; } - String fqNameStr = fqName.getFqName(); + String fqNameStr = fqName.asString(); return new FqName(fqNameStr.substring(fqNameStr.indexOf('.'), fqNameStr.length())); } @@ -93,12 +93,12 @@ public final class QualifiedNamesUtil { @NotNull public static String tail(@NotNull FqName headFQN, @NotNull FqName fullFQN) { if (!isSubpackageOf(fullFQN, headFQN) || headFQN.isRoot()) { - return fullFQN.getFqName(); + return fullFQN.asString(); } return fullFQN.equals(headFQN) ? "" : - fullFQN.getFqName().substring(headFQN.getFqName().length() + 1); // (headFQN + '.').length + fullFQN.asString().substring(headFQN.asString().length() + 1); // (headFQN + '.').length } /** diff --git a/compiler/jet.as.java.psi/src/org/jetbrains/jet/asJava/JetLightPackage.java b/compiler/jet.as.java.psi/src/org/jetbrains/jet/asJava/JetLightPackage.java index 84548b8a917..aae66c8a4d9 100644 --- a/compiler/jet.as.java.psi/src/org/jetbrains/jet/asJava/JetLightPackage.java +++ b/compiler/jet.as.java.psi/src/org/jetbrains/jet/asJava/JetLightPackage.java @@ -31,7 +31,7 @@ public class JetLightPackage extends PsiPackageImpl { private final GlobalSearchScope scope; public JetLightPackage(PsiManager manager, FqName qualifiedName, GlobalSearchScope scope) { - super(manager, qualifiedName.getFqName()); + super(manager, qualifiedName.asString()); this.fqName = qualifiedName; this.scope = scope; } diff --git a/compiler/jet.as.java.psi/src/org/jetbrains/jet/asJava/KotlinJavaFileStubProvider.java b/compiler/jet.as.java.psi/src/org/jetbrains/jet/asJava/KotlinJavaFileStubProvider.java index d6f04fcad3f..2a4a9da49ee 100644 --- a/compiler/jet.as.java.psi/src/org/jetbrains/jet/asJava/KotlinJavaFileStubProvider.java +++ b/compiler/jet.as.java.psi/src/org/jetbrains/jet/asJava/KotlinJavaFileStubProvider.java @@ -189,7 +189,7 @@ public class KotlinJavaFileStubProvider implements CachedValueProvider stub) { - if (stub instanceof PsiClassStub && Comparing.equal(fqn.getFqName(), ((PsiClassStub) stub).getQualifiedName())) { + if (stub instanceof PsiClassStub && Comparing.equal(fqn.asString(), ((PsiClassStub) stub).getQualifiedName())) { return (PsiClass)stub.getPsi(); } @@ -222,7 +222,7 @@ public class LightClassUtil { if (jvmName != null) { Project project = declaration.getProject(); - String fqName = jvmName.getFqName().getFqName(); + String fqName = jvmName.getFqName().asString(); return JavaElementFinder.getInstance(project).findClass(fqName, GlobalSearchScope.allScope(project)); } } diff --git a/compiler/tests/org/jetbrains/jet/FqNameTest.java b/compiler/tests/org/jetbrains/jet/FqNameTest.java index 9397ca49cee..bcd2b1d8414 100644 --- a/compiler/tests/org/jetbrains/jet/FqNameTest.java +++ b/compiler/tests/org/jetbrains/jet/FqNameTest.java @@ -34,46 +34,46 @@ public class FqNameTest { public void pathRoot() { List path = new FqName("").path(); Assert.assertEquals(1, path.size()); - Assert.assertEquals("", path.get(0).getFqName()); + Assert.assertEquals("", path.get(0).asString()); } @Test public void pathLevel1() { List path = new FqName("com").path(); Assert.assertEquals(2, path.size()); - Assert.assertEquals("", path.get(0).getFqName()); - Assert.assertEquals("com", path.get(1).getFqName()); - Assert.assertEquals("com", path.get(1).shortName().getName()); - Assert.assertEquals("", path.get(1).parent().getFqName()); + Assert.assertEquals("", path.get(0).asString()); + Assert.assertEquals("com", path.get(1).asString()); + Assert.assertEquals("com", path.get(1).shortName().asString()); + Assert.assertEquals("", path.get(1).parent().asString()); } @Test public void pathLevel2() { List path = new FqName("com.jetbrains").path(); Assert.assertEquals(3, path.size()); - Assert.assertEquals("", path.get(0).getFqName()); - Assert.assertEquals("com", path.get(1).getFqName()); - Assert.assertEquals("com", path.get(1).shortName().getName()); - Assert.assertEquals("", path.get(1).parent().getFqName()); - Assert.assertEquals("com.jetbrains", path.get(2).getFqName()); - Assert.assertEquals("jetbrains", path.get(2).shortName().getName()); - Assert.assertEquals("com", path.get(2).parent().getFqName()); + Assert.assertEquals("", path.get(0).asString()); + Assert.assertEquals("com", path.get(1).asString()); + Assert.assertEquals("com", path.get(1).shortName().asString()); + Assert.assertEquals("", path.get(1).parent().asString()); + Assert.assertEquals("com.jetbrains", path.get(2).asString()); + Assert.assertEquals("jetbrains", path.get(2).shortName().asString()); + Assert.assertEquals("com", path.get(2).parent().asString()); } @Test public void pathLevel3() { List path = new FqName("com.jetbrains.jet").path(); Assert.assertEquals(4, path.size()); - Assert.assertEquals("", path.get(0).getFqName()); - Assert.assertEquals("com", path.get(1).getFqName()); - Assert.assertEquals("com", path.get(1).shortName().getName()); - Assert.assertEquals("", path.get(1).parent().getFqName()); - Assert.assertEquals("com.jetbrains", path.get(2).getFqName()); - Assert.assertEquals("jetbrains", path.get(2).shortName().getName()); - Assert.assertEquals("com", path.get(2).parent().getFqName()); - Assert.assertEquals("com.jetbrains.jet", path.get(3).getFqName()); - Assert.assertEquals("jet", path.get(3).shortName().getName()); - Assert.assertEquals("com.jetbrains", path.get(3).parent().getFqName()); + Assert.assertEquals("", path.get(0).asString()); + Assert.assertEquals("com", path.get(1).asString()); + Assert.assertEquals("com", path.get(1).shortName().asString()); + Assert.assertEquals("", path.get(1).parent().asString()); + Assert.assertEquals("com.jetbrains", path.get(2).asString()); + Assert.assertEquals("jetbrains", path.get(2).shortName().asString()); + Assert.assertEquals("com", path.get(2).parent().asString()); + Assert.assertEquals("com.jetbrains.jet", path.get(3).asString()); + Assert.assertEquals("jet", path.get(3).shortName().asString()); + Assert.assertEquals("com.jetbrains", path.get(3).parent().asString()); } @Test @@ -84,7 +84,7 @@ public class FqNameTest { List segments = new FqName(name).pathSegments(); List segmentsStrings = new ArrayList(); for (Name segment : segments) { - segmentsStrings.add(segment.getName()); + segmentsStrings.add(segment.asString()); } Assert.assertEquals(Arrays.asList(name.split("\\.")), segmentsStrings); } diff --git a/compiler/tests/org/jetbrains/jet/codegen/CodegenTestCase.java b/compiler/tests/org/jetbrains/jet/codegen/CodegenTestCase.java index b456eb546ad..ec039288105 100644 --- a/compiler/tests/org/jetbrains/jet/codegen/CodegenTestCase.java +++ b/compiler/tests/org/jetbrains/jet/codegen/CodegenTestCase.java @@ -137,7 +137,7 @@ public abstract class CodegenTestCase extends UsefulTestCase { @NotNull protected Class generateNamespaceClass() { JvmClassName name = NamespaceCodegen.getJVMClassNameForKotlinNs(JetPsiUtil.getFQName(myFiles.getPsiFile())); - return generateClass(name.getFqName().getFqName()); + return generateClass(name.getFqName().asString()); } @NotNull diff --git a/compiler/tests/org/jetbrains/jet/codegen/generated/AbstractBlackBoxCodegenTest.java b/compiler/tests/org/jetbrains/jet/codegen/generated/AbstractBlackBoxCodegenTest.java index 4f0b48715e8..b5a729460be 100644 --- a/compiler/tests/org/jetbrains/jet/codegen/generated/AbstractBlackBoxCodegenTest.java +++ b/compiler/tests/org/jetbrains/jet/codegen/generated/AbstractBlackBoxCodegenTest.java @@ -97,7 +97,7 @@ public abstract class AbstractBlackBoxCodegenTest extends CodegenTestCase { // If there are many files, the first of them should contain the 'box(): String' function JetFile firstFile = myFiles.getPsiFiles().get(0); - String fqName = NamespaceCodegen.getJVMClassNameForKotlinNs(JetPsiUtil.getFQName(firstFile)).getFqName().getFqName(); + String fqName = NamespaceCodegen.getJVMClassNameForKotlinNs(JetPsiUtil.getFQName(firstFile)).getFqName().asString(); try { Class namespaceClass = loader.loadClass(fqName); diff --git a/compiler/tests/org/jetbrains/jet/jvm/compiler/AbstractLoadCompiledKotlinTest.java b/compiler/tests/org/jetbrains/jet/jvm/compiler/AbstractLoadCompiledKotlinTest.java index ce0f25443a5..c9c3adaf9e8 100644 --- a/compiler/tests/org/jetbrains/jet/jvm/compiler/AbstractLoadCompiledKotlinTest.java +++ b/compiler/tests/org/jetbrains/jet/jvm/compiler/AbstractLoadCompiledKotlinTest.java @@ -54,7 +54,7 @@ public abstract class AbstractLoadCompiledKotlinTest extends TestCaseWithTmpdir NamespaceDescriptor namespaceFromSource = exhaust.getBindingContext().get(BindingContext.FQNAME_TO_NAMESPACE_DESCRIPTOR, TEST_PACKAGE_FQNAME); assert namespaceFromSource != null; - Assert.assertEquals("test", namespaceFromSource.getName().getName()); + Assert.assertEquals("test", namespaceFromSource.getName().asString()); NamespaceDescriptor namespaceFromClass = LoadDescriptorUtil.loadTestNamespaceAndBindingContextFromJavaRoot( tmpdir, getTestRootDisposable(), ConfigurationKind.JDK_ONLY).first; compareNamespaces(namespaceFromSource, namespaceFromClass, diff --git a/compiler/tests/org/jetbrains/jet/jvm/compiler/ExpectedLoadErrorsUtil.java b/compiler/tests/org/jetbrains/jet/jvm/compiler/ExpectedLoadErrorsUtil.java index 85f5bf952f8..07c2b97aa3b 100644 --- a/compiler/tests/org/jetbrains/jet/jvm/compiler/ExpectedLoadErrorsUtil.java +++ b/compiler/tests/org/jetbrains/jet/jvm/compiler/ExpectedLoadErrorsUtil.java @@ -28,7 +28,6 @@ import org.jetbrains.jet.lang.resolve.constants.CompileTimeConstant; import org.jetbrains.jet.lang.resolve.scopes.JetScope; import org.jetbrains.jet.renderer.DescriptorRenderer; -import java.io.File; import java.util.*; import static com.intellij.testFramework.UsefulTestCase.assertNotNull; @@ -85,7 +84,7 @@ public class ExpectedLoadErrorsUtil { ClassDescriptor annotationClass = (ClassDescriptor) annotation.getType().getConstructor().getDeclarationDescriptor(); assert annotationClass != null; - if (DescriptorUtils.getFQName(annotationClass).getFqName().equals(ANNOTATION_CLASS_NAME)) { + if (DescriptorUtils.getFQName(annotationClass).asString().equals(ANNOTATION_CLASS_NAME)) { // we expect exactly one annotation argument CompileTimeConstant argument = annotation.getAllValueArguments().values().iterator().next(); diff --git a/compiler/tests/org/jetbrains/jet/jvm/compiler/IdeaJdkAnnotationsReflectedTest.java b/compiler/tests/org/jetbrains/jet/jvm/compiler/IdeaJdkAnnotationsReflectedTest.java index e2819d69c09..e1df228e34e 100644 --- a/compiler/tests/org/jetbrains/jet/jvm/compiler/IdeaJdkAnnotationsReflectedTest.java +++ b/compiler/tests/org/jetbrains/jet/jvm/compiler/IdeaJdkAnnotationsReflectedTest.java @@ -79,7 +79,7 @@ public class IdeaJdkAnnotationsReflectedTest extends KotlinTestWithEnvironment { if (new FqName("org.jdom").equals(classFqName.parent())) continue; // filter unrelated jdom annotations if (new FqName("java.util.concurrent.TransferQueue").equals(classFqName)) continue; // filter JDK7-specific class - PsiClass psiClass = javaPsiFacade.findClass(classFqName.getFqName(), allScope); + PsiClass psiClass = javaPsiFacade.findClass(classFqName.asString(), allScope); assertNotNull("Class has annotation, but it is not found: " + classFqName, psiClass); psiClass.accept(new JavaRecursiveElementVisitor() { @@ -111,7 +111,7 @@ public class IdeaJdkAnnotationsReflectedTest extends KotlinTestWithEnvironment { if (hasAnnotation(ideaFakeAnnotationsManager, ideaOwner, AnnotationUtil.NOT_NULL)) { boolean kotlinHasNotNull = hasAnnotation(kotlinFakeAnnotationsManager, kotlinOwner, AnnotationUtil.NOT_NULL); boolean kotlinHasKotlinSignature = hasAnnotation(kotlinFakeAnnotationsManager, kotlinOwner, - JvmStdlibNames.KOTLIN_SIGNATURE.getFqName().getFqName()); + JvmStdlibNames.KOTLIN_SIGNATURE.getFqName().asString()); if (kotlinOwner == ideaOwner && kotlinHasNotNull || kotlinHasKotlinSignature) { // good } diff --git a/compiler/tests/org/jetbrains/jet/jvm/compiler/JvmClassNameTest.java b/compiler/tests/org/jetbrains/jet/jvm/compiler/JvmClassNameTest.java index 464387b34a1..073d95b9e91 100644 --- a/compiler/tests/org/jetbrains/jet/jvm/compiler/JvmClassNameTest.java +++ b/compiler/tests/org/jetbrains/jet/jvm/compiler/JvmClassNameTest.java @@ -61,8 +61,8 @@ public class JvmClassNameTest { ) { JvmClassName mapEntryName = JvmClassName.bySignatureName(className); assertEquals(innerClassName, mapEntryName.getInternalName()); - assertEquals(fqName, mapEntryName.getFqName().getFqName()); - assertEquals(outerClassName, mapEntryName.getOuterClassFqName().getFqName()); + assertEquals(fqName, mapEntryName.getFqName().asString()); + assertEquals(outerClassName, mapEntryName.getOuterClassFqName().asString()); assertEquals(innerClassNameList, mapEntryName.getInnerClassNameList()); } } diff --git a/compiler/tests/org/jetbrains/jet/test/util/NamespaceComparator.java b/compiler/tests/org/jetbrains/jet/test/util/NamespaceComparator.java index e89935e7fd4..ad16bcc839f 100644 --- a/compiler/tests/org/jetbrains/jet/test/util/NamespaceComparator.java +++ b/compiler/tests/org/jetbrains/jet/test/util/NamespaceComparator.java @@ -131,7 +131,7 @@ public class NamespaceComparator { private boolean shouldSkip(@NotNull DeclarationDescriptor subDescriptor) { return subDescriptor.getContainingDeclaration() instanceof ClassDescriptor && subDescriptor instanceof FunctionDescriptor - && JAVA_OBJECT_METHOD_NAMES.contains(subDescriptor.getName().getName()) + && JAVA_OBJECT_METHOD_NAMES.contains(subDescriptor.getName().asString()) && !conf.includeMethodsOfJavaObject || subDescriptor instanceof NamespaceDescriptor && !conf.recurseIntoPackage.apply(DescriptorUtils.getFQName(subDescriptor)); diff --git a/generators/org/jetbrains/jet/generators/jvm/GenerateJavaToKotlinMethodMap.java b/generators/org/jetbrains/jet/generators/jvm/GenerateJavaToKotlinMethodMap.java index 933ef159530..429c88b11c0 100644 --- a/generators/org/jetbrains/jet/generators/jvm/GenerateJavaToKotlinMethodMap.java +++ b/generators/org/jetbrains/jet/generators/jvm/GenerateJavaToKotlinMethodMap.java @@ -53,7 +53,7 @@ import static org.jetbrains.jet.lang.resolve.java.JavaToKotlinMethodMap.serializ public class GenerateJavaToKotlinMethodMap { - public static final String BUILTINS_FQNAME_PREFIX = KotlinBuiltIns.BUILT_INS_PACKAGE_FQ_NAME.getFqName() + "."; + public static final String BUILTINS_FQNAME_PREFIX = KotlinBuiltIns.BUILT_INS_PACKAGE_FQ_NAME.asString() + "."; public static void main(String[] args) throws IOException { CompilerConfiguration configuration = new CompilerConfiguration(); @@ -207,7 +207,7 @@ public class GenerateJavaToKotlinMethodMap { private void appendBeforeClass(@NotNull ClassDescriptor kotlinClass, @NotNull PsiClass psiClass) { String psiFqName = psiClass.getQualifiedName(); - String kotlinFqName = DescriptorUtils.getFQName(kotlinClass).toSafe().getFqName(); + String kotlinFqName = DescriptorUtils.getFQName(kotlinClass).toSafe().asString(); assert kotlinFqName.startsWith(BUILTINS_FQNAME_PREFIX); String kotlinSubQualifiedName = kotlinFqName.substring(BUILTINS_FQNAME_PREFIX.length()); diff --git a/idea/src/org/jetbrains/jet/plugin/JetPluginUtil.java b/idea/src/org/jetbrains/jet/plugin/JetPluginUtil.java index f04c8801db8..9d19e277e00 100644 --- a/idea/src/org/jetbrains/jet/plugin/JetPluginUtil.java +++ b/idea/src/org/jetbrains/jet/plugin/JetPluginUtil.java @@ -44,11 +44,11 @@ public class JetPluginUtil { LinkedList fullName = Lists.newLinkedList(); while (declarationDescriptor != null && !(declarationDescriptor instanceof ModuleDescriptor)) { - fullName.addFirst(declarationDescriptor.getName().getName()); + fullName.addFirst(declarationDescriptor.getName().asString()); declarationDescriptor = declarationDescriptor.getContainingDeclaration(); } assert fullName.size() > 0; - if (JavaDescriptorResolver.JAVA_ROOT.getName().equals(fullName.getFirst())) { + if (JavaDescriptorResolver.JAVA_ROOT.asString().equals(fullName.getFirst())) { fullName.removeFirst(); } return fullName; diff --git a/idea/src/org/jetbrains/jet/plugin/actions/JetAddImportAction.java b/idea/src/org/jetbrains/jet/plugin/actions/JetAddImportAction.java index 80430ad6ce4..57bbd85402b 100644 --- a/idea/src/org/jetbrains/jet/plugin/actions/JetAddImportAction.java +++ b/idea/src/org/jetbrains/jet/plugin/actions/JetAddImportAction.java @@ -107,7 +107,7 @@ public class JetAddImportAction implements QuestionAction { return FINAL_CHOICE; } - List toExclude = AddImportAction.getAllExcludableStrings(selectedValue.getFqName()); + List toExclude = AddImportAction.getAllExcludableStrings(selectedValue.asString()); return new BaseListPopupStep(null, toExclude) { @NotNull @@ -135,7 +135,7 @@ public class JetAddImportAction implements QuestionAction { @NotNull @Override public String getTextFor(FqName value) { - return value.getFqName(); + return value.asString(); } @Override diff --git a/idea/src/org/jetbrains/jet/plugin/caches/JetGotoClassContributor.java b/idea/src/org/jetbrains/jet/plugin/caches/JetGotoClassContributor.java index 58d6c0e95b8..ac98c103b4a 100644 --- a/idea/src/org/jetbrains/jet/plugin/caches/JetGotoClassContributor.java +++ b/idea/src/org/jetbrains/jet/plugin/caches/JetGotoClassContributor.java @@ -39,7 +39,7 @@ public class JetGotoClassContributor implements GotoClassContributor { JetNamedDeclaration jetClass = (JetNamedDeclaration) item; FqName name = JetPsiUtil.getFQName(jetClass); if (name != null) { - return name.getFqName(); + return name.asString(); } } diff --git a/idea/src/org/jetbrains/jet/plugin/caches/JetShortNamesCache.java b/idea/src/org/jetbrains/jet/plugin/caches/JetShortNamesCache.java index 2993f177059..38abadfafcf 100644 --- a/idea/src/org/jetbrains/jet/plugin/caches/JetShortNamesCache.java +++ b/idea/src/org/jetbrains/jet/plugin/caches/JetShortNamesCache.java @@ -107,7 +107,7 @@ public class JetShortNamesCache extends PsiShortNamesCache { Collection fqNames = packageClasses.get(name); if (!fqNames.isEmpty()) { for (FqName fqName : fqNames) { - PsiClass psiClass = JavaElementFinder.getInstance(project).findClass(fqName.getFqName(), scope); + PsiClass psiClass = JavaElementFinder.getInstance(project).findClass(fqName.asString(), scope); if (psiClass != null) { result.add(psiClass); } @@ -123,10 +123,10 @@ public class JetShortNamesCache extends PsiShortNamesCache { for (JetClassOrObject classOrObject : classOrObjects) { FqName fqName = JetPsiUtil.getFQName(classOrObject); if (fqName != null) { - assert fqName.shortName().getName().equals(name) : "A declaration obtained from index has non-matching name:\n" + + assert fqName.shortName().asString().equals(name) : "A declaration obtained from index has non-matching name:\n" + "in index: " + name + "\n" + "declared: " + fqName.shortName() + "(" + fqName + ")"; - PsiClass psiClass = JavaElementFinder.getInstance(project).findClass(fqName.getFqName(), scope); + PsiClass psiClass = JavaElementFinder.getInstance(project).findClass(fqName.asString(), scope); if (psiClass != null) { result.add(psiClass); } @@ -230,7 +230,7 @@ public class JetShortNamesCache extends PsiShortNamesCache { Set result = Sets.newHashSet(); Collection topLevelFunctionPrototypes = JetFromJavaDescriptorHelper.getTopLevelFunctionPrototypesByName( - referenceName.getName(), project, scope); + referenceName.asString(), project, scope); for (PsiMethod method : topLevelFunctionPrototypes) { FqName functionFQN = JetFromJavaDescriptorHelper.getJetTopLevelDeclarationFQN(method); if (functionFQN != null) { @@ -246,7 +246,7 @@ public class JetShortNamesCache extends PsiShortNamesCache { } Set affectedPackages = Sets.newHashSet(); - Collection jetNamedFunctions = JetShortFunctionNameIndex.getInstance().get(referenceName.getName(), project, scope); + Collection jetNamedFunctions = JetShortFunctionNameIndex.getInstance().get(referenceName.asString(), project, scope); for (JetNamedFunction jetNamedFunction : jetNamedFunctions) { PsiFile containingFile = jetNamedFunction.getContainingFile(); if (containingFile instanceof JetFile) { @@ -354,7 +354,7 @@ public class JetShortNamesCache extends PsiShortNamesCache { for (String fqName : JetFullClassNameIndex.getInstance().getAllKeys(project)) { FqName classFQName = new FqName(fqName); - if (acceptedShortNameCondition.value(classFQName.shortName().getName())) { + if (acceptedShortNameCondition.value(classFQName.shortName().asString())) { classDescriptors.addAll(getJetClassesDescriptorsByFQName(analyzer, classFQName)); } } @@ -364,7 +364,7 @@ public class JetShortNamesCache extends PsiShortNamesCache { private Collection getJetClassesDescriptorsByFQName(@NotNull KotlinCodeAnalyzer analyzer, @NotNull FqName classFQName) { Collection jetClassOrObjects = JetFullClassNameIndex.getInstance().get( - classFQName.getFqName(), project, GlobalSearchScope.allScope(project)); + classFQName.asString(), project, GlobalSearchScope.allScope(project)); if (jetClassOrObjects.isEmpty()) { // This fqn is absent in caches, dead or not in scope diff --git a/idea/src/org/jetbrains/jet/plugin/caches/resolve/IDELightClassGenerationSupport.java b/idea/src/org/jetbrains/jet/plugin/caches/resolve/IDELightClassGenerationSupport.java index a35c2cf6997..75365972681 100644 --- a/idea/src/org/jetbrains/jet/plugin/caches/resolve/IDELightClassGenerationSupport.java +++ b/idea/src/org/jetbrains/jet/plugin/caches/resolve/IDELightClassGenerationSupport.java @@ -31,11 +31,9 @@ import org.jetbrains.annotations.Nullable; import org.jetbrains.jet.asJava.KotlinLightClassForExplicitDeclaration; import org.jetbrains.jet.asJava.LightClassConstructionContext; import org.jetbrains.jet.asJava.LightClassGenerationSupport; -import org.jetbrains.jet.codegen.binding.PsiCodegenPredictor; import org.jetbrains.jet.lang.psi.JetClassOrObject; import org.jetbrains.jet.lang.psi.JetFile; import org.jetbrains.jet.lang.psi.JetPsiUtil; -import org.jetbrains.jet.lang.resolve.java.JvmClassName; import org.jetbrains.jet.lang.resolve.java.PackageClassUtils; import org.jetbrains.jet.lang.resolve.name.FqName; import org.jetbrains.jet.plugin.libraries.JetSourceNavigationHelper; @@ -70,13 +68,13 @@ public class IDELightClassGenerationSupport extends LightClassGenerationSupport @NotNull @Override public Collection findClassOrObjectDeclarations(@NotNull FqName fqName, @NotNull GlobalSearchScope searchScope) { - return JetFullClassNameIndex.getInstance().get(fqName.getFqName(), project, kotlinSources(searchScope)); + return JetFullClassNameIndex.getInstance().get(fqName.asString(), project, kotlinSources(searchScope)); } @NotNull @Override public Collection findFilesForPackage(@NotNull final FqName fqName, @NotNull GlobalSearchScope searchScope) { - Collection files = JetAllPackagesIndex.getInstance().get(fqName.getFqName(), project, kotlinSources(searchScope)); + Collection files = JetAllPackagesIndex.getInstance().get(fqName.asString(), project, kotlinSources(searchScope)); return ContainerUtil.filter(files, new Condition() { @Override public boolean value(JetFile file) { @@ -90,20 +88,20 @@ public class IDELightClassGenerationSupport extends LightClassGenerationSupport public Collection findClassOrObjectDeclarationsInPackage( @NotNull FqName packageFqName, @NotNull GlobalSearchScope searchScope ) { - return JetClassByPackageIndex.getInstance().get(packageFqName.getFqName(), project, kotlinSources(searchScope)); + return JetClassByPackageIndex.getInstance().get(packageFqName.asString(), project, kotlinSources(searchScope)); } @Override public boolean packageExists( @NotNull FqName fqName, @NotNull GlobalSearchScope scope ) { - return !JetAllPackagesIndex.getInstance().get(fqName.getFqName(), project, kotlinSources(scope)).isEmpty(); + return !JetAllPackagesIndex.getInstance().get(fqName.asString(), project, kotlinSources(scope)).isEmpty(); } @NotNull @Override public Collection getSubPackages(@NotNull FqName fqn, @NotNull GlobalSearchScope scope) { - Collection files = JetAllPackagesIndex.getInstance().get(fqn.getFqName(), project, kotlinSources(scope)); + Collection files = JetAllPackagesIndex.getInstance().get(fqn.asString(), project, kotlinSources(scope)); Set result = Sets.newHashSet(); for (JetFile file : files) { @@ -141,7 +139,7 @@ public class IDELightClassGenerationSupport extends LightClassGenerationSupport Collection files = findFilesForPackage(new FqName(packageFqName), scope); if (!files.isEmpty()) { FqName packageClassFqName = PackageClassUtils.getPackageClassFqName(new FqName(packageFqName)); - result.putValue(packageClassFqName.shortName().getName(), packageClassFqName); + result.putValue(packageClassFqName.shortName().asString(), packageClassFqName); } } diff --git a/idea/src/org/jetbrains/jet/plugin/codeInsight/ReferenceToClassesShortening.java b/idea/src/org/jetbrains/jet/plugin/codeInsight/ReferenceToClassesShortening.java index 6831179e9e2..d312e623cb3 100644 --- a/idea/src/org/jetbrains/jet/plugin/codeInsight/ReferenceToClassesShortening.java +++ b/idea/src/org/jetbrains/jet/plugin/codeInsight/ReferenceToClassesShortening.java @@ -81,7 +81,7 @@ public class ReferenceToClassesShortening { } private void compactReferenceToClass(JetUserType userType, ClassDescriptor targetClass) { - String name = targetClass.getName().getName(); + String name = targetClass.getName().asString(); DeclarationDescriptor parent = targetClass.getContainingDeclaration(); while (parent instanceof ClassDescriptor) { name = parent.getName() + "." + name; diff --git a/idea/src/org/jetbrains/jet/plugin/codeInsight/ktSignature/KotlinSignatureUtil.java b/idea/src/org/jetbrains/jet/plugin/codeInsight/ktSignature/KotlinSignatureUtil.java index 773d9e2f247..65af5942ce2 100644 --- a/idea/src/org/jetbrains/jet/plugin/codeInsight/ktSignature/KotlinSignatureUtil.java +++ b/idea/src/org/jetbrains/jet/plugin/codeInsight/ktSignature/KotlinSignatureUtil.java @@ -30,7 +30,7 @@ import org.jetbrains.jet.lang.resolve.java.JvmStdlibNames; import org.jetbrains.jet.lang.resolve.java.resolver.JavaAnnotationResolver; class KotlinSignatureUtil { - static final String KOTLIN_SIGNATURE_ANNOTATION = JvmStdlibNames.KOTLIN_SIGNATURE.getFqName().getFqName(); + static final String KOTLIN_SIGNATURE_ANNOTATION = JvmStdlibNames.KOTLIN_SIGNATURE.getFqName().asString(); private KotlinSignatureUtil() { } diff --git a/idea/src/org/jetbrains/jet/plugin/completion/DescriptorLookupConverter.java b/idea/src/org/jetbrains/jet/plugin/completion/DescriptorLookupConverter.java index 38f33ad85fb..c1116b5c19b 100644 --- a/idea/src/org/jetbrains/jet/plugin/completion/DescriptorLookupConverter.java +++ b/idea/src/org/jetbrains/jet/plugin/completion/DescriptorLookupConverter.java @@ -68,9 +68,9 @@ public final class DescriptorLookupConverter { } LookupElementBuilder element = LookupElementBuilder.create( - new JetLookupObject(descriptor, analyzer, declaration), descriptor.getName().getName()); + new JetLookupObject(descriptor, analyzer, declaration), descriptor.getName().asString()); - String presentableText = descriptor.getName().getName(); + String presentableText = descriptor.getName().asString(); String typeText = ""; String tailText = ""; boolean tailTextGrayed = true; diff --git a/idea/src/org/jetbrains/jet/plugin/editor/importOptimizer/JetImportOptimizer.java b/idea/src/org/jetbrains/jet/plugin/editor/importOptimizer/JetImportOptimizer.java index d528c38288d..814ded11302 100644 --- a/idea/src/org/jetbrains/jet/plugin/editor/importOptimizer/JetImportOptimizer.java +++ b/idea/src/org/jetbrains/jet/plugin/editor/importOptimizer/JetImportOptimizer.java @@ -227,7 +227,7 @@ public class JetImportOptimizer implements ImportOptimizer { for (JetSimpleNameExpression nameExpression : simpleNameExpressions) { Name referencedName = nameExpression.getReferencedNameAsName(); if (fqName == null) { - fqName = new FqName(referencedName.getName()); + fqName = new FqName(referencedName.asString()); } else { fqName = QualifiedNamesUtil.combine(fqName, referencedName); } diff --git a/idea/src/org/jetbrains/jet/plugin/highlighter/DeprecatedAnnotationVisitor.java b/idea/src/org/jetbrains/jet/plugin/highlighter/DeprecatedAnnotationVisitor.java index eac200f4299..cc209359ffd 100644 --- a/idea/src/org/jetbrains/jet/plugin/highlighter/DeprecatedAnnotationVisitor.java +++ b/idea/src/org/jetbrains/jet/plugin/highlighter/DeprecatedAnnotationVisitor.java @@ -247,7 +247,7 @@ public class DeprecatedAnnotationVisitor extends AfterAnalysisHighlightingVisito private static String getDescriptorString(@NotNull DeclarationDescriptor descriptor) { if (descriptor instanceof ClassDescriptor) { - return DescriptorUtils.getFQName(descriptor).getFqName(); + return DescriptorUtils.getFQName(descriptor).asString(); } else if (descriptor instanceof ConstructorDescriptor) { DeclarationDescriptor containingDeclaration = descriptor.getContainingDeclaration(); diff --git a/idea/src/org/jetbrains/jet/plugin/highlighter/IdeRenderers.java b/idea/src/org/jetbrains/jet/plugin/highlighter/IdeRenderers.java index 6f45895de6a..ebdaed8df0c 100644 --- a/idea/src/org/jetbrains/jet/plugin/highlighter/IdeRenderers.java +++ b/idea/src/org/jetbrains/jet/plugin/highlighter/IdeRenderers.java @@ -166,7 +166,7 @@ public class IdeRenderers { DeclarationDescriptor containingDeclaration = funDescriptor.getContainingDeclaration(); if (containingDeclaration != null) { FqNameUnsafe fqName = DescriptorUtils.getFQName(containingDeclaration); - stringBuilder.append(FqName.ROOT.equalsTo(fqName) ? "root package" : fqName.getFqName()); + stringBuilder.append(FqName.ROOT.equalsTo(fqName) ? "root package" : fqName.asString()); } stringBuilder.append(""); } diff --git a/idea/src/org/jetbrains/jet/plugin/libraries/JetSourceNavigationHelper.java b/idea/src/org/jetbrains/jet/plugin/libraries/JetSourceNavigationHelper.java index 36593693a47..e81aa42ffc6 100644 --- a/idea/src/org/jetbrains/jet/plugin/libraries/JetSourceNavigationHelper.java +++ b/idea/src/org/jetbrains/jet/plugin/libraries/JetSourceNavigationHelper.java @@ -255,7 +255,7 @@ public class JetSourceNavigationHelper { return null; } Collection classes = JetFullClassNameIndex.getInstance() - .get(classFqName.getFqName(), decompiledClassOrObject.getProject(), librarySourcesScope); + .get(classFqName.asString(), decompiledClassOrObject.getProject(), librarySourcesScope); if (classes.isEmpty()) { return null; } @@ -274,7 +274,7 @@ public class JetSourceNavigationHelper { //noinspection unchecked StringStubIndexExtension index = (StringStubIndexExtension) getIndexForTopLevelPropertyOrFunction(decompiledDeclaration); - return index.get(memberFqName.getFqName(), decompiledDeclaration.getProject(), librarySourcesScope); + return index.get(memberFqName.asString(), decompiledDeclaration.getProject(), librarySourcesScope); } private static StringStubIndexExtension getIndexForTopLevelPropertyOrFunction( @@ -360,7 +360,7 @@ public class JetSourceNavigationHelper { if (javaAnalog.getSort() != Type.OBJECT) { return null; } - String fqName = JvmClassName.byType(javaAnalog).getFqName().getFqName(); + String fqName = JvmClassName.byType(javaAnalog).getFqName().asString(); return JavaPsiFacade.getInstance(classOrObject.getProject()). findClass(fqName, GlobalSearchScope.allScope(classOrObject.getProject())); } @@ -378,7 +378,7 @@ public class JetSourceNavigationHelper { if (className == null) { return null; } - String fqName = className.getFqName().getFqName(); + String fqName = className.getFqName().asString(); JetFile file = (JetFile) classOrObject.getContainingFile(); diff --git a/idea/src/org/jetbrains/jet/plugin/libraries/MemberMatching.java b/idea/src/org/jetbrains/jet/plugin/libraries/MemberMatching.java index e4ccd6a6072..d04da005cba 100644 --- a/idea/src/org/jetbrains/jet/plugin/libraries/MemberMatching.java +++ b/idea/src/org/jetbrains/jet/plugin/libraries/MemberMatching.java @@ -84,10 +84,10 @@ public class MemberMatching { int parameterCount = type.getParameters().size(); if (type.getReceiverTypeRef() == null) { - return builtIns.getFunction(parameterCount).getName().getName(); + return builtIns.getFunction(parameterCount).getName().asString(); } else { - return builtIns.getExtensionFunction(parameterCount).getName().getName(); + return builtIns.getExtensionFunction(parameterCount).getName().asString(); } } diff --git a/idea/src/org/jetbrains/jet/plugin/quickfix/AddFunctionParametersFix.java b/idea/src/org/jetbrains/jet/plugin/quickfix/AddFunctionParametersFix.java index bb05a682110..2e2e8b4c1f8 100644 --- a/idea/src/org/jetbrains/jet/plugin/quickfix/AddFunctionParametersFix.java +++ b/idea/src/org/jetbrains/jet/plugin/quickfix/AddFunctionParametersFix.java @@ -65,7 +65,7 @@ public class AddFunctionParametersFix extends ChangeFunctionSignatureFix { String subjectSuffix = newParametersCnt > 1 ? "s" : ""; if (functionDescriptor instanceof ConstructorDescriptor) { - String className = functionDescriptor.getContainingDeclaration().getName().getName(); + String className = functionDescriptor.getContainingDeclaration().getName().asString(); if (hasTypeMismatches) return JetBundle.message("change.constructor.signature", className); @@ -73,7 +73,7 @@ public class AddFunctionParametersFix extends ChangeFunctionSignatureFix { return JetBundle.message("add.parameters.to.constructor", subjectSuffix, className); } else { - String functionName = functionDescriptor.getName().getName(); + String functionName = functionDescriptor.getName().asString(); if (hasTypeMismatches) return JetBundle.message("change.function.signature", functionName); @@ -95,7 +95,7 @@ public class AddFunctionParametersFix extends ChangeFunctionSignatureFix { JetExpression expression = argument.getArgumentExpression(); if (i < parameters.size()) { - validator.validateName(parameters.get(i).getName().getName()); + validator.validateName(parameters.get(i).getName().asString()); JetType argumentType = expression != null ? bindingContext.get(BindingContext.EXPRESSION_TYPE, expression) : null; JetType parameterType = parameters.get(i).getType(); diff --git a/idea/src/org/jetbrains/jet/plugin/quickfix/AddNameToArgumentFix.java b/idea/src/org/jetbrains/jet/plugin/quickfix/AddNameToArgumentFix.java index cc0f03947f3..cc53c6ad0e3 100644 --- a/idea/src/org/jetbrains/jet/plugin/quickfix/AddNameToArgumentFix.java +++ b/idea/src/org/jetbrains/jet/plugin/quickfix/AddNameToArgumentFix.java @@ -75,7 +75,7 @@ public class AddNameToArgumentFix extends JetIntentionAction { Set usedParameters = getUsedParameters(callElement, callableDescriptor); List names = Lists.newArrayList(); for (ValueParameterDescriptor parameter: callableDescriptor.getValueParameters()) { - String name = parameter.getName().getName(); + String name = parameter.getName().asString(); if (usedParameters.contains(name)) continue; if (type == null || JetTypeChecker.INSTANCE.isSubtypeOf(type, parameter.getType())) { names.add(name); @@ -98,7 +98,7 @@ public class AddNameToArgumentFix extends JetIntentionAction { } else if (isPositionalArgument) { ValueParameterDescriptor parameter = callableDescriptor.getValueParameters().get(idx); - usedParameters.add(parameter.getName().getName()); + usedParameters.add(parameter.getName().asString()); idx++; } } diff --git a/idea/src/org/jetbrains/jet/plugin/quickfix/AutoImportFix.java b/idea/src/org/jetbrains/jet/plugin/quickfix/AutoImportFix.java index 5b47b60d8d6..c4cdd8d9533 100644 --- a/idea/src/org/jetbrains/jet/plugin/quickfix/AutoImportFix.java +++ b/idea/src/org/jetbrains/jet/plugin/quickfix/AutoImportFix.java @@ -239,7 +239,7 @@ public class AutoImportFix extends JetHintAction implem } if (!ApplicationManager.getApplication().isUnitTestMode()) { - String hintText = ShowAutoImportPass.getMessage(suggestions.size() > 1, suggestions.iterator().next().getFqName()); + String hintText = ShowAutoImportPass.getMessage(suggestions.size() > 1, suggestions.iterator().next().asString()); HintManager.getInstance().showQuestionHint( editor, hintText, diff --git a/idea/src/org/jetbrains/jet/plugin/quickfix/ChangeFunctionReturnTypeFix.java b/idea/src/org/jetbrains/jet/plugin/quickfix/ChangeFunctionReturnTypeFix.java index f27f58cecf8..e8368c9a771 100644 --- a/idea/src/org/jetbrains/jet/plugin/quickfix/ChangeFunctionReturnTypeFix.java +++ b/idea/src/org/jetbrains/jet/plugin/quickfix/ChangeFunctionReturnTypeFix.java @@ -28,7 +28,6 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.jet.lang.descriptors.CallableDescriptor; import org.jetbrains.jet.lang.descriptors.FunctionDescriptor; -import org.jetbrains.jet.lang.descriptors.SimpleFunctionDescriptor; import org.jetbrains.jet.lang.diagnostics.Diagnostic; import org.jetbrains.jet.lang.diagnostics.DiagnosticWithParameters3; import org.jetbrains.jet.lang.psi.*; @@ -58,7 +57,7 @@ public class ChangeFunctionReturnTypeFix extends JetIntentionAction) diagnostic).getA().getName(); + String componentName = ((DiagnosticWithParameters3) diagnostic).getA().asString(); int componentIndex = Integer.valueOf(componentName.substring(DescriptorResolver.COMPONENT_FUNCTION_NAME_PREFIX.length())); JetMultiDeclaration multiDeclaration = QuickFixUtil.getParentElementOfType(diagnostic, JetMultiDeclaration.class); assert multiDeclaration != null : "COMPONENT_FUNCTION_RETURN_TYPE_MISMATCH reported on expression that is not within any multi declaration"; diff --git a/idea/src/org/jetbrains/jet/plugin/quickfix/ImportInsertHelper.java b/idea/src/org/jetbrains/jet/plugin/quickfix/ImportInsertHelper.java index 7f0e9c84c4a..1763374647c 100644 --- a/idea/src/org/jetbrains/jet/plugin/quickfix/ImportInsertHelper.java +++ b/idea/src/org/jetbrains/jet/plugin/quickfix/ImportInsertHelper.java @@ -87,7 +87,7 @@ public class ImportInsertHelper { boolean same = file.getManager().areElementsEquivalent(target, targetElement); if (!same) { - same = target instanceof PsiClass && importFqn.getFqName().equals(((PsiClass)target).getQualifiedName()); + same = target instanceof PsiClass && importFqn.asString().equals(((PsiClass)target).getQualifiedName()); } if (!same) { @@ -106,7 +106,7 @@ public class ImportInsertHelper { if (!same) { Document document = PsiDocumentManager.getInstance(file.getProject()).getDocument(file); TextRange refRange = reference.getElement().getTextRange(); - document.replaceString(refRange.getStartOffset(), refRange.getEndOffset(), importFqn.getFqName()); + document.replaceString(refRange.getStartOffset(), refRange.getEndOffset(), importFqn.asString()); } return; } diff --git a/idea/src/org/jetbrains/jet/plugin/quickfix/MakeOverriddenMemberOpenFix.java b/idea/src/org/jetbrains/jet/plugin/quickfix/MakeOverriddenMemberOpenFix.java index c3c286131dc..6dbe519d36a 100644 --- a/idea/src/org/jetbrains/jet/plugin/quickfix/MakeOverriddenMemberOpenFix.java +++ b/idea/src/org/jetbrains/jet/plugin/quickfix/MakeOverriddenMemberOpenFix.java @@ -69,7 +69,7 @@ public class MakeOverriddenMemberOpenFix extends JetIntentionAction 1) { LinkedHashSet possibleTypes = new LinkedHashSet(); for (ClassDescriptor klass : possibleClasses) { - possibleTypes.add(klass.getName().getName()); + possibleTypes.add(klass.getName().asString()); } buildAndShowTemplate(project, editor, file, replacedElements, possibleTypes); } @@ -120,7 +120,7 @@ public class MapPlatformClassToKotlinFix extends JetIntentionAction replaceUsagesWithFirstClass(Project project, List usages) { ClassDescriptor replacementClass = possibleClasses.iterator().next(); - String replacementClassName = replacementClass.getName().getName(); + String replacementClassName = replacementClass.getName().asString(); List replacedElements = new ArrayList(); for (JetUserType usage : usages) { JetTypeArgumentList typeArguments = usage.getTypeArgumentList(); diff --git a/idea/src/org/jetbrains/jet/plugin/quickfix/RemoveFunctionParametersFix.java b/idea/src/org/jetbrains/jet/plugin/quickfix/RemoveFunctionParametersFix.java index da0681e3e1d..94c116d31c4 100644 --- a/idea/src/org/jetbrains/jet/plugin/quickfix/RemoveFunctionParametersFix.java +++ b/idea/src/org/jetbrains/jet/plugin/quickfix/RemoveFunctionParametersFix.java @@ -44,7 +44,7 @@ public class RemoveFunctionParametersFix extends ChangeFunctionSignatureFix { @NotNull @Override public String getText() { - return JetBundle.message("remove.parameter", parameterToRemove.getName().getName()); + return JetBundle.message("remove.parameter", parameterToRemove.getName().asString()); } @Override diff --git a/idea/src/org/jetbrains/jet/plugin/quickfix/RenameParameterToMatchOverriddenMethodFix.java b/idea/src/org/jetbrains/jet/plugin/quickfix/RenameParameterToMatchOverriddenMethodFix.java index 7dd46e5e6f9..59c7b6fa088 100644 --- a/idea/src/org/jetbrains/jet/plugin/quickfix/RenameParameterToMatchOverriddenMethodFix.java +++ b/idea/src/org/jetbrains/jet/plugin/quickfix/RenameParameterToMatchOverriddenMethodFix.java @@ -54,9 +54,9 @@ public class RenameParameterToMatchOverriddenMethodFix extends JetIntentionActio } for (CallableDescriptor parameterFromSuperclass : parameterDescriptor.getOverriddenDescriptors()) { if (parameterFromSuperclassName == null) { - parameterFromSuperclassName = parameterFromSuperclass.getName().getName(); + parameterFromSuperclassName = parameterFromSuperclass.getName().asString(); } - else if (!parameterFromSuperclassName.equals(parameterFromSuperclass.getName().getName())) { + else if (!parameterFromSuperclassName.equals(parameterFromSuperclass.getName().asString())) { return false; } } diff --git a/idea/src/org/jetbrains/jet/plugin/refactoring/JetNameSuggester.java b/idea/src/org/jetbrains/jet/plugin/refactoring/JetNameSuggester.java index 13e05abc668..91a0a1effe0 100644 --- a/idea/src/org/jetbrains/jet/plugin/refactoring/JetNameSuggester.java +++ b/idea/src/org/jetbrains/jet/plugin/refactoring/JetNameSuggester.java @@ -153,7 +153,7 @@ public class JetNameSuggester { ClassDescriptor classDescriptor = TypeUtils.getClassDescriptor(argument); if (classDescriptor != null) { Name className = classDescriptor.getName(); - addName(result, "arrayOf" + StringUtil.capitalize(className.getName()) + "s", validator); + addName(result, "arrayOf" + StringUtil.capitalize(className.asString()) + "s", validator); } } } @@ -173,7 +173,7 @@ public class JetNameSuggester { ClassDescriptor classDescriptor = TypeUtils.getClassDescriptor(jetType); if (classDescriptor != null) { Name className = classDescriptor.getName(); - addCamelNames(result, className.getName(), validator); + addCamelNames(result, className.asString(), validator); } } diff --git a/idea/src/org/jetbrains/jet/plugin/refactoring/JetNameValidatorImpl.java b/idea/src/org/jetbrains/jet/plugin/refactoring/JetNameValidatorImpl.java index 4c194e63cd8..d041c3e9661 100644 --- a/idea/src/org/jetbrains/jet/plugin/refactoring/JetNameValidatorImpl.java +++ b/idea/src/org/jetbrains/jet/plugin/refactoring/JetNameValidatorImpl.java @@ -84,7 +84,7 @@ public class JetNameValidatorImpl extends JetNameValidator { Collection variants = TipsManager.getVariantsNoReceiver(expression, myBindingContext); for (DeclarationDescriptor variant : variants) { - if (variant.getName().getName().equals(name) && variant instanceof VariableDescriptor) { + if (variant.getName().asString().equals(name) && variant instanceof VariableDescriptor) { result.set(false); return; } diff --git a/idea/src/org/jetbrains/jet/plugin/refactoring/changeSignature/JetChangeInfo.java b/idea/src/org/jetbrains/jet/plugin/refactoring/changeSignature/JetChangeInfo.java index bb4a739b123..af2f35d2aff 100644 --- a/idea/src/org/jetbrains/jet/plugin/refactoring/changeSignature/JetChangeInfo.java +++ b/idea/src/org/jetbrains/jet/plugin/refactoring/changeSignature/JetChangeInfo.java @@ -132,7 +132,7 @@ public class JetChangeInfo implements ChangeInfo { for (int i = 0; i < parameters.size(); i++) { ValueParameterDescriptor oldParameter = parameters.get(i); - map.put(oldParameter.getName().getName(), i); + map.put(oldParameter.getName().asString(), i); } } diff --git a/idea/src/org/jetbrains/jet/plugin/refactoring/changeSignature/JetFunctionPlatformDescriptorImpl.java b/idea/src/org/jetbrains/jet/plugin/refactoring/changeSignature/JetFunctionPlatformDescriptorImpl.java index 52293387f0c..1a2fa088e39 100644 --- a/idea/src/org/jetbrains/jet/plugin/refactoring/changeSignature/JetFunctionPlatformDescriptorImpl.java +++ b/idea/src/org/jetbrains/jet/plugin/refactoring/changeSignature/JetFunctionPlatformDescriptorImpl.java @@ -47,7 +47,7 @@ public class JetFunctionPlatformDescriptorImpl implements JetFunctionPlatformDes @Override public JetParameterInfo fun(ValueParameterDescriptor param) { JetParameter parameter = valueParameters.get(param.getIndex()); - return new JetParameterInfo(param.getIndex(), param.getName().getName(), param.getType(), parameter.getDefaultValue(), parameter.getValOrVarNode()); + return new JetParameterInfo(param.getIndex(), param.getName().asString(), param.getType(), parameter.getDefaultValue(), parameter.getValOrVarNode()); } })); } @@ -55,11 +55,11 @@ public class JetFunctionPlatformDescriptorImpl implements JetFunctionPlatformDes @Override public String getName() { if (funDescriptor instanceof ConstructorDescriptor) - return funDescriptor.getContainingDeclaration().getName().getName(); + return funDescriptor.getContainingDeclaration().getName().asString(); else if (funDescriptor instanceof AnonymousFunctionDescriptor) return ""; else - return funDescriptor.getName().getName(); + return funDescriptor.getName().asString(); } @Override diff --git a/idea/src/org/jetbrains/jet/plugin/run/JetRunConfigurationProducer.java b/idea/src/org/jetbrains/jet/plugin/run/JetRunConfigurationProducer.java index e13c82952ef..f7cac7ca7c4 100644 --- a/idea/src/org/jetbrains/jet/plugin/run/JetRunConfigurationProducer.java +++ b/idea/src/org/jetbrains/jet/plugin/run/JetRunConfigurationProducer.java @@ -92,8 +92,8 @@ public class JetRunConfigurationProducer extends RuntimeConfigurationProducer im RunnerAndConfigurationSettings settings = cloneTemplateConfiguration(module.getProject(), context); JetRunConfiguration configuration = (JetRunConfiguration) settings.getConfiguration(); configuration.setModule(module); - configuration.setName(StringUtil.trimEnd(fqName.getFqName(), "." + PackageClassUtils.getPackageClassName(fqName))); - configuration.setRunClass(fqName.getFqName()); + configuration.setName(StringUtil.trimEnd(fqName.asString(), "." + PackageClassUtils.getPackageClassName(fqName))); + configuration.setRunClass(fqName.asString()); return settings; } @@ -111,7 +111,7 @@ public class JetRunConfigurationProducer extends RuntimeConfigurationProducer im for (RunnerAndConfigurationSettings existingConfiguration : existingConfigurations) { if (existingConfiguration.getType() instanceof JetRunConfigurationType) { JetRunConfiguration jetConfiguration = (JetRunConfiguration)existingConfiguration.getConfiguration(); - if (Comparing.equal(jetConfiguration.getRunClass(), startClassFQName.getFqName())) { + if (Comparing.equal(jetConfiguration.getRunClass(), startClassFQName.asString())) { if (Comparing.equal(location.getModule(), jetConfiguration.getConfigurationModule().getModule())) { return existingConfiguration; } diff --git a/idea/src/org/jetbrains/jet/plugin/search/KotlinAnnotatedElementsSearcher.java b/idea/src/org/jetbrains/jet/plugin/search/KotlinAnnotatedElementsSearcher.java index baff1388452..83e1ea859c4 100644 --- a/idea/src/org/jetbrains/jet/plugin/search/KotlinAnnotatedElementsSearcher.java +++ b/idea/src/org/jetbrains/jet/plugin/search/KotlinAnnotatedElementsSearcher.java @@ -78,7 +78,7 @@ public class KotlinAnnotatedElementsSearcher extends AnnotatedElementsSearcher { ClassifierDescriptor descriptor = annotationDescriptor.getType().getConstructor().getDeclarationDescriptor(); if (descriptor == null) return; - if (!(DescriptorUtils.getFQName(descriptor).getFqName().equals(annotationFQN))) return; + if (!(DescriptorUtils.getFQName(descriptor).asString().equals(annotationFQN))) return; if (parentOfType instanceof JetClass) { PsiClass lightClass = LightClassUtil.getPsiClass((JetClass) parentOfType); diff --git a/idea/src/org/jetbrains/jet/plugin/search/KotlinDirectInheritorsSearcher.java b/idea/src/org/jetbrains/jet/plugin/search/KotlinDirectInheritorsSearcher.java index cab4b6ee39c..aefbdb7ba67 100644 --- a/idea/src/org/jetbrains/jet/plugin/search/KotlinDirectInheritorsSearcher.java +++ b/idea/src/org/jetbrains/jet/plugin/search/KotlinDirectInheritorsSearcher.java @@ -68,7 +68,7 @@ public class KotlinDirectInheritorsSearcher extends QueryExecutorBase candidateClassNames = ImmutableList.of( kotlinPackageClassFqName, diff --git a/idea/tests/org/jetbrains/jet/plugin/codeInsight/OverrideImplementTest.java b/idea/tests/org/jetbrains/jet/plugin/codeInsight/OverrideImplementTest.java index b74c14560dc..80fe095353b 100644 --- a/idea/tests/org/jetbrains/jet/plugin/codeInsight/OverrideImplementTest.java +++ b/idea/tests/org/jetbrains/jet/plugin/codeInsight/OverrideImplementTest.java @@ -224,7 +224,7 @@ public class OverrideImplementTest extends LightCodeInsightFixtureTestCase { else { CallableMemberDescriptor candidateToOverride = null; for (CallableMemberDescriptor callable : descriptors) { - if (callable.getName().getName().equals(memberToOverride)) { + if (callable.getName().asString().equals(memberToOverride)) { if (candidateToOverride != null) { throw new IllegalStateException("more then one descriptor with name " + memberToOverride); } diff --git a/idea/tests/org/jetbrains/jet/plugin/libraries/NavigateToStdlibSourceRegressionTest.java b/idea/tests/org/jetbrains/jet/plugin/libraries/NavigateToStdlibSourceRegressionTest.java index 48a7b8d58ec..245b2d82e7f 100644 --- a/idea/tests/org/jetbrains/jet/plugin/libraries/NavigateToStdlibSourceRegressionTest.java +++ b/idea/tests/org/jetbrains/jet/plugin/libraries/NavigateToStdlibSourceRegressionTest.java @@ -22,7 +22,6 @@ import com.intellij.openapi.roots.ContentEntry; import com.intellij.openapi.roots.ModifiableRootModel; import com.intellij.openapi.roots.OrderRootType; import com.intellij.openapi.roots.libraries.Library; -import com.intellij.openapi.util.io.FileUtil; import com.intellij.openapi.vfs.VfsUtil; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.psi.PsiClass; @@ -33,7 +32,6 @@ import com.intellij.testFramework.LightPlatformTestCase; import com.intellij.testFramework.LightProjectDescriptor; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import org.jetbrains.jet.codegen.binding.PsiCodegenPredictor; import org.jetbrains.jet.lang.psi.JetClass; import org.jetbrains.jet.lang.psi.JetPsiUtil; import org.jetbrains.jet.plugin.JetWithJdkAndRuntimeLightProjectDescriptor; @@ -98,7 +96,7 @@ public class NavigateToStdlibSourceRegressionTest extends NavigateToLibraryRegre assertEquals(expectedName, ((PsiClass) element).getQualifiedName()); } else if (element instanceof JetClass) { - assertEquals(expectedName, JetPsiUtil.getFQName((JetClass) element).getFqName()); + assertEquals(expectedName, JetPsiUtil.getFQName((JetClass) element).asString()); } else { fail("Navigation element should be JetClass or PsiClass: " + element.getClass() + ", " + element.getText()); diff --git a/idea/tests/org/jetbrains/jet/plugin/references/BuiltInsReferenceResolverTest.java b/idea/tests/org/jetbrains/jet/plugin/references/BuiltInsReferenceResolverTest.java index 1bc918937d5..ccfd43a74f1 100644 --- a/idea/tests/org/jetbrains/jet/plugin/references/BuiltInsReferenceResolverTest.java +++ b/idea/tests/org/jetbrains/jet/plugin/references/BuiltInsReferenceResolverTest.java @@ -74,7 +74,7 @@ public class BuiltInsReferenceResolverTest extends ResolveTestCase { public void testAllReferencesResolved() { BuiltInsReferenceResolver referenceResolver = getProject().getComponent(BuiltInsReferenceResolver.class); for (DeclarationDescriptor descriptor : getAllStandardDescriptors(KotlinBuiltIns.getInstance().getBuiltInsPackage())) { - if (descriptor instanceof NamespaceDescriptor && "jet".equals(descriptor.getName().getName())) continue; + if (descriptor instanceof NamespaceDescriptor && "jet".equals(descriptor.getName().asString())) continue; assertNotNull("Can't resolve " + descriptor, referenceResolver.resolveStandardLibrarySymbol(descriptor)); } } diff --git a/j2k/src/org/jetbrains/jet/j2k/visitors/TypeVisitor.java b/j2k/src/org/jetbrains/jet/j2k/visitors/TypeVisitor.java index a1cfa977c02..32841871ae1 100644 --- a/j2k/src/org/jetbrains/jet/j2k/visitors/TypeVisitor.java +++ b/j2k/src/org/jetbrains/jet/j2k/visitors/TypeVisitor.java @@ -59,7 +59,7 @@ public class TypeVisitor extends PsiTypeVisitor implements J2KVisitor { IdentifierImpl identifier = new IdentifierImpl(name); if (name.equals("void")) { - myResult = new PrimitiveType(new IdentifierImpl(KotlinBuiltIns.getInstance().getUnit().getName().getName())); + myResult = new PrimitiveType(new IdentifierImpl(KotlinBuiltIns.getInstance().getUnit().getName().asString())); } else if (Node.PRIMITIVE_TYPES.contains(name)) { myResult = new PrimitiveType(new IdentifierImpl(AstUtil.upperFirstCharacter(name))); diff --git a/js/js.translator/src/org/jetbrains/k2js/translate/context/Namer.java b/js/js.translator/src/org/jetbrains/k2js/translate/context/Namer.java index 8de782ddb18..443c2293a2b 100644 --- a/js/js.translator/src/org/jetbrains/k2js/translate/context/Namer.java +++ b/js/js.translator/src/org/jetbrains/k2js/translate/context/Namer.java @@ -191,7 +191,7 @@ public final class Namer { return getRootNamespaceName(); } else { - return descriptor.getName().getName(); + return descriptor.getName().asString(); } } diff --git a/js/js.translator/src/org/jetbrains/k2js/translate/context/StaticContext.java b/js/js.translator/src/org/jetbrains/k2js/translate/context/StaticContext.java index 3d8780728c0..fc3e81d99e1 100644 --- a/js/js.translator/src/org/jetbrains/k2js/translate/context/StaticContext.java +++ b/js/js.translator/src/org/jetbrains/k2js/translate/context/StaticContext.java @@ -202,7 +202,7 @@ public final class StaticContext { @Nullable public JsName apply(@NotNull DeclarationDescriptor descriptor) { JsScope scope = getEnclosingScope(descriptor); - return scope.declareFreshName(descriptor.getName().getName()); + return scope.declareFreshName(descriptor.getName().asString()); } }; Rule constructorHasTheSameNameAsTheClass = new Rule() { @@ -224,7 +224,7 @@ public final class StaticContext { } PropertyAccessorDescriptor accessorDescriptor = (PropertyAccessorDescriptor) descriptor; - String propertyName = accessorDescriptor.getCorrespondingProperty().getName().getName(); + String propertyName = accessorDescriptor.getCorrespondingProperty().getName().asString(); if (isObjectDeclaration(bindingContext, accessorDescriptor.getCorrespondingProperty())) { return declareName(descriptor, propertyName); } @@ -244,7 +244,7 @@ public final class StaticContext { continue; } String name = getNameForAnnotatedObject(descriptor, annotation); - name = (name != null) ? name : descriptor.getName().getName(); + name = (name != null) ? name : descriptor.getName().asString(); return getEnclosingScope(descriptor).declareName(name); } return null; @@ -257,7 +257,7 @@ public final class StaticContext { return null; } - String name = descriptor.getName().getName(); + String name = descriptor.getName().asString(); if (!isEcma5() || JsDescriptorUtils.isAsPrivate((PropertyDescriptor) descriptor)) { name = Namer.getKotlinBackingFieldName(name); } @@ -272,7 +272,7 @@ public final class StaticContext { if (!(descriptor instanceof FunctionDescriptor)) { return null; } - if (!descriptor.getName().getName().equals("toString")) { + if (!descriptor.getName().asString().equals("toString")) { return null; } if (((FunctionDescriptor) descriptor).getValueParameters().isEmpty()) { diff --git a/js/js.translator/src/org/jetbrains/k2js/translate/context/TranslationContext.java b/js/js.translator/src/org/jetbrains/k2js/translate/context/TranslationContext.java index 4c74149e522..374123af50c 100644 --- a/js/js.translator/src/org/jetbrains/k2js/translate/context/TranslationContext.java +++ b/js/js.translator/src/org/jetbrains/k2js/translate/context/TranslationContext.java @@ -163,7 +163,7 @@ public class TranslationContext { //TODO: util @NotNull public JsStringLiteral nameToLiteral(@NotNull Named named) { - return program().getStringLiteral(named.getName().getName()); + return program().getStringLiteral(named.getName().asString()); } @Nullable diff --git a/js/js.translator/src/org/jetbrains/k2js/translate/expression/StringTemplateTranslator.java b/js/js.translator/src/org/jetbrains/k2js/translate/expression/StringTemplateTranslator.java index 3a27c02e8c7..baa7fed8e0f 100644 --- a/js/js.translator/src/org/jetbrains/k2js/translate/expression/StringTemplateTranslator.java +++ b/js/js.translator/src/org/jetbrains/k2js/translate/expression/StringTemplateTranslator.java @@ -96,10 +96,10 @@ public final class StringTemplateTranslator extends AbstractTranslator { return true; } //TODO: this is a hacky optimization, should use some generic approach - if (typeName.getName().equals("String")) { + if (typeName.asString().equals("String")) { return false; } - if (typeName.getName().equals("Int") && resultingExpression != null) { + if (typeName.asString().equals("Int") && resultingExpression != null) { return false; } return true; diff --git a/js/js.translator/src/org/jetbrains/k2js/translate/expression/foreach/ArrayForTranslator.java b/js/js.translator/src/org/jetbrains/k2js/translate/expression/foreach/ArrayForTranslator.java index 988625f8cd4..9d5c24db24e 100644 --- a/js/js.translator/src/org/jetbrains/k2js/translate/expression/foreach/ArrayForTranslator.java +++ b/js/js.translator/src/org/jetbrains/k2js/translate/expression/foreach/ArrayForTranslator.java @@ -50,8 +50,8 @@ public final class ArrayForTranslator extends ForTranslator { JetType rangeType = BindingUtils.getTypeForExpression(context.bindingContext(), loopRange); //TODO: better check //TODO: IMPORTANT! - return getClassDescriptorForType(rangeType).getName().getName().equals("Array") - || getClassDescriptorForType(rangeType).getName().getName().equals("IntArray"); + return getClassDescriptorForType(rangeType).getName().asString().equals("Array") + || getClassDescriptorForType(rangeType).getName().asString().equals("IntArray"); } @NotNull diff --git a/js/js.translator/src/org/jetbrains/k2js/translate/expression/foreach/RangeForTranslator.java b/js/js.translator/src/org/jetbrains/k2js/translate/expression/foreach/RangeForTranslator.java index 48a086959dd..34e01b75e84 100644 --- a/js/js.translator/src/org/jetbrains/k2js/translate/expression/foreach/RangeForTranslator.java +++ b/js/js.translator/src/org/jetbrains/k2js/translate/expression/foreach/RangeForTranslator.java @@ -48,7 +48,7 @@ public final class RangeForTranslator extends ForTranslator { JetType rangeType = BindingUtils.getTypeForExpression(context.bindingContext(), loopRange); //TODO: better check //TODO: long range? - return getClassDescriptorForType(rangeType).getName().getName().equals("IntRange"); + return getClassDescriptorForType(rangeType).getName().asString().equals("IntRange"); } @NotNull diff --git a/js/js.translator/src/org/jetbrains/k2js/translate/initializer/InitializerUtils.java b/js/js.translator/src/org/jetbrains/k2js/translate/initializer/InitializerUtils.java index 4e444bbe636..21e7dfc64db 100644 --- a/js/js.translator/src/org/jetbrains/k2js/translate/initializer/InitializerUtils.java +++ b/js/js.translator/src/org/jetbrains/k2js/translate/initializer/InitializerUtils.java @@ -66,10 +66,10 @@ public final class InitializerUtils { public static JsStatement create(Named named, JsExpression value, TranslationContext context) { JsExpression expression; if (context.isEcma5()) { - expression = JsAstUtils.defineProperty(named.getName().getName(), JsAstUtils.createDataDescriptor(value), context); + expression = JsAstUtils.defineProperty(named.getName().asString(), JsAstUtils.createDataDescriptor(value), context); } else { - expression = assignment(new JsNameRef(named.getName().getName(), JsLiteral.THIS), value); + expression = assignment(new JsNameRef(named.getName().asString(), JsLiteral.THIS), value); } return expression.makeStmt(); } diff --git a/js/js.translator/src/org/jetbrains/k2js/translate/intrinsic/functions/factories/PrimitiveBinaryOperationFIF.java b/js/js.translator/src/org/jetbrains/k2js/translate/intrinsic/functions/factories/PrimitiveBinaryOperationFIF.java index 5dbb4d127c7..b17feec05e1 100644 --- a/js/js.translator/src/org/jetbrains/k2js/translate/intrinsic/functions/factories/PrimitiveBinaryOperationFIF.java +++ b/js/js.translator/src/org/jetbrains/k2js/translate/intrinsic/functions/factories/PrimitiveBinaryOperationFIF.java @@ -112,7 +112,7 @@ public enum PrimitiveBinaryOperationFIF implements FunctionIntrinsicFactory { return RANGE_TO_INTRINSIC; } if (INT_WITH_BIT_OPERATIONS.apply(descriptor)) { - JsBinaryOperator op = BINARY_BITWISE_OPERATIONS.get(descriptor.getName().getName()); + JsBinaryOperator op = BINARY_BITWISE_OPERATIONS.get(descriptor.getName().asString()); if (op != null) { return new PrimitiveBinaryOperationFunctionIntrinsic(op); } @@ -128,7 +128,7 @@ public enum PrimitiveBinaryOperationFIF implements FunctionIntrinsicFactory { token = OperatorConventions.BOOLEAN_OPERATIONS.inverse().get(descriptor.getName()); } if (token == null) { - assert descriptor.getName().getName().equals("xor"); + assert descriptor.getName().asString().equals("xor"); return JsBinaryOperator.BIT_XOR; } return OperatorTable.getBinaryOperator(token); diff --git a/js/js.translator/src/org/jetbrains/k2js/translate/intrinsic/functions/factories/PrimitiveUnaryOperationFIF.java b/js/js.translator/src/org/jetbrains/k2js/translate/intrinsic/functions/factories/PrimitiveUnaryOperationFIF.java index af747aefb74..15de3d52f58 100644 --- a/js/js.translator/src/org/jetbrains/k2js/translate/intrinsic/functions/factories/PrimitiveUnaryOperationFIF.java +++ b/js/js.translator/src/org/jetbrains/k2js/translate/intrinsic/functions/factories/PrimitiveUnaryOperationFIF.java @@ -73,7 +73,7 @@ public enum PrimitiveUnaryOperationFIF implements FunctionIntrinsicFactory { Name name = descriptor.getName(); JsUnaryOperator jsOperator = null; - if ("inv".equals(name.getName())) { + if ("inv".equals(name.asString())) { jsOperator = JsUnaryOperator.BIT_NOT; } else { diff --git a/js/js.translator/src/org/jetbrains/k2js/translate/intrinsic/functions/patterns/NamePredicate.java b/js/js.translator/src/org/jetbrains/k2js/translate/intrinsic/functions/patterns/NamePredicate.java index 3235cbc7722..d309fcffe41 100644 --- a/js/js.translator/src/org/jetbrains/k2js/translate/intrinsic/functions/patterns/NamePredicate.java +++ b/js/js.translator/src/org/jetbrains/k2js/translate/intrinsic/functions/patterns/NamePredicate.java @@ -36,7 +36,7 @@ public final class NamePredicate implements Predicate { ContainerUtil.map(PrimitiveType.NUMBER_TYPES, new Function() { @Override public String fun(PrimitiveType type) { - return type.getTypeName().getName(); + return type.getTypeName().asString(); } })); diff --git a/js/js.translator/src/org/jetbrains/k2js/translate/reference/CallTranslator.java b/js/js.translator/src/org/jetbrains/k2js/translate/reference/CallTranslator.java index 6e12ed2223d..cec4259636f 100644 --- a/js/js.translator/src/org/jetbrains/k2js/translate/reference/CallTranslator.java +++ b/js/js.translator/src/org/jetbrains/k2js/translate/reference/CallTranslator.java @@ -93,7 +93,7 @@ public final class CallTranslator extends AbstractTranslator { //TODO: private boolean isInvoke() { - return descriptor.getName().getName().equals("invoke"); + return descriptor.getName().asString().equals("invoke"); } @NotNull diff --git a/js/js.translator/src/org/jetbrains/k2js/translate/utils/AnnotationsUtils.java b/js/js.translator/src/org/jetbrains/k2js/translate/utils/AnnotationsUtils.java index e7cebde182b..9f95c9a0759 100644 --- a/js/js.translator/src/org/jetbrains/k2js/translate/utils/AnnotationsUtils.java +++ b/js/js.translator/src/org/jetbrains/k2js/translate/utils/AnnotationsUtils.java @@ -88,7 +88,7 @@ public final class AnnotationsUtils { DeclarationDescriptor annotationDeclaration = annotationDescriptor.getType().getConstructor().getDeclarationDescriptor(); assert annotationDeclaration != null : "Annotation supposed to have a declaration"; - return DescriptorUtils.getFQName(annotationDeclaration).getFqName(); + return DescriptorUtils.getFQName(annotationDeclaration).asString(); } public static boolean isNativeObject(@NotNull DeclarationDescriptor descriptor) { From 7761d7d646471273d70c72bdebc6cac630603da9 Mon Sep 17 00:00:00 2001 From: Martin Lau Date: Wed, 22 May 2013 12:05:05 +1000 Subject: [PATCH 133/249] Added scanning for annotations.xml entries within maven dependencies --- libraries/tools/kotlin-maven-plugin/pom.xml | 7 +- .../kotlin/maven/KotlinCompileMojoBase.java | 77 +++++++++++++++++++ 2 files changed, 83 insertions(+), 1 deletion(-) diff --git a/libraries/tools/kotlin-maven-plugin/pom.xml b/libraries/tools/kotlin-maven-plugin/pom.xml index fdbd1c3d930..548c9a40337 100644 --- a/libraries/tools/kotlin-maven-plugin/pom.xml +++ b/libraries/tools/kotlin-maven-plugin/pom.xml @@ -20,7 +20,12 @@ maven-plugin - + + org.apache.maven + maven-core + ${maven.version} + + org.apache.maven maven-plugin-api ${maven.version} diff --git a/libraries/tools/kotlin-maven-plugin/src/main/java/org/jetbrains/kotlin/maven/KotlinCompileMojoBase.java b/libraries/tools/kotlin-maven-plugin/src/main/java/org/jetbrains/kotlin/maven/KotlinCompileMojoBase.java index 55d7324d7d7..79086a63022 100644 --- a/libraries/tools/kotlin-maven-plugin/src/main/java/org/jetbrains/kotlin/maven/KotlinCompileMojoBase.java +++ b/libraries/tools/kotlin-maven-plugin/src/main/java/org/jetbrains/kotlin/maven/KotlinCompileMojoBase.java @@ -18,10 +18,12 @@ package org.jetbrains.kotlin.maven; import com.google.common.base.Joiner; import com.intellij.openapi.util.text.StringUtil; +import org.apache.maven.artifact.Artifact; import org.apache.maven.plugin.AbstractMojo; import org.apache.maven.plugin.MojoExecutionException; import org.apache.maven.plugin.MojoFailureException; import org.apache.maven.plugin.logging.Log; +import org.apache.maven.project.MavenProject; import org.jetbrains.annotations.NotNull; import org.jetbrains.jet.cli.common.CLICompiler; import org.jetbrains.jet.cli.common.CompilerArguments; @@ -34,12 +36,17 @@ import org.jetbrains.jet.cli.jvm.K2JVMCompiler; import org.jetbrains.jet.cli.jvm.K2JVMCompilerArguments; import java.io.File; +import java.io.IOException; import java.lang.reflect.Field; import java.net.URL; import java.net.URLClassLoader; import java.util.ArrayList; import java.util.Arrays; +import java.util.Enumeration; import java.util.List; +import java.util.Set; +import java.util.zip.ZipEntry; +import java.util.zip.ZipFile; import static com.intellij.openapi.util.text.StringUtil.join; @@ -81,7 +88,17 @@ public abstract class KotlinCompileMojoBase extends AbstractMojo { // TODO not sure why this doesn't work :( // * @parameter default-value="$(project.basedir}/src/main/resources" + /** + * @parameter default-value="${project}" + * @required + * @readonly + */ + public MavenProject project; + /** + * @parameter default-value="true" + */ + public boolean scanForAnnotations; /** * Project classpath. @@ -296,6 +313,15 @@ public abstract class KotlinCompileMojoBase extends AbstractMojo { } } } + + if (scanForAnnotations) { + for (String path : scanAnnotations(log)) { + if (!list.contains(path)) { + list.add(path); + } + } + } + return join(list, File.pathSeparator); } @@ -320,4 +346,55 @@ public abstract class KotlinCompileMojoBase extends AbstractMojo { throw new RuntimeException("Could not get jdk annotations from Kotlin plugin`s classpath"); } + + protected List scanAnnotations(Log log) { + final List annotations = new ArrayList(); + + final Set artifacts = project.getArtifacts(); + for (Artifact artifact : artifacts) { + final File file = artifact.getFile(); + if (containsAnnotations(file, log)) { + log.info("Discovered kotlin annotations in: " + file); + try { + annotations.add(file.getCanonicalPath()); + } + catch (IOException e) { + log.warn("Error extracting canonical path from: " + file, e); + } + } + } + + return annotations; + } + + protected boolean containsAnnotations(File file, Log log) { + log.debug("Scanning for kotlin annotations in " + file); + + ZipFile zipFile = null; + try { + zipFile = new ZipFile(file); + + final Enumeration entries = zipFile.entries(); + while (entries.hasMoreElements()) { + String name = entries.nextElement().getName(); + if (name.endsWith("/annotations.xml")) { + return true; + } + } + } + catch (IOException e) { + log.warn("Error reading contents of jar: " + file, e); + } + finally { + if (zipFile != null) { + try { + zipFile.close(); + } + catch (IOException e) { + log.warn("Error closing: " + zipFile, e); + } + } + } + return false; + } } From ba90f07c8dbbd783dd7966c5bd9e159e195a6ff6 Mon Sep 17 00:00:00 2001 From: Evgeny Gerashchenko Date: Wed, 22 May 2013 20:52:09 +0400 Subject: [PATCH 134/249] Fixed compilation after renaming Name.getName() to asString() --- .../jetbrains/kotlin/doc/model/KotlinModel.kt | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/libraries/tools/kdoc/src/main/kotlin/org/jetbrains/kotlin/doc/model/KotlinModel.kt b/libraries/tools/kdoc/src/main/kotlin/org/jetbrains/kotlin/doc/model/KotlinModel.kt index 95e55797415..299c8512e6a 100644 --- a/libraries/tools/kdoc/src/main/kotlin/org/jetbrains/kotlin/doc/model/KotlinModel.kt +++ b/libraries/tools/kdoc/src/main/kotlin/org/jetbrains/kotlin/doc/model/KotlinModel.kt @@ -59,7 +59,7 @@ fun qualifiedName(descriptor: DeclarationDescriptor?): String { return "" } else { val parent = containerName(descriptor) - var name = descriptor.getName()?.getName() ?: "" + var name = descriptor.getName()?.asString() ?: "" if (name.startsWith("<")) { name = "" } @@ -385,7 +385,7 @@ class KModel(val context: BindingContext, val config: KDocConfig, val sourceDirs val descriptors = scope.getAllDescriptors() for (descriptor in descriptors) { if (descriptor is PropertyDescriptor) { - val name = descriptor.getName().getName() + val name = descriptor.getName().asString() val returnType = getType(descriptor.getReturnType()) if (returnType != null) { val receiver = descriptor.getReceiverParameter() @@ -413,7 +413,7 @@ class KModel(val context: BindingContext, val config: KDocConfig, val sourceDirs protected fun createFunction(owner: KClassOrPackage, descriptor: CallableDescriptor): KFunction? { val returnType = getType(descriptor.getReturnType()) if (returnType != null) { - val name = descriptor.getName().getName() + val name = descriptor.getName().asString() val parameters = ArrayList() val params = descriptor.getValueParameters() for (param in params) { @@ -450,7 +450,7 @@ class KModel(val context: BindingContext, val config: KDocConfig, val sourceDirs } protected fun createTypeParameter(descriptor: TypeParameterDescriptor): KTypeParameter? { - val name = descriptor.getName().getName() + val name = descriptor.getName().asString() val answer = KTypeParameter(name, descriptor, this) configureComments(answer, descriptor) return answer @@ -459,7 +459,7 @@ class KModel(val context: BindingContext, val config: KDocConfig, val sourceDirs protected fun createParameter(descriptor: ValueParameterDescriptor): KParameter? { val returnType = getType(descriptor.getReturnType()) if (returnType != null) { - val name = descriptor.getName().getName() + val name = descriptor.getName().asString() val answer = KParameter(descriptor, name, returnType) configureComments(answer, descriptor) return answer @@ -704,7 +704,7 @@ $highlight""" } fun getClass(classElement: ClassDescriptor): KClass? { - val name = classElement.getName().getName() + val name = classElement.getName().asString() var dec: DeclarationDescriptor? = classElement.getContainingDeclaration() while (dec != null) { val container = dec @@ -958,7 +958,7 @@ class KPackage(model: KModel, val descriptor: NamespaceDescriptor, fun toString() = "KPackage($name)" fun getClass(descriptor: ClassDescriptor): KClass { - val name = descriptor.getName().getName() + val name = descriptor.getName().asString() var created = false val klass = classMap.getOrPut(name) { created = true @@ -1074,7 +1074,7 @@ class KClass( val sourceInfo: SourceInfo?) : KClassOrPackage(pkg.model, descriptor), Comparable { - val simpleName = descriptor.getName().getName() + val simpleName = descriptor.getName().asString() var group: String = "Other" var annotations: List = arrayList() var typeParameters: MutableList = arrayList() @@ -1130,7 +1130,7 @@ class KClass( return $url } - public val name: String = pkg.qualifiedName(descriptor.getName().getName()) + public val name: String = pkg.qualifiedName(descriptor.getName().asString()) public val packageName: String = pkg.name From 3299957c0c85fe3548fb43f7883bc53f1b82d9aa Mon Sep 17 00:00:00 2001 From: Andrey Breslav Date: Wed, 22 May 2013 20:31:26 +0400 Subject: [PATCH 135/249] Support jps.kotlin.home --- compiler/util/src/org/jetbrains/jet/utils/PathUtil.java | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/compiler/util/src/org/jetbrains/jet/utils/PathUtil.java b/compiler/util/src/org/jetbrains/jet/utils/PathUtil.java index e17331e4f12..e895d7b83b8 100644 --- a/compiler/util/src/org/jetbrains/jet/utils/PathUtil.java +++ b/compiler/util/src/org/jetbrains/jet/utils/PathUtil.java @@ -49,6 +49,13 @@ public class PathUtil { @NotNull public static KotlinPaths getKotlinPathsForJpsPluginOrJpsTests() { + // When JPS is run on TeamCity, it can not rely on Kotlin plugin layout, + // so the path to Kotlin is specified in a system property + String jpsKotlinHome = System.getProperty("jps.kotlin.home"); + if (jpsKotlinHome != null) { + return new KotlinPathsFromHomeDir(new File(jpsKotlinHome)); + } + if ("true".equalsIgnoreCase(System.getProperty("kotlin.jps.tests"))) { return getKotlinPathsForDistDirectory(); } From 1a5c9430572eef7e390ce45168a5f535bb919c65 Mon Sep 17 00:00:00 2001 From: Andrey Breslav Date: Mon, 27 May 2013 13:55:05 +0400 Subject: [PATCH 136/249] Support jps.kotlin.home --- compiler/util/src/org/jetbrains/jet/utils/PathUtil.java | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/compiler/util/src/org/jetbrains/jet/utils/PathUtil.java b/compiler/util/src/org/jetbrains/jet/utils/PathUtil.java index e895d7b83b8..cbafebff153 100644 --- a/compiler/util/src/org/jetbrains/jet/utils/PathUtil.java +++ b/compiler/util/src/org/jetbrains/jet/utils/PathUtil.java @@ -44,18 +44,17 @@ public class PathUtil { @NotNull public static KotlinPaths getKotlinPathsForJpsPlugin() { - return new KotlinPathsFromHomeDir(getCompilerPathForJpsPlugin()); - } - - @NotNull - public static KotlinPaths getKotlinPathsForJpsPluginOrJpsTests() { // When JPS is run on TeamCity, it can not rely on Kotlin plugin layout, // so the path to Kotlin is specified in a system property String jpsKotlinHome = System.getProperty("jps.kotlin.home"); if (jpsKotlinHome != null) { return new KotlinPathsFromHomeDir(new File(jpsKotlinHome)); } + return new KotlinPathsFromHomeDir(getCompilerPathForJpsPlugin()); + } + @NotNull + public static KotlinPaths getKotlinPathsForJpsPluginOrJpsTests() { if ("true".equalsIgnoreCase(System.getProperty("kotlin.jps.tests"))) { return getKotlinPathsForDistDirectory(); } From e96cf045ddba580fb5e5e9c997b5153bfbf76468 Mon Sep 17 00:00:00 2001 From: Mikhael Bogdanov Date: Mon, 27 May 2013 14:38:05 +0400 Subject: [PATCH 137/249] KT-3652: Char is converted to Int when used inside string interpolation #KT-3652 Fixed --- .../backend/src/org/jetbrains/jet/codegen/AsmUtil.java | 4 ++-- .../src/org/jetbrains/jet/codegen/ExpressionCodegen.java | 3 ++- .../org/jetbrains/jet/codegen/intrinsics/ToString.java | 2 +- compiler/testData/codegen/box/strings/kt3652.kt | 9 +++++++++ .../codegen/generated/BlackBoxCodegenTestGenerated.java | 9 +++++++-- 5 files changed, 21 insertions(+), 6 deletions(-) create mode 100644 compiler/testData/codegen/box/strings/kt3652.kt diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/AsmUtil.java b/compiler/backend/src/org/jetbrains/jet/codegen/AsmUtil.java index 76d717a323b..8a818ac3f6d 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/AsmUtil.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/AsmUtil.java @@ -354,8 +354,8 @@ public class AsmUtil { v.invokevirtual("java/lang/StringBuilder", "append", "(" + type.getDescriptor() + ")Ljava/lang/StringBuilder;"); } - public static StackValue genToString(InstructionAdapter v, StackValue receiver) { - Type type = stringValueOfOrStringBuilderAppendType(receiver.type); + public static StackValue genToString(InstructionAdapter v, StackValue receiver, Type receiverType) { + Type type = stringValueOfOrStringBuilderAppendType(receiverType); receiver.put(type, v); v.invokestatic("java/lang/String", "valueOf", "(" + type.getDescriptor() + ")Ljava/lang/String;"); return StackValue.onStack(JAVA_STRING_TYPE); diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java index adb1cf703f6..46b869544f4 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java @@ -1173,7 +1173,8 @@ public class ExpressionCodegen extends JetVisitor implem JetStringTemplateEntry[] entries = expression.getEntries(); if (entries.length == 1 && entries[0] instanceof JetStringTemplateEntryWithExpression) { - return genToString(v, gen(entries[0].getExpression())); + JetExpression expr = entries[0].getExpression(); + return genToString(v, gen(expr), expressionType(expr)); } for (JetStringTemplateEntry entry : entries) { diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/ToString.java b/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/ToString.java index e9ba927ae5f..be44473606d 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/ToString.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/ToString.java @@ -40,6 +40,6 @@ public class ToString implements IntrinsicMethod { StackValue receiver, @NotNull GenerationState state ) { - return genToString(v, receiver); + return genToString(v, receiver, receiver.type); } } diff --git a/compiler/testData/codegen/box/strings/kt3652.kt b/compiler/testData/codegen/box/strings/kt3652.kt new file mode 100644 index 00000000000..f9e678089b8 --- /dev/null +++ b/compiler/testData/codegen/box/strings/kt3652.kt @@ -0,0 +1,9 @@ +fun box(): String { + var a = 'a' + + if ("${a++}x" != "ax") return "fail1" + + if ("${a++}" != "b") return "fail2" + + return "OK" +} diff --git a/compiler/tests/org/jetbrains/jet/codegen/generated/BlackBoxCodegenTestGenerated.java b/compiler/tests/org/jetbrains/jet/codegen/generated/BlackBoxCodegenTestGenerated.java index 2d7d964b432..aa30ff43a69 100644 --- a/compiler/tests/org/jetbrains/jet/codegen/generated/BlackBoxCodegenTestGenerated.java +++ b/compiler/tests/org/jetbrains/jet/codegen/generated/BlackBoxCodegenTestGenerated.java @@ -1546,8 +1546,8 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest { doTest("compiler/testData/codegen/box/defaultArguments/constructor/kt2852.kt"); } - } - + } + @TestMetadata("compiler/testData/codegen/box/defaultArguments/function") public static class Function extends AbstractBlackBoxCodegenTest { public void testAllFilesPresentInFunction() throws Exception { @@ -3686,6 +3686,11 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest { doTest("compiler/testData/codegen/box/strings/ea35743.kt"); } + @TestMetadata("kt3652.kt") + public void testKt3652() throws Exception { + doTest("compiler/testData/codegen/box/strings/kt3652.kt"); + } + @TestMetadata("kt881.kt") public void testKt881() throws Exception { doTest("compiler/testData/codegen/box/strings/kt881.kt"); From d4fc814d764bb332d0192e8f42a1b102d0c4d47e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Sapalski?= Date: Mon, 22 Apr 2013 15:26:54 +0200 Subject: [PATCH 138/249] Quickfix for NOTHING_TO_OVERRIDE: add function to one of supertypes. --- .../jetbrains/jet/plugin/JetBundle.properties | 7 +- .../JetAddFunctionToClassifierAction.java | 184 ++++++++++++++++++ .../DescriptorToDeclarationUtil.java | 7 +- .../quickfix/AddFunctionToSupertypeFix.java | 171 ++++++++++++++++ .../jet/plugin/quickfix/QuickFixes.java | 1 + .../nothingToOverride/afterAddFunction.kt | 8 + .../afterAddFunctionAbstractClass.kt | 7 + .../afterAddFunctionNoBody.kt | 8 + .../afterAddFunctionNonUnitReturnType.kt | 9 + .../afterAddFunctionTrait.kt | 7 + .../afterAddFunctionTwoSuperclasses.kt | 10 + .../afterAddFunctionTwoTraits.kt | 8 + .../afterNoOpenSuperFunction.kt | 11 -- .../nothingToOverride/beforeAddFunction.kt | 6 + .../beforeAddFunctionAbstractClass.kt | 6 + .../beforeAddFunctionNoBody.kt | 5 + .../beforeAddFunctionNonUnitReturnType.kt | 6 + .../beforeAddFunctionTrait.kt | 6 + .../beforeAddFunctionTwoSuperclasses.kt | 8 + .../beforeAddFunctionTwoTraits.kt | 6 + .../beforeNoOpenSuperFunction.kt | 1 + .../quickfix/QuickFixTestGenerated.java | 35 ++++ 22 files changed, 504 insertions(+), 13 deletions(-) create mode 100644 idea/src/org/jetbrains/jet/plugin/actions/JetAddFunctionToClassifierAction.java create mode 100644 idea/src/org/jetbrains/jet/plugin/quickfix/AddFunctionToSupertypeFix.java create mode 100644 idea/testData/quickfix/override/nothingToOverride/afterAddFunction.kt create mode 100644 idea/testData/quickfix/override/nothingToOverride/afterAddFunctionAbstractClass.kt create mode 100644 idea/testData/quickfix/override/nothingToOverride/afterAddFunctionNoBody.kt create mode 100644 idea/testData/quickfix/override/nothingToOverride/afterAddFunctionNonUnitReturnType.kt create mode 100644 idea/testData/quickfix/override/nothingToOverride/afterAddFunctionTrait.kt create mode 100644 idea/testData/quickfix/override/nothingToOverride/afterAddFunctionTwoSuperclasses.kt create mode 100644 idea/testData/quickfix/override/nothingToOverride/afterAddFunctionTwoTraits.kt delete mode 100644 idea/testData/quickfix/override/nothingToOverride/afterNoOpenSuperFunction.kt create mode 100644 idea/testData/quickfix/override/nothingToOverride/beforeAddFunction.kt create mode 100644 idea/testData/quickfix/override/nothingToOverride/beforeAddFunctionAbstractClass.kt create mode 100644 idea/testData/quickfix/override/nothingToOverride/beforeAddFunctionNoBody.kt create mode 100644 idea/testData/quickfix/override/nothingToOverride/beforeAddFunctionNonUnitReturnType.kt create mode 100644 idea/testData/quickfix/override/nothingToOverride/beforeAddFunctionTrait.kt create mode 100644 idea/testData/quickfix/override/nothingToOverride/beforeAddFunctionTwoSuperclasses.kt create mode 100644 idea/testData/quickfix/override/nothingToOverride/beforeAddFunctionTwoTraits.kt diff --git a/idea/src/org/jetbrains/jet/plugin/JetBundle.properties b/idea/src/org/jetbrains/jet/plugin/JetBundle.properties index 868da4e6b67..9536b7af1f7 100644 --- a/idea/src/org/jetbrains/jet/plugin/JetBundle.properties +++ b/idea/src/org/jetbrains/jet/plugin/JetBundle.properties @@ -209,4 +209,9 @@ property.is.implemented.header=Is implemented in
property.is.overridden.header=Is overridden in
navigation.title.overriding.property=Choose Implementation of {0} -navigation.findUsages.title.overriding.property=Overriding properties of {0} \ No newline at end of file +navigation.findUsages.title.overriding.property=Overriding properties of {0} +add.function.to.supertype.family=Add Function to Supertype +add.function.to.supertype.action.multiple=Add function to supertype... +add.function.to.type.action.single=Add ''{0}'' to ''{1}'' +add.function.to.type.action=Add function to type +add.function.to.type.action.type.chooser=Choose type... diff --git a/idea/src/org/jetbrains/jet/plugin/actions/JetAddFunctionToClassifierAction.java b/idea/src/org/jetbrains/jet/plugin/actions/JetAddFunctionToClassifierAction.java new file mode 100644 index 00000000000..f9f7ff26f13 --- /dev/null +++ b/idea/src/org/jetbrains/jet/plugin/actions/JetAddFunctionToClassifierAction.java @@ -0,0 +1,184 @@ +/* + * Copyright 2010-2013 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.jetbrains.jet.plugin.actions; + +import com.intellij.codeInsight.hint.QuestionAction; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.command.CommandProcessor; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.ui.popup.JBPopupFactory; +import com.intellij.openapi.ui.popup.ListPopupStep; +import com.intellij.openapi.ui.popup.PopupStep; +import com.intellij.openapi.ui.popup.util.BaseListPopupStep; +import com.intellij.psi.PsiDocumentManager; +import com.intellij.psi.PsiElement; +import com.intellij.util.PlatformIcons; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.jet.lang.descriptors.ClassDescriptor; +import org.jetbrains.jet.lang.descriptors.ClassKind; +import org.jetbrains.jet.lang.descriptors.FunctionDescriptor; +import org.jetbrains.jet.lang.descriptors.Modality; +import org.jetbrains.jet.lang.psi.JetClass; +import org.jetbrains.jet.lang.psi.JetClassBody; +import org.jetbrains.jet.lang.psi.JetNamedFunction; +import org.jetbrains.jet.lang.psi.JetPsiFactory; +import org.jetbrains.jet.lang.resolve.BindingContext; +import org.jetbrains.jet.lang.types.JetType; +import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns; +import org.jetbrains.jet.plugin.JetBundle; +import org.jetbrains.jet.plugin.codeInsight.CodeInsightUtils; +import org.jetbrains.jet.plugin.codeInsight.DescriptorToDeclarationUtil; +import org.jetbrains.jet.plugin.codeInsight.ReferenceToClassesShortening; + +import javax.swing.*; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +/** + * Changes method signature to one of provided signatures. + * Based on {@link JetAddImportAction} + */ +public class JetAddFunctionToClassifierAction implements QuestionAction { + private final List functionsToAdd; + private final Project project; + private final Editor editor; + private final BindingContext bindingContext; + + /** + * @param project Project where action takes place. + * @param editor Editor where modification should be done. + * @param bindingContext BindingContext to be used for finding type declarations. + * @param functionsToAdd List of possible functions to add. + */ + public JetAddFunctionToClassifierAction( + @NotNull Project project, + @NotNull Editor editor, + @NotNull BindingContext bindingContext, + @NotNull List functionsToAdd + ) { + this.project = project; + this.editor = editor; + this.bindingContext = bindingContext; + this.functionsToAdd = new ArrayList(functionsToAdd); + } + + private static void addFunction( + @NotNull final Project project, + @NotNull final ClassDescriptor typeDescriptor, + @NotNull final FunctionDescriptor functionDescriptor, + @NotNull BindingContext bindingContext + ) { + final String signatureString = CodeInsightUtils.createFunctionSignatureStringFromDescriptor( + functionDescriptor, + /* shortTypeNames = */ false); + + PsiDocumentManager.getInstance(project).commitAllDocuments(); + + final JetClass classifierDeclaration = (JetClass) DescriptorToDeclarationUtil.getDeclaration(project, typeDescriptor, bindingContext); + CommandProcessor.getInstance().executeCommand(project, new Runnable() { + @Override + public void run() { + ApplicationManager.getApplication().runWriteAction(new Runnable() { + @Override + public void run() { + JetClassBody body = classifierDeclaration.getBody(); + if (body == null) { + PsiElement whitespaceBefore = classifierDeclaration.add(JetPsiFactory.createWhiteSpace(project)); + body = (JetClassBody) classifierDeclaration.addAfter(JetPsiFactory.createEmptyClassBody(project), whitespaceBefore); + classifierDeclaration.addAfter(JetPsiFactory.createNewLine(project), body); + } + + String functionBody = ""; + if (typeDescriptor.getKind() != ClassKind.TRAIT && functionDescriptor.getModality() != Modality.ABSTRACT) { + functionBody = "{}"; + JetType returnType = functionDescriptor.getReturnType(); + if (returnType == null || !KotlinBuiltIns.getInstance().isUnit(returnType)) { + functionBody = "{ throw UnsupportedOperationException() }"; + } + } + JetNamedFunction functionElement = JetPsiFactory.createFunction(project, signatureString + functionBody); + PsiElement anchor = body.getRBrace(); + JetNamedFunction insertedFunctionElement = (JetNamedFunction) body.addBefore(functionElement, anchor); + + ReferenceToClassesShortening.compactReferenceToClasses(Collections.singletonList(insertedFunctionElement)); + } + }); + } + }, JetBundle.message("add.function.to.type.action"), null); + } + + @Override + public boolean execute() { + if (functionsToAdd.isEmpty()) { + return false; + } + + if (functionsToAdd.size() == 1 || !editor.getComponent().isShowing()) { + addFunction(functionsToAdd.get(0)); + } + else { + chooseFunctionAndAdd(); + } + + return true; + } + + private void chooseFunctionAndAdd() { + JBPopupFactory.getInstance().createListPopup(getFunctionPopup()).showInBestPositionFor(editor); + } + + private ListPopupStep getFunctionPopup() { + return new BaseListPopupStep( + JetBundle.message("add.function.to.type.action.type.chooser"), functionsToAdd) { + @Override + public boolean isAutoSelectionEnabled() { + return false; + } + + @Override + public PopupStep onChosen(FunctionDescriptor selectedValue, boolean finalChoice) { + if (finalChoice) { + addFunction(selectedValue); + } + return FINAL_CHOICE; + } + + @Override + public Icon getIconFor(FunctionDescriptor aValue) { + return PlatformIcons.FUNCTION_ICON; + } + + @NotNull + @Override + public String getTextFor(FunctionDescriptor functionDescriptor) { + ClassDescriptor type = (ClassDescriptor) functionDescriptor.getContainingDeclaration(); + return JetBundle.message("add.function.to.type.action.single", + CodeInsightUtils.createFunctionSignatureStringFromDescriptor( + functionDescriptor, + /* shortTypeNames = */ true), + type.getName().toString()); + } + }; + } + + private void addFunction(FunctionDescriptor functionToAdd) { + addFunction(project, (ClassDescriptor) functionToAdd.getContainingDeclaration(), + functionToAdd, bindingContext); + } +} diff --git a/idea/src/org/jetbrains/jet/plugin/codeInsight/DescriptorToDeclarationUtil.java b/idea/src/org/jetbrains/jet/plugin/codeInsight/DescriptorToDeclarationUtil.java index ca707dba1e4..d914eba74f2 100644 --- a/idea/src/org/jetbrains/jet/plugin/codeInsight/DescriptorToDeclarationUtil.java +++ b/idea/src/org/jetbrains/jet/plugin/codeInsight/DescriptorToDeclarationUtil.java @@ -16,6 +16,7 @@ package org.jetbrains.jet.plugin.codeInsight; +import com.intellij.openapi.project.Project; import com.intellij.psi.PsiElement; import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor; import org.jetbrains.jet.lang.psi.JetFile; @@ -30,11 +31,15 @@ public final class DescriptorToDeclarationUtil { } public static PsiElement getDeclaration(JetFile file, DeclarationDescriptor descriptor, BindingContext bindingContext) { + return getDeclaration(file.getProject(), descriptor, bindingContext); + } + + public static PsiElement getDeclaration(Project project, DeclarationDescriptor descriptor, BindingContext bindingContext) { Collection elements = BindingContextUtils.descriptorToDeclarations(bindingContext, descriptor); if (elements.isEmpty()) { BuiltInsReferenceResolver libraryReferenceResolver = - file.getProject().getComponent(BuiltInsReferenceResolver.class); + project.getComponent(BuiltInsReferenceResolver.class); elements = libraryReferenceResolver.resolveStandardLibrarySymbol(descriptor); } diff --git a/idea/src/org/jetbrains/jet/plugin/quickfix/AddFunctionToSupertypeFix.java b/idea/src/org/jetbrains/jet/plugin/quickfix/AddFunctionToSupertypeFix.java new file mode 100644 index 00000000000..05844b5f937 --- /dev/null +++ b/idea/src/org/jetbrains/jet/plugin/quickfix/AddFunctionToSupertypeFix.java @@ -0,0 +1,171 @@ +/* + * Copyright 2010-2013 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.jetbrains.jet.plugin.quickfix; + +import com.google.common.collect.Lists; +import com.intellij.codeInsight.intention.IntentionAction; +import com.intellij.openapi.command.CommandProcessor; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.project.Project; +import com.intellij.psi.PsiFile; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import org.jetbrains.jet.lang.descriptors.*; +import org.jetbrains.jet.lang.diagnostics.Diagnostic; +import org.jetbrains.jet.lang.psi.JetFile; +import org.jetbrains.jet.lang.psi.JetNamedFunction; +import org.jetbrains.jet.lang.resolve.BindingContext; +import org.jetbrains.jet.lang.resolve.DescriptorUtils; +import org.jetbrains.jet.lang.types.JetType; +import org.jetbrains.jet.lang.types.TypeUtils; +import org.jetbrains.jet.lang.types.checker.JetTypeChecker; +import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns; +import org.jetbrains.jet.plugin.JetBundle; +import org.jetbrains.jet.plugin.actions.JetAddFunctionToClassifierAction; +import org.jetbrains.jet.plugin.caches.resolve.KotlinCacheManagerUtil; +import org.jetbrains.jet.plugin.codeInsight.CodeInsightUtils; + +import java.util.Collections; +import java.util.Comparator; +import java.util.List; + +public class AddFunctionToSupertypeFix extends JetHintAction { + private final List functionsToAdd; + + public AddFunctionToSupertypeFix(JetNamedFunction element) { + super(element); + functionsToAdd = generateFunctionsToAdd(element); + } + + private static List generateFunctionsToAdd(JetNamedFunction functionElement) { + BindingContext context = KotlinCacheManagerUtil.getDeclarationsFromProject(functionElement).getBindingContext(); + + FunctionDescriptor functionDescriptor = context.get(BindingContext.FUNCTION, functionElement); + if (functionDescriptor == null) return Collections.emptyList(); + + DeclarationDescriptor containingDeclaration = functionDescriptor.getContainingDeclaration(); + if (!(containingDeclaration instanceof ClassDescriptor)) return Collections.emptyList(); + + List functions = Lists.newArrayList(); + ClassDescriptor classDescriptor = (ClassDescriptor) containingDeclaration; + // TODO: filter out impossible supertypes (for example when argument's type isn't visible in a superclass). + for (ClassDescriptor supertypeDescriptor : getSupertypes(classDescriptor)) { + if (KotlinBuiltIns.getInstance().isAny(supertypeDescriptor.getDefaultType())) continue; + functions.add(generateFunctionSignatureForType(functionDescriptor, supertypeDescriptor)); + } + return functions; + } + + private static List getSupertypes(ClassDescriptor classDescriptor) { + List supertypes = Lists.newArrayList(TypeUtils.getAllSupertypes(classDescriptor.getDefaultType())); + Collections.sort(supertypes, new Comparator() { + @Override + public int compare(JetType o1, JetType o2) { + if (o1.equals(o2)) { + return 0; + } + if (JetTypeChecker.INSTANCE.isSubtypeOf(o1, o2)) { + return -1; + } + if (JetTypeChecker.INSTANCE.isSubtypeOf(o2, o1)) { + return 1; + } + return o1.toString().compareTo(o2.toString()); + } + }); + List supertypesDescriptors = Lists.newArrayList(); + for (JetType supertype : supertypes) { + supertypesDescriptors.add(DescriptorUtils.getClassDescriptorForType(supertype)); + } + return supertypesDescriptors; + } + + private static FunctionDescriptor generateFunctionSignatureForType( + FunctionDescriptor functionDescriptor, + ClassDescriptor typeDescriptor + ) { + // TODO: support for generics. + Modality modality = typeDescriptor.getModality(); + if (typeDescriptor.getKind() == ClassKind.TRAIT) { + modality = Modality.OPEN; + } + return functionDescriptor.copy( + typeDescriptor, + modality, + functionDescriptor.getVisibility(), + CallableMemberDescriptor.Kind.DECLARATION, + /* copyOverrides = */ false); + } + + @Override + public boolean isAvailable(@NotNull Project project, Editor editor, PsiFile file) { + return super.isAvailable(project, editor, file) && !functionsToAdd.isEmpty(); + } + + @Override + public boolean showHint(Editor editor) { + return false; + } + + @NotNull + @Override + public String getText() { + if (functionsToAdd.size() == 1) { + FunctionDescriptor newFunction = functionsToAdd.get(0); + ClassDescriptor supertype = (ClassDescriptor) newFunction.getContainingDeclaration(); + return JetBundle.message("add.function.to.type.action.single", + CodeInsightUtils.createFunctionSignatureStringFromDescriptor(newFunction, /* shortTypeNames */ true), + supertype.getName().toString()); + } + else { + return JetBundle.message("add.function.to.supertype.action.multiple"); + } + } + + @NotNull + @Override + public String getFamilyName() { + return JetBundle.message("add.function.to.supertype.family"); + } + + @Override + protected void invoke(@NotNull final Project project, final Editor editor, JetFile file) { + CommandProcessor.getInstance().runUndoTransparentAction(new Runnable() { + @Override + public void run() { + createAction(project, editor).execute(); + } + }); + } + + @NotNull + private JetAddFunctionToClassifierAction createAction(Project project, Editor editor) { + BindingContext bindingContext = KotlinCacheManagerUtil.getDeclarationsFromProject(element).getBindingContext(); + return new JetAddFunctionToClassifierAction(project, editor, bindingContext, functionsToAdd); + } + + public static JetIntentionActionFactory createFactory() { + return new JetIntentionActionFactory() { + @Nullable + @Override + public IntentionAction createAction(Diagnostic diagnostic) { + JetNamedFunction function = QuickFixUtil.getParentElementOfType(diagnostic, JetNamedFunction.class); + return function == null ? null : new AddFunctionToSupertypeFix(function); + } + }; + } +} diff --git a/idea/src/org/jetbrains/jet/plugin/quickfix/QuickFixes.java b/idea/src/org/jetbrains/jet/plugin/quickfix/QuickFixes.java index 9369f5b330b..be8f7fb5b30 100644 --- a/idea/src/org/jetbrains/jet/plugin/quickfix/QuickFixes.java +++ b/idea/src/org/jetbrains/jet/plugin/quickfix/QuickFixes.java @@ -91,6 +91,7 @@ public class QuickFixes { factories.put(NOTHING_TO_OVERRIDE, RemoveModifierFix.createRemoveModifierFromListOwnerFactory(OVERRIDE_KEYWORD)); factories.put(NOTHING_TO_OVERRIDE, ChangeMemberFunctionSignatureFix.createFactory()); + factories.put(NOTHING_TO_OVERRIDE, AddFunctionToSupertypeFix.createFactory()); factories.put(VIRTUAL_MEMBER_HIDDEN, AddModifierFix.createFactory(OVERRIDE_KEYWORD)); factories.put(USELESS_CAST_STATIC_ASSERT_IS_FINE, ReplaceOperationInBinaryExpressionFix.createChangeCastToStaticAssertFactory()); diff --git a/idea/testData/quickfix/override/nothingToOverride/afterAddFunction.kt b/idea/testData/quickfix/override/nothingToOverride/afterAddFunction.kt new file mode 100644 index 00000000000..63779357b90 --- /dev/null +++ b/idea/testData/quickfix/override/nothingToOverride/afterAddFunction.kt @@ -0,0 +1,8 @@ +// "Add 'open fun f()' to 'A'" "true" +open class A { + open fun f() { + } +} +class B : A() { + override fun f() {} +} \ No newline at end of file diff --git a/idea/testData/quickfix/override/nothingToOverride/afterAddFunctionAbstractClass.kt b/idea/testData/quickfix/override/nothingToOverride/afterAddFunctionAbstractClass.kt new file mode 100644 index 00000000000..49ccd13b9be --- /dev/null +++ b/idea/testData/quickfix/override/nothingToOverride/afterAddFunctionAbstractClass.kt @@ -0,0 +1,7 @@ +// "Add 'abstract fun f()' to 'A'" "true" +abstract class A { + abstract fun f() +} +class B : A() { + override fun f() {} +} \ No newline at end of file diff --git a/idea/testData/quickfix/override/nothingToOverride/afterAddFunctionNoBody.kt b/idea/testData/quickfix/override/nothingToOverride/afterAddFunctionNoBody.kt new file mode 100644 index 00000000000..dfa3a7dee99 --- /dev/null +++ b/idea/testData/quickfix/override/nothingToOverride/afterAddFunctionNoBody.kt @@ -0,0 +1,8 @@ +// "Add 'open fun f()' to 'A'" "true" +trait A +{ + open fun f() +} +class B : A { + override fun f() {} +} \ No newline at end of file diff --git a/idea/testData/quickfix/override/nothingToOverride/afterAddFunctionNonUnitReturnType.kt b/idea/testData/quickfix/override/nothingToOverride/afterAddFunctionNonUnitReturnType.kt new file mode 100644 index 00000000000..cda0f209598 --- /dev/null +++ b/idea/testData/quickfix/override/nothingToOverride/afterAddFunctionNonUnitReturnType.kt @@ -0,0 +1,9 @@ +// "Add 'open fun f(): Int' to 'A'" "true" +open class A { + open fun f(): Int { + throw UnsupportedOperationException() + } +} +class B : A() { + override fun f(): Int = 5 +} \ No newline at end of file diff --git a/idea/testData/quickfix/override/nothingToOverride/afterAddFunctionTrait.kt b/idea/testData/quickfix/override/nothingToOverride/afterAddFunctionTrait.kt new file mode 100644 index 00000000000..92dda9599a1 --- /dev/null +++ b/idea/testData/quickfix/override/nothingToOverride/afterAddFunctionTrait.kt @@ -0,0 +1,7 @@ +// "Add 'open fun f()' to 'A'" "true" +trait A { + open fun f() +} +class B : A { + override fun f() {} +} \ No newline at end of file diff --git a/idea/testData/quickfix/override/nothingToOverride/afterAddFunctionTwoSuperclasses.kt b/idea/testData/quickfix/override/nothingToOverride/afterAddFunctionTwoSuperclasses.kt new file mode 100644 index 00000000000..d151ba2fd15 --- /dev/null +++ b/idea/testData/quickfix/override/nothingToOverride/afterAddFunctionTwoSuperclasses.kt @@ -0,0 +1,10 @@ +// "Add function to supertype..." "true" +open class A { +} +open class B : A() { + open fun f() { + } +} +class C : B() { + override fun f() {} +} \ No newline at end of file diff --git a/idea/testData/quickfix/override/nothingToOverride/afterAddFunctionTwoTraits.kt b/idea/testData/quickfix/override/nothingToOverride/afterAddFunctionTwoTraits.kt new file mode 100644 index 00000000000..32dcc19553a --- /dev/null +++ b/idea/testData/quickfix/override/nothingToOverride/afterAddFunctionTwoTraits.kt @@ -0,0 +1,8 @@ +// "Add function to supertype..." "true" +trait A { + open fun foo() +} +trait B {} +class C: A, B { + override fun foo() {} +} \ No newline at end of file diff --git a/idea/testData/quickfix/override/nothingToOverride/afterNoOpenSuperFunction.kt b/idea/testData/quickfix/override/nothingToOverride/afterNoOpenSuperFunction.kt deleted file mode 100644 index b42fbdf5f47..00000000000 --- a/idea/testData/quickfix/override/nothingToOverride/afterNoOpenSuperFunction.kt +++ /dev/null @@ -1,11 +0,0 @@ -// "Change function signature to 'override fun f(a: Int)'" "false" -// ERROR: 'f' overrides nothing -// ACTION: Remove 'override' modifier -open class A { - open fun foo() {} - fun f(a: Int) {} -} - -class B : A(){ - override fun f(a: String) {} -} diff --git a/idea/testData/quickfix/override/nothingToOverride/beforeAddFunction.kt b/idea/testData/quickfix/override/nothingToOverride/beforeAddFunction.kt new file mode 100644 index 00000000000..3136907d089 --- /dev/null +++ b/idea/testData/quickfix/override/nothingToOverride/beforeAddFunction.kt @@ -0,0 +1,6 @@ +// "Add 'open fun f()' to 'A'" "true" +open class A { +} +class B : A() { + override fun f() {} +} \ No newline at end of file diff --git a/idea/testData/quickfix/override/nothingToOverride/beforeAddFunctionAbstractClass.kt b/idea/testData/quickfix/override/nothingToOverride/beforeAddFunctionAbstractClass.kt new file mode 100644 index 00000000000..f6b022c0513 --- /dev/null +++ b/idea/testData/quickfix/override/nothingToOverride/beforeAddFunctionAbstractClass.kt @@ -0,0 +1,6 @@ +// "Add 'abstract fun f()' to 'A'" "true" +abstract class A { +} +class B : A() { + override fun f() {} +} \ No newline at end of file diff --git a/idea/testData/quickfix/override/nothingToOverride/beforeAddFunctionNoBody.kt b/idea/testData/quickfix/override/nothingToOverride/beforeAddFunctionNoBody.kt new file mode 100644 index 00000000000..705d1af6ec4 --- /dev/null +++ b/idea/testData/quickfix/override/nothingToOverride/beforeAddFunctionNoBody.kt @@ -0,0 +1,5 @@ +// "Add 'open fun f()' to 'A'" "true" +trait A +class B : A { + override fun f() {} +} \ No newline at end of file diff --git a/idea/testData/quickfix/override/nothingToOverride/beforeAddFunctionNonUnitReturnType.kt b/idea/testData/quickfix/override/nothingToOverride/beforeAddFunctionNonUnitReturnType.kt new file mode 100644 index 00000000000..8f76628cbb3 --- /dev/null +++ b/idea/testData/quickfix/override/nothingToOverride/beforeAddFunctionNonUnitReturnType.kt @@ -0,0 +1,6 @@ +// "Add 'open fun f(): Int' to 'A'" "true" +open class A { +} +class B : A() { + override fun f(): Int = 5 +} \ No newline at end of file diff --git a/idea/testData/quickfix/override/nothingToOverride/beforeAddFunctionTrait.kt b/idea/testData/quickfix/override/nothingToOverride/beforeAddFunctionTrait.kt new file mode 100644 index 00000000000..3d2c4024c5b --- /dev/null +++ b/idea/testData/quickfix/override/nothingToOverride/beforeAddFunctionTrait.kt @@ -0,0 +1,6 @@ +// "Add 'open fun f()' to 'A'" "true" +trait A { +} +class B : A { + override fun f() {} +} \ No newline at end of file diff --git a/idea/testData/quickfix/override/nothingToOverride/beforeAddFunctionTwoSuperclasses.kt b/idea/testData/quickfix/override/nothingToOverride/beforeAddFunctionTwoSuperclasses.kt new file mode 100644 index 00000000000..d717c14cf3f --- /dev/null +++ b/idea/testData/quickfix/override/nothingToOverride/beforeAddFunctionTwoSuperclasses.kt @@ -0,0 +1,8 @@ +// "Add function to supertype..." "true" +open class A { +} +open class B : A() { +} +class C : B() { + override fun f() {} +} \ No newline at end of file diff --git a/idea/testData/quickfix/override/nothingToOverride/beforeAddFunctionTwoTraits.kt b/idea/testData/quickfix/override/nothingToOverride/beforeAddFunctionTwoTraits.kt new file mode 100644 index 00000000000..48498de2050 --- /dev/null +++ b/idea/testData/quickfix/override/nothingToOverride/beforeAddFunctionTwoTraits.kt @@ -0,0 +1,6 @@ +// "Add function to supertype..." "true" +trait A {} +trait B {} +class C: A, B { + override fun foo() {} +} \ No newline at end of file diff --git a/idea/testData/quickfix/override/nothingToOverride/beforeNoOpenSuperFunction.kt b/idea/testData/quickfix/override/nothingToOverride/beforeNoOpenSuperFunction.kt index b42fbdf5f47..1ae08772709 100644 --- a/idea/testData/quickfix/override/nothingToOverride/beforeNoOpenSuperFunction.kt +++ b/idea/testData/quickfix/override/nothingToOverride/beforeNoOpenSuperFunction.kt @@ -1,5 +1,6 @@ // "Change function signature to 'override fun f(a: Int)'" "false" // ERROR: 'f' overrides nothing +// ACTION: Add 'open fun f(a: String)' to 'A' // ACTION: Remove 'override' modifier open class A { open fun foo() {} diff --git a/idea/tests/org/jetbrains/jet/plugin/quickfix/QuickFixTestGenerated.java b/idea/tests/org/jetbrains/jet/plugin/quickfix/QuickFixTestGenerated.java index d35d22f475b..d5fc32546e1 100644 --- a/idea/tests/org/jetbrains/jet/plugin/quickfix/QuickFixTestGenerated.java +++ b/idea/tests/org/jetbrains/jet/plugin/quickfix/QuickFixTestGenerated.java @@ -866,6 +866,41 @@ public class QuickFixTestGenerated extends AbstractQuickFixTest { @TestMetadata("idea/testData/quickfix/override/nothingToOverride") public static class NothingToOverride extends AbstractQuickFixTest { + @TestMetadata("beforeAddFunction.kt") + public void testAddFunction() throws Exception { + doTest("idea/testData/quickfix/override/nothingToOverride/beforeAddFunction.kt"); + } + + @TestMetadata("beforeAddFunctionAbstractClass.kt") + public void testAddFunctionAbstractClass() throws Exception { + doTest("idea/testData/quickfix/override/nothingToOverride/beforeAddFunctionAbstractClass.kt"); + } + + @TestMetadata("beforeAddFunctionNoBody.kt") + public void testAddFunctionNoBody() throws Exception { + doTest("idea/testData/quickfix/override/nothingToOverride/beforeAddFunctionNoBody.kt"); + } + + @TestMetadata("beforeAddFunctionNonUnitReturnType.kt") + public void testAddFunctionNonUnitReturnType() throws Exception { + doTest("idea/testData/quickfix/override/nothingToOverride/beforeAddFunctionNonUnitReturnType.kt"); + } + + @TestMetadata("beforeAddFunctionTrait.kt") + public void testAddFunctionTrait() throws Exception { + doTest("idea/testData/quickfix/override/nothingToOverride/beforeAddFunctionTrait.kt"); + } + + @TestMetadata("beforeAddFunctionTwoSuperclasses.kt") + public void testAddFunctionTwoSuperclasses() throws Exception { + doTest("idea/testData/quickfix/override/nothingToOverride/beforeAddFunctionTwoSuperclasses.kt"); + } + + @TestMetadata("beforeAddFunctionTwoTraits.kt") + public void testAddFunctionTwoTraits() throws Exception { + doTest("idea/testData/quickfix/override/nothingToOverride/beforeAddFunctionTwoTraits.kt"); + } + @TestMetadata("beforeAddParameter.kt") public void testAddParameter() throws Exception { doTest("idea/testData/quickfix/override/nothingToOverride/beforeAddParameter.kt"); From cacb4b26e4f73b194e6bedeb5a40a7f1c1036403 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Sapalski?= Date: Sat, 2 Mar 2013 15:08:00 +0100 Subject: [PATCH 139/249] Support for generic classes in quickfix for NOTHING_TO_OVERRIDE --- .../lang/descriptors/ValueParameterDescriptor.java | 3 ++- .../impl/ValueParameterDescriptorImpl.java | 5 +++-- .../quickfix/ChangeMemberFunctionSignatureFix.java | 13 +++++++++---- .../afterAddParameterGenericClass.kt | 8 ++++++++ .../afterSwapParametersGenericClass.kt | 8 ++++++++ .../beforeAddParameterGenericClass.kt | 8 ++++++++ .../beforeSwapParametersGenericClass.kt | 8 ++++++++ .../jet/plugin/quickfix/QuickFixTestGenerated.java | 10 ++++++++++ 8 files changed, 56 insertions(+), 7 deletions(-) create mode 100644 idea/testData/quickfix/override/nothingToOverride/afterAddParameterGenericClass.kt create mode 100644 idea/testData/quickfix/override/nothingToOverride/afterSwapParametersGenericClass.kt create mode 100644 idea/testData/quickfix/override/nothingToOverride/beforeAddParameterGenericClass.kt create mode 100644 idea/testData/quickfix/override/nothingToOverride/beforeSwapParametersGenericClass.kt diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/ValueParameterDescriptor.java b/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/ValueParameterDescriptor.java index 8b01d2f35e7..262a44541d3 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/ValueParameterDescriptor.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/ValueParameterDescriptor.java @@ -19,6 +19,7 @@ package org.jetbrains.jet.lang.descriptors; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.jet.lang.descriptors.annotations.Annotated; +import org.jetbrains.jet.lang.resolve.name.Name; import org.jetbrains.jet.lang.types.JetType; import java.util.Set; @@ -57,7 +58,7 @@ public interface ValueParameterDescriptor extends VariableDescriptor, Annotated ValueParameterDescriptor getOriginal(); @NotNull - ValueParameterDescriptor copy(DeclarationDescriptor newOwner); + ValueParameterDescriptor copy(DeclarationDescriptor newOwner, Name newName); /** * Parameter p1 overrides p2 iff diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/impl/ValueParameterDescriptorImpl.java b/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/impl/ValueParameterDescriptorImpl.java index 2e52abd0de7..464f1bad64c 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/impl/ValueParameterDescriptorImpl.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/impl/ValueParameterDescriptorImpl.java @@ -111,6 +111,7 @@ public class ValueParameterDescriptorImpl extends VariableDescriptorImpl impleme } @Nullable + @Override public JetType getVarargElementType() { return varargElementType; } @@ -139,8 +140,8 @@ public class ValueParameterDescriptorImpl extends VariableDescriptorImpl impleme @NotNull @Override - public ValueParameterDescriptor copy(@NotNull DeclarationDescriptor newOwner) { - return new ValueParameterDescriptorImpl(newOwner, index, Lists.newArrayList(getAnnotations()), getName(), getType(), hasDefaultValue, varargElementType); + public ValueParameterDescriptor copy(@NotNull DeclarationDescriptor newOwner, @NotNull Name newName) { + return new ValueParameterDescriptorImpl(newOwner, index, Lists.newArrayList(getAnnotations()), newName, getType(), declaresDefaultValue(), varargElementType); } @NotNull diff --git a/idea/src/org/jetbrains/jet/plugin/quickfix/ChangeMemberFunctionSignatureFix.java b/idea/src/org/jetbrains/jet/plugin/quickfix/ChangeMemberFunctionSignatureFix.java index 21e14bf9684..92baa0490f1 100644 --- a/idea/src/org/jetbrains/jet/plugin/quickfix/ChangeMemberFunctionSignatureFix.java +++ b/idea/src/org/jetbrains/jet/plugin/quickfix/ChangeMemberFunctionSignatureFix.java @@ -34,11 +34,11 @@ import org.jetbrains.jet.lang.diagnostics.Diagnostic; import org.jetbrains.jet.lang.psi.JetFile; import org.jetbrains.jet.lang.psi.JetNamedFunction; import org.jetbrains.jet.lang.resolve.BindingContext; -import org.jetbrains.jet.lang.resolve.DescriptorUtils; import org.jetbrains.jet.lang.resolve.VisibilityUtil; import org.jetbrains.jet.lang.resolve.name.Name; import org.jetbrains.jet.lang.resolve.scopes.JetScope; import org.jetbrains.jet.lang.types.JetType; +import org.jetbrains.jet.lang.types.TypeUtils; import org.jetbrains.jet.lang.types.checker.JetTypeChecker; import org.jetbrains.jet.plugin.JetBundle; import org.jetbrains.jet.plugin.actions.JetChangeFunctionSignatureAction; @@ -187,7 +187,13 @@ public class ChangeMemberFunctionSignatureFix extends JetHintAction { + fun f(a: Int, b: R) +} + +class B : A { + override fun f(a: Int, x: T) {} +} diff --git a/idea/testData/quickfix/override/nothingToOverride/afterSwapParametersGenericClass.kt b/idea/testData/quickfix/override/nothingToOverride/afterSwapParametersGenericClass.kt new file mode 100644 index 00000000000..285b28cb7a3 --- /dev/null +++ b/idea/testData/quickfix/override/nothingToOverride/afterSwapParametersGenericClass.kt @@ -0,0 +1,8 @@ +// "Change function signature to 'override fun f(y: S, x: List>)'" "true" +trait A { + fun f(a: Q, b: List>) +} + +class B : A { + override fun f(y: S, x: List>) {} +} diff --git a/idea/testData/quickfix/override/nothingToOverride/beforeAddParameterGenericClass.kt b/idea/testData/quickfix/override/nothingToOverride/beforeAddParameterGenericClass.kt new file mode 100644 index 00000000000..4fae2df2a06 --- /dev/null +++ b/idea/testData/quickfix/override/nothingToOverride/beforeAddParameterGenericClass.kt @@ -0,0 +1,8 @@ +// "Change function signature to 'override fun f(a: Int, x: T)'" "true" +trait A { + fun f(a: Int, b: R) +} + +class B : A { + override fun f(x: T) {} +} diff --git a/idea/testData/quickfix/override/nothingToOverride/beforeSwapParametersGenericClass.kt b/idea/testData/quickfix/override/nothingToOverride/beforeSwapParametersGenericClass.kt new file mode 100644 index 00000000000..b8dac5dbef7 --- /dev/null +++ b/idea/testData/quickfix/override/nothingToOverride/beforeSwapParametersGenericClass.kt @@ -0,0 +1,8 @@ +// "Change function signature to 'override fun f(y: S, x: List>)'" "true" +trait A { + fun f(a: Q, b: List>) +} + +class B : A { + override fun f(x: List>, y: S) {} +} diff --git a/idea/tests/org/jetbrains/jet/plugin/quickfix/QuickFixTestGenerated.java b/idea/tests/org/jetbrains/jet/plugin/quickfix/QuickFixTestGenerated.java index d5fc32546e1..350eaa4bd87 100644 --- a/idea/tests/org/jetbrains/jet/plugin/quickfix/QuickFixTestGenerated.java +++ b/idea/tests/org/jetbrains/jet/plugin/quickfix/QuickFixTestGenerated.java @@ -906,6 +906,11 @@ public class QuickFixTestGenerated extends AbstractQuickFixTest { doTest("idea/testData/quickfix/override/nothingToOverride/beforeAddParameter.kt"); } + @TestMetadata("beforeAddParameterGenericClass.kt") + public void testAddParameterGenericClass() throws Exception { + doTest("idea/testData/quickfix/override/nothingToOverride/beforeAddParameterGenericClass.kt"); + } + @TestMetadata("beforeAddParameterMultiple.kt") public void testAddParameterMultiple() throws Exception { doTest("idea/testData/quickfix/override/nothingToOverride/beforeAddParameterMultiple.kt"); @@ -1000,6 +1005,11 @@ public class QuickFixTestGenerated extends AbstractQuickFixTest { doTest("idea/testData/quickfix/override/nothingToOverride/beforeRemoveParameterTwoTraits.kt"); } + @TestMetadata("beforeSwapParametersGenericClass.kt") + public void testSwapParametersGenericClass() throws Exception { + doTest("idea/testData/quickfix/override/nothingToOverride/beforeSwapParametersGenericClass.kt"); + } + } @TestMetadata("idea/testData/quickfix/override/typeMismatchOnOverride") From 2ad1bfa7438ef9c81e3d80192928459bcc3cc984 Mon Sep 17 00:00:00 2001 From: Sergey Rostov Date: Wed, 22 May 2013 19:23:59 +0400 Subject: [PATCH 140/249] KT-3161 JetCommenter implementation stub --- .../jetbrains/jet/plugin/JetCommenter.java | 42 +++++++++++++- .../editor/commenter/generateDocComment.kt | 2 + .../commenter/generateDocComment_after.kt | 4 ++ .../editor/commenter/newLineInComment.kt | 4 ++ .../commenter/newLineInComment_after.kt | 5 ++ .../jet/editor/JetCommenterTest.java | 58 +++++++++++++++++++ 6 files changed, 113 insertions(+), 2 deletions(-) create mode 100644 idea/testData/editor/commenter/generateDocComment.kt create mode 100644 idea/testData/editor/commenter/generateDocComment_after.kt create mode 100644 idea/testData/editor/commenter/newLineInComment.kt create mode 100644 idea/testData/editor/commenter/newLineInComment_after.kt create mode 100644 idea/tests/org/jetbrains/jet/editor/JetCommenterTest.java diff --git a/idea/src/org/jetbrains/jet/plugin/JetCommenter.java b/idea/src/org/jetbrains/jet/plugin/JetCommenter.java index b7c260dfa93..2e3d3ba5e1f 100644 --- a/idea/src/org/jetbrains/jet/plugin/JetCommenter.java +++ b/idea/src/org/jetbrains/jet/plugin/JetCommenter.java @@ -16,9 +16,12 @@ package org.jetbrains.jet.plugin; -import com.intellij.lang.Commenter; +import com.intellij.lang.CodeDocumentationAwareCommenter; +import com.intellij.psi.PsiComment; +import com.intellij.psi.tree.IElementType; +import org.jetbrains.jet.lexer.JetTokens; -public class JetCommenter implements Commenter { +public class JetCommenter implements CodeDocumentationAwareCommenter { @Override public String getLineCommentPrefix() { return "//"; @@ -43,4 +46,39 @@ public class JetCommenter implements Commenter { public String getCommentedBlockCommentSuffix() { return null; } + + @Override + public IElementType getLineCommentTokenType() { + return JetTokens.EOL_COMMENT; + } + + @Override + public IElementType getBlockCommentTokenType() { + return JetTokens.BLOCK_COMMENT; + } + + @Override + public IElementType getDocumentationCommentTokenType() { + return JetTokens.DOC_COMMENT; + } + + @Override + public String getDocumentationCommentPrefix() { + return "/**"; + } + + @Override + public String getDocumentationCommentLinePrefix() { + return "*"; + } + + @Override + public String getDocumentationCommentSuffix() { + return "*/"; + } + + @Override + public boolean isDocumentationComment(PsiComment element) { + return element.getTokenType().equals(JetTokens.DOC_COMMENT); + } } diff --git a/idea/testData/editor/commenter/generateDocComment.kt b/idea/testData/editor/commenter/generateDocComment.kt new file mode 100644 index 00000000000..7e76a37c71b --- /dev/null +++ b/idea/testData/editor/commenter/generateDocComment.kt @@ -0,0 +1,2 @@ +/** +fun test() = 0 \ No newline at end of file diff --git a/idea/testData/editor/commenter/generateDocComment_after.kt b/idea/testData/editor/commenter/generateDocComment_after.kt new file mode 100644 index 00000000000..f60322d8e68 --- /dev/null +++ b/idea/testData/editor/commenter/generateDocComment_after.kt @@ -0,0 +1,4 @@ +/** + * + */ +fun test() = 0 \ No newline at end of file diff --git a/idea/testData/editor/commenter/newLineInComment.kt b/idea/testData/editor/commenter/newLineInComment.kt new file mode 100644 index 00000000000..5f9507de398 --- /dev/null +++ b/idea/testData/editor/commenter/newLineInComment.kt @@ -0,0 +1,4 @@ +/** + * x + */ +fun test() = 0 \ No newline at end of file diff --git a/idea/testData/editor/commenter/newLineInComment_after.kt b/idea/testData/editor/commenter/newLineInComment_after.kt new file mode 100644 index 00000000000..130bcc93cb1 --- /dev/null +++ b/idea/testData/editor/commenter/newLineInComment_after.kt @@ -0,0 +1,5 @@ +/** + * x + * + */ +fun test() = 0 \ No newline at end of file diff --git a/idea/tests/org/jetbrains/jet/editor/JetCommenterTest.java b/idea/tests/org/jetbrains/jet/editor/JetCommenterTest.java new file mode 100644 index 00000000000..967ef967b7d --- /dev/null +++ b/idea/tests/org/jetbrains/jet/editor/JetCommenterTest.java @@ -0,0 +1,58 @@ +/* + * Copyright 2010-2013 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.jetbrains.jet.editor; + +import com.intellij.openapi.util.io.FileUtil; +import com.intellij.openapi.util.text.StringUtil; +import com.intellij.testFramework.EditorTestUtil; +import com.intellij.testFramework.LightCodeInsightTestCase; +import org.jetbrains.jet.plugin.PluginTestCaseBase; + +import java.io.File; + +public class JetCommenterTest extends LightCodeInsightTestCase { + private static final String BASE_PATH = + new File(PluginTestCaseBase.getTestDataPathBase(), "/editor/commenter/").getAbsolutePath(); + + public void testGenerateDocComment() throws Exception { + doNewLineTypingTest(); + } + + public void testNewLineInComment() throws Exception { + doNewLineTypingTest(); + } + + private void doNewLineTypingTest() throws Exception { + configure(); + EditorTestUtil.performTypingAction(getEditor(), '\n'); + check(); + } + + private void configure() throws Exception { + configureFromFileText("a.kt", loadFile(getTestName(false) + ".kt")); + } + + private void check() throws Exception { + checkResultByText(loadFile(getTestName(false) + "_after.kt")); + } + + protected static String loadFile(String name) throws Exception { + String text = FileUtil.loadFile(new File(BASE_PATH, name)); + text = StringUtil.convertLineSeparators(text); + return text; + } +} From 5ff1f746d4eda34fa8c0e2be72f7e546da07f215 Mon Sep 17 00:00:00 2001 From: Sergey Rostov Date: Thu, 23 May 2013 18:32:13 +0400 Subject: [PATCH 141/249] KT-1545, KT-3161 KDoc lexer & parser --- compiler/frontend/buildLexer.xml | 4 +- .../org/jetbrains/jet/kdoc/lexer/KDoc.flex | 75 +++ .../jetbrains/jet/kdoc/lexer/KDocLexer.java | 27 + .../jetbrains/jet/kdoc/lexer/KDocToken.java | 27 + .../jetbrains/jet/kdoc/lexer/KDocTokens.java | 56 ++ .../jetbrains/jet/kdoc/lexer/_KDocLexer.java | 539 ++++++++++++++++++ .../jetbrains/jet/kdoc/parser/KDocParser.java | 39 ++ .../org/jetbrains/jet/kdoc/psi/api/KDoc.java | 23 + .../jet/kdoc/psi/api/KDocElement.java | 22 + .../jet/kdoc/psi/impl/KDocElementImpl.java | 40 ++ .../jetbrains/jet/kdoc/psi/impl/KDocImpl.java | 48 ++ .../jetbrains/jet/lang/psi/JetVisitor.java | 1 - .../org/jetbrains/jet/lexer/JetTokens.java | 11 +- .../org/jetbrains/jet/lexer/_JetLexer.java | 253 ++++---- .../psi/DocCommentAtBeginningOfFile2.txt | 4 - .../psi/DocCommentAtBeginningOfFile3.txt | 4 - .../psi/DocCommentAtBeginningOfFile4.txt | 4 - compiler/testData/psi/EOLsInComments.txt | 10 +- compiler/testData/psi/NestedComments.txt | 19 +- .../psi/examples/array/MutableArray.txt | 41 +- .../DocCommentAtBeginningOfFile1.jet | 0 .../DocCommentAtBeginningOfFile1.txt | 3 +- .../DocCommentAtBeginningOfFile2.jet | 0 .../psi/kdoc/DocCommentAtBeginningOfFile2.txt | 7 + .../DocCommentAtBeginningOfFile3.jet | 0 .../psi/kdoc/DocCommentAtBeginningOfFile3.txt | 7 + .../DocCommentAtBeginningOfFile4.jet | 0 .../psi/kdoc/DocCommentAtBeginningOfFile4.txt | 9 + .../psi/kdoc/EndOnLeadingAsterisks.kt | 2 + .../psi/kdoc/EndOnLeadingAsterisks.txt | 7 + .../testData/psi/kdoc/EndRightAfterText.kt | 1 + .../testData/psi/kdoc/EndRightAfterText.txt | 7 + compiler/testData/psi/kdoc/Incomplete.kt | 2 + compiler/testData/psi/kdoc/Incomplete.txt | 7 + compiler/testData/psi/kdoc/Simple.kt | 7 + compiler/testData/psi/kdoc/Simple.txt | 52 ++ .../psi/kdoc/TextRightAfterLeadAsterisks.kt | 3 + .../psi/kdoc/TextRightAfterLeadAsterisks.txt | 10 + .../jetbrains/jet/parsing/JetParsingTest.java | 1 + .../jetbrains/jet/plugin/JetCommenter.java | 3 +- 40 files changed, 1221 insertions(+), 154 deletions(-) create mode 100644 compiler/frontend/src/org/jetbrains/jet/kdoc/lexer/KDoc.flex create mode 100644 compiler/frontend/src/org/jetbrains/jet/kdoc/lexer/KDocLexer.java create mode 100644 compiler/frontend/src/org/jetbrains/jet/kdoc/lexer/KDocToken.java create mode 100644 compiler/frontend/src/org/jetbrains/jet/kdoc/lexer/KDocTokens.java create mode 100644 compiler/frontend/src/org/jetbrains/jet/kdoc/lexer/_KDocLexer.java create mode 100644 compiler/frontend/src/org/jetbrains/jet/kdoc/parser/KDocParser.java create mode 100644 compiler/frontend/src/org/jetbrains/jet/kdoc/psi/api/KDoc.java create mode 100644 compiler/frontend/src/org/jetbrains/jet/kdoc/psi/api/KDocElement.java create mode 100644 compiler/frontend/src/org/jetbrains/jet/kdoc/psi/impl/KDocElementImpl.java create mode 100644 compiler/frontend/src/org/jetbrains/jet/kdoc/psi/impl/KDocImpl.java delete mode 100644 compiler/testData/psi/DocCommentAtBeginningOfFile2.txt delete mode 100644 compiler/testData/psi/DocCommentAtBeginningOfFile3.txt delete mode 100644 compiler/testData/psi/DocCommentAtBeginningOfFile4.txt rename compiler/testData/psi/{ => kdoc}/DocCommentAtBeginningOfFile1.jet (100%) rename compiler/testData/psi/{ => kdoc}/DocCommentAtBeginningOfFile1.txt (65%) rename compiler/testData/psi/{ => kdoc}/DocCommentAtBeginningOfFile2.jet (100%) create mode 100644 compiler/testData/psi/kdoc/DocCommentAtBeginningOfFile2.txt rename compiler/testData/psi/{ => kdoc}/DocCommentAtBeginningOfFile3.jet (100%) create mode 100644 compiler/testData/psi/kdoc/DocCommentAtBeginningOfFile3.txt rename compiler/testData/psi/{ => kdoc}/DocCommentAtBeginningOfFile4.jet (100%) create mode 100644 compiler/testData/psi/kdoc/DocCommentAtBeginningOfFile4.txt create mode 100644 compiler/testData/psi/kdoc/EndOnLeadingAsterisks.kt create mode 100644 compiler/testData/psi/kdoc/EndOnLeadingAsterisks.txt create mode 100644 compiler/testData/psi/kdoc/EndRightAfterText.kt create mode 100644 compiler/testData/psi/kdoc/EndRightAfterText.txt create mode 100644 compiler/testData/psi/kdoc/Incomplete.kt create mode 100644 compiler/testData/psi/kdoc/Incomplete.txt create mode 100644 compiler/testData/psi/kdoc/Simple.kt create mode 100644 compiler/testData/psi/kdoc/Simple.txt create mode 100644 compiler/testData/psi/kdoc/TextRightAfterLeadAsterisks.kt create mode 100644 compiler/testData/psi/kdoc/TextRightAfterLeadAsterisks.txt diff --git a/compiler/frontend/buildLexer.xml b/compiler/frontend/buildLexer.xml index f39f99d46cd..b7539670c0d 100644 --- a/compiler/frontend/buildLexer.xml +++ b/compiler/frontend/buildLexer.xml @@ -46,6 +46,8 @@ + destdir="${home}/src/org/jetbrains/jet/lexer/"/> + diff --git a/compiler/frontend/src/org/jetbrains/jet/kdoc/lexer/KDoc.flex b/compiler/frontend/src/org/jetbrains/jet/kdoc/lexer/KDoc.flex new file mode 100644 index 00000000000..ff96ccf0bec --- /dev/null +++ b/compiler/frontend/src/org/jetbrains/jet/kdoc/lexer/KDoc.flex @@ -0,0 +1,75 @@ +package org.jetbrains.jet.kdoc.lexer; + +import com.intellij.lexer.FlexLexer; +import com.intellij.psi.TokenType; +import com.intellij.psi.tree.IElementType; +import com.intellij.util.text.CharArrayUtil; + +%% + +%unicode +%class _KDocLexer +%implements FlexLexer + +%{ + public _KDocLexer() { + this((java.io.Reader)null); + } + + private final boolean isLastToken() { + return zzMarkedPos == zzBuffer.length(); + } + + private final Boolean yytextContainLineBreaks() { + return CharArrayUtil.containLineBreaks(zzBuffer, zzStartRead, zzMarkedPos); + } + + private final void pushbackEnd() { + if (isLastToken() && CharArrayUtil.regionMatches(zzBuffer, zzMarkedPos - 2, zzMarkedPos, "*/")) { + yypushback(2); + } + } + + private final void pushbackText() { + int i = zzStartRead; + while (zzBuffer.charAt(i) == '*') i++; + yypushback(zzMarkedPos - i); + } +%} + +%function advance +%type IElementType +%eof{ + return; +%eof} + +%state CONTENTS +%state LINE_BEGINNING + +WHITE_SPACE_CHAR =[\ \t\f\n\r] +NOT_WHITE_SPACE_CHAR=[^\ \t\f\n\r] + +%% + + + "/**" { yybegin(CONTENTS); + return KDocTokens.START; } +"*"+ "/" { if (isLastToken()) + return KDocTokens.END; } + +// hack: make longest match + "*"+ {NOT_WHITE_SPACE_CHAR}* { pushbackText(); + yybegin(CONTENTS); + return KDocTokens.LEADING_ASTERISK; } + + { + // todo: put markdown and @tags token patterns here + + {NOT_WHITE_SPACE_CHAR}+ { pushbackEnd(); + return KDocTokens.TEXT; } + {WHITE_SPACE_CHAR}+ { if (yytextContainLineBreaks()) + yybegin(LINE_BEGINNING); + return TokenType.WHITE_SPACE; } +} + +. { return TokenType.BAD_CHARACTER; } \ No newline at end of file diff --git a/compiler/frontend/src/org/jetbrains/jet/kdoc/lexer/KDocLexer.java b/compiler/frontend/src/org/jetbrains/jet/kdoc/lexer/KDocLexer.java new file mode 100644 index 00000000000..dd9be21a218 --- /dev/null +++ b/compiler/frontend/src/org/jetbrains/jet/kdoc/lexer/KDocLexer.java @@ -0,0 +1,27 @@ +/* + * Copyright 2010-2013 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.jetbrains.jet.kdoc.lexer; + +import com.intellij.lexer.FlexAdapter; + +import java.io.Reader; + +public class KDocLexer extends FlexAdapter { + public KDocLexer() { + super(new _KDocLexer((Reader) null)); + } +} diff --git a/compiler/frontend/src/org/jetbrains/jet/kdoc/lexer/KDocToken.java b/compiler/frontend/src/org/jetbrains/jet/kdoc/lexer/KDocToken.java new file mode 100644 index 00000000000..3d321b008f7 --- /dev/null +++ b/compiler/frontend/src/org/jetbrains/jet/kdoc/lexer/KDocToken.java @@ -0,0 +1,27 @@ +/* + * Copyright 2010-2013 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.jetbrains.jet.kdoc.lexer; + +import org.jetbrains.annotations.NonNls; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.jet.lexer.JetToken; + +public class KDocToken extends JetToken { + public KDocToken(@NotNull @NonNls String debugName) { + super(debugName); + } +} diff --git a/compiler/frontend/src/org/jetbrains/jet/kdoc/lexer/KDocTokens.java b/compiler/frontend/src/org/jetbrains/jet/kdoc/lexer/KDocTokens.java new file mode 100644 index 00000000000..217eb51c14d --- /dev/null +++ b/compiler/frontend/src/org/jetbrains/jet/kdoc/lexer/KDocTokens.java @@ -0,0 +1,56 @@ +/* + * Copyright 2010-2013 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.jetbrains.jet.kdoc.lexer; + +import com.intellij.lang.ASTNode; +import com.intellij.lang.PsiBuilder; +import com.intellij.lang.PsiBuilderFactory; +import com.intellij.lang.PsiParser; +import com.intellij.openapi.project.Project; +import com.intellij.psi.PsiElement; +import com.intellij.psi.tree.ILazyParseableElementType; +import org.jetbrains.annotations.Nullable; +import org.jetbrains.jet.kdoc.parser.KDocParser; +import org.jetbrains.jet.kdoc.psi.impl.KDocImpl; +import org.jetbrains.jet.plugin.JetLanguage; + +public interface KDocTokens { + ILazyParseableElementType KDOC = new ILazyParseableElementType("KDoc", JetLanguage.INSTANCE) { + @Override + public ASTNode parseContents(ASTNode chameleon) { + PsiElement parentElement = chameleon.getTreeParent().getPsi(); + Project project = parentElement.getProject(); + PsiBuilder builder = PsiBuilderFactory.getInstance().createBuilder(project, chameleon, new KDocLexer(), getLanguage(), + chameleon.getText()); + PsiParser parser = new KDocParser(); + + return parser.parse(this, builder).getFirstChildNode(); + } + + @Nullable + @Override + public ASTNode createNode(CharSequence text) { + return new KDocImpl(text); + } + }; + + KDocToken START = new KDocToken("KDOC_START"); + KDocToken END = new KDocToken("KDOC_END"); + KDocToken LEADING_ASTERISK = new KDocToken("KDOC_LEADING_ASTERISK"); + + KDocToken TEXT = new KDocToken("KDOC_TEXT"); +} diff --git a/compiler/frontend/src/org/jetbrains/jet/kdoc/lexer/_KDocLexer.java b/compiler/frontend/src/org/jetbrains/jet/kdoc/lexer/_KDocLexer.java new file mode 100644 index 00000000000..c2007811156 --- /dev/null +++ b/compiler/frontend/src/org/jetbrains/jet/kdoc/lexer/_KDocLexer.java @@ -0,0 +1,539 @@ +/* The following code was generated by JFlex 1.4.3 on 23.05.13 19:26 */ + +package org.jetbrains.jet.kdoc.lexer; + +import com.intellij.lexer.FlexLexer; +import com.intellij.psi.TokenType; +import com.intellij.psi.tree.IElementType; +import com.intellij.util.text.CharArrayUtil; + + +/** + * This class is a scanner generated by + * JFlex 1.4.3 + * on 23.05.13 19:26 from the specification file + * /Users/factitious/Documents/kotlin/compiler/frontend/src/org/jetbrains/jet/kdoc/lexer/KDoc.flex + */ +class _KDocLexer implements FlexLexer { + /** initial size of the lookahead buffer */ + private static final int ZZ_BUFFERSIZE = 16384; + + /** lexical states */ + public static final int LINE_BEGINNING = 4; + public static final int CONTENTS = 2; + public static final int YYINITIAL = 0; + + /** + * ZZ_LEXSTATE[l] is the state in the DFA for the lexical state l + * ZZ_LEXSTATE[l+1] is the state in the DFA for the lexical state l + * at the beginning of a line + * l is of the form l = 2*k, k a non negative integer + */ + private static final int ZZ_LEXSTATE[] = { + 0, 0, 1, 1, 2, 2 + }; + + /** + * Translates characters to character classes + */ + private static final String ZZ_CMAP_PACKED = + "\11\0\1\1\1\4\1\0\2\1\22\0\1\1\11\0\1\3\4\0"+ + "\1\2\uffd0\0"; + + /** + * Translates characters to character classes + */ + private static final char [] ZZ_CMAP = zzUnpackCMap(ZZ_CMAP_PACKED); + + /** + * Translates DFA states to action switch labels. + */ + private static final int [] ZZ_ACTION = zzUnpackAction(); + + private static final String ZZ_ACTION_PACKED_0 = + "\3\0\3\1\1\2\1\3\1\2\1\4\1\0\1\5"+ + "\1\0\1\5\1\4\1\5\1\6"; + + private static int [] zzUnpackAction() { + int [] result = new int[17]; + int offset = 0; + offset = zzUnpackAction(ZZ_ACTION_PACKED_0, offset, result); + return result; + } + + private static int zzUnpackAction(String packed, int offset, int [] result) { + int i = 0; /* index in packed string */ + int j = offset; /* index in unpacked array */ + int l = packed.length(); + while (i < l) { + int count = packed.charAt(i++); + int value = packed.charAt(i++); + do result[j++] = value; while (--count > 0); + } + return j; + } + + + /** + * Translates a state to a row index in the transition table + */ + private static final int [] ZZ_ROWMAP = zzUnpackRowMap(); + + private static final String ZZ_ROWMAP_PACKED_0 = + "\0\0\0\5\0\12\0\17\0\24\0\31\0\36\0\43"+ + "\0\50\0\55\0\62\0\17\0\31\0\36\0\67\0\67"+ + "\0\17"; + + private static int [] zzUnpackRowMap() { + int [] result = new int[17]; + int offset = 0; + offset = zzUnpackRowMap(ZZ_ROWMAP_PACKED_0, offset, result); + return result; + } + + private static int zzUnpackRowMap(String packed, int offset, int [] result) { + int i = 0; /* index in packed string */ + int j = offset; /* index in unpacked array */ + int l = packed.length(); + while (i < l) { + int high = packed.charAt(i++) << 16; + result[j++] = high | packed.charAt(i++); + } + return j; + } + + /** + * The transition table of the DFA + */ + private static final int [] ZZ_TRANS = zzUnpackTrans(); + + private static final String ZZ_TRANS_PACKED_0 = + "\2\4\1\5\1\6\1\0\1\7\1\10\1\7\1\11"+ + "\1\10\1\7\1\10\1\7\1\12\1\10\10\0\1\13"+ + "\3\0\1\14\1\15\1\0\1\7\1\0\2\7\2\0"+ + "\1\10\2\0\1\10\1\7\1\0\1\16\1\11\1\0"+ + "\1\17\1\0\1\20\1\12\4\0\1\21\1\0\1\17"+ + "\1\0\2\17\1\0"; + + private static int [] zzUnpackTrans() { + int [] result = new int[60]; + int offset = 0; + offset = zzUnpackTrans(ZZ_TRANS_PACKED_0, offset, result); + return result; + } + + private static int zzUnpackTrans(String packed, int offset, int [] result) { + int i = 0; /* index in packed string */ + int j = offset; /* index in unpacked array */ + int l = packed.length(); + while (i < l) { + int count = packed.charAt(i++); + int value = packed.charAt(i++); + value--; + do result[j++] = value; while (--count > 0); + } + return j; + } + + + /* error codes */ + private static final int ZZ_UNKNOWN_ERROR = 0; + private static final int ZZ_NO_MATCH = 1; + private static final int ZZ_PUSHBACK_2BIG = 2; + private static final char[] EMPTY_BUFFER = new char[0]; + private static final int YYEOF = -1; + private static java.io.Reader zzReader = null; // Fake + + /* error messages for the codes above */ + private static final String ZZ_ERROR_MSG[] = { + "Unkown internal scanner error", + "Error: could not match input", + "Error: pushback value was too large" + }; + + /** + * ZZ_ATTRIBUTE[aState] contains the attributes of state aState + */ + private static final int [] ZZ_ATTRIBUTE = zzUnpackAttribute(); + + private static final String ZZ_ATTRIBUTE_PACKED_0 = + "\3\0\1\11\6\1\1\0\1\11\1\0\3\1\1\11"; + + private static int [] zzUnpackAttribute() { + int [] result = new int[17]; + int offset = 0; + offset = zzUnpackAttribute(ZZ_ATTRIBUTE_PACKED_0, offset, result); + return result; + } + + private static int zzUnpackAttribute(String packed, int offset, int [] result) { + int i = 0; /* index in packed string */ + int j = offset; /* index in unpacked array */ + int l = packed.length(); + while (i < l) { + int count = packed.charAt(i++); + int value = packed.charAt(i++); + do result[j++] = value; while (--count > 0); + } + return j; + } + + /** the current state of the DFA */ + private int zzState; + + /** the current lexical state */ + private int zzLexicalState = YYINITIAL; + + /** this buffer contains the current text to be matched and is + the source of the yytext() string */ + private CharSequence zzBuffer = ""; + + /** this buffer may contains the current text array to be matched when it is cheap to acquire it */ + private char[] zzBufferArray; + + /** the textposition at the last accepting state */ + private int zzMarkedPos; + + /** the textposition at the last state to be included in yytext */ + private int zzPushbackPos; + + /** the current text position in the buffer */ + private int zzCurrentPos; + + /** startRead marks the beginning of the yytext() string in the buffer */ + private int zzStartRead; + + /** endRead marks the last character in the buffer, that has been read + from input */ + private int zzEndRead; + + /** + * zzAtBOL == true <=> the scanner is currently at the beginning of a line + */ + private boolean zzAtBOL = true; + + /** zzAtEOF == true <=> the scanner is at the EOF */ + private boolean zzAtEOF; + + /** denotes if the user-EOF-code has already been executed */ + private boolean zzEOFDone; + + /* user code: */ + public _KDocLexer() { + this((java.io.Reader)null); + } + + private final boolean isLastToken() { + return zzMarkedPos == zzBuffer.length(); + } + + private final Boolean yytextContainLineBreaks() { + return CharArrayUtil.containLineBreaks(zzBuffer, zzStartRead, zzMarkedPos); + } + + private final void pushbackEnd() { + if (isLastToken() && CharArrayUtil.regionMatches(zzBuffer, zzMarkedPos - 2, zzMarkedPos, "*/")) { + yypushback(2); + } + } + + private final void pushbackText() { + int i = zzStartRead; + while (zzBuffer.charAt(i) == '*') i++; + yypushback(zzMarkedPos - i); + } + + + _KDocLexer(java.io.Reader in) { + this.zzReader = in; + } + + /** + * Creates a new scanner. + * There is also java.io.Reader version of this constructor. + * + * @param in the java.io.Inputstream to read input from. + */ + _KDocLexer(java.io.InputStream in) { + this(new java.io.InputStreamReader(in)); + } + + /** + * Unpacks the compressed character translation table. + * + * @param packed the packed character translation table + * @return the unpacked character translation table + */ + private static char [] zzUnpackCMap(String packed) { + char [] map = new char[0x10000]; + int i = 0; /* index in packed string */ + int j = 0; /* index in unpacked array */ + while (i < 24) { + int count = packed.charAt(i++); + char value = packed.charAt(i++); + do map[j++] = value; while (--count > 0); + } + return map; + } + + public final int getTokenStart(){ + return zzStartRead; + } + + public final int getTokenEnd(){ + return getTokenStart() + yylength(); + } + + public void reset(CharSequence buffer, int start, int end,int initialState){ + zzBuffer = buffer; + zzBufferArray = com.intellij.util.text.CharArrayUtil.fromSequenceWithoutCopying(buffer); + zzCurrentPos = zzMarkedPos = zzStartRead = start; + zzPushbackPos = 0; + zzAtEOF = false; + zzAtBOL = true; + zzEndRead = end; + yybegin(initialState); + } + + /** + * Refills the input buffer. + * + * @return false, iff there was new input. + * + * @exception java.io.IOException if any I/O-Error occurs + */ + private boolean zzRefill() throws java.io.IOException { + return true; + } + + + /** + * Returns the current lexical state. + */ + public final int yystate() { + return zzLexicalState; + } + + + /** + * Enters a new lexical state + * + * @param newState the new lexical state + */ + public final void yybegin(int newState) { + zzLexicalState = newState; + } + + + /** + * Returns the text matched by the current regular expression. + */ + public final CharSequence yytext() { + return zzBuffer.subSequence(zzStartRead, zzMarkedPos); + } + + + /** + * Returns the character at position pos from the + * matched text. + * + * It is equivalent to yytext().charAt(pos), but faster + * + * @param pos the position of the character to fetch. + * A value from 0 to yylength()-1. + * + * @return the character at position pos + */ + public final char yycharat(int pos) { + return zzBufferArray != null ? zzBufferArray[zzStartRead+pos]:zzBuffer.charAt(zzStartRead+pos); + } + + + /** + * Returns the length of the matched text region. + */ + public final int yylength() { + return zzMarkedPos-zzStartRead; + } + + + /** + * Reports an error that occured while scanning. + * + * In a wellformed scanner (no or only correct usage of + * yypushback(int) and a match-all fallback rule) this method + * will only be called with things that "Can't Possibly Happen". + * If this method is called, something is seriously wrong + * (e.g. a JFlex bug producing a faulty scanner etc.). + * + * Usual syntax/scanner level error handling should be done + * in error fallback rules. + * + * @param errorCode the code of the errormessage to display + */ + private void zzScanError(int errorCode) { + String message; + try { + message = ZZ_ERROR_MSG[errorCode]; + } + catch (ArrayIndexOutOfBoundsException e) { + message = ZZ_ERROR_MSG[ZZ_UNKNOWN_ERROR]; + } + + throw new Error(message); + } + + + /** + * Pushes the specified amount of characters back into the input stream. + * + * They will be read again by then next call of the scanning method + * + * @param number the number of characters to be read again. + * This number must not be greater than yylength()! + */ + public void yypushback(int number) { + if ( number > yylength() ) + zzScanError(ZZ_PUSHBACK_2BIG); + + zzMarkedPos -= number; + } + + + /** + * Contains user EOF-code, which will be executed exactly once, + * when the end of file is reached + */ + private void zzDoEOF() { + if (!zzEOFDone) { + zzEOFDone = true; + return; + + } + } + + + /** + * Resumes scanning until the next regular expression is matched, + * the end of input is encountered or an I/O-Error occurs. + * + * @return the next token + * @exception java.io.IOException if any I/O-Error occurs + */ + public IElementType advance() throws java.io.IOException { + int zzInput; + int zzAction; + + // cached fields: + int zzCurrentPosL; + int zzMarkedPosL; + int zzEndReadL = zzEndRead; + CharSequence zzBufferL = zzBuffer; + char[] zzBufferArrayL = zzBufferArray; + char [] zzCMapL = ZZ_CMAP; + + int [] zzTransL = ZZ_TRANS; + int [] zzRowMapL = ZZ_ROWMAP; + int [] zzAttrL = ZZ_ATTRIBUTE; + + while (true) { + zzMarkedPosL = zzMarkedPos; + + zzAction = -1; + + zzCurrentPosL = zzCurrentPos = zzStartRead = zzMarkedPosL; + + zzState = ZZ_LEXSTATE[zzLexicalState]; + + + zzForAction: { + while (true) { + + if (zzCurrentPosL < zzEndReadL) + zzInput = (zzBufferArrayL != null ? zzBufferArrayL[zzCurrentPosL++] : zzBufferL.charAt(zzCurrentPosL++)); + else if (zzAtEOF) { + zzInput = YYEOF; + break zzForAction; + } + else { + // store back cached positions + zzCurrentPos = zzCurrentPosL; + zzMarkedPos = zzMarkedPosL; + boolean eof = zzRefill(); + // get translated positions and possibly new buffer + zzCurrentPosL = zzCurrentPos; + zzMarkedPosL = zzMarkedPos; + zzBufferL = zzBuffer; + zzEndReadL = zzEndRead; + if (eof) { + zzInput = YYEOF; + break zzForAction; + } + else { + zzInput = (zzBufferArrayL != null ? zzBufferArrayL[zzCurrentPosL++] : zzBufferL.charAt(zzCurrentPosL++)); + } + } + int zzNext = zzTransL[ zzRowMapL[zzState] + zzCMapL[zzInput] ]; + if (zzNext == -1) break zzForAction; + zzState = zzNext; + + int zzAttributes = zzAttrL[zzState]; + if ( (zzAttributes & 1) == 1 ) { + zzAction = zzState; + zzMarkedPosL = zzCurrentPosL; + if ( (zzAttributes & 8) == 8 ) break zzForAction; + } + + } + } + + // store back cached position + zzMarkedPos = zzMarkedPosL; + + switch (zzAction < 0 ? zzAction : ZZ_ACTION[zzAction]) { + case 6: + { yybegin(CONTENTS); + return KDocTokens.START; + } + case 7: break; + case 5: + { if (isLastToken()) + return KDocTokens.END; + } + case 8: break; + case 1: + { return TokenType.BAD_CHARACTER; + } + case 9: break; + case 2: + { pushbackEnd(); + return KDocTokens.TEXT; + } + case 10: break; + case 4: + { pushbackText(); + yybegin(CONTENTS); + return KDocTokens.LEADING_ASTERISK; + } + case 11: break; + case 3: + { if (yytextContainLineBreaks()) + yybegin(LINE_BEGINNING); + return TokenType.WHITE_SPACE; + } + case 12: break; + default: + if (zzInput == YYEOF && zzStartRead == zzCurrentPos) { + zzAtEOF = true; + zzDoEOF(); + return null; + } + else { + zzScanError(ZZ_NO_MATCH); + } + } + } + } + + +} diff --git a/compiler/frontend/src/org/jetbrains/jet/kdoc/parser/KDocParser.java b/compiler/frontend/src/org/jetbrains/jet/kdoc/parser/KDocParser.java new file mode 100644 index 00000000000..dd2e07e168c --- /dev/null +++ b/compiler/frontend/src/org/jetbrains/jet/kdoc/parser/KDocParser.java @@ -0,0 +1,39 @@ +/* + * Copyright 2010-2013 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.jetbrains.jet.kdoc.parser; + +import com.intellij.lang.ASTNode; +import com.intellij.lang.PsiBuilder; +import com.intellij.lang.PsiParser; +import com.intellij.psi.tree.IElementType; +import org.jetbrains.annotations.NotNull; + +public class KDocParser implements PsiParser { + @Override + @NotNull + public ASTNode parse(IElementType root, PsiBuilder builder) { + PsiBuilder.Marker rootMarker = builder.mark(); + + // todo: parse KDoc tags, markdown, etc... + while (!builder.eof()) { + builder.advanceLexer(); + } + + rootMarker.done(root); + return builder.getTreeBuilt(); + } +} diff --git a/compiler/frontend/src/org/jetbrains/jet/kdoc/psi/api/KDoc.java b/compiler/frontend/src/org/jetbrains/jet/kdoc/psi/api/KDoc.java new file mode 100644 index 00000000000..5c5c40daef1 --- /dev/null +++ b/compiler/frontend/src/org/jetbrains/jet/kdoc/psi/api/KDoc.java @@ -0,0 +1,23 @@ +/* + * Copyright 2010-2013 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.jetbrains.jet.kdoc.psi.api; + +import com.intellij.psi.PsiComment; + +// Don't implement JetElement (or it will be treated as statement) +public interface KDoc extends PsiComment { +} diff --git a/compiler/frontend/src/org/jetbrains/jet/kdoc/psi/api/KDocElement.java b/compiler/frontend/src/org/jetbrains/jet/kdoc/psi/api/KDocElement.java new file mode 100644 index 00000000000..32119bebdd9 --- /dev/null +++ b/compiler/frontend/src/org/jetbrains/jet/kdoc/psi/api/KDocElement.java @@ -0,0 +1,22 @@ +/* + * Copyright 2010-2013 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.jetbrains.jet.kdoc.psi.api; + +import org.jetbrains.jet.lang.psi.JetElement; + +public interface KDocElement extends JetElement { +} diff --git a/compiler/frontend/src/org/jetbrains/jet/kdoc/psi/impl/KDocElementImpl.java b/compiler/frontend/src/org/jetbrains/jet/kdoc/psi/impl/KDocElementImpl.java new file mode 100644 index 00000000000..39716bac4b7 --- /dev/null +++ b/compiler/frontend/src/org/jetbrains/jet/kdoc/psi/impl/KDocElementImpl.java @@ -0,0 +1,40 @@ +/* + * Copyright 2010-2013 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.jetbrains.jet.kdoc.psi.impl; + +import com.intellij.extapi.psi.ASTWrapperPsiElement; +import com.intellij.lang.ASTNode; +import com.intellij.lang.Language; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.jet.plugin.JetLanguage; + +public abstract class KDocElementImpl extends ASTWrapperPsiElement { + @NotNull + @Override + public Language getLanguage() { + return JetLanguage.INSTANCE; + } + + @Override + public String toString() { + return getNode().getElementType().toString(); + } + + public KDocElementImpl(@NotNull ASTNode node) { + super(node); + } +} diff --git a/compiler/frontend/src/org/jetbrains/jet/kdoc/psi/impl/KDocImpl.java b/compiler/frontend/src/org/jetbrains/jet/kdoc/psi/impl/KDocImpl.java new file mode 100644 index 00000000000..5cb4db81a40 --- /dev/null +++ b/compiler/frontend/src/org/jetbrains/jet/kdoc/psi/impl/KDocImpl.java @@ -0,0 +1,48 @@ +/* + * Copyright 2010-2013 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.jetbrains.jet.kdoc.psi.impl; + +import com.intellij.lang.Language; +import com.intellij.psi.impl.source.tree.LazyParseablePsiElement; +import com.intellij.psi.tree.IElementType; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.jet.kdoc.lexer.KDocTokens; +import org.jetbrains.jet.kdoc.psi.api.KDoc; +import org.jetbrains.jet.lexer.JetTokens; +import org.jetbrains.jet.plugin.JetLanguage; + +public class KDocImpl extends LazyParseablePsiElement implements KDoc { + public KDocImpl(CharSequence buffer) { + super(KDocTokens.KDOC, buffer); + } + + @NotNull + @Override + public Language getLanguage() { + return JetLanguage.INSTANCE; + } + + @Override + public String toString() { + return getNode().getElementType().toString(); + } + + @Override + public IElementType getTokenType() { + return JetTokens.DOC_COMMENT; + } +} diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetVisitor.java b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetVisitor.java index 082ad68d492..7c6058ef924 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetVisitor.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetVisitor.java @@ -408,5 +408,4 @@ public class JetVisitor extends PsiElementVisitor { public R visitEscapeStringTemplateEntry(JetEscapeStringTemplateEntry entry, D data) { return visitStringTemplateEntry(entry, data); } - } diff --git a/compiler/frontend/src/org/jetbrains/jet/lexer/JetTokens.java b/compiler/frontend/src/org/jetbrains/jet/lexer/JetTokens.java index 8bd4eb4594d..0c0124566b7 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lexer/JetTokens.java +++ b/compiler/frontend/src/org/jetbrains/jet/lexer/JetTokens.java @@ -19,14 +19,17 @@ package org.jetbrains.jet.lexer; import com.intellij.psi.TokenType; import com.intellij.psi.tree.IElementType; import com.intellij.psi.tree.TokenSet; +import org.jetbrains.jet.kdoc.lexer.KDocTokens; public interface JetTokens { JetToken EOF = new JetToken("EOF"); - JetToken BLOCK_COMMENT = new JetToken("BLOCK_COMMENT"); - JetToken DOC_COMMENT = new JetToken("DOC_COMMENT"); - JetToken EOL_COMMENT = new JetToken("EOL_COMMENT"); - JetToken SHEBANG_COMMENT = new JetToken("SHEBANG_COMMENT"); + JetToken BLOCK_COMMENT = new JetToken("BLOCK_COMMENT"); + JetToken EOL_COMMENT = new JetToken("EOL_COMMENT"); + JetToken SHEBANG_COMMENT = new JetToken("SHEBANG_COMMENT"); + + //JetToken DOC_COMMENT = new JetToken("DOC_COMMENT"); + IElementType DOC_COMMENT = KDocTokens.KDOC; IElementType WHITE_SPACE = TokenType.WHITE_SPACE; diff --git a/compiler/frontend/src/org/jetbrains/jet/lexer/_JetLexer.java b/compiler/frontend/src/org/jetbrains/jet/lexer/_JetLexer.java index d7cf8fbff21..f56cf18375f 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lexer/_JetLexer.java +++ b/compiler/frontend/src/org/jetbrains/jet/lexer/_JetLexer.java @@ -1,21 +1,18 @@ -/* The following code was generated by JFlex 1.4.3 on 3/12/13 8:22 PM */ +/* The following code was generated by JFlex 1.4.3 on 23.05.13 19:26 */ package org.jetbrains.jet.lexer; -import java.util.*; -import com.intellij.lexer.*; -import com.intellij.psi.*; +import com.intellij.lexer.FlexLexer; +import com.intellij.psi.TokenType; import com.intellij.psi.tree.IElementType; import com.intellij.util.containers.Stack; -import org.jetbrains.jet.lexer.JetTokens; - /** * This class is a scanner generated by * JFlex 1.4.3 - * on 3/12/13 8:22 PM from the specification file - * C:/1/kotlin/compiler/frontend/src/org/jetbrains/jet/lexer/Jet.flex + * on 23.05.13 19:26 from the specification file + * /Users/factitious/Documents/kotlin/compiler/frontend/src/org/jetbrains/jet/lexer/Jet.flex */ class _JetLexer implements FlexLexer { /** initial size of the lookahead buffer */ @@ -843,7 +840,7 @@ class _JetLexer implements FlexLexer { while (true) { if (zzCurrentPosL < zzEndReadL) - zzInput = zzBufferArrayL != null ? zzBufferArrayL[zzCurrentPosL++]:zzBufferL.charAt(zzCurrentPosL++); + zzInput = (zzBufferArrayL != null ? zzBufferArrayL[zzCurrentPosL++] : zzBufferL.charAt(zzCurrentPosL++)); else if (zzAtEOF) { zzInput = YYEOF; break zzForAction; @@ -863,7 +860,7 @@ class _JetLexer implements FlexLexer { break zzForAction; } else { - zzInput = zzBufferArrayL != null ? zzBufferArrayL[zzCurrentPosL++]:zzBufferL.charAt(zzCurrentPosL++); + zzInput = (zzBufferArrayL != null ? zzBufferArrayL[zzCurrentPosL++] : zzBufferL.charAt(zzCurrentPosL++)); } } int zzNext = zzTransL[ zzRowMapL[zzState] + zzCMapL[zzInput] ]; @@ -904,193 +901,202 @@ class _JetLexer implements FlexLexer { { return JetTokens.NULL_KEYWORD ; } case 110: break; + case 35: + { if (lBraceCount == 0) { + popState(); + return JetTokens.LONG_TEMPLATE_ENTRY_END; + } + lBraceCount--; + return JetTokens.RBRACE; + } + case 111: break; case 16: { return JetTokens.LT ; } - case 111: break; + case 112: break; case 54: { return JetTokens.DO_KEYWORD ; } - case 112: break; + case 113: break; case 20: { return JetTokens.PLUS ; } - case 113: break; + case 114: break; case 59: { return JetTokens.PLUSEQ ; } - case 114: break; + case 115: break; case 94: { popState(); return JetTokens.THIS_KEYWORD; } - case 115: break; + case 116: break; case 28: { return JetTokens.COMMA ; } - case 116: break; + case 117: break; case 17: { return JetTokens.GT ; } - case 117: break; + case 118: break; case 4: { return JetTokens.WHITE_SPACE; } - case 118: break; + case 119: break; case 26: { return JetTokens.RPAR ; } - case 119: break; + case 120: break; case 57: { return JetTokens.DOUBLE_ARROW; } - case 120: break; + case 121: break; case 88: { return JetTokens.TRUE_KEYWORD ; } - case 121: break; + case 122: break; case 82: { return JetTokens.IDE_TEMPLATE_START ; } - case 122: break; + case 123: break; case 37: { return JetTokens.FIELD_IDENTIFIER; } - case 123: break; + case 124: break; case 61: { return JetTokens.ANDAND ; } - case 124: break; + case 125: break; case 66: { pushState(LONG_TEMPLATE_ENTRY); return JetTokens.LONG_TEMPLATE_ENTRY_START; } - case 125: break; + case 126: break; case 36: { return JetTokens.FLOAT_LITERAL; } - case 126: break; + case 127: break; case 40: { return JetTokens.EOL_COMMENT; } - case 127: break; + case 128: break; case 92: { return JetTokens.WHEN_KEYWORD ; } - case 128: break; + case 129: break; case 75: { pushState(RAW_STRING); return JetTokens.OPEN_QUOTE; } - case 129: break; + case 130: break; case 22: { return JetTokens.COLON ; } - case 130: break; + case 131: break; case 55: { return JetTokens.LTEQ ; } - case 131: break; + case 132: break; case 47: { return JetTokens.ARROW ; } - case 132: break; + case 133: break; case 32: { popState(); return JetTokens.IDENTIFIER; } - case 133: break; + case 134: break; case 23: { return JetTokens.LBRACKET ; } - case 134: break; + case 135: break; case 70: { yypushback(2); return JetTokens.INTEGER_LITERAL; } - case 135: break; + case 136: break; case 11: { return JetTokens.CHARACTER_LITERAL; } - case 136: break; + case 137: break; case 80: { return JetTokens.VAR_KEYWORD ; } - case 137: break; + case 138: break; case 56: { return JetTokens.GTEQ ; } - case 138: break; + case 139: break; case 2: { return JetTokens.INTEGER_LITERAL; } - case 139: break; + case 140: break; case 14: { return JetTokens.RBRACE ; } - case 140: break; + case 141: break; case 98: { return JetTokens.CLASS_KEYWORD ; } - case 141: break; + case 142: break; case 76: { return JetTokens.TRY_KEYWORD ; } - case 142: break; + case 143: break; case 8: { return JetTokens.EXCL ; } - case 143: break; + case 144: break; case 44: { return JetTokens.EXCLEQ ; } - case 144: break; + case 145: break; case 48: { return JetTokens.MINUSEQ ; } - case 145: break; + case 146: break; case 104: { return JetTokens.PACKAGE_KEYWORD ; } - case 146: break; + case 147: break; case 95: { return JetTokens.THROW_KEYWORD ; } - case 147: break; + case 148: break; case 97: { return JetTokens.SUPER_KEYWORD ; } - case 148: break; + case 149: break; + case 69: + { if (commentDepth > 0) { + commentDepth--; + } + else { + int state = yystate(); + popState(); + zzStartRead = commentStart; + return commentStateToTokenType(state); + } + } + case 150: break; case 100: { return JetTokens.WHILE_KEYWORD ; } - case 149: break; + case 151: break; case 46: { return JetTokens.MINUSMINUS; } - case 150: break; + case 152: break; case 105: { return JetTokens.CONTINUE_KEYWORD ; } - case 151: break; + case 153: break; case 73: { return JetTokens.NOT_IN; } - case 152: break; + case 154: break; case 39: { return JetTokens.ATAT ; } - case 153: break; - case 71: - { pushState(DOC_COMMENT); - commentDepth = 0; - commentStart = getTokenStart(); - } - case 154: break; + case 155: break; case 6: { return JetTokens.DIV ; } - case 155: break; - case 65: - { pushState(SHORT_TEMPLATE_ENTRY); - yypushback(yylength() - 1); - return JetTokens.SHORT_TEMPLATE_ENTRY_START; - } case 156: break; case 83: { return JetTokens.IDE_TEMPLATE_END ; @@ -1108,14 +1114,10 @@ class _JetLexer implements FlexLexer { { return JetTokens.QUEST ; } case 160: break; - case 43: - { if (zzCurrentPos == 0) { - return JetTokens.SHEBANG_COMMENT; - } - else { - yypushback(yylength() - 1); - return JetTokens.HASH; - } + case 71: + { pushState(DOC_COMMENT); + commentDepth = 0; + commentStart = getTokenStart(); } case 161: break; case 62: @@ -1142,83 +1144,77 @@ class _JetLexer implements FlexLexer { { return TokenType.BAD_CHARACTER; } case 167: break; + case 65: + { pushState(SHORT_TEMPLATE_ENTRY); + yypushback(yylength() - 1); + return JetTokens.SHORT_TEMPLATE_ENTRY_START; + } + case 168: break; case 72: { return JetTokens.NOT_IS; } - case 168: break; + case 169: break; case 15: { return JetTokens.MUL ; } - case 169: break; + case 170: break; case 24: { return JetTokens.RBRACKET ; } - case 170: break; + case 171: break; case 60: { return JetTokens.PLUSPLUS ; } - case 171: break; - case 87: - { return JetTokens.THIS_KEYWORD ; - } case 172: break; - case 9: - { return JetTokens.DOT ; - } - case 173: break; - case 27: - { return JetTokens.SEMICOLON ; - } - case 174: break; - case 51: - { return JetTokens.IF_KEYWORD ; - } - case 175: break; - case 67: - { return JetTokens.ESCAPE_SEQUENCE; - } - case 176: break; case 41: { pushState(BLOCK_COMMENT); commentDepth = 0; commentStart = getTokenStart(); } + case 173: break; + case 87: + { return JetTokens.THIS_KEYWORD ; + } + case 174: break; + case 9: + { return JetTokens.DOT ; + } + case 175: break; + case 27: + { return JetTokens.SEMICOLON ; + } + case 176: break; + case 51: + { return JetTokens.IF_KEYWORD ; + } case 177: break; + case 67: + { return JetTokens.ESCAPE_SEQUENCE; + } + case 178: break; case 31: { popState(); return JetTokens.CLOSING_QUOTE; } - case 178: break; + case 179: break; case 18: { return JetTokens.EQ ; } - case 179: break; + case 180: break; case 5: { return JetTokens.AT ; } - case 180: break; + case 181: break; case 77: { return JetTokens.AS_SAFE; } - case 181: break; + case 182: break; case 25: { return JetTokens.LPAR ; } - case 182: break; + case 183: break; case 10: { return JetTokens.MINUS ; } - case 183: break; - case 69: - { if (commentDepth > 0) { - commentDepth--; - } - else { - int state = yystate(); - popState(); - zzStartRead = commentStart; - return commentStateToTokenType(state); - } - } case 184: break; case 101: { return JetTokens.FALSE_KEYWORD ; @@ -1288,42 +1284,43 @@ class _JetLexer implements FlexLexer { { return JetTokens.MULTEQ ; } case 201: break; + case 43: + { if (zzCurrentPos == 0) { + return JetTokens.SHEBANG_COMMENT; + } + else { + yypushback(yylength() - 1); + return JetTokens.HASH; + } + } + case 202: break; case 13: { return JetTokens.LBRACE ; } - case 202: break; + case 203: break; case 102: { return JetTokens.OBJECT_KEYWORD ; } - case 203: break; + case 204: break; case 99: { return JetTokens.BREAK_KEYWORD ; } - case 204: break; + case 205: break; case 85: { return JetTokens.BLOCK_COMMENT; } - case 205: break; + case 206: break; case 96: { return JetTokens.TRAIT_KEYWORD ; } - case 206: break; + case 207: break; case 64: { return JetTokens.COLONCOLON; } - case 207: break; + case 208: break; case 33: { } - case 208: break; - case 35: - { if (lBraceCount == 0) { - popState(); - return JetTokens.LONG_TEMPLATE_ENTRY_END; - } - lBraceCount--; - return JetTokens.RBRACE; - } case 209: break; case 7: { return JetTokens.HASH ; diff --git a/compiler/testData/psi/DocCommentAtBeginningOfFile2.txt b/compiler/testData/psi/DocCommentAtBeginningOfFile2.txt deleted file mode 100644 index b6686bdc4a1..00000000000 --- a/compiler/testData/psi/DocCommentAtBeginningOfFile2.txt +++ /dev/null @@ -1,4 +0,0 @@ -JetFile: DocCommentAtBeginningOfFile2.jet - PsiComment(DOC_COMMENT)('/**\n/**') - NAMESPACE_HEADER - \ No newline at end of file diff --git a/compiler/testData/psi/DocCommentAtBeginningOfFile3.txt b/compiler/testData/psi/DocCommentAtBeginningOfFile3.txt deleted file mode 100644 index 9e62678cdd3..00000000000 --- a/compiler/testData/psi/DocCommentAtBeginningOfFile3.txt +++ /dev/null @@ -1,4 +0,0 @@ -JetFile: DocCommentAtBeginningOfFile3.jet - PsiComment(DOC_COMMENT)('/**\n\nfooo') - NAMESPACE_HEADER - \ No newline at end of file diff --git a/compiler/testData/psi/DocCommentAtBeginningOfFile4.txt b/compiler/testData/psi/DocCommentAtBeginningOfFile4.txt deleted file mode 100644 index 3c3a4906909..00000000000 --- a/compiler/testData/psi/DocCommentAtBeginningOfFile4.txt +++ /dev/null @@ -1,4 +0,0 @@ -JetFile: DocCommentAtBeginningOfFile4.jet - PsiComment(DOC_COMMENT)('/**\n\n/**foo*/\n\nasdfas') - NAMESPACE_HEADER - \ No newline at end of file diff --git a/compiler/testData/psi/EOLsInComments.txt b/compiler/testData/psi/EOLsInComments.txt index 6e5482c96d2..22d6429ed4a 100644 --- a/compiler/testData/psi/EOLsInComments.txt +++ b/compiler/testData/psi/EOLsInComments.txt @@ -25,7 +25,10 @@ JetFile: EOLsInComments.jet REFERENCE_EXPRESSION PsiElement(IDENTIFIER)('a') PsiWhiteSpace('\n ') - PsiComment(DOC_COMMENT)('/** */') + KDoc + PsiElement(KDOC_START)('/**') + PsiWhiteSpace(' ') + PsiElement(KDOC_END)('*/') PREFIX_EXPRESSION OPERATION_REFERENCE PsiElement(PLUS)('+') @@ -72,7 +75,10 @@ JetFile: EOLsInComments.jet REFERENCE_EXPRESSION PsiElement(IDENTIFIER)('a') PsiWhiteSpace(' ') - PsiComment(DOC_COMMENT)('/**\n */') + KDoc + PsiElement(KDOC_START)('/**') + PsiWhiteSpace('\n ') + PsiElement(KDOC_END)('*/') PsiWhiteSpace(' ') OPERATION_REFERENCE PsiElement(PLUS)('+') diff --git a/compiler/testData/psi/NestedComments.txt b/compiler/testData/psi/NestedComments.txt index 59e29c154d8..69704f67b61 100644 --- a/compiler/testData/psi/NestedComments.txt +++ b/compiler/testData/psi/NestedComments.txt @@ -32,17 +32,30 @@ JetFile: NestedComments.jet REFERENCE_EXPRESSION PsiElement(IDENTIFIER)('b') PsiWhiteSpace('\n') - PsiComment(DOC_COMMENT)('/***/') + KDoc + PsiElement(KDOC_START)('/**') + PsiElement(KDOC_END)('*/') PsiWhiteSpace('\n') REFERENCE_EXPRESSION PsiElement(IDENTIFIER)('b') PsiWhiteSpace('\n') - PsiComment(DOC_COMMENT)('/** /***/*/') + KDoc + PsiElement(KDOC_START)('/**') + PsiWhiteSpace(' ') + PsiElement(KDOC_TEXT)('/***/') + PsiElement(KDOC_END)('*/') PsiWhiteSpace('\n') REFERENCE_EXPRESSION PsiElement(IDENTIFIER)('b') PsiWhiteSpace('\n') - PsiComment(DOC_COMMENT)('/** /**\n\n*/***/') + KDoc + PsiElement(KDOC_START)('/**') + PsiWhiteSpace(' ') + PsiElement(KDOC_TEXT)('/**') + PsiWhiteSpace('\n\n') + PsiElement(KDOC_LEADING_ASTERISK)('*') + PsiElement(KDOC_TEXT)('/**') + PsiElement(KDOC_END)('*/') PsiWhiteSpace('\n') REFERENCE_EXPRESSION PsiElement(IDENTIFIER)('b') diff --git a/compiler/testData/psi/examples/array/MutableArray.txt b/compiler/testData/psi/examples/array/MutableArray.txt index 9d26293ba66..5f3a7339998 100644 --- a/compiler/testData/psi/examples/array/MutableArray.txt +++ b/compiler/testData/psi/examples/array/MutableArray.txt @@ -1,5 +1,44 @@ JetFile: MutableArray.jet - PsiComment(DOC_COMMENT)('/**\n These declarations are "shallow" in the sense that they are not really compiled, only the type-checker uses them\n*/') + KDoc + PsiElement(KDOC_START)('/**') + PsiWhiteSpace('\n ') + PsiElement(KDOC_TEXT)('These') + PsiWhiteSpace(' ') + PsiElement(KDOC_TEXT)('declarations') + PsiWhiteSpace(' ') + PsiElement(KDOC_TEXT)('are') + PsiWhiteSpace(' ') + PsiElement(KDOC_TEXT)('"shallow"') + PsiWhiteSpace(' ') + PsiElement(KDOC_TEXT)('in') + PsiWhiteSpace(' ') + PsiElement(KDOC_TEXT)('the') + PsiWhiteSpace(' ') + PsiElement(KDOC_TEXT)('sense') + PsiWhiteSpace(' ') + PsiElement(KDOC_TEXT)('that') + PsiWhiteSpace(' ') + PsiElement(KDOC_TEXT)('they') + PsiWhiteSpace(' ') + PsiElement(KDOC_TEXT)('are') + PsiWhiteSpace(' ') + PsiElement(KDOC_TEXT)('not') + PsiWhiteSpace(' ') + PsiElement(KDOC_TEXT)('really') + PsiWhiteSpace(' ') + PsiElement(KDOC_TEXT)('compiled,') + PsiWhiteSpace(' ') + PsiElement(KDOC_TEXT)('only') + PsiWhiteSpace(' ') + PsiElement(KDOC_TEXT)('the') + PsiWhiteSpace(' ') + PsiElement(KDOC_TEXT)('type-checker') + PsiWhiteSpace(' ') + PsiElement(KDOC_TEXT)('uses') + PsiWhiteSpace(' ') + PsiElement(KDOC_TEXT)('them') + PsiWhiteSpace('\n') + PsiElement(KDOC_END)('*/') PsiWhiteSpace('\n\n') NAMESPACE_HEADER diff --git a/compiler/testData/psi/DocCommentAtBeginningOfFile1.jet b/compiler/testData/psi/kdoc/DocCommentAtBeginningOfFile1.jet similarity index 100% rename from compiler/testData/psi/DocCommentAtBeginningOfFile1.jet rename to compiler/testData/psi/kdoc/DocCommentAtBeginningOfFile1.jet diff --git a/compiler/testData/psi/DocCommentAtBeginningOfFile1.txt b/compiler/testData/psi/kdoc/DocCommentAtBeginningOfFile1.txt similarity index 65% rename from compiler/testData/psi/DocCommentAtBeginningOfFile1.txt rename to compiler/testData/psi/kdoc/DocCommentAtBeginningOfFile1.txt index b0c76e51b08..92ddc1091be 100644 --- a/compiler/testData/psi/DocCommentAtBeginningOfFile1.txt +++ b/compiler/testData/psi/kdoc/DocCommentAtBeginningOfFile1.txt @@ -1,4 +1,5 @@ JetFile: DocCommentAtBeginningOfFile1.jet - PsiComment(DOC_COMMENT)('/**') + KDoc + PsiElement(KDOC_START)('/**') NAMESPACE_HEADER \ No newline at end of file diff --git a/compiler/testData/psi/DocCommentAtBeginningOfFile2.jet b/compiler/testData/psi/kdoc/DocCommentAtBeginningOfFile2.jet similarity index 100% rename from compiler/testData/psi/DocCommentAtBeginningOfFile2.jet rename to compiler/testData/psi/kdoc/DocCommentAtBeginningOfFile2.jet diff --git a/compiler/testData/psi/kdoc/DocCommentAtBeginningOfFile2.txt b/compiler/testData/psi/kdoc/DocCommentAtBeginningOfFile2.txt new file mode 100644 index 00000000000..671a1aee945 --- /dev/null +++ b/compiler/testData/psi/kdoc/DocCommentAtBeginningOfFile2.txt @@ -0,0 +1,7 @@ +JetFile: DocCommentAtBeginningOfFile2.jet + KDoc + PsiElement(KDOC_START)('/**') + PsiWhiteSpace('\n') + PsiElement(KDOC_TEXT)('/**') + NAMESPACE_HEADER + \ No newline at end of file diff --git a/compiler/testData/psi/DocCommentAtBeginningOfFile3.jet b/compiler/testData/psi/kdoc/DocCommentAtBeginningOfFile3.jet similarity index 100% rename from compiler/testData/psi/DocCommentAtBeginningOfFile3.jet rename to compiler/testData/psi/kdoc/DocCommentAtBeginningOfFile3.jet diff --git a/compiler/testData/psi/kdoc/DocCommentAtBeginningOfFile3.txt b/compiler/testData/psi/kdoc/DocCommentAtBeginningOfFile3.txt new file mode 100644 index 00000000000..b52d14d6751 --- /dev/null +++ b/compiler/testData/psi/kdoc/DocCommentAtBeginningOfFile3.txt @@ -0,0 +1,7 @@ +JetFile: DocCommentAtBeginningOfFile3.jet + KDoc + PsiElement(KDOC_START)('/**') + PsiWhiteSpace('\n\n') + PsiElement(KDOC_TEXT)('fooo') + NAMESPACE_HEADER + \ No newline at end of file diff --git a/compiler/testData/psi/DocCommentAtBeginningOfFile4.jet b/compiler/testData/psi/kdoc/DocCommentAtBeginningOfFile4.jet similarity index 100% rename from compiler/testData/psi/DocCommentAtBeginningOfFile4.jet rename to compiler/testData/psi/kdoc/DocCommentAtBeginningOfFile4.jet diff --git a/compiler/testData/psi/kdoc/DocCommentAtBeginningOfFile4.txt b/compiler/testData/psi/kdoc/DocCommentAtBeginningOfFile4.txt new file mode 100644 index 00000000000..448c37b71ec --- /dev/null +++ b/compiler/testData/psi/kdoc/DocCommentAtBeginningOfFile4.txt @@ -0,0 +1,9 @@ +JetFile: DocCommentAtBeginningOfFile4.jet + KDoc + PsiElement(KDOC_START)('/**') + PsiWhiteSpace('\n\n') + PsiElement(KDOC_TEXT)('/**foo*/') + PsiWhiteSpace('\n\n') + PsiElement(KDOC_TEXT)('asdfas') + NAMESPACE_HEADER + \ No newline at end of file diff --git a/compiler/testData/psi/kdoc/EndOnLeadingAsterisks.kt b/compiler/testData/psi/kdoc/EndOnLeadingAsterisks.kt new file mode 100644 index 00000000000..a33dbe069c4 --- /dev/null +++ b/compiler/testData/psi/kdoc/EndOnLeadingAsterisks.kt @@ -0,0 +1,2 @@ +/** + */ \ No newline at end of file diff --git a/compiler/testData/psi/kdoc/EndOnLeadingAsterisks.txt b/compiler/testData/psi/kdoc/EndOnLeadingAsterisks.txt new file mode 100644 index 00000000000..ae11f8e6eaf --- /dev/null +++ b/compiler/testData/psi/kdoc/EndOnLeadingAsterisks.txt @@ -0,0 +1,7 @@ +JetFile: EndOnLeadingAsterisks.kt + KDoc + PsiElement(KDOC_START)('/**') + PsiWhiteSpace('\n ') + PsiElement(KDOC_END)('*/') + NAMESPACE_HEADER + \ No newline at end of file diff --git a/compiler/testData/psi/kdoc/EndRightAfterText.kt b/compiler/testData/psi/kdoc/EndRightAfterText.kt new file mode 100644 index 00000000000..ccbbe6b06a8 --- /dev/null +++ b/compiler/testData/psi/kdoc/EndRightAfterText.kt @@ -0,0 +1 @@ +/**text*/ \ No newline at end of file diff --git a/compiler/testData/psi/kdoc/EndRightAfterText.txt b/compiler/testData/psi/kdoc/EndRightAfterText.txt new file mode 100644 index 00000000000..77d84b91e6c --- /dev/null +++ b/compiler/testData/psi/kdoc/EndRightAfterText.txt @@ -0,0 +1,7 @@ +JetFile: EndRightAfterText.kt + KDoc + PsiElement(KDOC_START)('/**') + PsiElement(KDOC_TEXT)('text') + PsiElement(KDOC_END)('*/') + NAMESPACE_HEADER + \ No newline at end of file diff --git a/compiler/testData/psi/kdoc/Incomplete.kt b/compiler/testData/psi/kdoc/Incomplete.kt new file mode 100644 index 00000000000..cd45fbeed1d --- /dev/null +++ b/compiler/testData/psi/kdoc/Incomplete.kt @@ -0,0 +1,2 @@ +/** + contents \ No newline at end of file diff --git a/compiler/testData/psi/kdoc/Incomplete.txt b/compiler/testData/psi/kdoc/Incomplete.txt new file mode 100644 index 00000000000..349ed596f2f --- /dev/null +++ b/compiler/testData/psi/kdoc/Incomplete.txt @@ -0,0 +1,7 @@ +JetFile: Incomplete.kt + KDoc + PsiElement(KDOC_START)('/**') + PsiWhiteSpace('\n ') + PsiElement(KDOC_TEXT)('contents') + NAMESPACE_HEADER + \ No newline at end of file diff --git a/compiler/testData/psi/kdoc/Simple.kt b/compiler/testData/psi/kdoc/Simple.kt new file mode 100644 index 00000000000..af292d07506 --- /dev/null +++ b/compiler/testData/psi/kdoc/Simple.kt @@ -0,0 +1,7 @@ + /** line 0 + line 1 // + ** line 2 /* + line 3 /** +* line * 4 + *** line */ 5 + ** line 6 */ \ No newline at end of file diff --git a/compiler/testData/psi/kdoc/Simple.txt b/compiler/testData/psi/kdoc/Simple.txt new file mode 100644 index 00000000000..8b705e5e454 --- /dev/null +++ b/compiler/testData/psi/kdoc/Simple.txt @@ -0,0 +1,52 @@ +JetFile: Simple.kt + KDoc + PsiElement(KDOC_START)('/**') + PsiWhiteSpace(' ') + PsiElement(KDOC_TEXT)('line') + PsiWhiteSpace(' ') + PsiElement(KDOC_TEXT)('0') + PsiWhiteSpace('\n ') + PsiElement(KDOC_TEXT)('line') + PsiWhiteSpace(' ') + PsiElement(KDOC_TEXT)('1') + PsiWhiteSpace(' ') + PsiElement(KDOC_TEXT)('//') + PsiWhiteSpace('\n ') + PsiElement(KDOC_LEADING_ASTERISK)('**') + PsiWhiteSpace(' ') + PsiElement(KDOC_TEXT)('line') + PsiWhiteSpace(' ') + PsiElement(KDOC_TEXT)('2') + PsiWhiteSpace(' ') + PsiElement(KDOC_TEXT)('/*') + PsiWhiteSpace('\n ') + PsiElement(KDOC_TEXT)('line') + PsiWhiteSpace(' ') + PsiElement(KDOC_TEXT)('3') + PsiWhiteSpace(' ') + PsiElement(KDOC_TEXT)('/**') + PsiWhiteSpace('\n') + PsiElement(KDOC_LEADING_ASTERISK)('*') + PsiWhiteSpace(' ') + PsiElement(KDOC_TEXT)('line') + PsiWhiteSpace(' ') + PsiElement(KDOC_TEXT)('*') + PsiWhiteSpace(' ') + PsiElement(KDOC_TEXT)('4') + PsiWhiteSpace('\n ') + PsiElement(KDOC_LEADING_ASTERISK)('***') + PsiWhiteSpace(' ') + PsiElement(KDOC_TEXT)('line') + PsiWhiteSpace(' */') + PsiWhiteSpace(' ') + PsiElement(KDOC_TEXT)('5') + PsiWhiteSpace('\n ') + PsiElement(KDOC_LEADING_ASTERISK)('**') + PsiWhiteSpace(' ') + PsiElement(KDOC_TEXT)('line') + PsiWhiteSpace(' ') + PsiElement(KDOC_TEXT)('6') + PsiWhiteSpace(' ') + PsiElement(KDOC_END)('*/') + NAMESPACE_HEADER + \ No newline at end of file diff --git a/compiler/testData/psi/kdoc/TextRightAfterLeadAsterisks.kt b/compiler/testData/psi/kdoc/TextRightAfterLeadAsterisks.kt new file mode 100644 index 00000000000..fe101cccbd4 --- /dev/null +++ b/compiler/testData/psi/kdoc/TextRightAfterLeadAsterisks.kt @@ -0,0 +1,3 @@ +/** +**test + */ \ No newline at end of file diff --git a/compiler/testData/psi/kdoc/TextRightAfterLeadAsterisks.txt b/compiler/testData/psi/kdoc/TextRightAfterLeadAsterisks.txt new file mode 100644 index 00000000000..4123145ff44 --- /dev/null +++ b/compiler/testData/psi/kdoc/TextRightAfterLeadAsterisks.txt @@ -0,0 +1,10 @@ +JetFile: TextRightAfterLeadAsterisks.kt + KDoc + PsiElement(KDOC_START)('/**') + PsiWhiteSpace('\n') + PsiElement(KDOC_LEADING_ASTERISK)('**') + PsiElement(KDOC_TEXT)('test') + PsiWhiteSpace('\n ') + PsiElement(KDOC_END)('*/') + NAMESPACE_HEADER + \ No newline at end of file diff --git a/compiler/tests/org/jetbrains/jet/parsing/JetParsingTest.java b/compiler/tests/org/jetbrains/jet/parsing/JetParsingTest.java index 5ab65c1a2e3..c4e8de90ed4 100644 --- a/compiler/tests/org/jetbrains/jet/parsing/JetParsingTest.java +++ b/compiler/tests/org/jetbrains/jet/parsing/JetParsingTest.java @@ -139,6 +139,7 @@ public class JetParsingTest extends ParsingTestCase { suite.addTest(JetTestCaseBuilder.suiteForDirectory(prefix, "script", true, factory)); suite.addTest(JetTestCaseBuilder.suiteForDirectory(prefix, "recovery", true, factory)); suite.addTest(JetTestCaseBuilder.suiteForDirectory(prefix, "propertyDelegate", true, factory)); + suite.addTest(JetTestCaseBuilder.suiteForDirectory(prefix, "kdoc", true, factory)); return suite; } diff --git a/idea/src/org/jetbrains/jet/plugin/JetCommenter.java b/idea/src/org/jetbrains/jet/plugin/JetCommenter.java index 2e3d3ba5e1f..c5a11639197 100644 --- a/idea/src/org/jetbrains/jet/plugin/JetCommenter.java +++ b/idea/src/org/jetbrains/jet/plugin/JetCommenter.java @@ -19,6 +19,7 @@ package org.jetbrains.jet.plugin; import com.intellij.lang.CodeDocumentationAwareCommenter; import com.intellij.psi.PsiComment; import com.intellij.psi.tree.IElementType; +import org.jetbrains.jet.kdoc.psi.api.KDoc; import org.jetbrains.jet.lexer.JetTokens; public class JetCommenter implements CodeDocumentationAwareCommenter { @@ -79,6 +80,6 @@ public class JetCommenter implements CodeDocumentationAwareCommenter { @Override public boolean isDocumentationComment(PsiComment element) { - return element.getTokenType().equals(JetTokens.DOC_COMMENT); + return element instanceof KDoc; } } From f9e8683db560a0d01f72891350c63eb3b0464003 Mon Sep 17 00:00:00 2001 From: Sergey Rostov Date: Fri, 24 May 2013 13:42:15 +0400 Subject: [PATCH 142/249] KT-1545, KT-3161 KDoc formatter --- .../jetbrains/jet/plugin/formatter/JetBlock.java | 15 ++++++++++++++- .../formatter/JetFormattingModelBuilder.java | 8 +++++++- .../testData/editor/commenter/newLineInComment.kt | 3 +-- .../editor/commenter/newLineInComment_after.kt | 3 +-- idea/testData/formatter/KDoc.kt | 4 ++++ idea/testData/formatter/KDoc_after.kt | 6 ++++++ .../jetbrains/jet/formatter/JetFormatterTest.java | 4 ++++ 7 files changed, 37 insertions(+), 6 deletions(-) create mode 100644 idea/testData/formatter/KDoc.kt create mode 100644 idea/testData/formatter/KDoc_after.kt diff --git a/idea/src/org/jetbrains/jet/plugin/formatter/JetBlock.java b/idea/src/org/jetbrains/jet/plugin/formatter/JetBlock.java index 34f3616a936..cad36209958 100644 --- a/idea/src/org/jetbrains/jet/plugin/formatter/JetBlock.java +++ b/idea/src/org/jetbrains/jet/plugin/formatter/JetBlock.java @@ -27,9 +27,13 @@ import com.intellij.psi.tree.IElementType; import com.intellij.psi.tree.TokenSet; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import org.jetbrains.jet.kdoc.lexer.KDocTokens; import org.jetbrains.jet.plugin.JetLanguage; -import java.util.*; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; import static org.jetbrains.jet.JetNodeTypes.*; import static org.jetbrains.jet.lexer.JetTokens.*; @@ -38,6 +42,7 @@ import static org.jetbrains.jet.lexer.JetTokens.*; * @see Block for good JavaDoc documentation */ public class JetBlock extends AbstractBlock { + private static final int KDOC_COMMENT_INDENT = 1; private final ASTAlignmentStrategy myAlignmentStrategy; private final Indent myIndent; private final CodeStyleSettings mySettings; @@ -208,6 +213,9 @@ public class JetBlock extends AbstractBlock { } return new ChildAttributes(Indent.getContinuationIndent(), null); } + else if (type == DOC_COMMENT) { + return new ChildAttributes(Indent.getSpaceIndent(KDOC_COMMENT_INDENT), null); + } if (isIncomplete()) { return super.getChildAttributes(newChildIndex); @@ -321,6 +329,11 @@ public class JetBlock extends AbstractBlock { .in(PROPERTY, FUN) .notForType(BLOCK) .set(Indent.getContinuationWithoutFirstIndent()), + + ASTIndentStrategy.forNode("KDoc comment indent") + .in(DOC_COMMENT) + .forType(KDocTokens.LEADING_ASTERISK, KDocTokens.END) + .set(Indent.getSpaceIndent(KDOC_COMMENT_INDENT)), }; @Nullable diff --git a/idea/src/org/jetbrains/jet/plugin/formatter/JetFormattingModelBuilder.java b/idea/src/org/jetbrains/jet/plugin/formatter/JetFormattingModelBuilder.java index b30cd9184d5..13d4e7e8dc5 100644 --- a/idea/src/org/jetbrains/jet/plugin/formatter/JetFormattingModelBuilder.java +++ b/idea/src/org/jetbrains/jet/plugin/formatter/JetFormattingModelBuilder.java @@ -25,6 +25,7 @@ import com.intellij.psi.codeStyle.CodeStyleSettings; import com.intellij.psi.codeStyle.CommonCodeStyleSettings; import com.intellij.psi.tree.TokenSet; import org.jetbrains.annotations.NotNull; +import org.jetbrains.jet.kdoc.lexer.KDocTokens; import org.jetbrains.jet.plugin.JetLanguage; import static org.jetbrains.jet.JetNodeTypes.*; @@ -34,8 +35,9 @@ public class JetFormattingModelBuilder implements FormattingModelBuilder { @NotNull @Override public FormattingModel createModel(PsiElement element, CodeStyleSettings settings) { + PsiFile containingFile = element.getContainingFile().getViewProvider().getPsi(JetLanguage.INSTANCE); JetBlock block = new JetBlock( - element.getNode(), ASTAlignmentStrategy.getNullStrategy(), Indent.getNoneIndent(), null, settings, + containingFile.getNode(), ASTAlignmentStrategy.getNullStrategy(), Indent.getNoneIndent(), null, settings, createSpacingBuilder(settings)); return FormattingModelProvider.createFormattingModelForPsiFile( @@ -53,6 +55,7 @@ public class JetFormattingModelBuilder implements FormattingModelBuilder { .between(IMPORT_DIRECTIVE, IMPORT_DIRECTIVE).lineBreakInCode() .after(IMPORT_DIRECTIVE).blankLines(1) + .before(DOC_COMMENT).lineBreakInCode() .before(FUN).lineBreakInCode() .before(PROPERTY).lineBreakInCode() .between(FUN, FUN).blankLines(1) @@ -105,6 +108,9 @@ public class JetFormattingModelBuilder implements FormattingModelBuilder { .between(VALUE_ARGUMENT_LIST, FUNCTION_LITERAL_EXPRESSION).spaces(1) .aroundInside(ARROW, WHEN_ENTRY).spaces(1) + + // KDoc + .between(KDocTokens.LEADING_ASTERISK, KDocTokens.TEXT).spacing(1, 100, 0, true, 100) ; } diff --git a/idea/testData/editor/commenter/newLineInComment.kt b/idea/testData/editor/commenter/newLineInComment.kt index 5f9507de398..c933947394e 100644 --- a/idea/testData/editor/commenter/newLineInComment.kt +++ b/idea/testData/editor/commenter/newLineInComment.kt @@ -1,4 +1,3 @@ /** * x - */ -fun test() = 0 \ No newline at end of file + */ \ No newline at end of file diff --git a/idea/testData/editor/commenter/newLineInComment_after.kt b/idea/testData/editor/commenter/newLineInComment_after.kt index 130bcc93cb1..a15a2e7ab9e 100644 --- a/idea/testData/editor/commenter/newLineInComment_after.kt +++ b/idea/testData/editor/commenter/newLineInComment_after.kt @@ -1,5 +1,4 @@ /** * x * - */ -fun test() = 0 \ No newline at end of file + */ \ No newline at end of file diff --git a/idea/testData/formatter/KDoc.kt b/idea/testData/formatter/KDoc.kt new file mode 100644 index 00000000000..a764ec6cf31 --- /dev/null +++ b/idea/testData/formatter/KDoc.kt @@ -0,0 +1,4 @@ +class Test { /** +* do something + */ fun doSomething() = 0 +} \ No newline at end of file diff --git a/idea/testData/formatter/KDoc_after.kt b/idea/testData/formatter/KDoc_after.kt new file mode 100644 index 00000000000..58f3ca3aba3 --- /dev/null +++ b/idea/testData/formatter/KDoc_after.kt @@ -0,0 +1,6 @@ +class Test { + /** + * do something + */ + fun doSomething() = 0 +} \ No newline at end of file diff --git a/idea/tests/org/jetbrains/jet/formatter/JetFormatterTest.java b/idea/tests/org/jetbrains/jet/formatter/JetFormatterTest.java index 958481189ac..85f31b0e319 100644 --- a/idea/tests/org/jetbrains/jet/formatter/JetFormatterTest.java +++ b/idea/tests/org/jetbrains/jet/formatter/JetFormatterTest.java @@ -72,6 +72,10 @@ public class JetFormatterTest extends AbstractJetFormatterTest { doTest(); } + public void testKDoc() throws Exception { + doTest(); + } + public void testMultilineFunctionLiteral() throws Exception { doTest(); } From 365f097904ffcf75a6dc434b060aec7f0ae4fd0d Mon Sep 17 00:00:00 2001 From: Sergey Rostov Date: Sat, 25 May 2013 12:23:18 +0400 Subject: [PATCH 143/249] Update KetTokens.Comments TokenSet --- .../src/org/jetbrains/jet/kdoc/lexer/KDocTokens.java | 3 +++ compiler/frontend/src/org/jetbrains/jet/lexer/JetTokens.java | 5 +++-- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/compiler/frontend/src/org/jetbrains/jet/kdoc/lexer/KDocTokens.java b/compiler/frontend/src/org/jetbrains/jet/kdoc/lexer/KDocTokens.java index 217eb51c14d..96dedc596d7 100644 --- a/compiler/frontend/src/org/jetbrains/jet/kdoc/lexer/KDocTokens.java +++ b/compiler/frontend/src/org/jetbrains/jet/kdoc/lexer/KDocTokens.java @@ -23,6 +23,7 @@ import com.intellij.lang.PsiParser; import com.intellij.openapi.project.Project; import com.intellij.psi.PsiElement; import com.intellij.psi.tree.ILazyParseableElementType; +import com.intellij.psi.tree.TokenSet; import org.jetbrains.annotations.Nullable; import org.jetbrains.jet.kdoc.parser.KDocParser; import org.jetbrains.jet.kdoc.psi.impl.KDocImpl; @@ -53,4 +54,6 @@ public interface KDocTokens { KDocToken LEADING_ASTERISK = new KDocToken("KDOC_LEADING_ASTERISK"); KDocToken TEXT = new KDocToken("KDOC_TEXT"); + + TokenSet ALL_KDOC_TOKENS = TokenSet.create(START, END, LEADING_ASTERISK, TEXT); } diff --git a/compiler/frontend/src/org/jetbrains/jet/lexer/JetTokens.java b/compiler/frontend/src/org/jetbrains/jet/lexer/JetTokens.java index 0c0124566b7..4ac4870d047 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lexer/JetTokens.java +++ b/compiler/frontend/src/org/jetbrains/jet/lexer/JetTokens.java @@ -183,9 +183,10 @@ public interface JetTokens { OPEN_KEYWORD, INNER_KEYWORD, ANNOTATION_KEYWORD, OVERRIDE_KEYWORD, PRIVATE_KEYWORD, PUBLIC_KEYWORD, INTERNAL_KEYWORD, PROTECTED_KEYWORD, OUT_KEYWORD, IN_KEYWORD, FINAL_KEYWORD, VARARG_KEYWORD, INLINE_KEYWORD, REIFIED_KEYWORD ); - TokenSet WHITE_SPACE_OR_COMMENT_BIT_SET = TokenSet.create(WHITE_SPACE, BLOCK_COMMENT, EOL_COMMENT, DOC_COMMENT, SHEBANG_COMMENT); TokenSet WHITESPACES = TokenSet.create(TokenType.WHITE_SPACE); - TokenSet COMMENTS = TokenSet.create(EOL_COMMENT, BLOCK_COMMENT, DOC_COMMENT, SHEBANG_COMMENT); + TokenSet COMMENTS = TokenSet.orSet(TokenSet.create(EOL_COMMENT, BLOCK_COMMENT, DOC_COMMENT, SHEBANG_COMMENT), + KDocTokens.ALL_KDOC_TOKENS); + TokenSet WHITE_SPACE_OR_COMMENT_BIT_SET = TokenSet.orSet(COMMENTS, TokenSet.create(WHITE_SPACE)); TokenSet STRINGS = TokenSet.create(CHARACTER_LITERAL, REGULAR_STRING_PART); TokenSet OPERATIONS = TokenSet.create(AS_KEYWORD, AS_SAFE, IS_KEYWORD, IN_KEYWORD, DOT, PLUSPLUS, MINUSMINUS, EXCLEXCL, MUL, PLUS, From 12e20378a2adcc56396dac83222887205f3b0f33 Mon Sep 17 00:00:00 2001 From: Sergey Rostov Date: Sat, 25 May 2013 15:22:52 +0400 Subject: [PATCH 144/249] KDoc lexer refactored (got rid of hacks and separate tokens for words). Fixed bug with isInComment(element) detection. --- .../org/jetbrains/jet/kdoc/lexer/KDoc.flex | 41 +++++------ .../jetbrains/jet/kdoc/lexer/KDocLexer.java | 11 ++- .../jetbrains/jet/kdoc/lexer/KDocTokens.java | 5 +- .../jetbrains/jet/kdoc/lexer/_KDocLexer.java | 69 ++++++++----------- .../jet/kdoc/psi/api/KDocElement.java | 4 +- .../jetbrains/jet/lang/psi/JetPsiUtil.java | 15 ++++ .../org/jetbrains/jet/lexer/JetTokens.java | 10 ++- .../org/jetbrains/jet/lexer/_JetLexer.java | 4 +- compiler/testData/psi/EOLsInComments.txt | 2 +- compiler/testData/psi/NestedComments.txt | 11 ++- .../psi/examples/array/MutableArray.txt | 36 +--------- compiler/testData/psi/kdoc/Simple.txt | 43 ++---------- .../JetKeywordCompletionContributor.java | 3 +- .../formatter/JetFormattingModelBuilder.java | 4 -- 14 files changed, 97 insertions(+), 161 deletions(-) diff --git a/compiler/frontend/src/org/jetbrains/jet/kdoc/lexer/KDoc.flex b/compiler/frontend/src/org/jetbrains/jet/kdoc/lexer/KDoc.flex index ff96ccf0bec..7a1cbd60f21 100644 --- a/compiler/frontend/src/org/jetbrains/jet/kdoc/lexer/KDoc.flex +++ b/compiler/frontend/src/org/jetbrains/jet/kdoc/lexer/KDoc.flex @@ -23,18 +23,6 @@ import com.intellij.util.text.CharArrayUtil; private final Boolean yytextContainLineBreaks() { return CharArrayUtil.containLineBreaks(zzBuffer, zzStartRead, zzMarkedPos); } - - private final void pushbackEnd() { - if (isLastToken() && CharArrayUtil.regionMatches(zzBuffer, zzMarkedPos - 2, zzMarkedPos, "*/")) { - yypushback(2); - } - } - - private final void pushbackText() { - int i = zzStartRead; - while (zzBuffer.charAt(i) == '*') i++; - yypushback(zzMarkedPos - i); - } %} %function advance @@ -54,22 +42,25 @@ NOT_WHITE_SPACE_CHAR=[^\ \t\f\n\r] "/**" { yybegin(CONTENTS); return KDocTokens.START; } -"*"+ "/" { if (isLastToken()) - return KDocTokens.END; } +"*"+ "/" { if (isLastToken()) return KDocTokens.END; + else return KDocTokens.TEXT; } -// hack: make longest match - "*"+ {NOT_WHITE_SPACE_CHAR}* { pushbackText(); - yybegin(CONTENTS); - return KDocTokens.LEADING_ASTERISK; } + "*"+ { yybegin(CONTENTS); + return KDocTokens.LEADING_ASTERISK; } { - // todo: put markdown and @tags token patterns here + {WHITE_SPACE_CHAR}+ { + if (yytextContainLineBreaks()) { + yybegin(LINE_BEGINNING); + return TokenType.WHITE_SPACE; + } else { + yybegin(CONTENTS); + return KDocTokens.TEXT; // internal white space + } + } - {NOT_WHITE_SPACE_CHAR}+ { pushbackEnd(); - return KDocTokens.TEXT; } - {WHITE_SPACE_CHAR}+ { if (yytextContainLineBreaks()) - yybegin(LINE_BEGINNING); - return TokenType.WHITE_SPACE; } + . { yybegin(CONTENTS); + return KDocTokens.TEXT; } } -. { return TokenType.BAD_CHARACTER; } \ No newline at end of file +. { return TokenType.BAD_CHARACTER; } \ No newline at end of file diff --git a/compiler/frontend/src/org/jetbrains/jet/kdoc/lexer/KDocLexer.java b/compiler/frontend/src/org/jetbrains/jet/kdoc/lexer/KDocLexer.java index dd9be21a218..8f314730f73 100644 --- a/compiler/frontend/src/org/jetbrains/jet/kdoc/lexer/KDocLexer.java +++ b/compiler/frontend/src/org/jetbrains/jet/kdoc/lexer/KDocLexer.java @@ -17,11 +17,18 @@ package org.jetbrains.jet.kdoc.lexer; import com.intellij.lexer.FlexAdapter; +import com.intellij.lexer.MergingLexerAdapter; +import com.intellij.psi.tree.TokenSet; import java.io.Reader; -public class KDocLexer extends FlexAdapter { +public class KDocLexer extends MergingLexerAdapter { public KDocLexer() { - super(new _KDocLexer((Reader) null)); + super( + new FlexAdapter( + new _KDocLexer((Reader) null) + ), + TokenSet.create(KDocTokens.TEXT) + ); } } diff --git a/compiler/frontend/src/org/jetbrains/jet/kdoc/lexer/KDocTokens.java b/compiler/frontend/src/org/jetbrains/jet/kdoc/lexer/KDocTokens.java index 96dedc596d7..92bdb3cbb86 100644 --- a/compiler/frontend/src/org/jetbrains/jet/kdoc/lexer/KDocTokens.java +++ b/compiler/frontend/src/org/jetbrains/jet/kdoc/lexer/KDocTokens.java @@ -23,7 +23,6 @@ import com.intellij.lang.PsiParser; import com.intellij.openapi.project.Project; import com.intellij.psi.PsiElement; import com.intellij.psi.tree.ILazyParseableElementType; -import com.intellij.psi.tree.TokenSet; import org.jetbrains.annotations.Nullable; import org.jetbrains.jet.kdoc.parser.KDocParser; import org.jetbrains.jet.kdoc.psi.impl.KDocImpl; @@ -53,7 +52,5 @@ public interface KDocTokens { KDocToken END = new KDocToken("KDOC_END"); KDocToken LEADING_ASTERISK = new KDocToken("KDOC_LEADING_ASTERISK"); - KDocToken TEXT = new KDocToken("KDOC_TEXT"); - - TokenSet ALL_KDOC_TOKENS = TokenSet.create(START, END, LEADING_ASTERISK, TEXT); + KDocToken TEXT = new KDocToken("KDOC_TEXT"); } diff --git a/compiler/frontend/src/org/jetbrains/jet/kdoc/lexer/_KDocLexer.java b/compiler/frontend/src/org/jetbrains/jet/kdoc/lexer/_KDocLexer.java index c2007811156..c813e40dc93 100644 --- a/compiler/frontend/src/org/jetbrains/jet/kdoc/lexer/_KDocLexer.java +++ b/compiler/frontend/src/org/jetbrains/jet/kdoc/lexer/_KDocLexer.java @@ -1,4 +1,4 @@ -/* The following code was generated by JFlex 1.4.3 on 23.05.13 19:26 */ +/* The following code was generated by JFlex 1.4.3 on 25.05.13 15:08 */ package org.jetbrains.jet.kdoc.lexer; @@ -11,7 +11,7 @@ import com.intellij.util.text.CharArrayUtil; /** * This class is a scanner generated by * JFlex 1.4.3 - * on 23.05.13 19:26 from the specification file + * on 25.05.13 15:08 from the specification file * /Users/factitious/Documents/kotlin/compiler/frontend/src/org/jetbrains/jet/kdoc/lexer/KDoc.flex */ class _KDocLexer implements FlexLexer { @@ -19,9 +19,11 @@ class _KDocLexer implements FlexLexer { private static final int ZZ_BUFFERSIZE = 16384; /** lexical states */ - public static final int LINE_BEGINNING = 4; + public static final int LINE_BEGINNING = 8; + public static final int STRONG_CONTENTS = 6; public static final int CONTENTS = 2; public static final int YYINITIAL = 0; + public static final int EMPHASIS_CONTENTS = 4; /** * ZZ_LEXSTATE[l] is the state in the DFA for the lexical state l @@ -30,7 +32,7 @@ class _KDocLexer implements FlexLexer { * l is of the form l = 2*k, k a non negative integer */ private static final int ZZ_LEXSTATE[] = { - 0, 0, 1, 1, 2, 2 + 0, 0, 1, 1, 1, 1, 1, 1, 2, 2 }; /** @@ -52,10 +54,10 @@ class _KDocLexer implements FlexLexer { private static final String ZZ_ACTION_PACKED_0 = "\3\0\3\1\1\2\1\3\1\2\1\4\1\0\1\5"+ - "\1\0\1\5\1\4\1\5\1\6"; + "\1\0\1\6"; private static int [] zzUnpackAction() { - int [] result = new int[17]; + int [] result = new int[14]; int offset = 0; offset = zzUnpackAction(ZZ_ACTION_PACKED_0, offset, result); return result; @@ -80,12 +82,11 @@ class _KDocLexer implements FlexLexer { private static final int [] ZZ_ROWMAP = zzUnpackRowMap(); private static final String ZZ_ROWMAP_PACKED_0 = - "\0\0\0\5\0\12\0\17\0\24\0\31\0\36\0\43"+ - "\0\50\0\55\0\62\0\17\0\31\0\36\0\67\0\67"+ - "\0\17"; + "\0\0\0\5\0\12\0\17\0\24\0\31\0\17\0\36"+ + "\0\31\0\43\0\50\0\17\0\31\0\17"; private static int [] zzUnpackRowMap() { - int [] result = new int[17]; + int [] result = new int[14]; int offset = 0; offset = zzUnpackRowMap(ZZ_ROWMAP_PACKED_0, offset, result); return result; @@ -110,13 +111,11 @@ class _KDocLexer implements FlexLexer { private static final String ZZ_TRANS_PACKED_0 = "\2\4\1\5\1\6\1\0\1\7\1\10\1\7\1\11"+ "\1\10\1\7\1\10\1\7\1\12\1\10\10\0\1\13"+ - "\3\0\1\14\1\15\1\0\1\7\1\0\2\7\2\0"+ - "\1\10\2\0\1\10\1\7\1\0\1\16\1\11\1\0"+ - "\1\17\1\0\1\20\1\12\4\0\1\21\1\0\1\17"+ - "\1\0\2\17\1\0"; + "\3\0\1\14\1\15\2\0\1\10\2\0\1\10\2\0"+ + "\1\14\1\12\4\0\1\16\1\0"; private static int [] zzUnpackTrans() { - int [] result = new int[60]; + int [] result = new int[45]; int offset = 0; offset = zzUnpackTrans(ZZ_TRANS_PACKED_0, offset, result); return result; @@ -157,10 +156,11 @@ class _KDocLexer implements FlexLexer { private static final int [] ZZ_ATTRIBUTE = zzUnpackAttribute(); private static final String ZZ_ATTRIBUTE_PACKED_0 = - "\3\0\1\11\6\1\1\0\1\11\1\0\3\1\1\11"; + "\3\0\1\11\2\1\1\11\3\1\1\0\1\11\1\0"+ + "\1\11"; private static int [] zzUnpackAttribute() { - int [] result = new int[17]; + int [] result = new int[14]; int offset = 0; offset = zzUnpackAttribute(ZZ_ATTRIBUTE_PACKED_0, offset, result); return result; @@ -231,18 +231,6 @@ class _KDocLexer implements FlexLexer { return CharArrayUtil.containLineBreaks(zzBuffer, zzStartRead, zzMarkedPos); } - private final void pushbackEnd() { - if (isLastToken() && CharArrayUtil.regionMatches(zzBuffer, zzMarkedPos - 2, zzMarkedPos, "*/")) { - yypushback(2); - } - } - - private final void pushbackText() { - int i = zzStartRead; - while (zzBuffer.charAt(i) == '*') i++; - yypushback(zzMarkedPos - i); - } - _KDocLexer(java.io.Reader in) { this.zzReader = in; @@ -497,8 +485,8 @@ class _KDocLexer implements FlexLexer { } case 7: break; case 5: - { if (isLastToken()) - return KDocTokens.END; + { if (isLastToken()) return KDocTokens.END; + else return KDocTokens.TEXT; } case 8: break; case 1: @@ -506,20 +494,23 @@ class _KDocLexer implements FlexLexer { } case 9: break; case 2: - { pushbackEnd(); - return KDocTokens.TEXT; + { yybegin(CONTENTS); + return KDocTokens.TEXT; } case 10: break; case 4: - { pushbackText(); - yybegin(CONTENTS); - return KDocTokens.LEADING_ASTERISK; + { yybegin(CONTENTS); + return KDocTokens.LEADING_ASTERISK; } case 11: break; case 3: - { if (yytextContainLineBreaks()) - yybegin(LINE_BEGINNING); - return TokenType.WHITE_SPACE; + { if (yytextContainLineBreaks()) { + yybegin(LINE_BEGINNING); + return TokenType.WHITE_SPACE; + } else { + yybegin(CONTENTS); + return KDocTokens.TEXT; // internal white space + } } case 12: break; default: diff --git a/compiler/frontend/src/org/jetbrains/jet/kdoc/psi/api/KDocElement.java b/compiler/frontend/src/org/jetbrains/jet/kdoc/psi/api/KDocElement.java index 32119bebdd9..47c368e5cf5 100644 --- a/compiler/frontend/src/org/jetbrains/jet/kdoc/psi/api/KDocElement.java +++ b/compiler/frontend/src/org/jetbrains/jet/kdoc/psi/api/KDocElement.java @@ -16,7 +16,7 @@ package org.jetbrains.jet.kdoc.psi.api; -import org.jetbrains.jet.lang.psi.JetElement; +import com.intellij.psi.PsiElement; -public interface KDocElement extends JetElement { +public interface KDocElement extends PsiElement { } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetPsiUtil.java b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetPsiUtil.java index 0d02f57ad50..bb3a578a368 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetPsiUtil.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetPsiUtil.java @@ -28,10 +28,12 @@ import com.intellij.psi.impl.CheckUtil; import com.intellij.psi.impl.source.codeStyle.CodeEditUtil; import com.intellij.psi.tree.IElementType; import com.intellij.psi.util.PsiTreeUtil; +import com.intellij.util.codeInsight.CommentUtilCore; import com.intellij.util.containers.ContainerUtil; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.jet.JetNodeTypes; +import org.jetbrains.jet.kdoc.psi.api.KDocElement; import org.jetbrains.jet.lang.parsing.JetExpressionParsing; import org.jetbrains.jet.lang.resolve.ImportPath; import org.jetbrains.jet.lang.resolve.name.FqName; @@ -740,4 +742,17 @@ public class JetPsiUtil { public static String getText(@Nullable PsiElement element) { return element != null ? element.getText() : ""; } + + /** + * CommentUtilCore.isComment fails if element inside comment. + * + * Also, we can not add KDocTokens to COMMENTS TokenSet, because it is used in JetParserDefinition.getCommentTokens(), + * and therefor all COMMENTS tokens will be ignored by PsiBuilder. + * + * @param element + * @return + */ + public static boolean isInComment(PsiElement element) { + return CommentUtilCore.isComment(element) || element instanceof KDocElement; + } } diff --git a/compiler/frontend/src/org/jetbrains/jet/lexer/JetTokens.java b/compiler/frontend/src/org/jetbrains/jet/lexer/JetTokens.java index 4ac4870d047..6407280a4a1 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lexer/JetTokens.java +++ b/compiler/frontend/src/org/jetbrains/jet/lexer/JetTokens.java @@ -184,8 +184,14 @@ public interface JetTokens { PROTECTED_KEYWORD, OUT_KEYWORD, IN_KEYWORD, FINAL_KEYWORD, VARARG_KEYWORD, INLINE_KEYWORD, REIFIED_KEYWORD ); TokenSet WHITESPACES = TokenSet.create(TokenType.WHITE_SPACE); - TokenSet COMMENTS = TokenSet.orSet(TokenSet.create(EOL_COMMENT, BLOCK_COMMENT, DOC_COMMENT, SHEBANG_COMMENT), - KDocTokens.ALL_KDOC_TOKENS); + + /** + * Don't add KDocTokens to COMMENTS TokenSet, because it is used in JetParserDefinition.getCommentTokens(), + * and therefor all COMMENTS tokens will be ignored by PsiBuilder. + * + * @see org.jetbrains.jet.lang.psi.JetPsiUtil.isInComment() + */ + TokenSet COMMENTS = TokenSet.create(EOL_COMMENT, BLOCK_COMMENT, DOC_COMMENT, SHEBANG_COMMENT); TokenSet WHITE_SPACE_OR_COMMENT_BIT_SET = TokenSet.orSet(COMMENTS, TokenSet.create(WHITE_SPACE)); TokenSet STRINGS = TokenSet.create(CHARACTER_LITERAL, REGULAR_STRING_PART); diff --git a/compiler/frontend/src/org/jetbrains/jet/lexer/_JetLexer.java b/compiler/frontend/src/org/jetbrains/jet/lexer/_JetLexer.java index f56cf18375f..3cdd6255b6e 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lexer/_JetLexer.java +++ b/compiler/frontend/src/org/jetbrains/jet/lexer/_JetLexer.java @@ -1,4 +1,4 @@ -/* The following code was generated by JFlex 1.4.3 on 23.05.13 19:26 */ +/* The following code was generated by JFlex 1.4.3 on 25.05.13 15:08 */ package org.jetbrains.jet.lexer; @@ -11,7 +11,7 @@ import com.intellij.util.containers.Stack; /** * This class is a scanner generated by * JFlex 1.4.3 - * on 23.05.13 19:26 from the specification file + * on 25.05.13 15:08 from the specification file * /Users/factitious/Documents/kotlin/compiler/frontend/src/org/jetbrains/jet/lexer/Jet.flex */ class _JetLexer implements FlexLexer { diff --git a/compiler/testData/psi/EOLsInComments.txt b/compiler/testData/psi/EOLsInComments.txt index 22d6429ed4a..5102fdb525f 100644 --- a/compiler/testData/psi/EOLsInComments.txt +++ b/compiler/testData/psi/EOLsInComments.txt @@ -27,7 +27,7 @@ JetFile: EOLsInComments.jet PsiWhiteSpace('\n ') KDoc PsiElement(KDOC_START)('/**') - PsiWhiteSpace(' ') + PsiElement(KDOC_TEXT)(' ') PsiElement(KDOC_END)('*/') PREFIX_EXPRESSION OPERATION_REFERENCE diff --git a/compiler/testData/psi/NestedComments.txt b/compiler/testData/psi/NestedComments.txt index 69704f67b61..029c4c6d5dd 100644 --- a/compiler/testData/psi/NestedComments.txt +++ b/compiler/testData/psi/NestedComments.txt @@ -41,8 +41,7 @@ JetFile: NestedComments.jet PsiWhiteSpace('\n') KDoc PsiElement(KDOC_START)('/**') - PsiWhiteSpace(' ') - PsiElement(KDOC_TEXT)('/***/') + PsiElement(KDOC_TEXT)(' /***/') PsiElement(KDOC_END)('*/') PsiWhiteSpace('\n') REFERENCE_EXPRESSION @@ -50,12 +49,10 @@ JetFile: NestedComments.jet PsiWhiteSpace('\n') KDoc PsiElement(KDOC_START)('/**') - PsiWhiteSpace(' ') - PsiElement(KDOC_TEXT)('/**') + PsiElement(KDOC_TEXT)(' /**') PsiWhiteSpace('\n\n') - PsiElement(KDOC_LEADING_ASTERISK)('*') - PsiElement(KDOC_TEXT)('/**') - PsiElement(KDOC_END)('*/') + PsiElement(KDOC_TEXT)('*/') + PsiElement(KDOC_END)('***/') PsiWhiteSpace('\n') REFERENCE_EXPRESSION PsiElement(IDENTIFIER)('b') diff --git a/compiler/testData/psi/examples/array/MutableArray.txt b/compiler/testData/psi/examples/array/MutableArray.txt index 5f3a7339998..c08fd2add36 100644 --- a/compiler/testData/psi/examples/array/MutableArray.txt +++ b/compiler/testData/psi/examples/array/MutableArray.txt @@ -2,41 +2,7 @@ JetFile: MutableArray.jet KDoc PsiElement(KDOC_START)('/**') PsiWhiteSpace('\n ') - PsiElement(KDOC_TEXT)('These') - PsiWhiteSpace(' ') - PsiElement(KDOC_TEXT)('declarations') - PsiWhiteSpace(' ') - PsiElement(KDOC_TEXT)('are') - PsiWhiteSpace(' ') - PsiElement(KDOC_TEXT)('"shallow"') - PsiWhiteSpace(' ') - PsiElement(KDOC_TEXT)('in') - PsiWhiteSpace(' ') - PsiElement(KDOC_TEXT)('the') - PsiWhiteSpace(' ') - PsiElement(KDOC_TEXT)('sense') - PsiWhiteSpace(' ') - PsiElement(KDOC_TEXT)('that') - PsiWhiteSpace(' ') - PsiElement(KDOC_TEXT)('they') - PsiWhiteSpace(' ') - PsiElement(KDOC_TEXT)('are') - PsiWhiteSpace(' ') - PsiElement(KDOC_TEXT)('not') - PsiWhiteSpace(' ') - PsiElement(KDOC_TEXT)('really') - PsiWhiteSpace(' ') - PsiElement(KDOC_TEXT)('compiled,') - PsiWhiteSpace(' ') - PsiElement(KDOC_TEXT)('only') - PsiWhiteSpace(' ') - PsiElement(KDOC_TEXT)('the') - PsiWhiteSpace(' ') - PsiElement(KDOC_TEXT)('type-checker') - PsiWhiteSpace(' ') - PsiElement(KDOC_TEXT)('uses') - PsiWhiteSpace(' ') - PsiElement(KDOC_TEXT)('them') + PsiElement(KDOC_TEXT)('These declarations are "shallow" in the sense that they are not really compiled, only the type-checker uses them') PsiWhiteSpace('\n') PsiElement(KDOC_END)('*/') PsiWhiteSpace('\n\n') diff --git a/compiler/testData/psi/kdoc/Simple.txt b/compiler/testData/psi/kdoc/Simple.txt index 8b705e5e454..cba272a3bd0 100644 --- a/compiler/testData/psi/kdoc/Simple.txt +++ b/compiler/testData/psi/kdoc/Simple.txt @@ -1,52 +1,23 @@ JetFile: Simple.kt KDoc PsiElement(KDOC_START)('/**') - PsiWhiteSpace(' ') - PsiElement(KDOC_TEXT)('line') - PsiWhiteSpace(' ') - PsiElement(KDOC_TEXT)('0') + PsiElement(KDOC_TEXT)(' line 0') PsiWhiteSpace('\n ') - PsiElement(KDOC_TEXT)('line') - PsiWhiteSpace(' ') - PsiElement(KDOC_TEXT)('1') - PsiWhiteSpace(' ') - PsiElement(KDOC_TEXT)('//') + PsiElement(KDOC_TEXT)('line 1 //') PsiWhiteSpace('\n ') PsiElement(KDOC_LEADING_ASTERISK)('**') - PsiWhiteSpace(' ') - PsiElement(KDOC_TEXT)('line') - PsiWhiteSpace(' ') - PsiElement(KDOC_TEXT)('2') - PsiWhiteSpace(' ') - PsiElement(KDOC_TEXT)('/*') + PsiElement(KDOC_TEXT)(' line 2 /*') PsiWhiteSpace('\n ') - PsiElement(KDOC_TEXT)('line') - PsiWhiteSpace(' ') - PsiElement(KDOC_TEXT)('3') - PsiWhiteSpace(' ') - PsiElement(KDOC_TEXT)('/**') + PsiElement(KDOC_TEXT)('line 3 /**') PsiWhiteSpace('\n') PsiElement(KDOC_LEADING_ASTERISK)('*') - PsiWhiteSpace(' ') - PsiElement(KDOC_TEXT)('line') - PsiWhiteSpace(' ') - PsiElement(KDOC_TEXT)('*') - PsiWhiteSpace(' ') - PsiElement(KDOC_TEXT)('4') + PsiElement(KDOC_TEXT)(' line * 4') PsiWhiteSpace('\n ') PsiElement(KDOC_LEADING_ASTERISK)('***') - PsiWhiteSpace(' ') - PsiElement(KDOC_TEXT)('line') - PsiWhiteSpace(' */') - PsiWhiteSpace(' ') - PsiElement(KDOC_TEXT)('5') + PsiElement(KDOC_TEXT)(' line */ 5') PsiWhiteSpace('\n ') PsiElement(KDOC_LEADING_ASTERISK)('**') - PsiWhiteSpace(' ') - PsiElement(KDOC_TEXT)('line') - PsiWhiteSpace(' ') - PsiElement(KDOC_TEXT)('6') - PsiWhiteSpace(' ') + PsiElement(KDOC_TEXT)(' line 6 ') PsiElement(KDOC_END)('*/') NAMESPACE_HEADER \ No newline at end of file diff --git a/idea/src/org/jetbrains/jet/plugin/completion/JetKeywordCompletionContributor.java b/idea/src/org/jetbrains/jet/plugin/completion/JetKeywordCompletionContributor.java index 30e79e51300..5cc6cf04248 100644 --- a/idea/src/org/jetbrains/jet/plugin/completion/JetKeywordCompletionContributor.java +++ b/idea/src/org/jetbrains/jet/plugin/completion/JetKeywordCompletionContributor.java @@ -36,7 +36,6 @@ import com.intellij.psi.impl.source.tree.LeafPsiElement; import com.intellij.psi.util.PsiTreeUtil; import com.intellij.util.ArrayUtil; import com.intellij.util.ProcessingContext; -import com.intellij.util.codeInsight.CommentUtilCore; import org.jetbrains.annotations.NotNull; import org.jetbrains.jet.lang.psi.*; import org.jetbrains.jet.lexer.JetToken; @@ -103,7 +102,7 @@ public class JetKeywordCompletionContributor extends CompletionContributor { return false; } - return CommentUtilCore.isComment((PsiElement) element); + return JetPsiUtil.isInComment((PsiElement) element); } @Override diff --git a/idea/src/org/jetbrains/jet/plugin/formatter/JetFormattingModelBuilder.java b/idea/src/org/jetbrains/jet/plugin/formatter/JetFormattingModelBuilder.java index 13d4e7e8dc5..fb4b1f2dca9 100644 --- a/idea/src/org/jetbrains/jet/plugin/formatter/JetFormattingModelBuilder.java +++ b/idea/src/org/jetbrains/jet/plugin/formatter/JetFormattingModelBuilder.java @@ -25,7 +25,6 @@ import com.intellij.psi.codeStyle.CodeStyleSettings; import com.intellij.psi.codeStyle.CommonCodeStyleSettings; import com.intellij.psi.tree.TokenSet; import org.jetbrains.annotations.NotNull; -import org.jetbrains.jet.kdoc.lexer.KDocTokens; import org.jetbrains.jet.plugin.JetLanguage; import static org.jetbrains.jet.JetNodeTypes.*; @@ -108,9 +107,6 @@ public class JetFormattingModelBuilder implements FormattingModelBuilder { .between(VALUE_ARGUMENT_LIST, FUNCTION_LITERAL_EXPRESSION).spaces(1) .aroundInside(ARROW, WHEN_ENTRY).spaces(1) - - // KDoc - .between(KDocTokens.LEADING_ASTERISK, KDocTokens.TEXT).spacing(1, 100, 0, true, 100) ; } From bcc2c46e99ba1276bd13bc8d96770bc637cf5bcc Mon Sep 17 00:00:00 2001 From: Sergey Rostov Date: Sat, 25 May 2013 19:05:01 +0400 Subject: [PATCH 145/249] KDoc wiki links pair matcher and @tags highlighter --- .../org/jetbrains/jet/kdoc/lexer/KDoc.flex | 45 +++- .../jetbrains/jet/kdoc/lexer/KDocTokens.java | 8 + .../jetbrains/jet/kdoc/lexer/_KDocLexer.java | 195 +++++++++++++----- compiler/testData/psi/kdoc/AtTags.jet | 5 + compiler/testData/psi/kdoc/AtTags.txt | 17 ++ compiler/testData/psi/kdoc/Markdown.jet | 4 + compiler/testData/psi/kdoc/Markdown.txt | 20 ++ .../jetbrains/jet/plugin/JetBundle.properties | 2 + .../jetbrains/jet/plugin/JetPairMatcher.java | 6 +- .../highlighter/JetColorSettingsPage.java | 4 +- .../plugin/highlighter/JetHighlighter.java | 7 +- .../highlighter/JetHighlightingColors.java | 2 + .../highlighter/JetHighlightingLexer.java | 15 ++ 13 files changed, 267 insertions(+), 63 deletions(-) create mode 100644 compiler/testData/psi/kdoc/AtTags.jet create mode 100644 compiler/testData/psi/kdoc/AtTags.txt create mode 100644 compiler/testData/psi/kdoc/Markdown.jet create mode 100644 compiler/testData/psi/kdoc/Markdown.txt create mode 100644 idea/src/org/jetbrains/jet/plugin/highlighter/JetHighlightingLexer.java diff --git a/compiler/frontend/src/org/jetbrains/jet/kdoc/lexer/KDoc.flex b/compiler/frontend/src/org/jetbrains/jet/kdoc/lexer/KDoc.flex index 7a1cbd60f21..923e60e53be 100644 --- a/compiler/frontend/src/org/jetbrains/jet/kdoc/lexer/KDoc.flex +++ b/compiler/frontend/src/org/jetbrains/jet/kdoc/lexer/KDoc.flex @@ -4,6 +4,7 @@ import com.intellij.lexer.FlexLexer; import com.intellij.psi.TokenType; import com.intellij.psi.tree.IElementType; import com.intellij.util.text.CharArrayUtil; +import java.lang.Character; %% @@ -16,13 +17,21 @@ import com.intellij.util.text.CharArrayUtil; this((java.io.Reader)null); } - private final boolean isLastToken() { + private boolean isLastToken() { return zzMarkedPos == zzBuffer.length(); } - private final Boolean yytextContainLineBreaks() { + private Boolean yytextContainLineBreaks() { return CharArrayUtil.containLineBreaks(zzBuffer, zzStartRead, zzMarkedPos); } + + private boolean nextIsNotWhitespace() { + return zzMarkedPos <= zzBuffer.length() && !Character.isWhitespace(zzBuffer.charAt(zzMarkedPos + 1)); + } + + private boolean prevIsNotWhitespace() { + return zzMarkedPos != 0 && !Character.isWhitespace(zzBuffer.charAt(zzMarkedPos - 1)); + } %} %function advance @@ -31,12 +40,21 @@ import com.intellij.util.text.CharArrayUtil; return; %eof} -%state CONTENTS %state LINE_BEGINNING +%state CONTENTS_BEGINNING +%state CONTENTS +%state CODE +%state CODE2 WHITE_SPACE_CHAR =[\ \t\f\n\r] NOT_WHITE_SPACE_CHAR=[^\ \t\f\n\r] +DIGIT=[0-9] +ALPHA=[:jletter:] +TAG_NAME={ALPHA}({ALPHA}|{DIGIT})* + +MARKDOWN_EMPHASIS=[\*_] + %% @@ -45,22 +63,33 @@ NOT_WHITE_SPACE_CHAR=[^\ \t\f\n\r] "*"+ "/" { if (isLastToken()) return KDocTokens.END; else return KDocTokens.TEXT; } - "*"+ { yybegin(CONTENTS); + "*"+ { yybegin(CONTENTS_BEGINNING); return KDocTokens.LEADING_ASTERISK; } - { + "@"{TAG_NAME} { yybegin(CONTENTS); + return KDocTokens.TAG_NAME; } + + { {WHITE_SPACE_CHAR}+ { if (yytextContainLineBreaks()) { yybegin(LINE_BEGINNING); return TokenType.WHITE_SPACE; } else { - yybegin(CONTENTS); + yybegin(yystate() == CONTENTS_BEGINNING? CONTENTS_BEGINNING:CONTENTS); return KDocTokens.TEXT; // internal white space } } - . { yybegin(CONTENTS); - return KDocTokens.TEXT; } + "\\"[\[\]] { yybegin(CONTENTS); + return KDocTokens.MARKDOWN_ESCAPED_CHAR; } + + "[[" { yybegin(CONTENTS); + return KDocTokens.WIKI_LINK_OPEN; } + "]]" { yybegin(CONTENTS); + return KDocTokens.WIKI_LINK_CLOSE; } + + . { yybegin(CONTENTS); + return KDocTokens.TEXT; } } . { return TokenType.BAD_CHARACTER; } \ No newline at end of file diff --git a/compiler/frontend/src/org/jetbrains/jet/kdoc/lexer/KDocTokens.java b/compiler/frontend/src/org/jetbrains/jet/kdoc/lexer/KDocTokens.java index 92bdb3cbb86..da637335958 100644 --- a/compiler/frontend/src/org/jetbrains/jet/kdoc/lexer/KDocTokens.java +++ b/compiler/frontend/src/org/jetbrains/jet/kdoc/lexer/KDocTokens.java @@ -23,6 +23,7 @@ import com.intellij.lang.PsiParser; import com.intellij.openapi.project.Project; import com.intellij.psi.PsiElement; import com.intellij.psi.tree.ILazyParseableElementType; +import com.intellij.psi.tree.TokenSet; import org.jetbrains.annotations.Nullable; import org.jetbrains.jet.kdoc.parser.KDocParser; import org.jetbrains.jet.kdoc.psi.impl.KDocImpl; @@ -53,4 +54,11 @@ public interface KDocTokens { KDocToken LEADING_ASTERISK = new KDocToken("KDOC_LEADING_ASTERISK"); KDocToken TEXT = new KDocToken("KDOC_TEXT"); + KDocToken TAG_NAME = new KDocToken("KDOC_TAG_NAME"); + KDocToken WIKI_LINK_OPEN = new KDocToken("KDOC_WIKI_LINK_OPEN"); + KDocToken WIKI_LINK_CLOSE = new KDocToken("KDOC_WIKI_LINK_CLOSE"); + + KDocToken MARKDOWN_ESCAPED_CHAR = new KDocToken("KDOC_MARKDOWN_ESCAPED_CHAR"); + + TokenSet CONTENT_TOKENS = TokenSet.create(START, END, LEADING_ASTERISK, TEXT, WIKI_LINK_OPEN, WIKI_LINK_CLOSE, MARKDOWN_ESCAPED_CHAR); } diff --git a/compiler/frontend/src/org/jetbrains/jet/kdoc/lexer/_KDocLexer.java b/compiler/frontend/src/org/jetbrains/jet/kdoc/lexer/_KDocLexer.java index c813e40dc93..373b9284e9a 100644 --- a/compiler/frontend/src/org/jetbrains/jet/kdoc/lexer/_KDocLexer.java +++ b/compiler/frontend/src/org/jetbrains/jet/kdoc/lexer/_KDocLexer.java @@ -1,4 +1,4 @@ -/* The following code was generated by JFlex 1.4.3 on 25.05.13 15:08 */ +/* The following code was generated by JFlex 1.4.3 on 25.05.13 16:39 */ package org.jetbrains.jet.kdoc.lexer; @@ -11,7 +11,7 @@ import com.intellij.util.text.CharArrayUtil; /** * This class is a scanner generated by * JFlex 1.4.3 - * on 25.05.13 15:08 from the specification file + * on 25.05.13 16:39 from the specification file * /Users/factitious/Documents/kotlin/compiler/frontend/src/org/jetbrains/jet/kdoc/lexer/KDoc.flex */ class _KDocLexer implements FlexLexer { @@ -19,11 +19,12 @@ class _KDocLexer implements FlexLexer { private static final int ZZ_BUFFERSIZE = 16384; /** lexical states */ - public static final int LINE_BEGINNING = 8; - public static final int STRONG_CONTENTS = 6; - public static final int CONTENTS = 2; + public static final int CODE = 8; + public static final int CONTENTS_BEGINNING = 4; + public static final int CODE2 = 10; + public static final int LINE_BEGINNING = 2; + public static final int CONTENTS = 6; public static final int YYINITIAL = 0; - public static final int EMPHASIS_CONTENTS = 4; /** * ZZ_LEXSTATE[l] is the state in the DFA for the lexical state l @@ -32,15 +33,74 @@ class _KDocLexer implements FlexLexer { * l is of the form l = 2*k, k a non negative integer */ private static final int ZZ_LEXSTATE[] = { - 0, 0, 1, 1, 1, 1, 1, 1, 2, 2 + 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 4, 4 }; /** * Translates characters to character classes */ private static final String ZZ_CMAP_PACKED = - "\11\0\1\1\1\4\1\0\2\1\22\0\1\1\11\0\1\3\4\0"+ - "\1\2\uffd0\0"; + "\11\0\1\1\1\12\1\0\2\1\22\0\1\1\3\0\1\3\5\0"+ + "\1\4\4\0\1\5\12\2\6\0\1\6\32\3\1\11\1\7\1\10"+ + "\1\0\1\3\1\0\32\3\47\0\4\3\4\0\1\3\12\0\1\3"+ + "\4\0\1\3\5\0\27\3\1\0\37\3\1\0\u013f\3\31\0\162\3"+ + "\4\0\14\3\16\0\5\3\11\0\1\3\213\0\1\3\13\0\1\3"+ + "\1\0\3\3\1\0\1\3\1\0\24\3\1\0\54\3\1\0\46\3"+ + "\1\0\5\3\4\0\202\3\10\0\105\3\1\0\46\3\2\0\2\3"+ + "\6\0\20\3\41\0\46\3\2\0\1\3\7\0\47\3\110\0\33\3"+ + "\5\0\3\3\56\0\32\3\5\0\13\3\43\0\2\3\1\0\143\3"+ + "\1\0\1\3\17\0\2\3\7\0\2\3\12\0\3\3\2\0\1\3"+ + "\20\0\1\3\1\0\36\3\35\0\3\3\60\0\46\3\13\0\1\3"+ + "\u0152\0\66\3\3\0\1\3\22\0\1\3\7\0\12\3\43\0\10\3"+ + "\2\0\2\3\2\0\26\3\1\0\7\3\1\0\1\3\3\0\4\3"+ + "\3\0\1\3\36\0\2\3\1\0\3\3\16\0\4\3\21\0\6\3"+ + "\4\0\2\3\2\0\26\3\1\0\7\3\1\0\2\3\1\0\2\3"+ + "\1\0\2\3\37\0\4\3\1\0\1\3\23\0\3\3\20\0\11\3"+ + "\1\0\3\3\1\0\26\3\1\0\7\3\1\0\2\3\1\0\5\3"+ + "\3\0\1\3\22\0\1\3\17\0\2\3\17\0\1\3\23\0\10\3"+ + "\2\0\2\3\2\0\26\3\1\0\7\3\1\0\2\3\1\0\5\3"+ + "\3\0\1\3\36\0\2\3\1\0\3\3\17\0\1\3\21\0\1\3"+ + "\1\0\6\3\3\0\3\3\1\0\4\3\3\0\2\3\1\0\1\3"+ + "\1\0\2\3\3\0\2\3\3\0\3\3\3\0\10\3\1\0\3\3"+ + "\77\0\1\3\13\0\10\3\1\0\3\3\1\0\27\3\1\0\12\3"+ + "\1\0\5\3\46\0\2\3\43\0\10\3\1\0\3\3\1\0\27\3"+ + "\1\0\12\3\1\0\5\3\3\0\1\3\40\0\1\3\1\0\2\3"+ + "\43\0\10\3\1\0\3\3\1\0\27\3\1\0\20\3\46\0\2\3"+ + "\43\0\22\3\3\0\30\3\1\0\11\3\1\0\1\3\2\0\7\3"+ + "\72\0\60\3\1\0\2\3\13\0\10\3\72\0\2\3\1\0\1\3"+ + "\2\0\2\3\1\0\1\3\2\0\1\3\6\0\4\3\1\0\7\3"+ + "\1\0\3\3\1\0\1\3\1\0\1\3\2\0\2\3\1\0\4\3"+ + "\1\0\2\3\11\0\1\3\2\0\5\3\1\0\1\3\25\0\2\3"+ + "\42\0\1\3\77\0\10\3\1\0\42\3\35\0\4\3\164\0\42\3"+ + "\1\0\5\3\1\0\2\3\45\0\6\3\112\0\46\3\12\0\51\3"+ + "\7\0\132\3\5\0\104\3\5\0\122\3\6\0\7\3\1\0\77\3"+ + "\1\0\1\3\1\0\4\3\2\0\7\3\1\0\1\3\1\0\4\3"+ + "\2\0\47\3\1\0\1\3\1\0\4\3\2\0\37\3\1\0\1\3"+ + "\1\0\4\3\2\0\7\3\1\0\1\3\1\0\4\3\2\0\7\3"+ + "\1\0\7\3\1\0\27\3\1\0\37\3\1\0\1\3\1\0\4\3"+ + "\2\0\7\3\1\0\47\3\1\0\23\3\105\0\125\3\14\0\u026c\3"+ + "\2\0\10\3\12\0\32\3\5\0\113\3\3\0\3\3\17\0\15\3"+ + "\1\0\4\3\16\0\22\3\16\0\22\3\16\0\15\3\1\0\3\3"+ + "\17\0\64\3\43\0\1\3\3\0\2\3\103\0\130\3\10\0\51\3"+ + "\127\0\35\3\63\0\36\3\2\0\5\3\u038b\0\154\3\224\0\234\3"+ + "\4\0\132\3\6\0\26\3\2\0\6\3\2\0\46\3\2\0\6\3"+ + "\2\0\10\3\1\0\1\3\1\0\1\3\1\0\1\3\1\0\37\3"+ + "\2\0\65\3\1\0\7\3\1\0\1\3\3\0\3\3\1\0\7\3"+ + "\3\0\4\3\2\0\6\3\4\0\15\3\5\0\3\3\1\0\7\3"+ + "\102\0\2\3\23\0\1\3\34\0\1\3\15\0\1\3\40\0\22\3"+ + "\120\0\1\3\4\0\1\3\2\0\12\3\1\0\1\3\3\0\5\3"+ + "\6\0\1\3\1\0\1\3\1\0\1\3\1\0\4\3\1\0\3\3"+ + "\1\0\7\3\3\0\3\3\5\0\5\3\26\0\44\3\u0e81\0\3\3"+ + "\31\0\11\3\7\0\5\3\2\0\5\3\4\0\126\3\6\0\3\3"+ + "\1\0\137\3\5\0\50\3\4\0\136\3\21\0\30\3\70\0\20\3"+ + "\u0200\0\u19b6\3\112\0\u51a6\3\132\0\u048d\3\u0773\0\u2ba4\3\u215c\0\u012e\3"+ + "\2\0\73\3\225\0\7\3\14\0\5\3\5\0\1\3\1\0\12\3"+ + "\1\0\15\3\1\0\5\3\1\0\1\3\1\0\2\3\1\0\2\3"+ + "\1\0\154\3\41\0\u016b\3\22\0\100\3\2\0\66\3\50\0\15\3"+ + "\66\0\2\3\30\0\3\3\31\0\1\3\6\0\5\3\1\0\207\3"+ + "\7\0\1\3\34\0\32\3\4\0\1\3\1\0\32\3\12\0\132\3"+ + "\3\0\6\3\2\0\6\3\2\0\6\3\2\0\3\3\3\0\2\3"+ + "\3\0\2\3\31\0"; /** * Translates characters to character classes @@ -53,11 +113,11 @@ class _KDocLexer implements FlexLexer { private static final int [] ZZ_ACTION = zzUnpackAction(); private static final String ZZ_ACTION_PACKED_0 = - "\3\0\3\1\1\2\1\3\1\2\1\4\1\0\1\5"+ - "\1\0\1\6"; + "\5\0\3\1\1\2\1\3\1\4\5\2\1\0\1\5"+ + "\1\0\1\6\1\7\1\10\1\11\1\12"; private static int [] zzUnpackAction() { - int [] result = new int[14]; + int [] result = new int[24]; int offset = 0; offset = zzUnpackAction(ZZ_ACTION_PACKED_0, offset, result); return result; @@ -82,11 +142,12 @@ class _KDocLexer implements FlexLexer { private static final int [] ZZ_ROWMAP = zzUnpackRowMap(); private static final String ZZ_ROWMAP_PACKED_0 = - "\0\0\0\5\0\12\0\17\0\24\0\31\0\17\0\36"+ - "\0\31\0\43\0\50\0\17\0\31\0\17"; + "\0\0\0\13\0\26\0\41\0\54\0\67\0\102\0\115"+ + "\0\67\0\130\0\143\0\156\0\171\0\204\0\102\0\217"+ + "\0\102\0\67\0\232\0\67\0\67\0\67\0\245\0\67"; private static int [] zzUnpackRowMap() { - int [] result = new int[14]; + int [] result = new int[24]; int offset = 0; offset = zzUnpackRowMap(ZZ_ROWMAP_PACKED_0, offset, result); return result; @@ -109,13 +170,17 @@ class _KDocLexer implements FlexLexer { private static final int [] ZZ_TRANS = zzUnpackTrans(); private static final String ZZ_TRANS_PACKED_0 = - "\2\4\1\5\1\6\1\0\1\7\1\10\1\7\1\11"+ - "\1\10\1\7\1\10\1\7\1\12\1\10\10\0\1\13"+ - "\3\0\1\14\1\15\2\0\1\10\2\0\1\10\2\0"+ - "\1\14\1\12\4\0\1\16\1\0"; + "\4\6\1\7\1\10\4\6\1\0\1\11\1\12\2\11"+ + "\1\13\2\11\1\14\1\15\1\16\1\12\1\11\1\12"+ + "\2\11\1\17\1\11\1\20\1\14\1\15\1\16\1\12"+ + "\1\11\1\12\2\11\1\17\2\11\1\14\1\15\1\16"+ + "\1\12\4\6\1\7\5\6\20\0\1\21\1\22\11\0"+ + "\1\23\7\0\1\12\10\0\1\12\4\0\1\13\1\22"+ + "\15\0\2\24\11\0\1\25\13\0\1\26\4\0\1\27"+ + "\13\0\1\30\10\0\2\27\7\0"; private static int [] zzUnpackTrans() { - int [] result = new int[45]; + int [] result = new int[176]; int offset = 0; offset = zzUnpackTrans(ZZ_TRANS_PACKED_0, offset, result); return result; @@ -156,11 +221,11 @@ class _KDocLexer implements FlexLexer { private static final int [] ZZ_ATTRIBUTE = zzUnpackAttribute(); private static final String ZZ_ATTRIBUTE_PACKED_0 = - "\3\0\1\11\2\1\1\11\3\1\1\0\1\11\1\0"+ - "\1\11"; + "\5\0\1\11\2\1\1\11\7\1\1\0\1\11\1\0"+ + "\3\11\1\1\1\11"; private static int [] zzUnpackAttribute() { - int [] result = new int[14]; + int [] result = new int[24]; int offset = 0; offset = zzUnpackAttribute(ZZ_ATTRIBUTE_PACKED_0, offset, result); return result; @@ -223,14 +288,22 @@ class _KDocLexer implements FlexLexer { this((java.io.Reader)null); } - private final boolean isLastToken() { + private boolean isLastToken() { return zzMarkedPos == zzBuffer.length(); } - private final Boolean yytextContainLineBreaks() { + private Boolean yytextContainLineBreaks() { return CharArrayUtil.containLineBreaks(zzBuffer, zzStartRead, zzMarkedPos); } + private boolean nextIsNotWhitespace() { + return zzMarkedPos <= zzBuffer.length() && !Character.isWhitespace(zzBuffer.charAt(zzMarkedPos + 1)); + } + + private boolean prevIsNotWhitespace() { + return zzMarkedPos != 0 && !Character.isWhitespace(zzBuffer.charAt(zzMarkedPos - 1)); + } + _KDocLexer(java.io.Reader in) { this.zzReader = in; @@ -256,7 +329,7 @@ class _KDocLexer implements FlexLexer { char [] map = new char[0x10000]; int i = 0; /* index in packed string */ int j = 0; /* index in unpacked array */ - while (i < 24) { + while (i < 1206) { int count = packed.charAt(i++); char value = packed.charAt(i++); do map[j++] = value; while (--count > 0); @@ -479,40 +552,60 @@ class _KDocLexer implements FlexLexer { zzMarkedPos = zzMarkedPosL; switch (zzAction < 0 ? zzAction : ZZ_ACTION[zzAction]) { - case 6: - { yybegin(CONTENTS); - return KDocTokens.START; - } - case 7: break; - case 5: - { if (isLastToken()) return KDocTokens.END; - else return KDocTokens.TEXT; - } - case 8: break; - case 1: - { return TokenType.BAD_CHARACTER; - } - case 9: break; - case 2: - { yybegin(CONTENTS); - return KDocTokens.TEXT; - } - case 10: break; - case 4: - { yybegin(CONTENTS); - return KDocTokens.LEADING_ASTERISK; - } - case 11: break; case 3: { if (yytextContainLineBreaks()) { yybegin(LINE_BEGINNING); return TokenType.WHITE_SPACE; } else { - yybegin(CONTENTS); + yybegin(yystate() == CONTENTS_BEGINNING? CONTENTS_BEGINNING:CONTENTS); return KDocTokens.TEXT; // internal white space } } + case 11: break; + case 5: + { if (isLastToken()) return KDocTokens.END; + else return KDocTokens.TEXT; + } case 12: break; + case 9: + { yybegin(CONTENTS); + return KDocTokens.TAG_NAME; + } + case 13: break; + case 7: + { yybegin(CONTENTS); + return KDocTokens.WIKI_LINK_CLOSE; + } + case 14: break; + case 8: + { yybegin(CONTENTS); + return KDocTokens.WIKI_LINK_OPEN; + } + case 15: break; + case 10: + { yybegin(CONTENTS); + return KDocTokens.START; + } + case 16: break; + case 1: + { return TokenType.BAD_CHARACTER; + } + case 17: break; + case 6: + { yybegin(CONTENTS); + return KDocTokens.MARKDOWN_ESCAPED_CHAR; + } + case 18: break; + case 2: + { yybegin(CONTENTS); + return KDocTokens.TEXT; + } + case 19: break; + case 4: + { yybegin(CONTENTS_BEGINNING); + return KDocTokens.LEADING_ASTERISK; + } + case 20: break; default: if (zzInput == YYEOF && zzStartRead == zzCurrentPos) { zzAtEOF = true; diff --git a/compiler/testData/psi/kdoc/AtTags.jet b/compiler/testData/psi/kdoc/AtTags.jet new file mode 100644 index 00000000000..8798fcad57b --- /dev/null +++ b/compiler/testData/psi/kdoc/AtTags.jet @@ -0,0 +1,5 @@ +/** + * @tag + * text @notATag + * @ + */ \ No newline at end of file diff --git a/compiler/testData/psi/kdoc/AtTags.txt b/compiler/testData/psi/kdoc/AtTags.txt new file mode 100644 index 00000000000..8e1dd8be825 --- /dev/null +++ b/compiler/testData/psi/kdoc/AtTags.txt @@ -0,0 +1,17 @@ +JetFile: AtTags.jet + KDoc + PsiElement(KDOC_START)('/**') + PsiWhiteSpace('\n ') + PsiElement(KDOC_LEADING_ASTERISK)('*') + PsiElement(KDOC_TEXT)(' ') + PsiElement(KDOC_TAG_NAME)('@tag') + PsiWhiteSpace('\n ') + PsiElement(KDOC_LEADING_ASTERISK)('*') + PsiElement(KDOC_TEXT)(' text @notATag') + PsiWhiteSpace('\n ') + PsiElement(KDOC_LEADING_ASTERISK)('*') + PsiElement(KDOC_TEXT)(' @') + PsiWhiteSpace('\n ') + PsiElement(KDOC_END)('*/') + NAMESPACE_HEADER + \ No newline at end of file diff --git a/compiler/testData/psi/kdoc/Markdown.jet b/compiler/testData/psi/kdoc/Markdown.jet new file mode 100644 index 00000000000..8811d83ea2e --- /dev/null +++ b/compiler/testData/psi/kdoc/Markdown.jet @@ -0,0 +1,4 @@ +/** + * [[WikiLink]] + * Just \[[ and \]] + */ \ No newline at end of file diff --git a/compiler/testData/psi/kdoc/Markdown.txt b/compiler/testData/psi/kdoc/Markdown.txt new file mode 100644 index 00000000000..6755464bcff --- /dev/null +++ b/compiler/testData/psi/kdoc/Markdown.txt @@ -0,0 +1,20 @@ +JetFile: Markdown.jet + KDoc + PsiElement(KDOC_START)('/**') + PsiWhiteSpace('\n ') + PsiElement(KDOC_LEADING_ASTERISK)('*') + PsiElement(KDOC_TEXT)(' ') + PsiElement(KDOC_WIKI_LINK_OPEN)('[[') + PsiElement(KDOC_TEXT)('WikiLink') + PsiElement(KDOC_WIKI_LINK_CLOSE)(']]') + PsiWhiteSpace('\n ') + PsiElement(KDOC_LEADING_ASTERISK)('*') + PsiElement(KDOC_TEXT)(' Just ') + PsiElement(KDOC_MARKDOWN_ESCAPED_CHAR)('\[') + PsiElement(KDOC_TEXT)('[ and ') + PsiElement(KDOC_MARKDOWN_ESCAPED_CHAR)('\]') + PsiElement(KDOC_TEXT)(']') + PsiWhiteSpace('\n ') + PsiElement(KDOC_END)('*/') + NAMESPACE_HEADER + \ No newline at end of file diff --git a/idea/src/org/jetbrains/jet/plugin/JetBundle.properties b/idea/src/org/jetbrains/jet/plugin/JetBundle.properties index 9536b7af1f7..c640470d94b 100644 --- a/idea/src/org/jetbrains/jet/plugin/JetBundle.properties +++ b/idea/src/org/jetbrains/jet/plugin/JetBundle.properties @@ -110,6 +110,8 @@ options.jet.attribute.descriptor.closure.braces=Function literal braces and arro options.jet.attribute.descriptor.safe.access=Safe access dot options.jet.attribute.descriptor.arrow=Arrow options.jet.attribute.descriptor.kdoc.comment=KDoc comment +options.jet.attribute.descriptor.kdoc.tag=KDoc tag +options.jet.attribute.descriptor.kdoc.value=KDoc tag value options.jet.attribute.descriptor.trait=Trait options.jet.attribute.descriptor.annotation=Annotation options.jet.attribute.descriptor.var=Var (mutable variable, parameter or property) diff --git a/idea/src/org/jetbrains/jet/plugin/JetPairMatcher.java b/idea/src/org/jetbrains/jet/plugin/JetPairMatcher.java index 9bf05aa432b..40dd0154b1f 100644 --- a/idea/src/org/jetbrains/jet/plugin/JetPairMatcher.java +++ b/idea/src/org/jetbrains/jet/plugin/JetPairMatcher.java @@ -22,6 +22,7 @@ import com.intellij.psi.PsiFile; import com.intellij.psi.tree.IElementType; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import org.jetbrains.jet.kdoc.lexer.KDocTokens; import org.jetbrains.jet.lexer.JetTokens; public class JetPairMatcher implements PairedBraceMatcher { @@ -29,7 +30,8 @@ public class JetPairMatcher implements PairedBraceMatcher { new BracePair(JetTokens.LPAR, JetTokens.RPAR, false), new BracePair(JetTokens.LONG_TEMPLATE_ENTRY_START, JetTokens.LONG_TEMPLATE_ENTRY_END, false), new BracePair(JetTokens.LBRACE, JetTokens.RBRACE, true), - new BracePair(JetTokens.LBRACKET, JetTokens.RBRACKET, false) + new BracePair(JetTokens.LBRACKET, JetTokens.RBRACKET, false), + new BracePair(KDocTokens.WIKI_LINK_OPEN, KDocTokens.WIKI_LINK_CLOSE, false) }; @Override @@ -44,6 +46,8 @@ public class JetPairMatcher implements PairedBraceMatcher { return false; } + if (lbraceType == KDocTokens.WIKI_LINK_OPEN) return false; + return JetTokens.WHITE_SPACE_OR_COMMENT_BIT_SET.contains(contextType) || contextType == JetTokens.SEMICOLON || contextType == JetTokens.COMMA diff --git a/idea/src/org/jetbrains/jet/plugin/highlighter/JetColorSettingsPage.java b/idea/src/org/jetbrains/jet/plugin/highlighter/JetColorSettingsPage.java index c39db363ffd..c3ac0bccda9 100644 --- a/idea/src/org/jetbrains/jet/plugin/highlighter/JetColorSettingsPage.java +++ b/idea/src/org/jetbrains/jet/plugin/highlighter/JetColorSettingsPage.java @@ -54,7 +54,7 @@ public class JetColorSettingsPage implements ColorSettingsPage { "\n" + "/**\n" + " * Doc comment here for `SomeClass`\n" + - " * @see Iterator#next()\n" + + " * @see Iterator#next()\n" + " */\n" + "[Deprecated]\n" + "public class MyClass<out T : Iterable<T>>(var prop1 : Int) {\n" + @@ -126,6 +126,8 @@ public class JetColorSettingsPage implements ColorSettingsPage { new AttributesDescriptor(OptionsBundle.message("options.java.attribute.descriptor.block.comment"), JetHighlightingColors.BLOCK_COMMENT), new AttributesDescriptor(JetBundle.message("options.jet.attribute.descriptor.kdoc.comment"), JetHighlightingColors.DOC_COMMENT), + new AttributesDescriptor(JetBundle.message("options.jet.attribute.descriptor.kdoc.tag"), JetHighlightingColors.KDOC_TAG), + new AttributesDescriptor(JetBundle.message("options.jet.attribute.descriptor.kdoc.value"), JetHighlightingColors.KDOC_TAG_VALUE), new AttributesDescriptor(OptionsBundle.message("options.java.attribute.descriptor.class"), JetHighlightingColors.CLASS), new AttributesDescriptor(OptionsBundle.message("options.java.attribute.descriptor.type.parameter"), JetHighlightingColors.TYPE_PARAMETER), diff --git a/idea/src/org/jetbrains/jet/plugin/highlighter/JetHighlighter.java b/idea/src/org/jetbrains/jet/plugin/highlighter/JetHighlighter.java index d4452953aab..8b649b2ff68 100644 --- a/idea/src/org/jetbrains/jet/plugin/highlighter/JetHighlighter.java +++ b/idea/src/org/jetbrains/jet/plugin/highlighter/JetHighlighter.java @@ -23,7 +23,7 @@ import com.intellij.psi.TokenType; import com.intellij.psi.tree.IElementType; import com.intellij.psi.tree.TokenSet; import org.jetbrains.annotations.NotNull; -import org.jetbrains.jet.lexer.JetLexer; +import org.jetbrains.jet.kdoc.lexer.KDocTokens; import org.jetbrains.jet.lexer.JetTokens; import java.util.HashMap; @@ -34,7 +34,7 @@ public class JetHighlighter extends SyntaxHighlighterBase { @NotNull public Lexer getHighlightingLexer() { - return new JetLexer(); + return new JetHighlightingLexer(); } @NotNull @@ -83,6 +83,9 @@ public class JetHighlighter extends SyntaxHighlighterBase { keys.put(JetTokens.BLOCK_COMMENT, JetHighlightingColors.BLOCK_COMMENT); keys.put(JetTokens.DOC_COMMENT, JetHighlightingColors.DOC_COMMENT); + fillMap(keys, KDocTokens.CONTENT_TOKENS, JetHighlightingColors.DOC_COMMENT); + keys.put(KDocTokens.TAG_NAME, JetHighlightingColors.KDOC_TAG); + keys.put(TokenType.BAD_CHARACTER, JetHighlightingColors.BAD_CHARACTER); } } diff --git a/idea/src/org/jetbrains/jet/plugin/highlighter/JetHighlightingColors.java b/idea/src/org/jetbrains/jet/plugin/highlighter/JetHighlightingColors.java index e7d1bfad66a..4230cc48b03 100644 --- a/idea/src/org/jetbrains/jet/plugin/highlighter/JetHighlightingColors.java +++ b/idea/src/org/jetbrains/jet/plugin/highlighter/JetHighlightingColors.java @@ -44,6 +44,8 @@ public class JetHighlightingColors { public static final TextAttributesKey LINE_COMMENT = createTextAttributesKey("KOTLIN_LINE_COMMENT", DefaultLanguageHighlighterColors.LINE_COMMENT); public static final TextAttributesKey BLOCK_COMMENT = createTextAttributesKey("KOTLIN_BLOCK_COMMENT", DefaultLanguageHighlighterColors.BLOCK_COMMENT); public static final TextAttributesKey DOC_COMMENT = createTextAttributesKey("KOTLIN_DOC_COMMENT", DefaultLanguageHighlighterColors.DOC_COMMENT); + public static final TextAttributesKey KDOC_TAG = createTextAttributesKey("KDOC_TAG_NAME", DefaultLanguageHighlighterColors.DOC_COMMENT_TAG); + public static final TextAttributesKey KDOC_TAG_VALUE = createTextAttributesKey("KDOC_TAG_VALUE", DefaultLanguageHighlighterColors.DOC_COMMENT_TAG_VALUE); // class kinds public static final TextAttributesKey CLASS = createTextAttributesKey("KOTLIN_CLASS", CodeInsightColors.CLASS_NAME_ATTRIBUTES); diff --git a/idea/src/org/jetbrains/jet/plugin/highlighter/JetHighlightingLexer.java b/idea/src/org/jetbrains/jet/plugin/highlighter/JetHighlightingLexer.java new file mode 100644 index 00000000000..9e178dd5b1a --- /dev/null +++ b/idea/src/org/jetbrains/jet/plugin/highlighter/JetHighlightingLexer.java @@ -0,0 +1,15 @@ +package org.jetbrains.jet.plugin.highlighter; + +import com.intellij.lexer.LayeredLexer; +import com.intellij.psi.tree.IElementType; +import org.jetbrains.jet.kdoc.lexer.KDocLexer; +import org.jetbrains.jet.lexer.JetLexer; +import org.jetbrains.jet.lexer.JetTokens; + +public class JetHighlightingLexer extends LayeredLexer { + public JetHighlightingLexer() { + super(new JetLexer()); + + registerSelfStoppingLayer(new KDocLexer(), new IElementType[]{JetTokens.DOC_COMMENT}, IElementType.EMPTY_ARRAY); + } +} From 7b6505e54f9709a0fa8e0178a1f9dc91183bc3a0 Mon Sep 17 00:00:00 2001 From: Mikhael Bogdanov Date: Tue, 28 May 2013 15:55:57 +0400 Subject: [PATCH 146/249] Fixed 'lowercaseFirstLetter' for test data in 280 pull request --- idea/tests/org/jetbrains/jet/editor/JetCommenterTest.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/idea/tests/org/jetbrains/jet/editor/JetCommenterTest.java b/idea/tests/org/jetbrains/jet/editor/JetCommenterTest.java index 967ef967b7d..fd630cfd199 100644 --- a/idea/tests/org/jetbrains/jet/editor/JetCommenterTest.java +++ b/idea/tests/org/jetbrains/jet/editor/JetCommenterTest.java @@ -43,11 +43,11 @@ public class JetCommenterTest extends LightCodeInsightTestCase { } private void configure() throws Exception { - configureFromFileText("a.kt", loadFile(getTestName(false) + ".kt")); + configureFromFileText("a.kt", loadFile(getTestName(true) + ".kt")); } private void check() throws Exception { - checkResultByText(loadFile(getTestName(false) + "_after.kt")); + checkResultByText(loadFile(getTestName(true) + "_after.kt")); } protected static String loadFile(String name) throws Exception { From b7a99ac27244143b284294a4caf589389c54827e Mon Sep 17 00:00:00 2001 From: Evgeny Gerashchenko Date: Tue, 28 May 2013 19:47:07 +0400 Subject: [PATCH 147/249] Added my dictionary with "klass" word. --- .idea/dictionaries/geevee.xml | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 .idea/dictionaries/geevee.xml diff --git a/.idea/dictionaries/geevee.xml b/.idea/dictionaries/geevee.xml new file mode 100644 index 00000000000..a295409b23b --- /dev/null +++ b/.idea/dictionaries/geevee.xml @@ -0,0 +1,7 @@ + + + + klass + + + \ No newline at end of file From fcf990d80da52d500666c0c51ab432b854207df0 Mon Sep 17 00:00:00 2001 From: Evgeny Gerashchenko Date: Tue, 28 May 2013 19:47:32 +0400 Subject: [PATCH 148/249] Cleanup in .gitignore --- .gitignore | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/.gitignore b/.gitignore index daef9f5114c..11d3561b490 100644 --- a/.gitignore +++ b/.gitignore @@ -1,23 +1,12 @@ -compiler/frontend/idea.properties -examples/.idea/dictionaries -examples/.idea/workspace.xml -examples/example-vfs/.idea/workspace.xml -libraries/.idea/workspace.xml -confluence/target confluence/target pluginPublisher/plugin-verifier.jar pluginPublisher/idea* -patches-master out dist ideaSDK dependencies -.idea/dictionaries/yozh.xml .idea/workspace.xml tmp -*TestMy.java -.*.swp gh-pages -*.class .DS_Store android.tests.dependencies \ No newline at end of file From 79b904020d9d799102b95cc4215a119895c4f5fa Mon Sep 17 00:00:00 2001 From: Evgeny Gerashchenko Date: Tue, 28 May 2013 19:47:45 +0400 Subject: [PATCH 149/249] Sorted .gitignore --- .gitignore | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/.gitignore b/.gitignore index 11d3561b490..dd9b42ffd43 100644 --- a/.gitignore +++ b/.gitignore @@ -1,12 +1,12 @@ -confluence/target -pluginPublisher/plugin-verifier.jar -pluginPublisher/idea* -out -dist -ideaSDK -dependencies -.idea/workspace.xml -tmp -gh-pages .DS_Store -android.tests.dependencies \ No newline at end of file +.idea/workspace.xml +android.tests.dependencies +confluence/target +dependencies +dist +gh-pages +ideaSDK +out +pluginPublisher/idea* +pluginPublisher/plugin-verifier.jar +tmp \ No newline at end of file From 68d8716ba8e3453a15c2a66a8eabfdfa0e8b843c Mon Sep 17 00:00:00 2001 From: Evgeny Gerashchenko Date: Tue, 28 May 2013 20:06:39 +0400 Subject: [PATCH 150/249] Ignoring all workspace.xml files. --- .gitignore | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.gitignore b/.gitignore index dd9b42ffd43..7922f383f52 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,4 @@ .DS_Store -.idea/workspace.xml android.tests.dependencies confluence/target dependencies @@ -9,4 +8,5 @@ ideaSDK out pluginPublisher/idea* pluginPublisher/plugin-verifier.jar -tmp \ No newline at end of file +tmp +workspace.xml \ No newline at end of file From 35fa071e1b31b3c0c6f89fc07d20490c5a63a62e Mon Sep 17 00:00:00 2001 From: Wojciech Lopata Date: Tue, 30 Apr 2013 19:32:21 +0200 Subject: [PATCH 151/249] Better behaviour of "Change Type" quickfixes in case of function types --- .../plugin/quickfix/CastExpressionFix.java | 9 ++++-- .../quickfix/ChangeAccessorTypeFix.java | 30 +++++++++---------- .../quickfix/ChangeFunctionReturnTypeFix.java | 9 ++++-- .../jet/plugin/quickfix/ChangeTypeFix.java | 9 +++--- .../quickfix/ChangeVariableTypeFix.java | 9 +++--- ...ngeOverridingPropertyTypeToFunctionType.kt | 7 +++++ ...ngeOverridingPropertyTypeToFunctionType.kt | 7 +++++ .../afterChangeAccessorTypeToFunctionType.kt | 5 ++++ .../beforeChangeAccessorTypeToFunctionType.kt | 5 ++++ ...ctionLiteralParameterTypeToFunctionType.kt | 6 ++++ ...rChangeFunctionReturnTypeToFunctionType.kt | 4 +++ ...ctionLiteralParameterTypeToFunctionType.kt | 6 ++++ ...eChangeFunctionReturnTypeToFunctionType.kt | 4 +++ .../casts/afterCastToFunctionType.kt | 4 +++ .../casts/beforeCastToFunctionType.kt | 4 +++ .../quickfix/QuickFixTestGenerated.java | 25 ++++++++++++++++ 16 files changed, 113 insertions(+), 30 deletions(-) create mode 100644 idea/testData/quickfix/override/typeMismatchOnOverride/afterChangeOverridingPropertyTypeToFunctionType.kt create mode 100644 idea/testData/quickfix/override/typeMismatchOnOverride/beforeChangeOverridingPropertyTypeToFunctionType.kt create mode 100644 idea/testData/quickfix/typeAddition/afterChangeAccessorTypeToFunctionType.kt create mode 100644 idea/testData/quickfix/typeAddition/beforeChangeAccessorTypeToFunctionType.kt create mode 100644 idea/testData/quickfix/typeMismatch/afterChangeFunctionLiteralParameterTypeToFunctionType.kt create mode 100644 idea/testData/quickfix/typeMismatch/afterChangeFunctionReturnTypeToFunctionType.kt create mode 100644 idea/testData/quickfix/typeMismatch/beforeChangeFunctionLiteralParameterTypeToFunctionType.kt create mode 100644 idea/testData/quickfix/typeMismatch/beforeChangeFunctionReturnTypeToFunctionType.kt create mode 100644 idea/testData/quickfix/typeMismatch/casts/afterCastToFunctionType.kt create mode 100644 idea/testData/quickfix/typeMismatch/casts/beforeCastToFunctionType.kt diff --git a/idea/src/org/jetbrains/jet/plugin/quickfix/CastExpressionFix.java b/idea/src/org/jetbrains/jet/plugin/quickfix/CastExpressionFix.java index 1b4cc20a134..9d96a551817 100644 --- a/idea/src/org/jetbrains/jet/plugin/quickfix/CastExpressionFix.java +++ b/idea/src/org/jetbrains/jet/plugin/quickfix/CastExpressionFix.java @@ -33,19 +33,22 @@ import org.jetbrains.jet.lang.types.JetType; import org.jetbrains.jet.lang.types.checker.JetTypeChecker; import org.jetbrains.jet.plugin.JetBundle; import org.jetbrains.jet.plugin.project.AnalyzerFacadeWithCache; +import org.jetbrains.jet.renderer.DescriptorRenderer; public class CastExpressionFix extends JetIntentionAction { private final JetType type; + private final String renderedType; public CastExpressionFix(@NotNull JetExpression element, @NotNull JetType type) { super(element); this.type = type; + renderedType = DescriptorRenderer.SHORT_NAMES_IN_TYPES.renderType(type); } @NotNull @Override public String getText() { - return JetBundle.message("cast.expression.to.type", element.getText(), type.toString()); + return JetBundle.message("cast.expression.to.type", element.getText(), renderedType); } @NotNull @@ -64,9 +67,9 @@ public class CastExpressionFix extends JetIntentionAction { @Override public void invoke(@NotNull Project project, Editor editor, PsiFile file) throws IncorrectOperationException { JetBinaryExpressionWithTypeRHS castedExpression = - (JetBinaryExpressionWithTypeRHS) JetPsiFactory.createExpression(project, "(" + element.getText() + ") as " + type.toString()); + (JetBinaryExpressionWithTypeRHS) JetPsiFactory.createExpression(project, "(" + element.getText() + ") as " + renderedType); if (JetPsiUtil.areParenthesesUseless((JetParenthesizedExpression) castedExpression.getLeft())) { - castedExpression = (JetBinaryExpressionWithTypeRHS) JetPsiFactory.createExpression(project, element.getText() + " as " + type.toString()); + castedExpression = (JetBinaryExpressionWithTypeRHS) JetPsiFactory.createExpression(project, element.getText() + " as " + renderedType); } JetParenthesizedExpression castedExpressionInParentheses = diff --git a/idea/src/org/jetbrains/jet/plugin/quickfix/ChangeAccessorTypeFix.java b/idea/src/org/jetbrains/jet/plugin/quickfix/ChangeAccessorTypeFix.java index 102874d7f83..6eef4a97ffe 100644 --- a/idea/src/org/jetbrains/jet/plugin/quickfix/ChangeAccessorTypeFix.java +++ b/idea/src/org/jetbrains/jet/plugin/quickfix/ChangeAccessorTypeFix.java @@ -23,38 +23,38 @@ import com.intellij.psi.impl.source.codeStyle.CodeEditUtil; import com.intellij.psi.util.PsiTreeUtil; import com.intellij.util.IncorrectOperationException; import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; import org.jetbrains.jet.lang.diagnostics.Diagnostic; import org.jetbrains.jet.lang.psi.*; import org.jetbrains.jet.lang.types.ErrorUtils; import org.jetbrains.jet.lang.types.JetType; import org.jetbrains.jet.plugin.JetBundle; +import org.jetbrains.jet.renderer.DescriptorRenderer; public class ChangeAccessorTypeFix extends JetIntentionAction { + private String renderedType; + public ChangeAccessorTypeFix(@NotNull JetPropertyAccessor element) { super(element); } - @Nullable - private JetType getPropertyType() { - JetProperty property = PsiTreeUtil.getParentOfType(element, JetProperty.class); - if (property == null) return null; - return QuickFixUtil.getDeclarationReturnType(property); - } - @Override public boolean isAvailable(@NotNull Project project, Editor editor, PsiFile file) { - JetType type = getPropertyType(); - return super.isAvailable(project, editor, file) && type != null && !ErrorUtils.isErrorType(type); + JetProperty property = PsiTreeUtil.getParentOfType(element, JetProperty.class); + if (property == null) return false; + JetType type = QuickFixUtil.getDeclarationReturnType(property); + if (super.isAvailable(project, editor, file) && type != null && !ErrorUtils.isErrorType(type)) { + renderedType = DescriptorRenderer.SHORT_NAMES_IN_TYPES.renderType(type); + return true; + } + return false; } @NotNull @Override public String getText() { - JetType type = getPropertyType(); return element.isGetter() - ? JetBundle.message("change.getter.type", type) - : JetBundle.message("change.setter.type", type); + ? JetBundle.message("change.getter.type", renderedType) + : JetBundle.message("change.setter.type", renderedType); } @NotNull @@ -65,10 +65,8 @@ public class ChangeAccessorTypeFix extends JetIntentionAction { private final JetType type; + private final String renderedType; public ChangeFunctionReturnTypeFix(@NotNull JetNamedFunction element, @NotNull JetType type) { super(element); this.type = type; + renderedType = DescriptorRenderer.SHORT_NAMES_IN_TYPES.renderType(type); } @NotNull @@ -65,8 +68,8 @@ public class ChangeFunctionReturnTypeFix extends JetIntentionAction { - private final JetType type; + private final String renderedType; public ChangeTypeFix(@NotNull JetTypeReference element, JetType type) { super(element); - this.type = type; + renderedType = DescriptorRenderer.SHORT_NAMES_IN_TYPES.renderType(type); } @NotNull @Override public String getText() { - return JetBundle.message("change.type", element.getText(), type); + return JetBundle.message("change.type", element.getText(), renderedType); } @NotNull @@ -54,7 +55,7 @@ public class ChangeTypeFix extends JetIntentionAction { @Override public void invoke(@NotNull Project project, Editor editor, PsiFile file) throws IncorrectOperationException { - element.replace(JetPsiFactory.createType(project, type.toString())); + element.replace(JetPsiFactory.createType(project, renderedType)); } @NotNull diff --git a/idea/src/org/jetbrains/jet/plugin/quickfix/ChangeVariableTypeFix.java b/idea/src/org/jetbrains/jet/plugin/quickfix/ChangeVariableTypeFix.java index c3423fa6b28..92e7d23ea82 100644 --- a/idea/src/org/jetbrains/jet/plugin/quickfix/ChangeVariableTypeFix.java +++ b/idea/src/org/jetbrains/jet/plugin/quickfix/ChangeVariableTypeFix.java @@ -36,19 +36,20 @@ import org.jetbrains.jet.plugin.JetBundle; import org.jetbrains.jet.plugin.caches.resolve.KotlinCacheManagerUtil; import org.jetbrains.jet.plugin.intentions.SpecifyTypeExplicitlyAction; import org.jetbrains.jet.plugin.project.AnalyzerFacadeWithCache; +import org.jetbrains.jet.renderer.DescriptorRenderer; public class ChangeVariableTypeFix extends JetIntentionAction { - private final JetType type; + private final String renderedType; public ChangeVariableTypeFix(@NotNull JetVariableDeclaration element, @NotNull JetType type) { super(element); - this.type = type; + renderedType = DescriptorRenderer.SHORT_NAMES_IN_TYPES.renderType(type); } @NotNull @Override public String getText() { - return JetBundle.message("change.element.type", element.getName(), type); + return JetBundle.message("change.element.type", element.getName(), renderedType); } @NotNull @@ -62,7 +63,7 @@ public class ChangeVariableTypeFix extends JetIntentionAction typeWhiteSpaceAndColon = JetPsiFactory.createTypeWhiteSpaceAndColon(project, type.toString()); + Pair typeWhiteSpaceAndColon = JetPsiFactory.createTypeWhiteSpaceAndColon(project, renderedType); element.addRangeAfter(typeWhiteSpaceAndColon.first, typeWhiteSpaceAndColon.second, nameIdentifier); } diff --git a/idea/testData/quickfix/override/typeMismatchOnOverride/afterChangeOverridingPropertyTypeToFunctionType.kt b/idea/testData/quickfix/override/typeMismatchOnOverride/afterChangeOverridingPropertyTypeToFunctionType.kt new file mode 100644 index 00000000000..dea0db239e9 --- /dev/null +++ b/idea/testData/quickfix/override/typeMismatchOnOverride/afterChangeOverridingPropertyTypeToFunctionType.kt @@ -0,0 +1,7 @@ +// "Change 'x' type to '(String) -> Int'" "true" +trait A { + var x: (String) -> Int +} +trait B : A { + override var x: (String) -> Int +} \ No newline at end of file diff --git a/idea/testData/quickfix/override/typeMismatchOnOverride/beforeChangeOverridingPropertyTypeToFunctionType.kt b/idea/testData/quickfix/override/typeMismatchOnOverride/beforeChangeOverridingPropertyTypeToFunctionType.kt new file mode 100644 index 00000000000..86cf8bd43da --- /dev/null +++ b/idea/testData/quickfix/override/typeMismatchOnOverride/beforeChangeOverridingPropertyTypeToFunctionType.kt @@ -0,0 +1,7 @@ +// "Change 'x' type to '(String) -> Int'" "true" +trait A { + var x: (String) -> Int +} +trait B : A { + override var x: (Int) -> String +} \ No newline at end of file diff --git a/idea/testData/quickfix/typeAddition/afterChangeAccessorTypeToFunctionType.kt b/idea/testData/quickfix/typeAddition/afterChangeAccessorTypeToFunctionType.kt new file mode 100644 index 00000000000..642223733a3 --- /dev/null +++ b/idea/testData/quickfix/typeAddition/afterChangeAccessorTypeToFunctionType.kt @@ -0,0 +1,5 @@ +// "Change getter type to (String) -> Int" "true" +class A { + val x: (String) -> Int + get(): (String) -> Int = {42} +} \ No newline at end of file diff --git a/idea/testData/quickfix/typeAddition/beforeChangeAccessorTypeToFunctionType.kt b/idea/testData/quickfix/typeAddition/beforeChangeAccessorTypeToFunctionType.kt new file mode 100644 index 00000000000..2a070579945 --- /dev/null +++ b/idea/testData/quickfix/typeAddition/beforeChangeAccessorTypeToFunctionType.kt @@ -0,0 +1,5 @@ +// "Change getter type to (String) -> Int" "true" +class A { + val x: (String) -> Int + get(): Int = {42} +} \ No newline at end of file diff --git a/idea/testData/quickfix/typeMismatch/afterChangeFunctionLiteralParameterTypeToFunctionType.kt b/idea/testData/quickfix/typeMismatch/afterChangeFunctionLiteralParameterTypeToFunctionType.kt new file mode 100644 index 00000000000..89a07f91281 --- /dev/null +++ b/idea/testData/quickfix/typeMismatch/afterChangeFunctionLiteralParameterTypeToFunctionType.kt @@ -0,0 +1,6 @@ +// "Change type from 'String' to '(Int) -> String'" "true" +fun foo(f: ((Int) -> String) -> String) { + foo { + (f: (Int) -> String) -> f(42) + } +} \ No newline at end of file diff --git a/idea/testData/quickfix/typeMismatch/afterChangeFunctionReturnTypeToFunctionType.kt b/idea/testData/quickfix/typeMismatch/afterChangeFunctionReturnTypeToFunctionType.kt new file mode 100644 index 00000000000..4d6e718b946 --- /dev/null +++ b/idea/testData/quickfix/typeMismatch/afterChangeFunctionReturnTypeToFunctionType.kt @@ -0,0 +1,4 @@ +// "Change 'foo' function return type to '(Long) -> Int'" "true" +fun foo(x: Any): (Long) -> Int { + return {(x: Long) -> 42} +} \ No newline at end of file diff --git a/idea/testData/quickfix/typeMismatch/beforeChangeFunctionLiteralParameterTypeToFunctionType.kt b/idea/testData/quickfix/typeMismatch/beforeChangeFunctionLiteralParameterTypeToFunctionType.kt new file mode 100644 index 00000000000..c8897d3a65e --- /dev/null +++ b/idea/testData/quickfix/typeMismatch/beforeChangeFunctionLiteralParameterTypeToFunctionType.kt @@ -0,0 +1,6 @@ +// "Change type from 'String' to '(Int) -> String'" "true" +fun foo(f: ((Int) -> String) -> String) { + foo { + (f: String) -> f(42) + } +} \ No newline at end of file diff --git a/idea/testData/quickfix/typeMismatch/beforeChangeFunctionReturnTypeToFunctionType.kt b/idea/testData/quickfix/typeMismatch/beforeChangeFunctionReturnTypeToFunctionType.kt new file mode 100644 index 00000000000..2f90f8ee5e5 --- /dev/null +++ b/idea/testData/quickfix/typeMismatch/beforeChangeFunctionReturnTypeToFunctionType.kt @@ -0,0 +1,4 @@ +// "Change 'foo' function return type to '(Long) -> Int'" "true" +fun foo(x: Any): Int { + return {(x: Long) -> 42} +} \ No newline at end of file diff --git a/idea/testData/quickfix/typeMismatch/casts/afterCastToFunctionType.kt b/idea/testData/quickfix/typeMismatch/casts/afterCastToFunctionType.kt new file mode 100644 index 00000000000..989e55304cf --- /dev/null +++ b/idea/testData/quickfix/typeMismatch/casts/afterCastToFunctionType.kt @@ -0,0 +1,4 @@ +// "Cast expression 'x' to '() -> Int'" "true" +fun foo(x: Any): () -> Int { + return x as () -> Int +} diff --git a/idea/testData/quickfix/typeMismatch/casts/beforeCastToFunctionType.kt b/idea/testData/quickfix/typeMismatch/casts/beforeCastToFunctionType.kt new file mode 100644 index 00000000000..eb0f35b50c3 --- /dev/null +++ b/idea/testData/quickfix/typeMismatch/casts/beforeCastToFunctionType.kt @@ -0,0 +1,4 @@ +// "Cast expression 'x' to '() -> Int'" "true" +fun foo(x: Any): () -> Int { + return x +} diff --git a/idea/tests/org/jetbrains/jet/plugin/quickfix/QuickFixTestGenerated.java b/idea/tests/org/jetbrains/jet/plugin/quickfix/QuickFixTestGenerated.java index 350eaa4bd87..0d9ee817a72 100644 --- a/idea/tests/org/jetbrains/jet/plugin/quickfix/QuickFixTestGenerated.java +++ b/idea/tests/org/jetbrains/jet/plugin/quickfix/QuickFixTestGenerated.java @@ -1018,6 +1018,11 @@ public class QuickFixTestGenerated extends AbstractQuickFixTest { JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.GenerateTests", new File("idea/testData/quickfix/override/typeMismatchOnOverride"), Pattern.compile("^before(\\w+)\\.kt$"), true); } + @TestMetadata("beforeChangeOverridingPropertyTypeToFunctionType.kt") + public void testChangeOverridingPropertyTypeToFunctionType() throws Exception { + doTest("idea/testData/quickfix/override/typeMismatchOnOverride/beforeChangeOverridingPropertyTypeToFunctionType.kt"); + } + @TestMetadata("beforePropertyReturnTypeMismatchOnOverride.kt") public void testPropertyReturnTypeMismatchOnOverride() throws Exception { doTest("idea/testData/quickfix/override/typeMismatchOnOverride/beforePropertyReturnTypeMismatchOnOverride.kt"); @@ -1149,6 +1154,11 @@ public class QuickFixTestGenerated extends AbstractQuickFixTest { doTest("idea/testData/quickfix/typeAddition/beforeAmbiguousPropertyReturnType.kt"); } + @TestMetadata("beforeChangeAccessorTypeToFunctionType.kt") + public void testChangeAccessorTypeToFunctionType() throws Exception { + doTest("idea/testData/quickfix/typeAddition/beforeChangeAccessorTypeToFunctionType.kt"); + } + @TestMetadata("beforeNoAddErrorType.kt") public void testNoAddErrorType() throws Exception { doTest("idea/testData/quickfix/typeAddition/beforeNoAddErrorType.kt"); @@ -1236,6 +1246,16 @@ public class QuickFixTestGenerated extends AbstractQuickFixTest { JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.GenerateTests", new File("idea/testData/quickfix/typeMismatch"), Pattern.compile("^before(\\w+)\\.kt$"), true); } + @TestMetadata("beforeChangeFunctionReturnTypeToFunctionType.kt") + public void testChangeFunctionReturnTypeToFunctionType() throws Exception { + doTest("idea/testData/quickfix/typeMismatch/beforeChangeFunctionReturnTypeToFunctionType.kt"); + } + + @TestMetadata("beforeChangeParameterTypeToFunctionType.kt") + public void testChangeParameterTypeToFunctionType() throws Exception { + doTest("idea/testData/quickfix/typeMismatch/beforeChangeParameterTypeToFunctionType.kt"); + } + @TestMetadata("beforeChangeReturnTypeWhenFunctionNameIsMissing.kt") public void testChangeReturnTypeWhenFunctionNameIsMissing() throws Exception { doTest("idea/testData/quickfix/typeMismatch/beforeChangeReturnTypeWhenFunctionNameIsMissing.kt"); @@ -1332,6 +1352,11 @@ public class QuickFixTestGenerated extends AbstractQuickFixTest { doTest("idea/testData/quickfix/typeMismatch/casts/beforeAutocastImpossible3.kt"); } + @TestMetadata("beforeCastToFunctionType.kt") + public void testCastToFunctionType() throws Exception { + doTest("idea/testData/quickfix/typeMismatch/casts/beforeCastToFunctionType.kt"); + } + @TestMetadata("beforeTypeMismatch1.kt") public void testTypeMismatch1() throws Exception { doTest("idea/testData/quickfix/typeMismatch/casts/beforeTypeMismatch1.kt"); From 07ea3183612042d741162a05499f7ae573935461 Mon Sep 17 00:00:00 2001 From: Wojciech Lopata Date: Wed, 1 May 2013 18:22:40 +0200 Subject: [PATCH 152/249] Get rid of warnings in "Change Type" quickfixes --- .../jet/plugin/quickfix/ChangeFunctionReturnTypeFix.java | 4 ++-- idea/src/org/jetbrains/jet/plugin/quickfix/ChangeTypeFix.java | 4 ++-- .../jetbrains/jet/plugin/quickfix/ChangeVariableTypeFix.java | 3 +-- 3 files changed, 5 insertions(+), 6 deletions(-) diff --git a/idea/src/org/jetbrains/jet/plugin/quickfix/ChangeFunctionReturnTypeFix.java b/idea/src/org/jetbrains/jet/plugin/quickfix/ChangeFunctionReturnTypeFix.java index 0c4177e7911..3ae4dff778e 100644 --- a/idea/src/org/jetbrains/jet/plugin/quickfix/ChangeFunctionReturnTypeFix.java +++ b/idea/src/org/jetbrains/jet/plugin/quickfix/ChangeFunctionReturnTypeFix.java @@ -22,7 +22,6 @@ import com.intellij.openapi.project.Project; import com.intellij.openapi.util.Pair; import com.intellij.psi.PsiElement; import com.intellij.psi.PsiErrorElement; -import com.intellij.psi.PsiFile; import com.intellij.util.IncorrectOperationException; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -79,7 +78,7 @@ public class ChangeFunctionReturnTypeFix extends JetIntentionAction) diagnostic).getA().asString(); int componentIndex = Integer.valueOf(componentName.substring(DescriptorResolver.COMPONENT_FUNCTION_NAME_PREFIX.length())); JetMultiDeclaration multiDeclaration = QuickFixUtil.getParentElementOfType(diagnostic, JetMultiDeclaration.class); diff --git a/idea/src/org/jetbrains/jet/plugin/quickfix/ChangeTypeFix.java b/idea/src/org/jetbrains/jet/plugin/quickfix/ChangeTypeFix.java index 717179f49fd..318b74b0015 100644 --- a/idea/src/org/jetbrains/jet/plugin/quickfix/ChangeTypeFix.java +++ b/idea/src/org/jetbrains/jet/plugin/quickfix/ChangeTypeFix.java @@ -19,13 +19,13 @@ package org.jetbrains.jet.plugin.quickfix; import com.intellij.codeInsight.intention.IntentionAction; import com.intellij.openapi.editor.Editor; import com.intellij.openapi.project.Project; -import com.intellij.psi.PsiFile; import com.intellij.util.IncorrectOperationException; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.jet.lang.diagnostics.Diagnostic; import org.jetbrains.jet.lang.diagnostics.DiagnosticWithParameters1; import org.jetbrains.jet.lang.diagnostics.Errors; +import org.jetbrains.jet.lang.psi.JetFile; import org.jetbrains.jet.lang.psi.JetParameter; import org.jetbrains.jet.lang.psi.JetPsiFactory; import org.jetbrains.jet.lang.psi.JetTypeReference; @@ -54,7 +54,7 @@ public class ChangeTypeFix extends JetIntentionAction { } @Override - public void invoke(@NotNull Project project, Editor editor, PsiFile file) throws IncorrectOperationException { + public void invoke(@NotNull Project project, Editor editor, JetFile file) throws IncorrectOperationException { element.replace(JetPsiFactory.createType(project, renderedType)); } diff --git a/idea/src/org/jetbrains/jet/plugin/quickfix/ChangeVariableTypeFix.java b/idea/src/org/jetbrains/jet/plugin/quickfix/ChangeVariableTypeFix.java index 92e7d23ea82..3236e846711 100644 --- a/idea/src/org/jetbrains/jet/plugin/quickfix/ChangeVariableTypeFix.java +++ b/idea/src/org/jetbrains/jet/plugin/quickfix/ChangeVariableTypeFix.java @@ -21,7 +21,6 @@ import com.intellij.openapi.editor.Editor; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.Pair; import com.intellij.psi.PsiElement; -import com.intellij.psi.PsiFile; import com.intellij.util.IncorrectOperationException; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -59,7 +58,7 @@ public class ChangeVariableTypeFix extends JetIntentionAction Date: Wed, 1 May 2013 19:30:43 +0200 Subject: [PATCH 153/249] Cleanup in "type mismatch" tests --- ...terComponentFunctionReturnTypeMismatch1.kt | 0 ...terComponentFunctionReturnTypeMismatch2.kt | 0 ...terComponentFunctionReturnTypeMismatch3.kt | 0 ...terComponentFunctionReturnTypeMismatch4.kt | 0 ...terComponentFunctionReturnTypeMismatch5.kt | 0 ...oreComponentFunctionReturnTypeMismatch1.kt | 0 ...oreComponentFunctionReturnTypeMismatch2.kt | 0 ...oreComponentFunctionReturnTypeMismatch3.kt | 0 ...oreComponentFunctionReturnTypeMismatch4.kt | 0 ...oreComponentFunctionReturnTypeMismatch5.kt | 0 ...rChangeFunctionReturnTypeToFunctionType.kt | 0 .../afterTypeMismatchInInitializer.kt | 0 .../afterTypeMismatchInReturnStatement.kt | 0 ...eChangeFunctionReturnTypeToFunctionType.kt | 0 .../beforeTypeMismatchInInitializer.kt | 0 .../beforeTypeMismatchInReturnStatement.kt | 0 .../quickfix/QuickFixTestGenerated.java | 106 ++++++++++-------- 17 files changed, 62 insertions(+), 44 deletions(-) rename idea/testData/quickfix/typeMismatch/{ => componentFunctionReturnTypeMismatch}/afterComponentFunctionReturnTypeMismatch1.kt (100%) rename idea/testData/quickfix/typeMismatch/{ => componentFunctionReturnTypeMismatch}/afterComponentFunctionReturnTypeMismatch2.kt (100%) rename idea/testData/quickfix/typeMismatch/{ => componentFunctionReturnTypeMismatch}/afterComponentFunctionReturnTypeMismatch3.kt (100%) rename idea/testData/quickfix/typeMismatch/{ => componentFunctionReturnTypeMismatch}/afterComponentFunctionReturnTypeMismatch4.kt (100%) rename idea/testData/quickfix/typeMismatch/{ => componentFunctionReturnTypeMismatch}/afterComponentFunctionReturnTypeMismatch5.kt (100%) rename idea/testData/quickfix/typeMismatch/{ => componentFunctionReturnTypeMismatch}/beforeComponentFunctionReturnTypeMismatch1.kt (100%) rename idea/testData/quickfix/typeMismatch/{ => componentFunctionReturnTypeMismatch}/beforeComponentFunctionReturnTypeMismatch2.kt (100%) rename idea/testData/quickfix/typeMismatch/{ => componentFunctionReturnTypeMismatch}/beforeComponentFunctionReturnTypeMismatch3.kt (100%) rename idea/testData/quickfix/typeMismatch/{ => componentFunctionReturnTypeMismatch}/beforeComponentFunctionReturnTypeMismatch4.kt (100%) rename idea/testData/quickfix/typeMismatch/{ => componentFunctionReturnTypeMismatch}/beforeComponentFunctionReturnTypeMismatch5.kt (100%) rename idea/testData/quickfix/typeMismatch/{ => typeMismatchOnReturnedExpression}/afterChangeFunctionReturnTypeToFunctionType.kt (100%) rename idea/testData/quickfix/typeMismatch/{ => typeMismatchOnReturnedExpression}/afterTypeMismatchInInitializer.kt (100%) rename idea/testData/quickfix/typeMismatch/{ => typeMismatchOnReturnedExpression}/afterTypeMismatchInReturnStatement.kt (100%) rename idea/testData/quickfix/typeMismatch/{ => typeMismatchOnReturnedExpression}/beforeChangeFunctionReturnTypeToFunctionType.kt (100%) rename idea/testData/quickfix/typeMismatch/{ => typeMismatchOnReturnedExpression}/beforeTypeMismatchInInitializer.kt (100%) rename idea/testData/quickfix/typeMismatch/{ => typeMismatchOnReturnedExpression}/beforeTypeMismatchInReturnStatement.kt (100%) diff --git a/idea/testData/quickfix/typeMismatch/afterComponentFunctionReturnTypeMismatch1.kt b/idea/testData/quickfix/typeMismatch/componentFunctionReturnTypeMismatch/afterComponentFunctionReturnTypeMismatch1.kt similarity index 100% rename from idea/testData/quickfix/typeMismatch/afterComponentFunctionReturnTypeMismatch1.kt rename to idea/testData/quickfix/typeMismatch/componentFunctionReturnTypeMismatch/afterComponentFunctionReturnTypeMismatch1.kt diff --git a/idea/testData/quickfix/typeMismatch/afterComponentFunctionReturnTypeMismatch2.kt b/idea/testData/quickfix/typeMismatch/componentFunctionReturnTypeMismatch/afterComponentFunctionReturnTypeMismatch2.kt similarity index 100% rename from idea/testData/quickfix/typeMismatch/afterComponentFunctionReturnTypeMismatch2.kt rename to idea/testData/quickfix/typeMismatch/componentFunctionReturnTypeMismatch/afterComponentFunctionReturnTypeMismatch2.kt diff --git a/idea/testData/quickfix/typeMismatch/afterComponentFunctionReturnTypeMismatch3.kt b/idea/testData/quickfix/typeMismatch/componentFunctionReturnTypeMismatch/afterComponentFunctionReturnTypeMismatch3.kt similarity index 100% rename from idea/testData/quickfix/typeMismatch/afterComponentFunctionReturnTypeMismatch3.kt rename to idea/testData/quickfix/typeMismatch/componentFunctionReturnTypeMismatch/afterComponentFunctionReturnTypeMismatch3.kt diff --git a/idea/testData/quickfix/typeMismatch/afterComponentFunctionReturnTypeMismatch4.kt b/idea/testData/quickfix/typeMismatch/componentFunctionReturnTypeMismatch/afterComponentFunctionReturnTypeMismatch4.kt similarity index 100% rename from idea/testData/quickfix/typeMismatch/afterComponentFunctionReturnTypeMismatch4.kt rename to idea/testData/quickfix/typeMismatch/componentFunctionReturnTypeMismatch/afterComponentFunctionReturnTypeMismatch4.kt diff --git a/idea/testData/quickfix/typeMismatch/afterComponentFunctionReturnTypeMismatch5.kt b/idea/testData/quickfix/typeMismatch/componentFunctionReturnTypeMismatch/afterComponentFunctionReturnTypeMismatch5.kt similarity index 100% rename from idea/testData/quickfix/typeMismatch/afterComponentFunctionReturnTypeMismatch5.kt rename to idea/testData/quickfix/typeMismatch/componentFunctionReturnTypeMismatch/afterComponentFunctionReturnTypeMismatch5.kt diff --git a/idea/testData/quickfix/typeMismatch/beforeComponentFunctionReturnTypeMismatch1.kt b/idea/testData/quickfix/typeMismatch/componentFunctionReturnTypeMismatch/beforeComponentFunctionReturnTypeMismatch1.kt similarity index 100% rename from idea/testData/quickfix/typeMismatch/beforeComponentFunctionReturnTypeMismatch1.kt rename to idea/testData/quickfix/typeMismatch/componentFunctionReturnTypeMismatch/beforeComponentFunctionReturnTypeMismatch1.kt diff --git a/idea/testData/quickfix/typeMismatch/beforeComponentFunctionReturnTypeMismatch2.kt b/idea/testData/quickfix/typeMismatch/componentFunctionReturnTypeMismatch/beforeComponentFunctionReturnTypeMismatch2.kt similarity index 100% rename from idea/testData/quickfix/typeMismatch/beforeComponentFunctionReturnTypeMismatch2.kt rename to idea/testData/quickfix/typeMismatch/componentFunctionReturnTypeMismatch/beforeComponentFunctionReturnTypeMismatch2.kt diff --git a/idea/testData/quickfix/typeMismatch/beforeComponentFunctionReturnTypeMismatch3.kt b/idea/testData/quickfix/typeMismatch/componentFunctionReturnTypeMismatch/beforeComponentFunctionReturnTypeMismatch3.kt similarity index 100% rename from idea/testData/quickfix/typeMismatch/beforeComponentFunctionReturnTypeMismatch3.kt rename to idea/testData/quickfix/typeMismatch/componentFunctionReturnTypeMismatch/beforeComponentFunctionReturnTypeMismatch3.kt diff --git a/idea/testData/quickfix/typeMismatch/beforeComponentFunctionReturnTypeMismatch4.kt b/idea/testData/quickfix/typeMismatch/componentFunctionReturnTypeMismatch/beforeComponentFunctionReturnTypeMismatch4.kt similarity index 100% rename from idea/testData/quickfix/typeMismatch/beforeComponentFunctionReturnTypeMismatch4.kt rename to idea/testData/quickfix/typeMismatch/componentFunctionReturnTypeMismatch/beforeComponentFunctionReturnTypeMismatch4.kt diff --git a/idea/testData/quickfix/typeMismatch/beforeComponentFunctionReturnTypeMismatch5.kt b/idea/testData/quickfix/typeMismatch/componentFunctionReturnTypeMismatch/beforeComponentFunctionReturnTypeMismatch5.kt similarity index 100% rename from idea/testData/quickfix/typeMismatch/beforeComponentFunctionReturnTypeMismatch5.kt rename to idea/testData/quickfix/typeMismatch/componentFunctionReturnTypeMismatch/beforeComponentFunctionReturnTypeMismatch5.kt diff --git a/idea/testData/quickfix/typeMismatch/afterChangeFunctionReturnTypeToFunctionType.kt b/idea/testData/quickfix/typeMismatch/typeMismatchOnReturnedExpression/afterChangeFunctionReturnTypeToFunctionType.kt similarity index 100% rename from idea/testData/quickfix/typeMismatch/afterChangeFunctionReturnTypeToFunctionType.kt rename to idea/testData/quickfix/typeMismatch/typeMismatchOnReturnedExpression/afterChangeFunctionReturnTypeToFunctionType.kt diff --git a/idea/testData/quickfix/typeMismatch/afterTypeMismatchInInitializer.kt b/idea/testData/quickfix/typeMismatch/typeMismatchOnReturnedExpression/afterTypeMismatchInInitializer.kt similarity index 100% rename from idea/testData/quickfix/typeMismatch/afterTypeMismatchInInitializer.kt rename to idea/testData/quickfix/typeMismatch/typeMismatchOnReturnedExpression/afterTypeMismatchInInitializer.kt diff --git a/idea/testData/quickfix/typeMismatch/afterTypeMismatchInReturnStatement.kt b/idea/testData/quickfix/typeMismatch/typeMismatchOnReturnedExpression/afterTypeMismatchInReturnStatement.kt similarity index 100% rename from idea/testData/quickfix/typeMismatch/afterTypeMismatchInReturnStatement.kt rename to idea/testData/quickfix/typeMismatch/typeMismatchOnReturnedExpression/afterTypeMismatchInReturnStatement.kt diff --git a/idea/testData/quickfix/typeMismatch/beforeChangeFunctionReturnTypeToFunctionType.kt b/idea/testData/quickfix/typeMismatch/typeMismatchOnReturnedExpression/beforeChangeFunctionReturnTypeToFunctionType.kt similarity index 100% rename from idea/testData/quickfix/typeMismatch/beforeChangeFunctionReturnTypeToFunctionType.kt rename to idea/testData/quickfix/typeMismatch/typeMismatchOnReturnedExpression/beforeChangeFunctionReturnTypeToFunctionType.kt diff --git a/idea/testData/quickfix/typeMismatch/beforeTypeMismatchInInitializer.kt b/idea/testData/quickfix/typeMismatch/typeMismatchOnReturnedExpression/beforeTypeMismatchInInitializer.kt similarity index 100% rename from idea/testData/quickfix/typeMismatch/beforeTypeMismatchInInitializer.kt rename to idea/testData/quickfix/typeMismatch/typeMismatchOnReturnedExpression/beforeTypeMismatchInInitializer.kt diff --git a/idea/testData/quickfix/typeMismatch/beforeTypeMismatchInReturnStatement.kt b/idea/testData/quickfix/typeMismatch/typeMismatchOnReturnedExpression/beforeTypeMismatchInReturnStatement.kt similarity index 100% rename from idea/testData/quickfix/typeMismatch/beforeTypeMismatchInReturnStatement.kt rename to idea/testData/quickfix/typeMismatch/typeMismatchOnReturnedExpression/beforeTypeMismatchInReturnStatement.kt diff --git a/idea/tests/org/jetbrains/jet/plugin/quickfix/QuickFixTestGenerated.java b/idea/tests/org/jetbrains/jet/plugin/quickfix/QuickFixTestGenerated.java index 0d9ee817a72..fb646cabc37 100644 --- a/idea/tests/org/jetbrains/jet/plugin/quickfix/QuickFixTestGenerated.java +++ b/idea/tests/org/jetbrains/jet/plugin/quickfix/QuickFixTestGenerated.java @@ -1240,20 +1240,15 @@ public class QuickFixTestGenerated extends AbstractQuickFixTest { } @TestMetadata("idea/testData/quickfix/typeMismatch") - @InnerTestClasses({TypeMismatch.Casts.class}) + @InnerTestClasses({TypeMismatch.Casts.class, TypeMismatch.ComponentFunctionReturnTypeMismatch.class, TypeMismatch.TypeMismatchOnReturnedExpression.class}) public static class TypeMismatch extends AbstractQuickFixTest { public void testAllFilesPresentInTypeMismatch() throws Exception { JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.GenerateTests", new File("idea/testData/quickfix/typeMismatch"), Pattern.compile("^before(\\w+)\\.kt$"), true); } - @TestMetadata("beforeChangeFunctionReturnTypeToFunctionType.kt") - public void testChangeFunctionReturnTypeToFunctionType() throws Exception { - doTest("idea/testData/quickfix/typeMismatch/beforeChangeFunctionReturnTypeToFunctionType.kt"); - } - - @TestMetadata("beforeChangeParameterTypeToFunctionType.kt") - public void testChangeParameterTypeToFunctionType() throws Exception { - doTest("idea/testData/quickfix/typeMismatch/beforeChangeParameterTypeToFunctionType.kt"); + @TestMetadata("beforeChangeFunctionLiteralParameterTypeToFunctionType.kt") + public void testChangeFunctionLiteralParameterTypeToFunctionType() throws Exception { + doTest("idea/testData/quickfix/typeMismatch/beforeChangeFunctionLiteralParameterTypeToFunctionType.kt"); } @TestMetadata("beforeChangeReturnTypeWhenFunctionNameIsMissing.kt") @@ -1271,31 +1266,6 @@ public class QuickFixTestGenerated extends AbstractQuickFixTest { doTest("idea/testData/quickfix/typeMismatch/beforeCompareToTypeMismatch.kt"); } - @TestMetadata("beforeComponentFunctionReturnTypeMismatch1.kt") - public void testComponentFunctionReturnTypeMismatch1() throws Exception { - doTest("idea/testData/quickfix/typeMismatch/beforeComponentFunctionReturnTypeMismatch1.kt"); - } - - @TestMetadata("beforeComponentFunctionReturnTypeMismatch2.kt") - public void testComponentFunctionReturnTypeMismatch2() throws Exception { - doTest("idea/testData/quickfix/typeMismatch/beforeComponentFunctionReturnTypeMismatch2.kt"); - } - - @TestMetadata("beforeComponentFunctionReturnTypeMismatch3.kt") - public void testComponentFunctionReturnTypeMismatch3() throws Exception { - doTest("idea/testData/quickfix/typeMismatch/beforeComponentFunctionReturnTypeMismatch3.kt"); - } - - @TestMetadata("beforeComponentFunctionReturnTypeMismatch4.kt") - public void testComponentFunctionReturnTypeMismatch4() throws Exception { - doTest("idea/testData/quickfix/typeMismatch/beforeComponentFunctionReturnTypeMismatch4.kt"); - } - - @TestMetadata("beforeComponentFunctionReturnTypeMismatch5.kt") - public void testComponentFunctionReturnTypeMismatch5() throws Exception { - doTest("idea/testData/quickfix/typeMismatch/beforeComponentFunctionReturnTypeMismatch5.kt"); - } - @TestMetadata("beforeExpectedParameterTypeMismatch.kt") public void testExpectedParameterTypeMismatch() throws Exception { doTest("idea/testData/quickfix/typeMismatch/beforeExpectedParameterTypeMismatch.kt"); @@ -1321,16 +1291,6 @@ public class QuickFixTestGenerated extends AbstractQuickFixTest { doTest("idea/testData/quickfix/typeMismatch/beforeReturnTypeMismatch.kt"); } - @TestMetadata("beforeTypeMismatchInInitializer.kt") - public void testTypeMismatchInInitializer() throws Exception { - doTest("idea/testData/quickfix/typeMismatch/beforeTypeMismatchInInitializer.kt"); - } - - @TestMetadata("beforeTypeMismatchInReturnStatement.kt") - public void testTypeMismatchInReturnStatement() throws Exception { - doTest("idea/testData/quickfix/typeMismatch/beforeTypeMismatchInReturnStatement.kt"); - } - @TestMetadata("idea/testData/quickfix/typeMismatch/casts") public static class Casts extends AbstractQuickFixTest { public void testAllFilesPresentInCasts() throws Exception { @@ -1384,10 +1344,68 @@ public class QuickFixTestGenerated extends AbstractQuickFixTest { } + @TestMetadata("idea/testData/quickfix/typeMismatch/componentFunctionReturnTypeMismatch") + public static class ComponentFunctionReturnTypeMismatch extends AbstractQuickFixTest { + public void testAllFilesPresentInComponentFunctionReturnTypeMismatch() throws Exception { + JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.GenerateTests", new File("idea/testData/quickfix/typeMismatch/componentFunctionReturnTypeMismatch"), Pattern.compile("^before(\\w+)\\.kt$"), true); + } + + @TestMetadata("beforeComponentFunctionReturnTypeMismatch1.kt") + public void testComponentFunctionReturnTypeMismatch1() throws Exception { + doTest("idea/testData/quickfix/typeMismatch/componentFunctionReturnTypeMismatch/beforeComponentFunctionReturnTypeMismatch1.kt"); + } + + @TestMetadata("beforeComponentFunctionReturnTypeMismatch2.kt") + public void testComponentFunctionReturnTypeMismatch2() throws Exception { + doTest("idea/testData/quickfix/typeMismatch/componentFunctionReturnTypeMismatch/beforeComponentFunctionReturnTypeMismatch2.kt"); + } + + @TestMetadata("beforeComponentFunctionReturnTypeMismatch3.kt") + public void testComponentFunctionReturnTypeMismatch3() throws Exception { + doTest("idea/testData/quickfix/typeMismatch/componentFunctionReturnTypeMismatch/beforeComponentFunctionReturnTypeMismatch3.kt"); + } + + @TestMetadata("beforeComponentFunctionReturnTypeMismatch4.kt") + public void testComponentFunctionReturnTypeMismatch4() throws Exception { + doTest("idea/testData/quickfix/typeMismatch/componentFunctionReturnTypeMismatch/beforeComponentFunctionReturnTypeMismatch4.kt"); + } + + @TestMetadata("beforeComponentFunctionReturnTypeMismatch5.kt") + public void testComponentFunctionReturnTypeMismatch5() throws Exception { + doTest("idea/testData/quickfix/typeMismatch/componentFunctionReturnTypeMismatch/beforeComponentFunctionReturnTypeMismatch5.kt"); + } + + } + + @TestMetadata("idea/testData/quickfix/typeMismatch/typeMismatchOnReturnedExpression") + public static class TypeMismatchOnReturnedExpression extends AbstractQuickFixTest { + public void testAllFilesPresentInTypeMismatchOnReturnedExpression() throws Exception { + JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.GenerateTests", new File("idea/testData/quickfix/typeMismatch/typeMismatchOnReturnedExpression"), Pattern.compile("^before(\\w+)\\.kt$"), true); + } + + @TestMetadata("beforeChangeFunctionReturnTypeToFunctionType.kt") + public void testChangeFunctionReturnTypeToFunctionType() throws Exception { + doTest("idea/testData/quickfix/typeMismatch/typeMismatchOnReturnedExpression/beforeChangeFunctionReturnTypeToFunctionType.kt"); + } + + @TestMetadata("beforeTypeMismatchInInitializer.kt") + public void testTypeMismatchInInitializer() throws Exception { + doTest("idea/testData/quickfix/typeMismatch/typeMismatchOnReturnedExpression/beforeTypeMismatchInInitializer.kt"); + } + + @TestMetadata("beforeTypeMismatchInReturnStatement.kt") + public void testTypeMismatchInReturnStatement() throws Exception { + doTest("idea/testData/quickfix/typeMismatch/typeMismatchOnReturnedExpression/beforeTypeMismatchInReturnStatement.kt"); + } + + } + public static Test innerSuite() { TestSuite suite = new TestSuite("TypeMismatch"); suite.addTestSuite(TypeMismatch.class); suite.addTestSuite(Casts.class); + suite.addTestSuite(ComponentFunctionReturnTypeMismatch.class); + suite.addTestSuite(TypeMismatchOnReturnedExpression.class); return suite; } } From 44fa32c617374627c6674f87322b2db88c887dd3 Mon Sep 17 00:00:00 2001 From: Wojciech Lopata Date: Wed, 8 May 2013 18:34:13 +0200 Subject: [PATCH 154/249] ChangeFunctionParameterTypeFix for TYPE_MISMATCH error --- .../jetbrains/jet/plugin/JetBundle.properties | 1 + .../ChangeFunctionParameterTypeFix.java | 110 ++++++++++++++++++ .../jet/plugin/quickfix/QuickFixUtil.java | 62 +++++++++- .../jet/plugin/quickfix/QuickFixes.java | 4 +- .../afterChangeFunctionParameterType1.kt | 5 + .../afterChangeFunctionParameterType2.kt | 4 + .../afterChangeFunctionParameterType3.kt | 4 + .../beforeChangeFunctionParameterType1.kt | 5 + .../beforeChangeFunctionParameterType2.kt | 4 + .../beforeChangeFunctionParameterType3.kt | 4 + .../beforeChangeFunctionParameterType4.kt | 8 ++ .../beforeChangeFunctionParameterType5.kt | 5 + .../quickfix/QuickFixTestGenerated.java | 36 +++++- 13 files changed, 247 insertions(+), 5 deletions(-) create mode 100644 idea/src/org/jetbrains/jet/plugin/quickfix/ChangeFunctionParameterTypeFix.java create mode 100644 idea/testData/quickfix/typeMismatch/functionParameterTypeMismatch/afterChangeFunctionParameterType1.kt create mode 100644 idea/testData/quickfix/typeMismatch/functionParameterTypeMismatch/afterChangeFunctionParameterType2.kt create mode 100644 idea/testData/quickfix/typeMismatch/functionParameterTypeMismatch/afterChangeFunctionParameterType3.kt create mode 100644 idea/testData/quickfix/typeMismatch/functionParameterTypeMismatch/beforeChangeFunctionParameterType1.kt create mode 100644 idea/testData/quickfix/typeMismatch/functionParameterTypeMismatch/beforeChangeFunctionParameterType2.kt create mode 100644 idea/testData/quickfix/typeMismatch/functionParameterTypeMismatch/beforeChangeFunctionParameterType3.kt create mode 100644 idea/testData/quickfix/typeMismatch/functionParameterTypeMismatch/beforeChangeFunctionParameterType4.kt create mode 100644 idea/testData/quickfix/typeMismatch/functionParameterTypeMismatch/beforeChangeFunctionParameterType5.kt diff --git a/idea/src/org/jetbrains/jet/plugin/JetBundle.properties b/idea/src/org/jetbrains/jet/plugin/JetBundle.properties index c640470d94b..eb1f9fda628 100644 --- a/idea/src/org/jetbrains/jet/plugin/JetBundle.properties +++ b/idea/src/org/jetbrains/jet/plugin/JetBundle.properties @@ -62,6 +62,7 @@ change.no.name.function.return.type=Change function return type to ''{0}'' remove.function.return.type=Remove explicitly specified return type in ''{0}'' function remove.no.name.function.return.type=Remove explicitly specified function return type change.element.type=Change ''{0}'' type to ''{1}'' +change.function.parameter.type=Change parameter ''{0}'' type of function ''{1}'' to ''{2}'' change.type=Change type from ''{0}'' to ''{1}'' change.type.family=Change Type add.parameters.to.function=Add parameter{0} to function ''{1}'' diff --git a/idea/src/org/jetbrains/jet/plugin/quickfix/ChangeFunctionParameterTypeFix.java b/idea/src/org/jetbrains/jet/plugin/quickfix/ChangeFunctionParameterTypeFix.java new file mode 100644 index 00000000000..0c7e797928f --- /dev/null +++ b/idea/src/org/jetbrains/jet/plugin/quickfix/ChangeFunctionParameterTypeFix.java @@ -0,0 +1,110 @@ +/* + * Copyright 2010-2013 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.jetbrains.jet.plugin.quickfix; + +import com.intellij.codeInsight.intention.IntentionAction; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.project.Project; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiFile; +import com.intellij.psi.util.PsiTreeUtil; +import com.intellij.util.IncorrectOperationException; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import org.jetbrains.jet.lang.descriptors.CallableDescriptor; +import org.jetbrains.jet.lang.diagnostics.Diagnostic; +import org.jetbrains.jet.lang.psi.*; +import org.jetbrains.jet.lang.resolve.BindingContext; +import org.jetbrains.jet.lang.resolve.BindingContextUtils; +import org.jetbrains.jet.lang.resolve.calls.model.ResolvedCall; +import org.jetbrains.jet.lang.resolve.name.FqName; +import org.jetbrains.jet.lang.resolve.name.NameUtils; +import org.jetbrains.jet.lang.types.JetType; +import org.jetbrains.jet.plugin.JetBundle; +import org.jetbrains.jet.plugin.project.AnalyzerFacadeWithCache; +import org.jetbrains.jet.renderer.DescriptorRenderer; + +public class ChangeFunctionParameterTypeFix extends JetIntentionAction { + private final String renderedType; + private final String containingFunctionName; + + public ChangeFunctionParameterTypeFix(@NotNull JetParameter element, @NotNull JetType type) { + super(element); + renderedType = DescriptorRenderer.SHORT_NAMES_IN_TYPES.renderType(type); + JetFunction function = PsiTreeUtil.getParentOfType(element, JetFunction.class); + FqName functionFQName = function == null ? null : JetPsiUtil.getFQName(function); + containingFunctionName = functionFQName == null ? null : functionFQName.getFqName(); + } + + @Override + public boolean isAvailable(@NotNull Project project, Editor editor, PsiFile file) { + return super.isAvailable(project, editor, file) && containingFunctionName != null; + } + + @NotNull + @Override + public String getText() { + return JetBundle.message("change.function.parameter.type", element.getName(), containingFunctionName, renderedType); + } + + @NotNull + @Override + public String getFamilyName() { + return JetBundle.message("change.type.family"); + } + + @Override + public void invoke(@NotNull Project project, Editor editor, JetFile file) throws IncorrectOperationException { + JetTypeReference typeReference = element.getTypeReference(); + assert typeReference != null : "Parameter without type annotation cannot cause type mismatch"; + typeReference.replace(JetPsiFactory.createType(project, renderedType)); + } + + @NotNull + public static JetIntentionActionFactory createFactory() { + return new JetIntentionActionFactory() { + @Nullable + @Override + public IntentionAction createAction(Diagnostic diagnostic) { + // Change type of function parameter in case TYPE_MISMATCH is reported on expression passed as value argument of call + JetParameter correspondingParameter = null; + JetType type = null; + + BindingContext context = AnalyzerFacadeWithCache.analyzeFileWithCache((JetFile) diagnostic.getPsiFile()).getBindingContext(); + JetFunctionLiteralExpression functionLiteralExpression = + QuickFixUtil.getParentElementOfType(diagnostic, JetFunctionLiteralExpression.class); + + if (functionLiteralExpression != null && diagnostic.getPsiElement() == functionLiteralExpression.getBodyExpression()) { + correspondingParameter = + QuickFixUtil.getFunctionParameterCorrespondingToFunctionLiteralPassedOutsideArgumentList(functionLiteralExpression); + type = context.get(BindingContext.EXPRESSION_TYPE, functionLiteralExpression); + } + else { + JetValueArgument valueArgument = QuickFixUtil.getParentElementOfType(diagnostic, JetValueArgument.class); + if (valueArgument != null && valueArgument.getArgumentExpression() == diagnostic.getPsiElement()) { + correspondingParameter = QuickFixUtil.getFunctionParameterCorrespondingToValueArgumentPassedInCall(valueArgument); + type = context.get(BindingContext.EXPRESSION_TYPE, valueArgument.getArgumentExpression()); + } + } + if (correspondingParameter != null && type != null) { + return new ChangeFunctionParameterTypeFix(correspondingParameter, type); + } + return null; + } + }; + } +} diff --git a/idea/src/org/jetbrains/jet/plugin/quickfix/QuickFixUtil.java b/idea/src/org/jetbrains/jet/plugin/quickfix/QuickFixUtil.java index a1d9aa40425..7c3f2971576 100644 --- a/idea/src/org/jetbrains/jet/plugin/quickfix/QuickFixUtil.java +++ b/idea/src/org/jetbrains/jet/plugin/quickfix/QuickFixUtil.java @@ -26,10 +26,10 @@ import org.jetbrains.annotations.Nullable; import org.jetbrains.jet.lang.descriptors.CallableDescriptor; import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor; import org.jetbrains.jet.lang.diagnostics.Diagnostic; -import org.jetbrains.jet.lang.psi.JetDeclaration; -import org.jetbrains.jet.lang.psi.JetFile; -import org.jetbrains.jet.lang.psi.JetNamedDeclaration; +import org.jetbrains.jet.lang.psi.*; import org.jetbrains.jet.lang.resolve.BindingContext; +import org.jetbrains.jet.lang.resolve.BindingContextUtils; +import org.jetbrains.jet.lang.resolve.calls.model.ResolvedCall; import org.jetbrains.jet.lang.types.DeferredType; import org.jetbrains.jet.lang.types.JetType; import org.jetbrains.jet.lang.types.checker.JetTypeChecker; @@ -93,4 +93,60 @@ public class QuickFixUtil { public static boolean canModifyElement(@NotNull PsiElement element) { return element.isWritable() && !BuiltInsReferenceResolver.isFromBuiltIns(element); } + + @Nullable + public static JetParameterList getParameterListOfCalledFunction(@NotNull JetCallExpression callExpression) { + BindingContext context = AnalyzerFacadeWithCache.analyzeFileWithCache((JetFile) callExpression.getContainingFile()).getBindingContext(); + ResolvedCall resolvedCall = context.get(BindingContext.RESOLVED_CALL, callExpression.getCalleeExpression()); + if (resolvedCall == null) return null; + PsiElement functionDeclaration = BindingContextUtils.descriptorToDeclaration(context, resolvedCall.getCandidateDescriptor()); + if (functionDeclaration instanceof JetFunction) { + return ((JetFunction) functionDeclaration).getValueParameterList(); + } + return null; + } + + @Nullable + public static JetParameter getFunctionParameterCorrespondingToFunctionLiteralPassedOutsideArgumentList(@NotNull JetFunctionLiteralExpression functionLiteralExpression) { + if (!(functionLiteralExpression.getParent() instanceof JetCallExpression)) { + return null; + } + JetCallExpression callExpression = (JetCallExpression) functionLiteralExpression.getParent(); + JetParameterList parameterList = getParameterListOfCalledFunction(callExpression); + if (parameterList == null) return null; + return parameterList.getParameters().get(parameterList.getParameters().size() - 1); + } + + @Nullable + public static JetParameter getFunctionParameterCorrespondingToValueArgumentPassedInCall(@NotNull JetValueArgument valueArgument) { + if (!(valueArgument.getParent() instanceof JetValueArgumentList)) { + return null; + } + JetValueArgumentList valueArgumentList = (JetValueArgumentList) valueArgument.getParent(); + if (!(valueArgumentList.getParent() instanceof JetCallExpression)) { + return null; + } + JetCallExpression callExpression = (JetCallExpression) valueArgumentList.getParent(); + JetParameterList parameterList = getParameterListOfCalledFunction(callExpression); + if (parameterList == null) return null; + int position = valueArgumentList.getArguments().indexOf(valueArgument); + if (position == -1) return null; + + if (valueArgument.isNamed()) { + JetValueArgumentName valueArgumentName = valueArgument.getArgumentName(); + JetSimpleNameExpression referenceExpression = valueArgumentName == null ? null : valueArgumentName.getReferenceExpression(); + String valueArgumentNameAsString = referenceExpression == null ? null : referenceExpression.getReferencedName(); + if (valueArgumentNameAsString == null) return null; + + for (JetParameter parameter: parameterList.getParameters()) { + if (valueArgumentNameAsString.equals(parameter.getName())) { + return parameter; + } + } + return null; + } + else { + return parameterList.getParameters().get(position); + } + } } diff --git a/idea/src/org/jetbrains/jet/plugin/quickfix/QuickFixes.java b/idea/src/org/jetbrains/jet/plugin/quickfix/QuickFixes.java index be8f7fb5b30..c1fd41dab2e 100644 --- a/idea/src/org/jetbrains/jet/plugin/quickfix/QuickFixes.java +++ b/idea/src/org/jetbrains/jet/plugin/quickfix/QuickFixes.java @@ -235,7 +235,9 @@ public class QuickFixes { factories.put(EXPECTED_PARAMETER_TYPE_MISMATCH, ChangeTypeFix.createFactoryForExpectedParameterTypeMismatch()); factories.put(EXPECTED_RETURN_TYPE_MISMATCH, ChangeTypeFix.createFactoryForExpectedReturnTypeMismatch()); - + + factories.put(TYPE_MISMATCH, ChangeFunctionParameterTypeFix.createFactory()); + factories.put(AUTOCAST_IMPOSSIBLE, CastExpressionFix.createFactoryForAutoCastImpossible()); factories.put(TYPE_MISMATCH, CastExpressionFix.createFactoryForTypeMismatch()); diff --git a/idea/testData/quickfix/typeMismatch/functionParameterTypeMismatch/afterChangeFunctionParameterType1.kt b/idea/testData/quickfix/typeMismatch/functionParameterTypeMismatch/afterChangeFunctionParameterType1.kt new file mode 100644 index 00000000000..b253e8b1782 --- /dev/null +++ b/idea/testData/quickfix/typeMismatch/functionParameterTypeMismatch/afterChangeFunctionParameterType1.kt @@ -0,0 +1,5 @@ +// "Change parameter 'x' type of function 'bar.foo' to '(String) -> Int'" "true" +package bar +fun foo(w: Int = 0, x: (String) -> Int, y: Int = 0, z: (Int) -> Int = {42}) { + foo(1, {(a: String) -> 42}, 1) +} diff --git a/idea/testData/quickfix/typeMismatch/functionParameterTypeMismatch/afterChangeFunctionParameterType2.kt b/idea/testData/quickfix/typeMismatch/functionParameterTypeMismatch/afterChangeFunctionParameterType2.kt new file mode 100644 index 00000000000..c1b3343642c --- /dev/null +++ b/idea/testData/quickfix/typeMismatch/functionParameterTypeMismatch/afterChangeFunctionParameterType2.kt @@ -0,0 +1,4 @@ +// "Change parameter 'y' type of function 'foo' to 'String'" "true" +fun foo(v: Int, w: Int = 0, x: Int = 0, y: String, z: (Int) -> Int = {42}) { + foo(0, 1, y = "") +} diff --git a/idea/testData/quickfix/typeMismatch/functionParameterTypeMismatch/afterChangeFunctionParameterType3.kt b/idea/testData/quickfix/typeMismatch/functionParameterTypeMismatch/afterChangeFunctionParameterType3.kt new file mode 100644 index 00000000000..30b490ba5ed --- /dev/null +++ b/idea/testData/quickfix/typeMismatch/functionParameterTypeMismatch/afterChangeFunctionParameterType3.kt @@ -0,0 +1,4 @@ +// "Change parameter 'z' type of function 'foo' to '(Int) -> Unit'" "true" +fun foo(w: Int = 0, x: Int, y: Int = 0, z: (Int) -> Unit) { + foo(0, 1) {} +} diff --git a/idea/testData/quickfix/typeMismatch/functionParameterTypeMismatch/beforeChangeFunctionParameterType1.kt b/idea/testData/quickfix/typeMismatch/functionParameterTypeMismatch/beforeChangeFunctionParameterType1.kt new file mode 100644 index 00000000000..deb5313f041 --- /dev/null +++ b/idea/testData/quickfix/typeMismatch/functionParameterTypeMismatch/beforeChangeFunctionParameterType1.kt @@ -0,0 +1,5 @@ +// "Change parameter 'x' type of function 'bar.foo' to '(String) -> Int'" "true" +package bar +fun foo(w: Int = 0, x: Int, y: Int = 0, z: (Int) -> Int = {42}) { + foo(1, {(a: String) -> 42}, 1) +} diff --git a/idea/testData/quickfix/typeMismatch/functionParameterTypeMismatch/beforeChangeFunctionParameterType2.kt b/idea/testData/quickfix/typeMismatch/functionParameterTypeMismatch/beforeChangeFunctionParameterType2.kt new file mode 100644 index 00000000000..c5e45b514be --- /dev/null +++ b/idea/testData/quickfix/typeMismatch/functionParameterTypeMismatch/beforeChangeFunctionParameterType2.kt @@ -0,0 +1,4 @@ +// "Change parameter 'y' type of function 'foo' to 'String'" "true" +fun foo(v: Int, w: Int = 0, x: Int = 0, y: Int, z: (Int) -> Int = {42}) { + foo(0, 1, y = "") +} diff --git a/idea/testData/quickfix/typeMismatch/functionParameterTypeMismatch/beforeChangeFunctionParameterType3.kt b/idea/testData/quickfix/typeMismatch/functionParameterTypeMismatch/beforeChangeFunctionParameterType3.kt new file mode 100644 index 00000000000..9d5f48d961d --- /dev/null +++ b/idea/testData/quickfix/typeMismatch/functionParameterTypeMismatch/beforeChangeFunctionParameterType3.kt @@ -0,0 +1,4 @@ +// "Change parameter 'z' type of function 'foo' to '(Int) -> Unit'" "true" +fun foo(w: Int = 0, x: Int, y: Int = 0, z: (Int) -> String) { + foo(0, 1) {} +} diff --git a/idea/testData/quickfix/typeMismatch/functionParameterTypeMismatch/beforeChangeFunctionParameterType4.kt b/idea/testData/quickfix/typeMismatch/functionParameterTypeMismatch/beforeChangeFunctionParameterType4.kt new file mode 100644 index 00000000000..a4c9f02baaf --- /dev/null +++ b/idea/testData/quickfix/typeMismatch/functionParameterTypeMismatch/beforeChangeFunctionParameterType4.kt @@ -0,0 +1,8 @@ +// "Change parameter 'z' type of function 'foo' to '(Int) -> String'" "false" +// ERROR: Type mismatch.
Required:jet.Int
Found:jet.String
+fun foo(y: Int = 0, z: (Int) -> String = {""}) { + foo { + "": Int + "" + } +} \ No newline at end of file diff --git a/idea/testData/quickfix/typeMismatch/functionParameterTypeMismatch/beforeChangeFunctionParameterType5.kt b/idea/testData/quickfix/typeMismatch/functionParameterTypeMismatch/beforeChangeFunctionParameterType5.kt new file mode 100644 index 00000000000..80f37c15a85 --- /dev/null +++ b/idea/testData/quickfix/typeMismatch/functionParameterTypeMismatch/beforeChangeFunctionParameterType5.kt @@ -0,0 +1,5 @@ +// "Change parameter 'y' type of function 'foo' to 'Int'" "false" +// ERROR: Type mismatch.
Required:jet.Int
Found:jet.String
+fun foo(y: Int = 0, z: (Int) -> String = {""}) { + foo("": Int) +} \ No newline at end of file diff --git a/idea/tests/org/jetbrains/jet/plugin/quickfix/QuickFixTestGenerated.java b/idea/tests/org/jetbrains/jet/plugin/quickfix/QuickFixTestGenerated.java index fb646cabc37..20ca2288240 100644 --- a/idea/tests/org/jetbrains/jet/plugin/quickfix/QuickFixTestGenerated.java +++ b/idea/tests/org/jetbrains/jet/plugin/quickfix/QuickFixTestGenerated.java @@ -1240,7 +1240,7 @@ public class QuickFixTestGenerated extends AbstractQuickFixTest { } @TestMetadata("idea/testData/quickfix/typeMismatch") - @InnerTestClasses({TypeMismatch.Casts.class, TypeMismatch.ComponentFunctionReturnTypeMismatch.class, TypeMismatch.TypeMismatchOnReturnedExpression.class}) + @InnerTestClasses({TypeMismatch.Casts.class, TypeMismatch.ComponentFunctionReturnTypeMismatch.class, TypeMismatch.FunctionParameterTypeMismatch.class, TypeMismatch.TypeMismatchOnReturnedExpression.class}) public static class TypeMismatch extends AbstractQuickFixTest { public void testAllFilesPresentInTypeMismatch() throws Exception { JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.GenerateTests", new File("idea/testData/quickfix/typeMismatch"), Pattern.compile("^before(\\w+)\\.kt$"), true); @@ -1377,6 +1377,39 @@ public class QuickFixTestGenerated extends AbstractQuickFixTest { } + @TestMetadata("idea/testData/quickfix/typeMismatch/functionParameterTypeMismatch") + public static class FunctionParameterTypeMismatch extends AbstractQuickFixTest { + public void testAllFilesPresentInFunctionParameterTypeMismatch() throws Exception { + JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.GenerateTests", new File("idea/testData/quickfix/typeMismatch/functionParameterTypeMismatch"), Pattern.compile("^before(\\w+)\\.kt$"), true); + } + + @TestMetadata("beforeChangeFunctionParameterType1.kt") + public void testChangeFunctionParameterType1() throws Exception { + doTest("idea/testData/quickfix/typeMismatch/functionParameterTypeMismatch/beforeChangeFunctionParameterType1.kt"); + } + + @TestMetadata("beforeChangeFunctionParameterType2.kt") + public void testChangeFunctionParameterType2() throws Exception { + doTest("idea/testData/quickfix/typeMismatch/functionParameterTypeMismatch/beforeChangeFunctionParameterType2.kt"); + } + + @TestMetadata("beforeChangeFunctionParameterType3.kt") + public void testChangeFunctionParameterType3() throws Exception { + doTest("idea/testData/quickfix/typeMismatch/functionParameterTypeMismatch/beforeChangeFunctionParameterType3.kt"); + } + + @TestMetadata("beforeChangeFunctionParameterType4.kt") + public void testChangeFunctionParameterType4() throws Exception { + doTest("idea/testData/quickfix/typeMismatch/functionParameterTypeMismatch/beforeChangeFunctionParameterType4.kt"); + } + + @TestMetadata("beforeChangeFunctionParameterType5.kt") + public void testChangeFunctionParameterType5() throws Exception { + doTest("idea/testData/quickfix/typeMismatch/functionParameterTypeMismatch/beforeChangeFunctionParameterType5.kt"); + } + + } + @TestMetadata("idea/testData/quickfix/typeMismatch/typeMismatchOnReturnedExpression") public static class TypeMismatchOnReturnedExpression extends AbstractQuickFixTest { public void testAllFilesPresentInTypeMismatchOnReturnedExpression() throws Exception { @@ -1405,6 +1438,7 @@ public class QuickFixTestGenerated extends AbstractQuickFixTest { suite.addTestSuite(TypeMismatch.class); suite.addTestSuite(Casts.class); suite.addTestSuite(ComponentFunctionReturnTypeMismatch.class); + suite.addTestSuite(FunctionParameterTypeMismatch.class); suite.addTestSuite(TypeMismatchOnReturnedExpression.class); return suite; } From 9b90ee2e8006ab376b296fa6bdb315ba3744ed72 Mon Sep 17 00:00:00 2001 From: Wojciech Lopata Date: Wed, 8 May 2013 18:55:31 +0200 Subject: [PATCH 155/249] ChangeFunctionLiteralReturnTypeFix for EXPECTED/ASSIGNMENT_TYPE_MISMATCH errors --- .../jetbrains/jet/plugin/JetBundle.properties | 1 + .../ChangeFunctionLiteralReturnTypeFix.java | 140 ++++++++++++++++++ .../jet/plugin/quickfix/QuickFixUtil.java | 25 ++++ .../jet/plugin/quickfix/QuickFixes.java | 4 + .../afterAssignmentTypeMismatch.kt | 7 + .../afterExpectedTypeMismatch.kt | 7 + .../beforeAssignmentTypeMismatch.kt | 7 + .../beforeExpectedTypeMismatch.kt | 7 + .../quickfix/QuickFixTestGenerated.java | 10 ++ 9 files changed, 208 insertions(+) create mode 100644 idea/src/org/jetbrains/jet/plugin/quickfix/ChangeFunctionLiteralReturnTypeFix.java create mode 100644 idea/testData/quickfix/typeMismatch/typeMismatchOnReturnedExpression/afterAssignmentTypeMismatch.kt create mode 100644 idea/testData/quickfix/typeMismatch/typeMismatchOnReturnedExpression/afterExpectedTypeMismatch.kt create mode 100644 idea/testData/quickfix/typeMismatch/typeMismatchOnReturnedExpression/beforeAssignmentTypeMismatch.kt create mode 100644 idea/testData/quickfix/typeMismatch/typeMismatchOnReturnedExpression/beforeExpectedTypeMismatch.kt diff --git a/idea/src/org/jetbrains/jet/plugin/JetBundle.properties b/idea/src/org/jetbrains/jet/plugin/JetBundle.properties index eb1f9fda628..6f7ebde6deb 100644 --- a/idea/src/org/jetbrains/jet/plugin/JetBundle.properties +++ b/idea/src/org/jetbrains/jet/plugin/JetBundle.properties @@ -59,6 +59,7 @@ add.semicolon.after.invocation=Add semicolon after invocation of ''{0}'' add.semicolon.family=Add Semicolon change.function.return.type=Change ''{0}'' function return type to ''{1}'' change.no.name.function.return.type=Change function return type to ''{0}'' +change.function.literal.return.type=Change function literal return type to ''{0}'' remove.function.return.type=Remove explicitly specified return type in ''{0}'' function remove.no.name.function.return.type=Remove explicitly specified function return type change.element.type=Change ''{0}'' type to ''{1}'' diff --git a/idea/src/org/jetbrains/jet/plugin/quickfix/ChangeFunctionLiteralReturnTypeFix.java b/idea/src/org/jetbrains/jet/plugin/quickfix/ChangeFunctionLiteralReturnTypeFix.java new file mode 100644 index 00000000000..c93d084532e --- /dev/null +++ b/idea/src/org/jetbrains/jet/plugin/quickfix/ChangeFunctionLiteralReturnTypeFix.java @@ -0,0 +1,140 @@ +/* + * Copyright 2010-2013 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.jetbrains.jet.plugin.quickfix; + +import com.intellij.codeInsight.intention.IntentionAction; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.project.Project; +import com.intellij.psi.PsiFile; +import com.intellij.psi.util.PsiTreeUtil; +import com.intellij.util.IncorrectOperationException; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import org.jetbrains.jet.lang.descriptors.ClassDescriptor; +import org.jetbrains.jet.lang.diagnostics.Diagnostic; +import org.jetbrains.jet.lang.psi.*; +import org.jetbrains.jet.lang.resolve.BindingContext; +import org.jetbrains.jet.lang.types.JetType; +import org.jetbrains.jet.lang.types.TypeProjection; +import org.jetbrains.jet.lang.types.TypeUtils; +import org.jetbrains.jet.lang.types.checker.JetTypeChecker; +import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns; +import org.jetbrains.jet.plugin.JetBundle; +import org.jetbrains.jet.plugin.project.AnalyzerFacadeWithCache; +import org.jetbrains.jet.renderer.DescriptorRenderer; + +import java.util.LinkedList; +import java.util.List; + +public class ChangeFunctionLiteralReturnTypeFix extends JetIntentionAction { + private final String renderedType; + private final JetTypeReference functionLiteralReturnTypeRef; + private IntentionAction appropriateQuickFix = null; + + public ChangeFunctionLiteralReturnTypeFix(@NotNull JetFunctionLiteralExpression element, @NotNull JetType type) { + super(element); + renderedType = DescriptorRenderer.SHORT_NAMES_IN_TYPES.renderType(type); + functionLiteralReturnTypeRef = element.getFunctionLiteral().getReturnTypeRef(); + + BindingContext context = AnalyzerFacadeWithCache.analyzeFileWithCache((JetFile) element.getContainingFile()).getBindingContext(); + JetType functionLiteralType = context.get(BindingContext.EXPRESSION_TYPE, element); + assert functionLiteralType != null : "Type of function literal not available in binding context"; + + ClassDescriptor functionClass = KotlinBuiltIns.getInstance().getFunction(functionLiteralType.getArguments().size() - 1); + List functionClassTypeParameters = new LinkedList(); + for (TypeProjection typeProjection: functionLiteralType.getArguments()) { + functionClassTypeParameters.add(typeProjection.getType()); + } + // Replacing return type: + functionClassTypeParameters.remove(functionClassTypeParameters.size() - 1); + functionClassTypeParameters.add(type); + JetType eventualFunctionLiteralType = TypeUtils.substituteParameters(functionClass, functionClassTypeParameters); + + JetProperty correspondingProperty = PsiTreeUtil.getParentOfType(element, JetProperty.class); + if (correspondingProperty != null && QuickFixUtil.canEvaluateTo(correspondingProperty.getInitializer(), element)) { + JetTypeReference correspondingPropertyTypeRef = correspondingProperty.getTypeRef(); + JetType propertyType = context.get(BindingContext.TYPE, correspondingPropertyTypeRef); + if (propertyType != null && !JetTypeChecker.INSTANCE.isSubtypeOf(eventualFunctionLiteralType, propertyType)) { + appropriateQuickFix = new ChangeVariableTypeFix(correspondingProperty, eventualFunctionLiteralType); + } + return; + } + + JetParameter correspondingParameter = QuickFixUtil.getFunctionParameterCorrespondingToFunctionLiteralPassedOutsideArgumentList(element); + if (correspondingParameter != null) { + JetTypeReference correspondingParameterTypeRef = correspondingParameter.getTypeReference(); + JetType parameterType = context.get(BindingContext.TYPE, correspondingParameterTypeRef); + if (parameterType != null && !JetTypeChecker.INSTANCE.isSubtypeOf(eventualFunctionLiteralType, parameterType)) { + appropriateQuickFix = new ChangeFunctionParameterTypeFix(correspondingParameter, eventualFunctionLiteralType); + } + return; + } + + JetFunction parentFunction = PsiTreeUtil.getParentOfType(element, JetFunction.class, true); + if (parentFunction != null && QuickFixUtil.canFunctionReturnExpression(parentFunction, element)) { + JetTypeReference parentFunctionReturnTypeRef = parentFunction.getReturnTypeRef(); + JetType parentFunctionReturnType = context.get(BindingContext.TYPE, parentFunctionReturnTypeRef); + if (parentFunctionReturnType != null && !JetTypeChecker.INSTANCE.isSubtypeOf(eventualFunctionLiteralType, parentFunctionReturnType)) { + appropriateQuickFix = new ChangeFunctionReturnTypeFix(parentFunction, eventualFunctionLiteralType); + } + } + } + + @NotNull + @Override + public String getText() { + if (appropriateQuickFix != null) { + return appropriateQuickFix.getText(); + } + return JetBundle.message("change.function.literal.return.type", renderedType); + } + + @NotNull + @Override + public String getFamilyName() { + return JetBundle.message("change.type.family"); + } + + @Override + public boolean isAvailable(@NotNull Project project, Editor editor, PsiFile file) { + return super.isAvailable(project, editor, file) && + (functionLiteralReturnTypeRef != null || (appropriateQuickFix != null && appropriateQuickFix.isAvailable(project, editor, file))); + } + + @Override + public void invoke(@NotNull Project project, Editor editor, JetFile file) throws IncorrectOperationException { + if (functionLiteralReturnTypeRef != null) { + functionLiteralReturnTypeRef.replace(JetPsiFactory.createType(project, renderedType)); + } + if (appropriateQuickFix != null && appropriateQuickFix.isAvailable(project, editor, file)) { + appropriateQuickFix.invoke(project, editor, file); + } + } + + @NotNull + public static JetIntentionActionFactory createFactoryForExpectedOrAssignmentTypeMismatch() { + return new JetIntentionActionFactory() { + @Nullable + @Override + public IntentionAction createAction(Diagnostic diagnostic) { + JetFunctionLiteralExpression functionLiteralExpression = QuickFixUtil.getParentElementOfType(diagnostic, JetFunctionLiteralExpression.class); + assert functionLiteralExpression != null : "ASSIGNMENT/EXPECTED_TYPE_MISMATCH reported outside any function literal"; + return new ChangeFunctionLiteralReturnTypeFix(functionLiteralExpression, KotlinBuiltIns.getInstance().getUnitType()); + } + }; + } +} diff --git a/idea/src/org/jetbrains/jet/plugin/quickfix/QuickFixUtil.java b/idea/src/org/jetbrains/jet/plugin/quickfix/QuickFixUtil.java index 7c3f2971576..beb270a8724 100644 --- a/idea/src/org/jetbrains/jet/plugin/quickfix/QuickFixUtil.java +++ b/idea/src/org/jetbrains/jet/plugin/quickfix/QuickFixUtil.java @@ -149,4 +149,29 @@ public class QuickFixUtil { return parameterList.getParameters().get(position); } } + + private static boolean equalOrLastInThenOrElse(JetExpression thenOrElse, JetExpression expression) { + if (thenOrElse == expression) return true; + return thenOrElse instanceof JetBlockExpression && expression.getParent() == thenOrElse && + PsiTreeUtil.getNextSiblingOfType(expression, JetExpression.class) == null; + } + + public static boolean canEvaluateTo(JetExpression parent, JetExpression child) { + if (parent == null || child == null) { + return false; + } + while (parent != child) { + if (child.getParent() instanceof JetParenthesizedExpression) { + child = (JetExpression) child.getParent(); + continue; + } + JetIfExpression jetIfExpression = PsiTreeUtil.getParentOfType(child, JetIfExpression.class, true); + if (jetIfExpression == null) return false; + if (!equalOrLastInThenOrElse(jetIfExpression.getThen(), child) && !equalOrLastInThenOrElse(jetIfExpression.getElse(), child)) { + return false; + } + child = jetIfExpression; + } + return true; + } } diff --git a/idea/src/org/jetbrains/jet/plugin/quickfix/QuickFixes.java b/idea/src/org/jetbrains/jet/plugin/quickfix/QuickFixes.java index c1fd41dab2e..a6b9c110a51 100644 --- a/idea/src/org/jetbrains/jet/plugin/quickfix/QuickFixes.java +++ b/idea/src/org/jetbrains/jet/plugin/quickfix/QuickFixes.java @@ -236,6 +236,10 @@ public class QuickFixes { factories.put(EXPECTED_PARAMETER_TYPE_MISMATCH, ChangeTypeFix.createFactoryForExpectedParameterTypeMismatch()); factories.put(EXPECTED_RETURN_TYPE_MISMATCH, ChangeTypeFix.createFactoryForExpectedReturnTypeMismatch()); + JetIntentionActionFactory changeFunctionLiteralReturnTypeFix = ChangeFunctionLiteralReturnTypeFix.createFactoryForExpectedOrAssignmentTypeMismatch(); + factories.put(EXPECTED_TYPE_MISMATCH, changeFunctionLiteralReturnTypeFix); + factories.put(ASSIGNMENT_TYPE_MISMATCH, changeFunctionLiteralReturnTypeFix); + factories.put(TYPE_MISMATCH, ChangeFunctionParameterTypeFix.createFactory()); factories.put(AUTOCAST_IMPOSSIBLE, CastExpressionFix.createFactoryForAutoCastImpossible()); diff --git a/idea/testData/quickfix/typeMismatch/typeMismatchOnReturnedExpression/afterAssignmentTypeMismatch.kt b/idea/testData/quickfix/typeMismatch/typeMismatchOnReturnedExpression/afterAssignmentTypeMismatch.kt new file mode 100644 index 00000000000..ac73a6453e9 --- /dev/null +++ b/idea/testData/quickfix/typeMismatch/typeMismatchOnReturnedExpression/afterAssignmentTypeMismatch.kt @@ -0,0 +1,7 @@ +// "Change 'f' type to '() -> Unit'" "true" +fun foo() { + val f: () -> Unit = { + var x = 1 + x += 21 + } +} \ No newline at end of file diff --git a/idea/testData/quickfix/typeMismatch/typeMismatchOnReturnedExpression/afterExpectedTypeMismatch.kt b/idea/testData/quickfix/typeMismatch/typeMismatchOnReturnedExpression/afterExpectedTypeMismatch.kt new file mode 100644 index 00000000000..d51e2648772 --- /dev/null +++ b/idea/testData/quickfix/typeMismatch/typeMismatchOnReturnedExpression/afterExpectedTypeMismatch.kt @@ -0,0 +1,7 @@ +// "Change 'bar' type to '(() -> Long) -> Unit'" "true" +fun foo() { + val bar: (() -> Long) -> Unit = { + (f: () -> Long): Unit -> + var x = 5 + } +} diff --git a/idea/testData/quickfix/typeMismatch/typeMismatchOnReturnedExpression/beforeAssignmentTypeMismatch.kt b/idea/testData/quickfix/typeMismatch/typeMismatchOnReturnedExpression/beforeAssignmentTypeMismatch.kt new file mode 100644 index 00000000000..ad45d53e8c7 --- /dev/null +++ b/idea/testData/quickfix/typeMismatch/typeMismatchOnReturnedExpression/beforeAssignmentTypeMismatch.kt @@ -0,0 +1,7 @@ +// "Change 'f' type to '() -> Unit'" "true" +fun foo() { + val f: () -> Int = { + var x = 1 + x += 21 + } +} \ No newline at end of file diff --git a/idea/testData/quickfix/typeMismatch/typeMismatchOnReturnedExpression/beforeExpectedTypeMismatch.kt b/idea/testData/quickfix/typeMismatch/typeMismatchOnReturnedExpression/beforeExpectedTypeMismatch.kt new file mode 100644 index 00000000000..379a397ab85 --- /dev/null +++ b/idea/testData/quickfix/typeMismatch/typeMismatchOnReturnedExpression/beforeExpectedTypeMismatch.kt @@ -0,0 +1,7 @@ +// "Change 'bar' type to '(() -> Long) -> Unit'" "true" +fun foo() { + val bar: () -> Double = { + (f: () -> Long): String -> + var x = 5 + } +} diff --git a/idea/tests/org/jetbrains/jet/plugin/quickfix/QuickFixTestGenerated.java b/idea/tests/org/jetbrains/jet/plugin/quickfix/QuickFixTestGenerated.java index 20ca2288240..810c38bc41d 100644 --- a/idea/tests/org/jetbrains/jet/plugin/quickfix/QuickFixTestGenerated.java +++ b/idea/tests/org/jetbrains/jet/plugin/quickfix/QuickFixTestGenerated.java @@ -1416,11 +1416,21 @@ public class QuickFixTestGenerated extends AbstractQuickFixTest { JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.GenerateTests", new File("idea/testData/quickfix/typeMismatch/typeMismatchOnReturnedExpression"), Pattern.compile("^before(\\w+)\\.kt$"), true); } + @TestMetadata("beforeAssignmentTypeMismatch.kt") + public void testAssignmentTypeMismatch() throws Exception { + doTest("idea/testData/quickfix/typeMismatch/typeMismatchOnReturnedExpression/beforeAssignmentTypeMismatch.kt"); + } + @TestMetadata("beforeChangeFunctionReturnTypeToFunctionType.kt") public void testChangeFunctionReturnTypeToFunctionType() throws Exception { doTest("idea/testData/quickfix/typeMismatch/typeMismatchOnReturnedExpression/beforeChangeFunctionReturnTypeToFunctionType.kt"); } + @TestMetadata("beforeExpectedTypeMismatch.kt") + public void testExpectedTypeMismatch() throws Exception { + doTest("idea/testData/quickfix/typeMismatch/typeMismatchOnReturnedExpression/beforeExpectedTypeMismatch.kt"); + } + @TestMetadata("beforeTypeMismatchInInitializer.kt") public void testTypeMismatchInInitializer() throws Exception { doTest("idea/testData/quickfix/typeMismatch/typeMismatchOnReturnedExpression/beforeTypeMismatchInInitializer.kt"); From 0144ad06706530c6d972ed15d3dfcff5d25cab65 Mon Sep 17 00:00:00 2001 From: Wojciech Lopata Date: Wed, 8 May 2013 23:18:36 +0200 Subject: [PATCH 156/249] Enable intention actions factories to return multiple quickfixes --- .../jet/plugin/highlighter/JetPsiChecker.java | 17 +++---- .../plugin/quickfix/AddFunctionBodyFix.java | 4 +- .../quickfix/AddFunctionToSupertypeFix.java | 4 +- .../jet/plugin/quickfix/AddModifierFix.java | 6 +-- .../plugin/quickfix/AddNameToArgumentFix.java | 4 +- .../AddOpenModifierToClassDeclarationFix.java | 4 +- .../AddSemicolonAfterFunctionCallFix.java | 4 +- .../quickfix/AddStarProjectionsFix.java | 8 ++-- .../plugin/quickfix/AddWhenElseBranchFix.java | 4 +- .../jet/plugin/quickfix/AutoImportFix.java | 4 +- .../plugin/quickfix/CastExpressionFix.java | 8 ++-- .../quickfix/ChangeAccessorTypeFix.java | 4 +- .../ChangeFunctionLiteralReturnTypeFix.java | 4 +- .../ChangeFunctionParameterTypeFix.java | 9 +--- .../quickfix/ChangeFunctionReturnTypeFix.java | 24 +++++----- .../quickfix/ChangeFunctionSignatureFix.java | 12 ++--- .../ChangeMemberFunctionSignatureFix.java | 4 +- .../quickfix/ChangeToBackingFieldFix.java | 4 +- .../ChangeToConstructorInvocationFix.java | 4 +- .../ChangeToFunctionInvocationFix.java | 4 +- .../quickfix/ChangeToPropertyNameFix.java | 4 +- .../quickfix/ChangeToStarProjectionFix.java | 4 +- .../jet/plugin/quickfix/ChangeTypeFix.java | 8 ++-- .../quickfix/ChangeVariableTypeFix.java | 8 ++-- .../quickfix/ChangeVisibilityModifierFix.java | 4 +- ...y.java => JetIntentionActionsFactory.java} | 9 ++-- .../JetSingleIntentionActionFactory.java | 42 +++++++++++++++++ .../MakeClassAnAnnotationClassFix.java | 4 +- .../quickfix/MakeOverriddenMemberOpenFix.java | 4 +- .../quickfix/MapPlatformClassToKotlinFix.java | 4 +- .../quickfix/MigrateSureInProjectFix.java | 4 +- .../quickfix/MoveWhenElseBranchFix.java | 4 +- .../jet/plugin/quickfix/QuickFixes.java | 46 +++++++++---------- .../quickfix/RemoveFunctionBodyFix.java | 4 +- .../plugin/quickfix/RemoveModifierFix.java | 20 ++++---- .../plugin/quickfix/RemoveNullableFix.java | 4 +- .../quickfix/RemovePartsFromPropertyFix.java | 4 +- .../quickfix/RemovePsiElementSimpleFix.java | 16 +++---- .../RemoveRightPartOfBinaryExpressionFix.java | 8 ++-- .../plugin/quickfix/RemoveSupertypeFix.java | 4 +- ...meParameterToMatchOverriddenMethodFix.java | 4 +- .../plugin/quickfix/ReplaceInfixCallFix.java | 4 +- ...ReplaceOperationInBinaryExpressionFix.java | 5 +- 43 files changed, 194 insertions(+), 160 deletions(-) rename idea/src/org/jetbrains/jet/plugin/quickfix/{JetIntentionActionFactory.java => JetIntentionActionsFactory.java} (80%) create mode 100644 idea/src/org/jetbrains/jet/plugin/quickfix/JetSingleIntentionActionFactory.java diff --git a/idea/src/org/jetbrains/jet/plugin/highlighter/JetPsiChecker.java b/idea/src/org/jetbrains/jet/plugin/highlighter/JetPsiChecker.java index 21d32d41fa7..21b4a2a6729 100644 --- a/idea/src/org/jetbrains/jet/plugin/highlighter/JetPsiChecker.java +++ b/idea/src/org/jetbrains/jet/plugin/highlighter/JetPsiChecker.java @@ -43,9 +43,8 @@ import org.jetbrains.jet.lang.psi.JetFile; import org.jetbrains.jet.lang.psi.JetReferenceExpression; import org.jetbrains.jet.lang.resolve.BindingContext; import org.jetbrains.jet.plugin.project.WholeProjectAnalyzerFacade; -import org.jetbrains.jet.plugin.quickfix.JetIntentionActionFactory; +import org.jetbrains.jet.plugin.quickfix.JetIntentionActionsFactory; import org.jetbrains.jet.plugin.quickfix.QuickFixes; -import org.jetbrains.jet.utils.ExceptionUtils; import java.util.Collection; import java.util.List; @@ -217,14 +216,12 @@ public class JetPsiChecker implements Annotator { return null; } - Collection intentionActionFactories = QuickFixes.getActionFactories(diagnostic.getFactory()); - for (JetIntentionActionFactory intentionActionFactory : intentionActionFactories) { - IntentionAction action = null; - if (intentionActionFactory != null) { - action = intentionActionFactory.createAction(diagnostic); - } - if (action != null) { - annotation.registerFix(action); + Collection intentionActionsFactories = QuickFixes.getActionsFactories(diagnostic.getFactory()); + for (JetIntentionActionsFactory intentionActionsFactory : intentionActionsFactories) { + if (intentionActionsFactory != null) { + for (IntentionAction action: intentionActionsFactory.createActions(diagnostic)) { + annotation.registerFix(action); + } } } diff --git a/idea/src/org/jetbrains/jet/plugin/quickfix/AddFunctionBodyFix.java b/idea/src/org/jetbrains/jet/plugin/quickfix/AddFunctionBodyFix.java index 2654f228e78..b0819791d25 100644 --- a/idea/src/org/jetbrains/jet/plugin/quickfix/AddFunctionBodyFix.java +++ b/idea/src/org/jetbrains/jet/plugin/quickfix/AddFunctionBodyFix.java @@ -67,8 +67,8 @@ public class AddFunctionBodyFix extends JetIntentionAction { element.replace(newElement); } - public static JetIntentionActionFactory createFactory() { - return new JetIntentionActionFactory() { + public static JetSingleIntentionActionFactory createFactory() { + return new JetSingleIntentionActionFactory() { @Nullable @Override public JetIntentionAction createAction(Diagnostic diagnostic) { diff --git a/idea/src/org/jetbrains/jet/plugin/quickfix/AddFunctionToSupertypeFix.java b/idea/src/org/jetbrains/jet/plugin/quickfix/AddFunctionToSupertypeFix.java index 05844b5f937..f565679cb6d 100644 --- a/idea/src/org/jetbrains/jet/plugin/quickfix/AddFunctionToSupertypeFix.java +++ b/idea/src/org/jetbrains/jet/plugin/quickfix/AddFunctionToSupertypeFix.java @@ -158,8 +158,8 @@ public class AddFunctionToSupertypeFix extends JetHintAction { return new JetAddFunctionToClassifierAction(project, editor, bindingContext, functionsToAdd); } - public static JetIntentionActionFactory createFactory() { - return new JetIntentionActionFactory() { + public static JetIntentionActionsFactory createFactory() { + return new JetSingleIntentionActionFactory() { @Nullable @Override public IntentionAction createAction(Diagnostic diagnostic) { diff --git a/idea/src/org/jetbrains/jet/plugin/quickfix/AddModifierFix.java b/idea/src/org/jetbrains/jet/plugin/quickfix/AddModifierFix.java index 162dc6b7aa3..d3bdd9b985e 100644 --- a/idea/src/org/jetbrains/jet/plugin/quickfix/AddModifierFix.java +++ b/idea/src/org/jetbrains/jet/plugin/quickfix/AddModifierFix.java @@ -164,8 +164,8 @@ public class AddModifierFix extends JetIntentionAction { return true; } - public static JetIntentionActionFactory createFactory(final JetKeywordToken modifier, final Class modifierOwnerClass) { - return new JetIntentionActionFactory() { + public static JetSingleIntentionActionFactory createFactory(final JetKeywordToken modifier, final Class modifierOwnerClass) { + return new JetSingleIntentionActionFactory() { @Override public IntentionAction createAction(Diagnostic diagnostic) { JetModifierListOwner modifierListOwner = QuickFixUtil.getParentElementOfType(diagnostic, modifierOwnerClass); @@ -175,7 +175,7 @@ public class AddModifierFix extends JetIntentionAction { }; } - public static JetIntentionActionFactory createFactory(JetKeywordToken modifier) { + public static JetSingleIntentionActionFactory createFactory(JetKeywordToken modifier) { return createFactory(modifier, JetModifierListOwner.class); } diff --git a/idea/src/org/jetbrains/jet/plugin/quickfix/AddNameToArgumentFix.java b/idea/src/org/jetbrains/jet/plugin/quickfix/AddNameToArgumentFix.java index cc53c6ad0e3..93c03343de2 100644 --- a/idea/src/org/jetbrains/jet/plugin/quickfix/AddNameToArgumentFix.java +++ b/idea/src/org/jetbrains/jet/plugin/quickfix/AddNameToArgumentFix.java @@ -183,8 +183,8 @@ public class AddNameToArgumentFix extends JetIntentionAction { return JetBundle.message("add.name.to.argument.family"); } @NotNull - public static JetIntentionActionFactory createFactory() { - return new JetIntentionActionFactory() { + public static JetIntentionActionsFactory createFactory() { + return new JetSingleIntentionActionFactory() { @Nullable @Override public IntentionAction createAction(Diagnostic diagnostic) { diff --git a/idea/src/org/jetbrains/jet/plugin/quickfix/AddOpenModifierToClassDeclarationFix.java b/idea/src/org/jetbrains/jet/plugin/quickfix/AddOpenModifierToClassDeclarationFix.java index 8fa3b39a8c6..13509245a17 100644 --- a/idea/src/org/jetbrains/jet/plugin/quickfix/AddOpenModifierToClassDeclarationFix.java +++ b/idea/src/org/jetbrains/jet/plugin/quickfix/AddOpenModifierToClassDeclarationFix.java @@ -81,8 +81,8 @@ public class AddOpenModifierToClassDeclarationFix extends JetIntentionAction editor.getCaretModel().moveToOffset(textRange.getStartOffset() + indexOfOpenBrace + 1); } - public static JetIntentionActionFactory createFactory() { - return new JetIntentionActionFactory() { + public static JetSingleIntentionActionFactory createFactory() { + return new JetSingleIntentionActionFactory() { @Nullable @Override public JetIntentionAction createAction(Diagnostic diagnostic) { diff --git a/idea/src/org/jetbrains/jet/plugin/quickfix/AutoImportFix.java b/idea/src/org/jetbrains/jet/plugin/quickfix/AutoImportFix.java index c4cdd8d9533..68b66bfa623 100644 --- a/idea/src/org/jetbrains/jet/plugin/quickfix/AutoImportFix.java +++ b/idea/src/org/jetbrains/jet/plugin/quickfix/AutoImportFix.java @@ -289,8 +289,8 @@ public class AutoImportFix extends JetHintAction implem } @Nullable - public static JetIntentionActionFactory createFactory() { - return new JetIntentionActionFactory() { + public static JetSingleIntentionActionFactory createFactory() { + return new JetSingleIntentionActionFactory() { @Nullable @Override public JetIntentionAction createAction(@NotNull Diagnostic diagnostic) { diff --git a/idea/src/org/jetbrains/jet/plugin/quickfix/CastExpressionFix.java b/idea/src/org/jetbrains/jet/plugin/quickfix/CastExpressionFix.java index 9d96a551817..6cbf68bf8a9 100644 --- a/idea/src/org/jetbrains/jet/plugin/quickfix/CastExpressionFix.java +++ b/idea/src/org/jetbrains/jet/plugin/quickfix/CastExpressionFix.java @@ -81,8 +81,8 @@ public class CastExpressionFix extends JetIntentionAction { } @NotNull - public static JetIntentionActionFactory createFactoryForAutoCastImpossible() { - return new JetIntentionActionFactory() { + public static JetSingleIntentionActionFactory createFactoryForAutoCastImpossible() { + return new JetSingleIntentionActionFactory() { @Nullable @Override public IntentionAction createAction(Diagnostic diagnostic) { @@ -96,8 +96,8 @@ public class CastExpressionFix extends JetIntentionAction { } @NotNull - public static JetIntentionActionFactory createFactoryForTypeMismatch() { - return new JetIntentionActionFactory() { + public static JetSingleIntentionActionFactory createFactoryForTypeMismatch() { + return new JetSingleIntentionActionFactory() { @Nullable @Override public IntentionAction createAction(Diagnostic diagnostic) { diff --git a/idea/src/org/jetbrains/jet/plugin/quickfix/ChangeAccessorTypeFix.java b/idea/src/org/jetbrains/jet/plugin/quickfix/ChangeAccessorTypeFix.java index 6eef4a97ffe..59dee5775e8 100644 --- a/idea/src/org/jetbrains/jet/plugin/quickfix/ChangeAccessorTypeFix.java +++ b/idea/src/org/jetbrains/jet/plugin/quickfix/ChangeAccessorTypeFix.java @@ -83,8 +83,8 @@ public class ChangeAccessorTypeFix extends JetIntentionAction createAction(Diagnostic diagnostic) { JetPropertyAccessor accessor = QuickFixUtil.getParentElementOfType(diagnostic, JetPropertyAccessor.class); diff --git a/idea/src/org/jetbrains/jet/plugin/quickfix/ChangeFunctionLiteralReturnTypeFix.java b/idea/src/org/jetbrains/jet/plugin/quickfix/ChangeFunctionLiteralReturnTypeFix.java index c93d084532e..b257b99cfdc 100644 --- a/idea/src/org/jetbrains/jet/plugin/quickfix/ChangeFunctionLiteralReturnTypeFix.java +++ b/idea/src/org/jetbrains/jet/plugin/quickfix/ChangeFunctionLiteralReturnTypeFix.java @@ -126,8 +126,8 @@ public class ChangeFunctionLiteralReturnTypeFix extends JetIntentionAction createAction(Diagnostic diagnostic) { JetSimpleNameExpression expression = QuickFixUtil.getParentElementOfType(diagnostic, JetSimpleNameExpression.class); diff --git a/idea/src/org/jetbrains/jet/plugin/quickfix/ChangeToConstructorInvocationFix.java b/idea/src/org/jetbrains/jet/plugin/quickfix/ChangeToConstructorInvocationFix.java index 7890d0a49da..3cb0532bf48 100644 --- a/idea/src/org/jetbrains/jet/plugin/quickfix/ChangeToConstructorInvocationFix.java +++ b/idea/src/org/jetbrains/jet/plugin/quickfix/ChangeToConstructorInvocationFix.java @@ -84,8 +84,8 @@ public class ChangeToConstructorInvocationFix extends JetIntentionAction createAction(Diagnostic diagnostic) { if (diagnostic.getPsiElement() instanceof JetDelegatorToSuperClass) { diff --git a/idea/src/org/jetbrains/jet/plugin/quickfix/ChangeToFunctionInvocationFix.java b/idea/src/org/jetbrains/jet/plugin/quickfix/ChangeToFunctionInvocationFix.java index acbdc338f17..b96a01b3155 100644 --- a/idea/src/org/jetbrains/jet/plugin/quickfix/ChangeToFunctionInvocationFix.java +++ b/idea/src/org/jetbrains/jet/plugin/quickfix/ChangeToFunctionInvocationFix.java @@ -50,8 +50,8 @@ public class ChangeToFunctionInvocationFix extends JetIntentionAction createAction(Diagnostic diagnostic) { if (diagnostic.getPsiElement() instanceof JetExpression) { diff --git a/idea/src/org/jetbrains/jet/plugin/quickfix/ChangeToPropertyNameFix.java b/idea/src/org/jetbrains/jet/plugin/quickfix/ChangeToPropertyNameFix.java index 96ecda49d7e..9d832492d35 100644 --- a/idea/src/org/jetbrains/jet/plugin/quickfix/ChangeToPropertyNameFix.java +++ b/idea/src/org/jetbrains/jet/plugin/quickfix/ChangeToPropertyNameFix.java @@ -58,8 +58,8 @@ public class ChangeToPropertyNameFix extends JetIntentionAction createAction(Diagnostic diagnostic) { JetSimpleNameExpression expression = QuickFixUtil.getParentElementOfType(diagnostic, JetSimpleNameExpression.class); diff --git a/idea/src/org/jetbrains/jet/plugin/quickfix/ChangeToStarProjectionFix.java b/idea/src/org/jetbrains/jet/plugin/quickfix/ChangeToStarProjectionFix.java index 18c050c42d3..ac083e375bd 100644 --- a/idea/src/org/jetbrains/jet/plugin/quickfix/ChangeToStarProjectionFix.java +++ b/idea/src/org/jetbrains/jet/plugin/quickfix/ChangeToStarProjectionFix.java @@ -54,8 +54,8 @@ public class ChangeToStarProjectionFix extends JetIntentionAction { } @NotNull - public static JetIntentionActionFactory createFactoryForExpectedParameterTypeMismatch() { - return new JetIntentionActionFactory() { + public static JetSingleIntentionActionFactory createFactoryForExpectedParameterTypeMismatch() { + return new JetSingleIntentionActionFactory() { @Nullable @Override public IntentionAction createAction(Diagnostic diagnostic) { @@ -75,8 +75,8 @@ public class ChangeTypeFix extends JetIntentionAction { } @NotNull - public static JetIntentionActionFactory createFactoryForExpectedReturnTypeMismatch() { - return new JetIntentionActionFactory() { + public static JetSingleIntentionActionFactory createFactoryForExpectedReturnTypeMismatch() { + return new JetSingleIntentionActionFactory() { @Nullable @Override public IntentionAction createAction(Diagnostic diagnostic) { diff --git a/idea/src/org/jetbrains/jet/plugin/quickfix/ChangeVariableTypeFix.java b/idea/src/org/jetbrains/jet/plugin/quickfix/ChangeVariableTypeFix.java index 3236e846711..c70d024f7a6 100644 --- a/idea/src/org/jetbrains/jet/plugin/quickfix/ChangeVariableTypeFix.java +++ b/idea/src/org/jetbrains/jet/plugin/quickfix/ChangeVariableTypeFix.java @@ -67,8 +67,8 @@ public class ChangeVariableTypeFix extends JetIntentionAction createAction(Diagnostic diagnostic) { PsiElement element = diagnostic.getPsiElement(); diff --git a/idea/src/org/jetbrains/jet/plugin/quickfix/JetIntentionActionFactory.java b/idea/src/org/jetbrains/jet/plugin/quickfix/JetIntentionActionsFactory.java similarity index 80% rename from idea/src/org/jetbrains/jet/plugin/quickfix/JetIntentionActionFactory.java rename to idea/src/org/jetbrains/jet/plugin/quickfix/JetIntentionActionsFactory.java index 3301507e6ac..953acf3469b 100644 --- a/idea/src/org/jetbrains/jet/plugin/quickfix/JetIntentionActionFactory.java +++ b/idea/src/org/jetbrains/jet/plugin/quickfix/JetIntentionActionsFactory.java @@ -17,12 +17,13 @@ package org.jetbrains.jet.plugin.quickfix; import com.intellij.codeInsight.intention.IntentionAction; -import org.jetbrains.annotations.Nullable; +import org.jetbrains.annotations.NotNull; import org.jetbrains.jet.lang.diagnostics.Diagnostic; -public interface JetIntentionActionFactory { +import java.util.List; - @Nullable - IntentionAction createAction(Diagnostic diagnostic); +public interface JetIntentionActionsFactory { + @NotNull + List createActions(Diagnostic diagnostic); } diff --git a/idea/src/org/jetbrains/jet/plugin/quickfix/JetSingleIntentionActionFactory.java b/idea/src/org/jetbrains/jet/plugin/quickfix/JetSingleIntentionActionFactory.java new file mode 100644 index 00000000000..1ecbd890a63 --- /dev/null +++ b/idea/src/org/jetbrains/jet/plugin/quickfix/JetSingleIntentionActionFactory.java @@ -0,0 +1,42 @@ +/* + * Copyright 2010-2013 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.jetbrains.jet.plugin.quickfix; + +import com.intellij.codeInsight.intention.IntentionAction; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import org.jetbrains.jet.lang.diagnostics.Diagnostic; + +import java.util.LinkedList; +import java.util.List; + +public abstract class JetSingleIntentionActionFactory implements JetIntentionActionsFactory { + + @Nullable + public abstract IntentionAction createAction(Diagnostic diagnostic); + + @NotNull + @Override + public final List createActions(Diagnostic diagnostic) { + List intentionActionList = new LinkedList(); + IntentionAction intentionAction = createAction(diagnostic); + if (intentionAction != null) { + intentionActionList.add(intentionAction); + } + return intentionActionList; + } +} diff --git a/idea/src/org/jetbrains/jet/plugin/quickfix/MakeClassAnAnnotationClassFix.java b/idea/src/org/jetbrains/jet/plugin/quickfix/MakeClassAnAnnotationClassFix.java index 4f5191179a3..6f2712cc75d 100644 --- a/idea/src/org/jetbrains/jet/plugin/quickfix/MakeClassAnAnnotationClassFix.java +++ b/idea/src/org/jetbrains/jet/plugin/quickfix/MakeClassAnAnnotationClassFix.java @@ -90,8 +90,8 @@ public class MakeClassAnAnnotationClassFix extends JetIntentionAction { } - public static JetIntentionActionFactory createFactory() { - return new JetIntentionActionFactory() { + public static JetSingleIntentionActionFactory createFactory() { + return new JetSingleIntentionActionFactory() { @Nullable @Override public JetIntentionAction createAction(Diagnostic diagnostic) { diff --git a/idea/src/org/jetbrains/jet/plugin/quickfix/MoveWhenElseBranchFix.java b/idea/src/org/jetbrains/jet/plugin/quickfix/MoveWhenElseBranchFix.java index 132d8989c9d..95e503a6eab 100644 --- a/idea/src/org/jetbrains/jet/plugin/quickfix/MoveWhenElseBranchFix.java +++ b/idea/src/org/jetbrains/jet/plugin/quickfix/MoveWhenElseBranchFix.java @@ -78,8 +78,8 @@ public class MoveWhenElseBranchFix extends JetIntentionAction editor.getCaretModel().moveToOffset(insertedWhenEntry.getTextOffset() + cursorOffset); } - public static JetIntentionActionFactory createFactory() { - return new JetIntentionActionFactory() { + public static JetSingleIntentionActionFactory createFactory() { + return new JetSingleIntentionActionFactory() { @Nullable @Override public JetIntentionAction createAction(Diagnostic diagnostic) { diff --git a/idea/src/org/jetbrains/jet/plugin/quickfix/QuickFixes.java b/idea/src/org/jetbrains/jet/plugin/quickfix/QuickFixes.java index a6b9c110a51..7a4ce23f253 100644 --- a/idea/src/org/jetbrains/jet/plugin/quickfix/QuickFixes.java +++ b/idea/src/org/jetbrains/jet/plugin/quickfix/QuickFixes.java @@ -30,10 +30,10 @@ import static org.jetbrains.jet.lexer.JetTokens.*; public class QuickFixes { - private static final Multimap factories = HashMultimap.create(); + private static final Multimap factories = HashMultimap.create(); private static final Multimap actions = HashMultimap.create(); - public static Collection getActionFactories(AbstractDiagnosticFactory diagnosticFactory) { + public static Collection getActionsFactories(AbstractDiagnosticFactory diagnosticFactory) { return factories.get(diagnosticFactory); } @@ -44,12 +44,12 @@ public class QuickFixes { private QuickFixes() {} static { - JetIntentionActionFactory removeAbstractModifierFactory = RemoveModifierFix.createRemoveModifierFromListOwnerFactory(ABSTRACT_KEYWORD); - JetIntentionActionFactory addAbstractModifierFactory = AddModifierFix.createFactory(ABSTRACT_KEYWORD); + JetSingleIntentionActionFactory removeAbstractModifierFactory = RemoveModifierFix.createRemoveModifierFromListOwnerFactory(ABSTRACT_KEYWORD); + JetSingleIntentionActionFactory addAbstractModifierFactory = AddModifierFix.createFactory(ABSTRACT_KEYWORD); factories.put(ABSTRACT_PROPERTY_IN_PRIMARY_CONSTRUCTOR_PARAMETERS, removeAbstractModifierFactory); - JetIntentionActionFactory removePartsFromPropertyFactory = RemovePartsFromPropertyFix.createFactory(); + JetSingleIntentionActionFactory removePartsFromPropertyFactory = RemovePartsFromPropertyFix.createFactory(); factories.put(ABSTRACT_PROPERTY_WITH_INITIALIZER, removeAbstractModifierFactory); factories.put(ABSTRACT_PROPERTY_WITH_INITIALIZER, removePartsFromPropertyFactory); @@ -63,13 +63,13 @@ public class QuickFixes { factories.put(MUST_BE_INITIALIZED_OR_BE_ABSTRACT, addAbstractModifierFactory); - JetIntentionActionFactory removeFinalModifierFactory = RemoveModifierFix.createRemoveModifierFromListOwnerFactory(FINAL_KEYWORD); + JetSingleIntentionActionFactory removeFinalModifierFactory = RemoveModifierFix.createRemoveModifierFromListOwnerFactory(FINAL_KEYWORD); - JetIntentionActionFactory addAbstractToClassFactory = AddModifierFix.createFactory(ABSTRACT_KEYWORD, JetClass.class); + JetSingleIntentionActionFactory addAbstractToClassFactory = AddModifierFix.createFactory(ABSTRACT_KEYWORD, JetClass.class); factories.put(ABSTRACT_PROPERTY_IN_NON_ABSTRACT_CLASS, removeAbstractModifierFactory); factories.put(ABSTRACT_PROPERTY_IN_NON_ABSTRACT_CLASS, addAbstractToClassFactory); - JetIntentionActionFactory removeFunctionBodyFactory = RemoveFunctionBodyFix.createFactory(); + JetSingleIntentionActionFactory removeFunctionBodyFactory = RemoveFunctionBodyFix.createFactory(); factories.put(ABSTRACT_FUNCTION_IN_NON_ABSTRACT_CLASS, removeAbstractModifierFactory); factories.put(ABSTRACT_FUNCTION_IN_NON_ABSTRACT_CLASS, addAbstractToClassFactory); @@ -79,7 +79,7 @@ public class QuickFixes { factories.put(FINAL_PROPERTY_IN_TRAIT, removeFinalModifierFactory); factories.put(FINAL_FUNCTION_WITH_NO_BODY, removeFinalModifierFactory); - JetIntentionActionFactory addFunctionBodyFactory = AddFunctionBodyFix.createFactory(); + JetSingleIntentionActionFactory addFunctionBodyFactory = AddFunctionBodyFix.createFactory(); factories.put(NON_ABSTRACT_FUNCTION_WITH_NO_BODY, addAbstractModifierFactory); factories.put(NON_ABSTRACT_FUNCTION_WITH_NO_BODY, addFunctionBodyFactory); @@ -97,13 +97,13 @@ public class QuickFixes { factories.put(USELESS_CAST_STATIC_ASSERT_IS_FINE, ReplaceOperationInBinaryExpressionFix.createChangeCastToStaticAssertFactory()); factories.put(USELESS_CAST, RemoveRightPartOfBinaryExpressionFix.createRemoveCastFactory()); - JetIntentionActionFactory changeAccessorTypeFactory = ChangeAccessorTypeFix.createFactory(); + JetSingleIntentionActionFactory changeAccessorTypeFactory = ChangeAccessorTypeFix.createFactory(); factories.put(WRONG_SETTER_PARAMETER_TYPE, changeAccessorTypeFactory); factories.put(WRONG_GETTER_RETURN_TYPE, changeAccessorTypeFactory); factories.put(USELESS_ELVIS, RemoveRightPartOfBinaryExpressionFix.createRemoveElvisOperatorFactory()); - JetIntentionActionFactory removeRedundantModifierFactory = RemoveModifierFix.createRemoveModifierFactory(true); + JetSingleIntentionActionFactory removeRedundantModifierFactory = RemoveModifierFix.createRemoveModifierFactory(true); factories.put(REDUNDANT_MODIFIER, removeRedundantModifierFactory); factories.put(ABSTRACT_MODIFIER_IN_TRAIT, RemoveModifierFix.createRemoveModifierFromListOwnerFactory(ABSTRACT_KEYWORD, true)); factories.put(OPEN_MODIFIER_IN_TRAIT, RemoveModifierFix.createRemoveModifierFromListOwnerFactory(OPEN_KEYWORD, true)); @@ -112,28 +112,28 @@ public class QuickFixes { factories.put(INCOMPATIBLE_MODIFIERS, RemoveModifierFix.createRemoveModifierFactory(false)); factories.put(VARIANCE_ON_TYPE_PARAMETER_OF_FUNCTION_OR_PROPERTY, RemoveModifierFix.createRemoveVarianceFactory()); - JetIntentionActionFactory removeOpenModifierFactory = RemoveModifierFix.createRemoveModifierFromListOwnerFactory(OPEN_KEYWORD); + JetSingleIntentionActionFactory removeOpenModifierFactory = RemoveModifierFix.createRemoveModifierFromListOwnerFactory(OPEN_KEYWORD); factories.put(NON_FINAL_MEMBER_IN_FINAL_CLASS, AddModifierFix.createFactory(OPEN_KEYWORD, JetClass.class)); factories.put(NON_FINAL_MEMBER_IN_FINAL_CLASS, removeOpenModifierFactory); - JetIntentionActionFactory removeModifierFactory = RemoveModifierFix.createRemoveModifierFactory(); + JetSingleIntentionActionFactory removeModifierFactory = RemoveModifierFix.createRemoveModifierFactory(); factories.put(GETTER_VISIBILITY_DIFFERS_FROM_PROPERTY_VISIBILITY, removeModifierFactory); factories.put(REDUNDANT_MODIFIER_IN_GETTER, removeRedundantModifierFactory); factories.put(ILLEGAL_MODIFIER, removeModifierFactory); - JetIntentionActionFactory changeToBackingFieldFactory = ChangeToBackingFieldFix.createFactory(); + JetSingleIntentionActionFactory changeToBackingFieldFactory = ChangeToBackingFieldFix.createFactory(); factories.put(INITIALIZATION_USING_BACKING_FIELD_CUSTOM_SETTER, changeToBackingFieldFactory); factories.put(INITIALIZATION_USING_BACKING_FIELD_OPEN_SETTER, changeToBackingFieldFactory); - JetIntentionActionFactory changeToPropertyNameFactory = ChangeToPropertyNameFix.createFactory(); + JetSingleIntentionActionFactory changeToPropertyNameFactory = ChangeToPropertyNameFix.createFactory(); factories.put(NO_BACKING_FIELD_ABSTRACT_PROPERTY, changeToPropertyNameFactory); factories.put(NO_BACKING_FIELD_CUSTOM_ACCESSORS, changeToPropertyNameFactory); factories.put(INACCESSIBLE_BACKING_FIELD, changeToPropertyNameFactory); - JetIntentionActionFactory unresolvedReferenceFactory = AutoImportFix.createFactory(); + JetSingleIntentionActionFactory unresolvedReferenceFactory = AutoImportFix.createFactory(); factories.put(UNRESOLVED_REFERENCE, unresolvedReferenceFactory); - JetIntentionActionFactory removeImportFixFactory = RemovePsiElementSimpleFix.createRemoveImportFactory(); + JetSingleIntentionActionFactory removeImportFixFactory = RemovePsiElementSimpleFix.createRemoveImportFactory(); factories.put(USELESS_SIMPLE_IMPORT, removeImportFixFactory); factories.put(USELESS_HIDDEN_IMPORT, removeImportFixFactory); @@ -173,7 +173,7 @@ public class QuickFixes { actions.put(UNNECESSARY_NOT_NULL_ASSERTION, ExclExclCallFix.removeExclExclCall()); factories.put(UNSAFE_INFIX_CALL, ReplaceInfixCallFix.createFactory()); - JetIntentionActionFactory removeProtectedModifierFactory = RemoveModifierFix.createRemoveModifierFromListOwnerFactory(PROTECTED_KEYWORD); + JetSingleIntentionActionFactory removeProtectedModifierFactory = RemoveModifierFix.createRemoveModifierFromListOwnerFactory(PROTECTED_KEYWORD); factories.put(PACKAGE_MEMBER_CANNOT_BE_PROTECTED, removeProtectedModifierFactory); actions.put(PUBLIC_MEMBER_SHOULD_SPECIFY_TYPE, new SpecifyTypeExplicitlyFix()); @@ -187,13 +187,13 @@ public class QuickFixes { factories.put(TYPE_ARGUMENTS_REDUNDANT_IN_SUPER_QUALIFIER, RemovePsiElementSimpleFix.createRemoveTypeArgumentsFactory()); - JetIntentionActionFactory changeToStarProjectionFactory = ChangeToStarProjectionFix.createFactory(); + JetSingleIntentionActionFactory changeToStarProjectionFactory = ChangeToStarProjectionFix.createFactory(); factories.put(UNCHECKED_CAST, changeToStarProjectionFactory); factories.put(CANNOT_CHECK_FOR_ERASED, changeToStarProjectionFactory); factories.put(INACCESSIBLE_OUTER_CLASS_EXPRESSION, AddModifierFix.createFactory(INNER_KEYWORD, JetClass.class)); - JetIntentionActionFactory addOpenModifierToClassDeclarationFix = AddOpenModifierToClassDeclarationFix.createFactory(); + JetSingleIntentionActionFactory addOpenModifierToClassDeclarationFix = AddOpenModifierToClassDeclarationFix.createFactory(); factories.put(FINAL_SUPERTYPE, addOpenModifierToClassDeclarationFix); factories.put(FINAL_UPPER_BOUND, addOpenModifierToClassDeclarationFix); @@ -214,12 +214,12 @@ public class QuickFixes { factories.put(DANGLING_FUNCTION_LITERAL_ARGUMENT_SUSPECTED, AddSemicolonAfterFunctionCallFix.createFactory()); - JetIntentionActionFactory changeVariableTypeFix = ChangeVariableTypeFix.createFactoryForPropertyOrReturnTypeMismatchOnOverride(); + JetSingleIntentionActionFactory changeVariableTypeFix = ChangeVariableTypeFix.createFactoryForPropertyOrReturnTypeMismatchOnOverride(); factories.put(RETURN_TYPE_MISMATCH_ON_OVERRIDE, changeVariableTypeFix); factories.put(PROPERTY_TYPE_MISMATCH_ON_OVERRIDE, changeVariableTypeFix); factories.put(COMPONENT_FUNCTION_RETURN_TYPE_MISMATCH, ChangeVariableTypeFix.createFactoryForComponentFunctionReturnTypeMismatch()); - JetIntentionActionFactory changeFunctionReturnTypeFix = ChangeFunctionReturnTypeFix.createFactoryForChangingReturnTypeToUnit(); + JetSingleIntentionActionFactory changeFunctionReturnTypeFix = ChangeFunctionReturnTypeFix.createFactoryForChangingReturnTypeToUnit(); factories.put(RETURN_TYPE_MISMATCH, changeFunctionReturnTypeFix); factories.put(NO_RETURN_IN_FUNCTION_WITH_BLOCK_BODY, changeFunctionReturnTypeFix); factories.put(RETURN_TYPE_MISMATCH_ON_OVERRIDE, ChangeFunctionReturnTypeFix.createFactoryForReturnTypeMismatchOnOverride()); @@ -236,7 +236,7 @@ public class QuickFixes { factories.put(EXPECTED_PARAMETER_TYPE_MISMATCH, ChangeTypeFix.createFactoryForExpectedParameterTypeMismatch()); factories.put(EXPECTED_RETURN_TYPE_MISMATCH, ChangeTypeFix.createFactoryForExpectedReturnTypeMismatch()); - JetIntentionActionFactory changeFunctionLiteralReturnTypeFix = ChangeFunctionLiteralReturnTypeFix.createFactoryForExpectedOrAssignmentTypeMismatch(); + JetSingleIntentionActionFactory changeFunctionLiteralReturnTypeFix = ChangeFunctionLiteralReturnTypeFix.createFactoryForExpectedOrAssignmentTypeMismatch(); factories.put(EXPECTED_TYPE_MISMATCH, changeFunctionLiteralReturnTypeFix); factories.put(ASSIGNMENT_TYPE_MISMATCH, changeFunctionLiteralReturnTypeFix); diff --git a/idea/src/org/jetbrains/jet/plugin/quickfix/RemoveFunctionBodyFix.java b/idea/src/org/jetbrains/jet/plugin/quickfix/RemoveFunctionBodyFix.java index f93954651f4..19e77848cd5 100644 --- a/idea/src/org/jetbrains/jet/plugin/quickfix/RemoveFunctionBodyFix.java +++ b/idea/src/org/jetbrains/jet/plugin/quickfix/RemoveFunctionBodyFix.java @@ -87,8 +87,8 @@ public class RemoveFunctionBodyFix extends JetIntentionAction { return false; } - public static JetIntentionActionFactory createFactory() { - return new JetIntentionActionFactory() { + public static JetSingleIntentionActionFactory createFactory() { + return new JetSingleIntentionActionFactory() { @Override public JetIntentionAction createAction(Diagnostic diagnostic) { JetFunction function = QuickFixUtil.getParentElementOfType(diagnostic, JetFunction.class); diff --git a/idea/src/org/jetbrains/jet/plugin/quickfix/RemoveModifierFix.java b/idea/src/org/jetbrains/jet/plugin/quickfix/RemoveModifierFix.java index 6dfe9a14c17..03d61b2998a 100644 --- a/idea/src/org/jetbrains/jet/plugin/quickfix/RemoveModifierFix.java +++ b/idea/src/org/jetbrains/jet/plugin/quickfix/RemoveModifierFix.java @@ -103,12 +103,12 @@ public class RemoveModifierFix extends JetIntentionAction } - public static JetIntentionActionFactory createRemoveModifierFromListOwnerFactory(JetKeywordToken modifier) { + public static JetSingleIntentionActionFactory createRemoveModifierFromListOwnerFactory(JetKeywordToken modifier) { return createRemoveModifierFromListOwnerFactory(modifier, false); } - public static JetIntentionActionFactory createRemoveModifierFromListOwnerFactory(final JetKeywordToken modifier, final boolean isRedundant) { - return new JetIntentionActionFactory() { + public static JetSingleIntentionActionFactory createRemoveModifierFromListOwnerFactory(final JetKeywordToken modifier, final boolean isRedundant) { + return new JetSingleIntentionActionFactory() { @Nullable @Override public JetIntentionAction createAction(Diagnostic diagnostic) { @@ -119,12 +119,12 @@ public class RemoveModifierFix extends JetIntentionAction }; } - public static JetIntentionActionFactory createRemoveModifierFactory() { + public static JetSingleIntentionActionFactory createRemoveModifierFactory() { return createRemoveModifierFactory(false); } - public static JetIntentionActionFactory createRemoveModifierFactory(final boolean isRedundant) { - return new JetIntentionActionFactory() { + public static JetSingleIntentionActionFactory createRemoveModifierFactory(final boolean isRedundant) { + return new JetSingleIntentionActionFactory() { @Nullable @Override public JetIntentionAction createAction(Diagnostic diagnostic) { @@ -139,8 +139,8 @@ public class RemoveModifierFix extends JetIntentionAction }; } - public static JetIntentionActionFactory createRemoveProjectionFactory(final boolean isRedundant) { - return new JetIntentionActionFactory() { + public static JetSingleIntentionActionFactory createRemoveProjectionFactory(final boolean isRedundant) { + return new JetSingleIntentionActionFactory() { @Nullable @Override public JetIntentionAction createAction(Diagnostic diagnostic) { @@ -156,8 +156,8 @@ public class RemoveModifierFix extends JetIntentionAction }; } - public static JetIntentionActionFactory createRemoveVarianceFactory() { - return new JetIntentionActionFactory() { + public static JetSingleIntentionActionFactory createRemoveVarianceFactory() { + return new JetSingleIntentionActionFactory() { @Nullable @Override public JetIntentionAction createAction(Diagnostic diagnostic) { diff --git a/idea/src/org/jetbrains/jet/plugin/quickfix/RemoveNullableFix.java b/idea/src/org/jetbrains/jet/plugin/quickfix/RemoveNullableFix.java index fdabcc18e73..a1f0e08fd8b 100644 --- a/idea/src/org/jetbrains/jet/plugin/quickfix/RemoveNullableFix.java +++ b/idea/src/org/jetbrains/jet/plugin/quickfix/RemoveNullableFix.java @@ -62,8 +62,8 @@ public class RemoveNullableFix extends JetIntentionAction { super.element.replace(type); } - public static JetIntentionActionFactory createFactory(final NullableKind typeOfError) { - return new JetIntentionActionFactory() { + public static JetSingleIntentionActionFactory createFactory(final NullableKind typeOfError) { + return new JetSingleIntentionActionFactory() { @Override public JetIntentionAction createAction(Diagnostic diagnostic) { JetNullableType nullType = QuickFixUtil.getParentElementOfType(diagnostic, JetNullableType.class); diff --git a/idea/src/org/jetbrains/jet/plugin/quickfix/RemovePartsFromPropertyFix.java b/idea/src/org/jetbrains/jet/plugin/quickfix/RemovePartsFromPropertyFix.java index 6854ba50f3c..6778eec9646 100644 --- a/idea/src/org/jetbrains/jet/plugin/quickfix/RemovePartsFromPropertyFix.java +++ b/idea/src/org/jetbrains/jet/plugin/quickfix/RemovePartsFromPropertyFix.java @@ -121,8 +121,8 @@ public class RemovePartsFromPropertyFix extends JetIntentionAction } } - public static JetIntentionActionFactory createFactory() { - return new JetIntentionActionFactory() { + public static JetSingleIntentionActionFactory createFactory() { + return new JetSingleIntentionActionFactory() { @Override public JetIntentionAction createAction(Diagnostic diagnostic) { PsiElement element = diagnostic.getPsiElement(); diff --git a/idea/src/org/jetbrains/jet/plugin/quickfix/RemovePsiElementSimpleFix.java b/idea/src/org/jetbrains/jet/plugin/quickfix/RemovePsiElementSimpleFix.java index 43388a24bb5..40f46346cf6 100644 --- a/idea/src/org/jetbrains/jet/plugin/quickfix/RemovePsiElementSimpleFix.java +++ b/idea/src/org/jetbrains/jet/plugin/quickfix/RemovePsiElementSimpleFix.java @@ -60,8 +60,8 @@ public class RemovePsiElementSimpleFix extends JetIntentionAction { element.delete(); } - public static JetIntentionActionFactory createRemoveImportFactory() { - return new JetIntentionActionFactory() { + public static JetSingleIntentionActionFactory createRemoveImportFactory() { + return new JetSingleIntentionActionFactory() { @Override public JetIntentionAction createAction(Diagnostic diagnostic) { JetImportDirective directive = QuickFixUtil.getParentElementOfType(diagnostic, JetImportDirective.class); @@ -79,8 +79,8 @@ public class RemovePsiElementSimpleFix extends JetIntentionAction { }; } - public static JetIntentionActionFactory createRemoveSpreadFactory() { - return new JetIntentionActionFactory() { + public static JetSingleIntentionActionFactory createRemoveSpreadFactory() { + return new JetSingleIntentionActionFactory() { @Override public JetIntentionAction createAction(Diagnostic diagnostic) { PsiElement element = diagnostic.getPsiElement(); @@ -92,8 +92,8 @@ public class RemovePsiElementSimpleFix extends JetIntentionAction { }; } - public static JetIntentionActionFactory createRemoveTypeArgumentsFactory() { - return new JetIntentionActionFactory() { + public static JetSingleIntentionActionFactory createRemoveTypeArgumentsFactory() { + return new JetSingleIntentionActionFactory() { @Override public JetIntentionAction createAction(Diagnostic diagnostic) { JetTypeArgumentList element = QuickFixUtil.getParentElementOfType(diagnostic, JetTypeArgumentList.class); @@ -104,8 +104,8 @@ public class RemovePsiElementSimpleFix extends JetIntentionAction { }; } - public static JetIntentionActionFactory createRemoveVariableFactory() { - return new JetIntentionActionFactory() { + public static JetSingleIntentionActionFactory createRemoveVariableFactory() { + return new JetSingleIntentionActionFactory() { @Override public JetIntentionAction createAction(Diagnostic diagnostic) { final JetProperty expression = QuickFixUtil.getParentElementOfType(diagnostic, JetProperty.class); diff --git a/idea/src/org/jetbrains/jet/plugin/quickfix/RemoveRightPartOfBinaryExpressionFix.java b/idea/src/org/jetbrains/jet/plugin/quickfix/RemoveRightPartOfBinaryExpressionFix.java index 3ad449a3bc4..a2918726a83 100644 --- a/idea/src/org/jetbrains/jet/plugin/quickfix/RemoveRightPartOfBinaryExpressionFix.java +++ b/idea/src/org/jetbrains/jet/plugin/quickfix/RemoveRightPartOfBinaryExpressionFix.java @@ -57,8 +57,8 @@ public class RemoveRightPartOfBinaryExpressionFix exten } } - public static JetIntentionActionFactory createRemoveCastFactory() { - return new JetIntentionActionFactory() { + public static JetSingleIntentionActionFactory createRemoveCastFactory() { + return new JetSingleIntentionActionFactory() { @Override public JetIntentionAction createAction(Diagnostic diagnostic) { JetBinaryExpressionWithTypeRHS expression = QuickFixUtil.getParentElementOfType(diagnostic, JetBinaryExpressionWithTypeRHS.class); @@ -68,8 +68,8 @@ public class RemoveRightPartOfBinaryExpressionFix exten }; } - public static JetIntentionActionFactory createRemoveElvisOperatorFactory() { - return new JetIntentionActionFactory() { + public static JetSingleIntentionActionFactory createRemoveElvisOperatorFactory() { + return new JetSingleIntentionActionFactory() { @Override public JetIntentionAction createAction(Diagnostic diagnostic) { JetBinaryExpression expression = QuickFixUtil.getParentElementOfType(diagnostic, JetBinaryExpression.class); diff --git a/idea/src/org/jetbrains/jet/plugin/quickfix/RemoveSupertypeFix.java b/idea/src/org/jetbrains/jet/plugin/quickfix/RemoveSupertypeFix.java index e6374d65aa4..fd7983caa1e 100644 --- a/idea/src/org/jetbrains/jet/plugin/quickfix/RemoveSupertypeFix.java +++ b/idea/src/org/jetbrains/jet/plugin/quickfix/RemoveSupertypeFix.java @@ -63,8 +63,8 @@ public class RemoveSupertypeFix extends JetIntentionAction createAction(Diagnostic diagnostic) { JetDelegationSpecifier superClass = QuickFixUtil.getParentElementOfType(diagnostic, JetDelegationSpecifier.class); diff --git a/idea/src/org/jetbrains/jet/plugin/quickfix/RenameParameterToMatchOverriddenMethodFix.java b/idea/src/org/jetbrains/jet/plugin/quickfix/RenameParameterToMatchOverriddenMethodFix.java index 59c7b6fa088..2c41571125c 100644 --- a/idea/src/org/jetbrains/jet/plugin/quickfix/RenameParameterToMatchOverriddenMethodFix.java +++ b/idea/src/org/jetbrains/jet/plugin/quickfix/RenameParameterToMatchOverriddenMethodFix.java @@ -82,8 +82,8 @@ public class RenameParameterToMatchOverriddenMethodFix extends JetIntentionActio } @NotNull - public static JetIntentionActionFactory createFactory() { - return new JetIntentionActionFactory() { + public static JetSingleIntentionActionFactory createFactory() { + return new JetSingleIntentionActionFactory() { @Nullable @Override public IntentionAction createAction(Diagnostic diagnostic) { diff --git a/idea/src/org/jetbrains/jet/plugin/quickfix/ReplaceInfixCallFix.java b/idea/src/org/jetbrains/jet/plugin/quickfix/ReplaceInfixCallFix.java index b4c93eb5b5c..7f31feeac9e 100644 --- a/idea/src/org/jetbrains/jet/plugin/quickfix/ReplaceInfixCallFix.java +++ b/idea/src/org/jetbrains/jet/plugin/quickfix/ReplaceInfixCallFix.java @@ -59,8 +59,8 @@ public class ReplaceInfixCallFix extends JetIntentionAction return true; } - public static JetIntentionActionFactory createFactory() { - return new JetIntentionActionFactory() { + public static JetSingleIntentionActionFactory createFactory() { + return new JetSingleIntentionActionFactory() { @Override public IntentionAction createAction(Diagnostic diagnostic) { JetBinaryExpression expression = QuickFixUtil.getParentElementOfType(diagnostic, JetBinaryExpression.class); diff --git a/idea/src/org/jetbrains/jet/plugin/quickfix/ReplaceOperationInBinaryExpressionFix.java b/idea/src/org/jetbrains/jet/plugin/quickfix/ReplaceOperationInBinaryExpressionFix.java index 317a2c3cd9d..2bb7c65bfdb 100644 --- a/idea/src/org/jetbrains/jet/plugin/quickfix/ReplaceOperationInBinaryExpressionFix.java +++ b/idea/src/org/jetbrains/jet/plugin/quickfix/ReplaceOperationInBinaryExpressionFix.java @@ -18,7 +18,6 @@ package org.jetbrains.jet.plugin.quickfix; import com.intellij.openapi.editor.Editor; import com.intellij.openapi.project.Project; -import com.intellij.psi.PsiElement; import com.intellij.psi.PsiFile; import com.intellij.util.IncorrectOperationException; import org.jetbrains.annotations.NotNull; @@ -55,8 +54,8 @@ public abstract class ReplaceOperationInBinaryExpressionFix createAction(Diagnostic diagnostic) { JetBinaryExpressionWithTypeRHS expression = QuickFixUtil.getParentElementOfType(diagnostic, JetBinaryExpressionWithTypeRHS.class); From 6c8096138a2e762316918ca7e067ff02ba177350 Mon Sep 17 00:00:00 2001 From: Wojciech Lopata Date: Thu, 9 May 2013 11:05:38 +0200 Subject: [PATCH 157/249] Make ChangeFunctionReturnTypeFix handle function literals --- .../quickfix/ChangeFunctionReturnTypeFix.java | 41 ++++++++++++++----- 1 file changed, 30 insertions(+), 11 deletions(-) diff --git a/idea/src/org/jetbrains/jet/plugin/quickfix/ChangeFunctionReturnTypeFix.java b/idea/src/org/jetbrains/jet/plugin/quickfix/ChangeFunctionReturnTypeFix.java index ad4e875ed06..599ef46e755 100644 --- a/idea/src/org/jetbrains/jet/plugin/quickfix/ChangeFunctionReturnTypeFix.java +++ b/idea/src/org/jetbrains/jet/plugin/quickfix/ChangeFunctionReturnTypeFix.java @@ -22,6 +22,7 @@ import com.intellij.openapi.project.Project; import com.intellij.openapi.util.Pair; import com.intellij.psi.PsiElement; import com.intellij.psi.PsiErrorElement; +import com.intellij.psi.util.PsiTreeUtil; import com.intellij.util.IncorrectOperationException; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -44,19 +45,32 @@ import org.jetbrains.jet.plugin.intentions.SpecifyTypeExplicitlyAction; import org.jetbrains.jet.plugin.project.AnalyzerFacadeWithCache; import org.jetbrains.jet.renderer.DescriptorRenderer; -public class ChangeFunctionReturnTypeFix extends JetIntentionAction { +public class ChangeFunctionReturnTypeFix extends JetIntentionAction { private final JetType type; private final String renderedType; + private final ChangeFunctionLiteralReturnTypeFix changeFunctionLiteralReturnTypeFix; - public ChangeFunctionReturnTypeFix(@NotNull JetNamedFunction element, @NotNull JetType type) { + public ChangeFunctionReturnTypeFix(@NotNull JetFunction element, @NotNull JetType type) { super(element); this.type = type; renderedType = DescriptorRenderer.SHORT_NAMES_IN_TYPES.renderType(type); + if (element instanceof JetFunctionLiteral) { + JetFunctionLiteralExpression functionLiteralExpression = PsiTreeUtil.getParentOfType(element, JetFunctionLiteralExpression.class); + assert functionLiteralExpression != null : "FunctionLiteral outside any FunctionLiteralExpression"; + changeFunctionLiteralReturnTypeFix = new ChangeFunctionLiteralReturnTypeFix(functionLiteralExpression, type); + } + else { + changeFunctionLiteralReturnTypeFix = null; + } } @NotNull @Override public String getText() { + if (changeFunctionLiteralReturnTypeFix != null) { + return changeFunctionLiteralReturnTypeFix.getText(); + } + String functionName = element.getName(); FqName fqName = JetPsiUtil.getFQName(element); if (fqName != null) functionName = fqName.asString(); @@ -79,9 +93,14 @@ public class ChangeFunctionReturnTypeFix extends JetIntentionAction resolvedCall = context.get(BindingContext.COMPONENT_RESOLVED_CALL, entry); if (resolvedCall == null) return null; - JetNamedFunction componentFunction = (JetNamedFunction) BindingContextUtils.descriptorToDeclaration(context, resolvedCall.getCandidateDescriptor()); + JetFunction componentFunction = (JetFunction) BindingContextUtils.descriptorToDeclaration(context, resolvedCall.getCandidateDescriptor()); JetType expectedType = context.get(BindingContext.TYPE, entry.getTypeRef()); if (componentFunction != null && expectedType != null) { return new ChangeFunctionReturnTypeFix(componentFunction, expectedType); @@ -138,7 +157,7 @@ public class ChangeFunctionReturnTypeFix extends JetIntentionAction resolvedCall = context.get(BindingContext.LOOP_RANGE_HAS_NEXT_RESOLVED_CALL, expression); if (resolvedCall == null) return null; - JetNamedFunction hasNextFunction = (JetNamedFunction) BindingContextUtils.descriptorToDeclaration(context, resolvedCall.getCandidateDescriptor()); + JetFunction hasNextFunction = (JetFunction) BindingContextUtils.descriptorToDeclaration(context, resolvedCall.getCandidateDescriptor()); if (hasNextFunction != null) { return new ChangeFunctionReturnTypeFix(hasNextFunction, KotlinBuiltIns.getInstance().getBooleanType()); } @@ -159,8 +178,8 @@ public class ChangeFunctionReturnTypeFix extends JetIntentionAction resolvedCall = context.get(BindingContext.RESOLVED_CALL, expression.getOperationReference()); if (resolvedCall == null) return null; PsiElement compareTo = BindingContextUtils.descriptorToDeclaration(context, resolvedCall.getCandidateDescriptor()); - if (!(compareTo instanceof JetNamedFunction)) return null; - return new ChangeFunctionReturnTypeFix((JetNamedFunction) compareTo, KotlinBuiltIns.getInstance().getIntType()); + if (!(compareTo instanceof JetFunction)) return null; + return new ChangeFunctionReturnTypeFix((JetFunction) compareTo, KotlinBuiltIns.getInstance().getIntType()); } }; } @@ -171,7 +190,7 @@ public class ChangeFunctionReturnTypeFix extends JetIntentionAction Date: Thu, 9 May 2013 22:07:31 +0200 Subject: [PATCH 158/249] Single factory for TYPE_MISMATCH error --- .../plugin/quickfix/CastExpressionFix.java | 29 ------- .../ChangeFunctionParameterTypeFix.java | 39 --------- .../quickfix/ChangeFunctionReturnTypeFix.java | 20 ----- .../QuickFixFactoryForTypeMismatchError.java | 84 +++++++++++++++++++ .../jet/plugin/quickfix/QuickFixUtil.java | 15 ++++ .../jet/plugin/quickfix/QuickFixes.java | 4 +- ...ypeWithoutChangingFunctionParameterType.kt | 7 ++ ...nLiteralTypeWithoutChangingPropertyType.kt | 7 ++ ...nTypeToMatchReturnTypeOfReturnedLiteral.kt | 4 + ...essionTypeMismatchFunctionParameterType.kt | 6 ++ ...MismatchInIfStatementReturnedByFunction.kt | 7 ++ ...eMismatchInIfStatementReturnedByLiteral.kt | 12 +++ ...ypeWithoutChangingFunctionParameterType.kt | 7 ++ ...nLiteralTypeWithoutChangingPropertyType.kt | 7 ++ ...nTypeToMatchReturnTypeOfReturnedLiteral.kt | 4 + ...CantEvaluateToExpresionThatTypeMismatch.kt | 6 ++ ...essionTypeMismatchFunctionParameterType.kt | 6 ++ ...MismatchInIfStatementReturnedByFunction.kt | 7 ++ ...eMismatchInIfStatementReturnedByLiteral.kt | 12 +++ .../quickfix/QuickFixTestGenerated.java | 35 ++++++++ 20 files changed, 227 insertions(+), 91 deletions(-) create mode 100644 idea/src/org/jetbrains/jet/plugin/quickfix/QuickFixFactoryForTypeMismatchError.java create mode 100644 idea/testData/quickfix/typeMismatch/typeMismatchOnReturnedExpression/afterChangeFunctionLiteralTypeWithoutChangingFunctionParameterType.kt create mode 100644 idea/testData/quickfix/typeMismatch/typeMismatchOnReturnedExpression/afterChangeFunctionLiteralTypeWithoutChangingPropertyType.kt create mode 100644 idea/testData/quickfix/typeMismatch/typeMismatchOnReturnedExpression/afterChangeFunctionReturnTypeToMatchReturnTypeOfReturnedLiteral.kt create mode 100644 idea/testData/quickfix/typeMismatch/typeMismatchOnReturnedExpression/afterReturnedExpressionTypeMismatchFunctionParameterType.kt create mode 100644 idea/testData/quickfix/typeMismatch/typeMismatchOnReturnedExpression/afterTypeMismatchInIfStatementReturnedByFunction.kt create mode 100644 idea/testData/quickfix/typeMismatch/typeMismatchOnReturnedExpression/afterTypeMismatchInIfStatementReturnedByLiteral.kt create mode 100644 idea/testData/quickfix/typeMismatch/typeMismatchOnReturnedExpression/beforeChangeFunctionLiteralTypeWithoutChangingFunctionParameterType.kt create mode 100644 idea/testData/quickfix/typeMismatch/typeMismatchOnReturnedExpression/beforeChangeFunctionLiteralTypeWithoutChangingPropertyType.kt create mode 100644 idea/testData/quickfix/typeMismatch/typeMismatchOnReturnedExpression/beforeChangeFunctionReturnTypeToMatchReturnTypeOfReturnedLiteral.kt create mode 100644 idea/testData/quickfix/typeMismatch/typeMismatchOnReturnedExpression/beforeReturnedExpresionCantEvaluateToExpresionThatTypeMismatch.kt create mode 100644 idea/testData/quickfix/typeMismatch/typeMismatchOnReturnedExpression/beforeReturnedExpressionTypeMismatchFunctionParameterType.kt create mode 100644 idea/testData/quickfix/typeMismatch/typeMismatchOnReturnedExpression/beforeTypeMismatchInIfStatementReturnedByFunction.kt create mode 100644 idea/testData/quickfix/typeMismatch/typeMismatchOnReturnedExpression/beforeTypeMismatchInIfStatementReturnedByLiteral.kt diff --git a/idea/src/org/jetbrains/jet/plugin/quickfix/CastExpressionFix.java b/idea/src/org/jetbrains/jet/plugin/quickfix/CastExpressionFix.java index 6cbf68bf8a9..d58f92e6ebd 100644 --- a/idea/src/org/jetbrains/jet/plugin/quickfix/CastExpressionFix.java +++ b/idea/src/org/jetbrains/jet/plugin/quickfix/CastExpressionFix.java @@ -20,7 +20,6 @@ import com.intellij.codeInsight.intention.IntentionAction; import com.intellij.openapi.editor.Editor; import com.intellij.openapi.project.Project; import com.intellij.psi.PsiFile; -import com.intellij.psi.util.PsiTreeUtil; import com.intellij.util.IncorrectOperationException; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -94,32 +93,4 @@ public class CastExpressionFix extends JetIntentionAction { } }; } - - @NotNull - public static JetSingleIntentionActionFactory createFactoryForTypeMismatch() { - return new JetSingleIntentionActionFactory() { - @Nullable - @Override - public IntentionAction createAction(Diagnostic diagnostic) { - assert diagnostic.getFactory() == Errors.TYPE_MISMATCH; - @SuppressWarnings("unchecked") - DiagnosticWithParameters2 diagnosticWithParameters = - (DiagnosticWithParameters2) diagnostic; - JetExpression expression = diagnosticWithParameters.getPsiElement(); - - // we don't want to cast a cast: - if (expression instanceof JetBinaryExpressionWithTypeRHS) { - return null; - } - - // 'x: Int' - TYPE_MISMATCH might be reported on 'x', and we don't want this quickfix to be available: - JetBinaryExpressionWithTypeRHS parentExpressionWithTypeRHS = - PsiTreeUtil.getParentOfType(expression, JetBinaryExpressionWithTypeRHS.class, true); - if (parentExpressionWithTypeRHS != null && parentExpressionWithTypeRHS.getLeft() == expression) { - return null; - } - return new CastExpressionFix(expression, diagnosticWithParameters.getA()); - } - }; - } } diff --git a/idea/src/org/jetbrains/jet/plugin/quickfix/ChangeFunctionParameterTypeFix.java b/idea/src/org/jetbrains/jet/plugin/quickfix/ChangeFunctionParameterTypeFix.java index 3c7d2b2ba67..3375089e6f7 100644 --- a/idea/src/org/jetbrains/jet/plugin/quickfix/ChangeFunctionParameterTypeFix.java +++ b/idea/src/org/jetbrains/jet/plugin/quickfix/ChangeFunctionParameterTypeFix.java @@ -16,21 +16,16 @@ package org.jetbrains.jet.plugin.quickfix; -import com.intellij.codeInsight.intention.IntentionAction; import com.intellij.openapi.editor.Editor; import com.intellij.openapi.project.Project; import com.intellij.psi.PsiFile; import com.intellij.psi.util.PsiTreeUtil; import com.intellij.util.IncorrectOperationException; import org.jetbrains.annotations.NotNull; -import org.jetbrains.annotations.Nullable; -import org.jetbrains.jet.lang.diagnostics.Diagnostic; import org.jetbrains.jet.lang.psi.*; -import org.jetbrains.jet.lang.resolve.BindingContext; import org.jetbrains.jet.lang.resolve.name.FqName; import org.jetbrains.jet.lang.types.JetType; import org.jetbrains.jet.plugin.JetBundle; -import org.jetbrains.jet.plugin.project.AnalyzerFacadeWithCache; import org.jetbrains.jet.renderer.DescriptorRenderer; public class ChangeFunctionParameterTypeFix extends JetIntentionAction { @@ -68,38 +63,4 @@ public class ChangeFunctionParameterTypeFix extends JetIntentionAction } }; } - - @NotNull - public static JetSingleIntentionActionFactory createFactoryForTypeMismatch() { - return new JetSingleIntentionActionFactory() { - @Nullable - @Override - public IntentionAction createAction(Diagnostic diagnostic) { - JetExpression expression = (JetExpression) diagnostic.getPsiElement(); - JetNamedFunction function = QuickFixUtil.getParentElementOfType(diagnostic, JetNamedFunction.class); - - if (function != null && (function.getInitializer() == expression || expression.getParent() instanceof JetReturnExpression)) { - BindingContext context = AnalyzerFacadeWithCache.analyzeFileWithCache((JetFile) diagnostic.getPsiFile()).getBindingContext(); - JetType type = context.get(BindingContext.EXPRESSION_TYPE, expression); - assert type != null : "Expression type mismatch, but expression has no type"; - return new ChangeFunctionReturnTypeFix(function, type); - } - return null; - } - }; - } } diff --git a/idea/src/org/jetbrains/jet/plugin/quickfix/QuickFixFactoryForTypeMismatchError.java b/idea/src/org/jetbrains/jet/plugin/quickfix/QuickFixFactoryForTypeMismatchError.java new file mode 100644 index 00000000000..1f0ae66d09b --- /dev/null +++ b/idea/src/org/jetbrains/jet/plugin/quickfix/QuickFixFactoryForTypeMismatchError.java @@ -0,0 +1,84 @@ +/* + * Copyright 2010-2013 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.jetbrains.jet.plugin.quickfix; + +import com.intellij.codeInsight.intention.IntentionAction; +import com.intellij.psi.util.PsiTreeUtil; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.jet.lang.diagnostics.Diagnostic; +import org.jetbrains.jet.lang.diagnostics.DiagnosticWithParameters2; +import org.jetbrains.jet.lang.diagnostics.Errors; +import org.jetbrains.jet.lang.psi.*; +import org.jetbrains.jet.lang.resolve.BindingContext; +import org.jetbrains.jet.lang.types.JetType; +import org.jetbrains.jet.plugin.project.AnalyzerFacadeWithCache; + +import java.util.LinkedList; +import java.util.List; + +public class QuickFixFactoryForTypeMismatchError implements JetIntentionActionsFactory { + @NotNull + @Override + public List createActions(Diagnostic diagnostic) { + List actions = new LinkedList(); + + assert diagnostic.getFactory() == Errors.TYPE_MISMATCH; + @SuppressWarnings("unchecked") + DiagnosticWithParameters2 diagnosticWithParameters = + (DiagnosticWithParameters2) diagnostic; + JetExpression expression = diagnosticWithParameters.getPsiElement(); + JetType expectedType = diagnosticWithParameters.getA(); + JetType expressionType = diagnosticWithParameters.getB(); + BindingContext context = AnalyzerFacadeWithCache.analyzeFileWithCache((JetFile) diagnostic.getPsiFile()).getBindingContext(); + + // We don't want to cast a cast or type-asserted expression: + if (!(expression instanceof JetBinaryExpressionWithTypeRHS) && !(expression.getParent() instanceof JetBinaryExpressionWithTypeRHS)) { + actions.add(new CastExpressionFix(expression, expectedType)); + } + + // Mismatch in returned expression: + JetFunction function = PsiTreeUtil.getParentOfType(expression, JetFunction.class, true); + if (function != null && QuickFixUtil.canFunctionReturnExpression(function, expression)) { + actions.add(new ChangeFunctionReturnTypeFix(function, expressionType)); + } + + // Change type of a function parameter in case TYPE_MISMATCH is reported on expression passed as value argument of call. + // 1) When an argument is a dangling function literal: + JetFunctionLiteralExpression functionLiteralExpression = + QuickFixUtil.getParentElementOfType(diagnostic, JetFunctionLiteralExpression.class); + if (functionLiteralExpression != null && functionLiteralExpression.getBodyExpression() == expression) { + JetParameter correspondingParameter = + QuickFixUtil.getFunctionParameterCorrespondingToFunctionLiteralPassedOutsideArgumentList(functionLiteralExpression); + JetType functionLiteralExpressionType = context.get(BindingContext.EXPRESSION_TYPE, functionLiteralExpression); + if (correspondingParameter != null && functionLiteralExpressionType != null) { + actions.add(new ChangeFunctionParameterTypeFix(correspondingParameter, functionLiteralExpressionType)); + } + } + // 2) When an argument is passed inside value argument list: + else { + JetValueArgument valueArgument = QuickFixUtil.getParentElementOfType(diagnostic, JetValueArgument.class); + if (valueArgument != null && valueArgument.getArgumentExpression() == expression) { + JetParameter correspondingParameter = QuickFixUtil.getFunctionParameterCorrespondingToValueArgumentPassedInCall(valueArgument); + JetType valueArgumentType = context.get(BindingContext.EXPRESSION_TYPE, valueArgument.getArgumentExpression()); + if (correspondingParameter != null && valueArgumentType != null) { + actions.add(new ChangeFunctionParameterTypeFix(correspondingParameter, valueArgumentType)); + } + } + } + return actions; + } +} diff --git a/idea/src/org/jetbrains/jet/plugin/quickfix/QuickFixUtil.java b/idea/src/org/jetbrains/jet/plugin/quickfix/QuickFixUtil.java index beb270a8724..a7217ba7006 100644 --- a/idea/src/org/jetbrains/jet/plugin/quickfix/QuickFixUtil.java +++ b/idea/src/org/jetbrains/jet/plugin/quickfix/QuickFixUtil.java @@ -174,4 +174,19 @@ public class QuickFixUtil { } return true; } + + public static boolean canFunctionReturnExpression(@NotNull JetFunction function, @NotNull JetExpression expression) { + if (function instanceof JetFunctionLiteral) { + JetBlockExpression functionLiteralBody = ((JetFunctionLiteral) function).getBodyExpression(); + PsiElement returnedElement = functionLiteralBody == null ? null : functionLiteralBody.getLastChild(); + return returnedElement instanceof JetExpression && canEvaluateTo((JetExpression) returnedElement, expression); + } + else { + if (function instanceof JetWithExpressionInitializer && canEvaluateTo(((JetWithExpressionInitializer) function).getInitializer(), expression)) { + return true; + } + JetReturnExpression returnExpression = PsiTreeUtil.getParentOfType(expression, JetReturnExpression.class); + return returnExpression != null && canEvaluateTo(returnExpression.getReturnedExpression(), expression); + } + } } diff --git a/idea/src/org/jetbrains/jet/plugin/quickfix/QuickFixes.java b/idea/src/org/jetbrains/jet/plugin/quickfix/QuickFixes.java index 7a4ce23f253..ad2eb561f5a 100644 --- a/idea/src/org/jetbrains/jet/plugin/quickfix/QuickFixes.java +++ b/idea/src/org/jetbrains/jet/plugin/quickfix/QuickFixes.java @@ -226,7 +226,6 @@ public class QuickFixes { factories.put(COMPONENT_FUNCTION_RETURN_TYPE_MISMATCH, ChangeFunctionReturnTypeFix.createFactoryForComponentFunctionReturnTypeMismatch()); factories.put(HAS_NEXT_FUNCTION_TYPE_MISMATCH, ChangeFunctionReturnTypeFix.createFactoryForHasNextFunctionTypeMismatch()); factories.put(COMPARE_TO_TYPE_MISMATCH, ChangeFunctionReturnTypeFix.createFactoryForCompareToTypeMismatch()); - factories.put(TYPE_MISMATCH, ChangeFunctionReturnTypeFix.createFactoryForTypeMismatch()); factories.put(TOO_MANY_ARGUMENTS, ChangeFunctionSignatureFix.createFactory()); factories.put(NO_VALUE_FOR_PARAMETER, ChangeFunctionSignatureFix.createFactory()); @@ -240,10 +239,9 @@ public class QuickFixes { factories.put(EXPECTED_TYPE_MISMATCH, changeFunctionLiteralReturnTypeFix); factories.put(ASSIGNMENT_TYPE_MISMATCH, changeFunctionLiteralReturnTypeFix); - factories.put(TYPE_MISMATCH, ChangeFunctionParameterTypeFix.createFactory()); + factories.put(TYPE_MISMATCH, new QuickFixFactoryForTypeMismatchError()); factories.put(AUTOCAST_IMPOSSIBLE, CastExpressionFix.createFactoryForAutoCastImpossible()); - factories.put(TYPE_MISMATCH, CastExpressionFix.createFactoryForTypeMismatch()); factories.put(PLATFORM_CLASS_MAPPED_TO_KOTLIN, MapPlatformClassToKotlinFix.createFactory()); diff --git a/idea/testData/quickfix/typeMismatch/typeMismatchOnReturnedExpression/afterChangeFunctionLiteralTypeWithoutChangingFunctionParameterType.kt b/idea/testData/quickfix/typeMismatch/typeMismatchOnReturnedExpression/afterChangeFunctionLiteralTypeWithoutChangingFunctionParameterType.kt new file mode 100644 index 00000000000..b2b6552068c --- /dev/null +++ b/idea/testData/quickfix/typeMismatch/typeMismatchOnReturnedExpression/afterChangeFunctionLiteralTypeWithoutChangingFunctionParameterType.kt @@ -0,0 +1,7 @@ +// "Change function literal return type to 'String'" "true" +fun foo(f: (String) -> Any) { + foo { + (s: String): String -> + s + } +} \ No newline at end of file diff --git a/idea/testData/quickfix/typeMismatch/typeMismatchOnReturnedExpression/afterChangeFunctionLiteralTypeWithoutChangingPropertyType.kt b/idea/testData/quickfix/typeMismatch/typeMismatchOnReturnedExpression/afterChangeFunctionLiteralTypeWithoutChangingPropertyType.kt new file mode 100644 index 00000000000..35be90c1bea --- /dev/null +++ b/idea/testData/quickfix/typeMismatch/typeMismatchOnReturnedExpression/afterChangeFunctionLiteralTypeWithoutChangingPropertyType.kt @@ -0,0 +1,7 @@ +// "Change function literal return type to 'String'" "true" +fun foo() { + val f: (String) -> String = { + (s: Any): String -> + "" + } +} \ No newline at end of file diff --git a/idea/testData/quickfix/typeMismatch/typeMismatchOnReturnedExpression/afterChangeFunctionReturnTypeToMatchReturnTypeOfReturnedLiteral.kt b/idea/testData/quickfix/typeMismatch/typeMismatchOnReturnedExpression/afterChangeFunctionReturnTypeToMatchReturnTypeOfReturnedLiteral.kt new file mode 100644 index 00000000000..5c7182093c5 --- /dev/null +++ b/idea/testData/quickfix/typeMismatch/typeMismatchOnReturnedExpression/afterChangeFunctionReturnTypeToMatchReturnTypeOfReturnedLiteral.kt @@ -0,0 +1,4 @@ +// "Change 'foo' function return type to '() -> Any'" "true" +fun foo(x: Any): () -> Any { + return {x} +} \ No newline at end of file diff --git a/idea/testData/quickfix/typeMismatch/typeMismatchOnReturnedExpression/afterReturnedExpressionTypeMismatchFunctionParameterType.kt b/idea/testData/quickfix/typeMismatch/typeMismatchOnReturnedExpression/afterReturnedExpressionTypeMismatchFunctionParameterType.kt new file mode 100644 index 00000000000..16a4b270648 --- /dev/null +++ b/idea/testData/quickfix/typeMismatch/typeMismatchOnReturnedExpression/afterReturnedExpressionTypeMismatchFunctionParameterType.kt @@ -0,0 +1,6 @@ +// "Change parameter 'f' type of function 'foo' to '() -> String'" "true" +fun foo(f: () -> String) { + foo { + "" + } +} \ No newline at end of file diff --git a/idea/testData/quickfix/typeMismatch/typeMismatchOnReturnedExpression/afterTypeMismatchInIfStatementReturnedByFunction.kt b/idea/testData/quickfix/typeMismatch/typeMismatchOnReturnedExpression/afterTypeMismatchInIfStatementReturnedByFunction.kt new file mode 100644 index 00000000000..031dded208b --- /dev/null +++ b/idea/testData/quickfix/typeMismatch/typeMismatchOnReturnedExpression/afterTypeMismatchInIfStatementReturnedByFunction.kt @@ -0,0 +1,7 @@ +// "Change 'boo' function return type to 'String'" "true" +fun boo(): String { + return ((if (true) { + val a = "" + a + } else "")) +} \ No newline at end of file diff --git a/idea/testData/quickfix/typeMismatch/typeMismatchOnReturnedExpression/afterTypeMismatchInIfStatementReturnedByLiteral.kt b/idea/testData/quickfix/typeMismatch/typeMismatchOnReturnedExpression/afterTypeMismatchInIfStatementReturnedByLiteral.kt new file mode 100644 index 00000000000..19f21d70c71 --- /dev/null +++ b/idea/testData/quickfix/typeMismatch/typeMismatchOnReturnedExpression/afterTypeMismatchInIfStatementReturnedByLiteral.kt @@ -0,0 +1,12 @@ +// "Change 'f' type to '(Int, Int) -> (String) -> Int'" "true" +fun foo() { + val f: (Int, Int) -> (String) -> Int = { + (a: Int, b: Int): (String) -> Int -> + val x = {(s: String) -> 42} + if (true) x + else if (true) x else { + var y = 42 + if (true) x else x + } + } +} \ No newline at end of file diff --git a/idea/testData/quickfix/typeMismatch/typeMismatchOnReturnedExpression/beforeChangeFunctionLiteralTypeWithoutChangingFunctionParameterType.kt b/idea/testData/quickfix/typeMismatch/typeMismatchOnReturnedExpression/beforeChangeFunctionLiteralTypeWithoutChangingFunctionParameterType.kt new file mode 100644 index 00000000000..0a04b9f473b --- /dev/null +++ b/idea/testData/quickfix/typeMismatch/typeMismatchOnReturnedExpression/beforeChangeFunctionLiteralTypeWithoutChangingFunctionParameterType.kt @@ -0,0 +1,7 @@ +// "Change function literal return type to 'String'" "true" +fun foo(f: (String) -> Any) { + foo { + (s: String): Int -> + s + } +} \ No newline at end of file diff --git a/idea/testData/quickfix/typeMismatch/typeMismatchOnReturnedExpression/beforeChangeFunctionLiteralTypeWithoutChangingPropertyType.kt b/idea/testData/quickfix/typeMismatch/typeMismatchOnReturnedExpression/beforeChangeFunctionLiteralTypeWithoutChangingPropertyType.kt new file mode 100644 index 00000000000..dbec7994ac1 --- /dev/null +++ b/idea/testData/quickfix/typeMismatch/typeMismatchOnReturnedExpression/beforeChangeFunctionLiteralTypeWithoutChangingPropertyType.kt @@ -0,0 +1,7 @@ +// "Change function literal return type to 'String'" "true" +fun foo() { + val f: (String) -> String = { + (s: Any): Int -> + "" + } +} \ No newline at end of file diff --git a/idea/testData/quickfix/typeMismatch/typeMismatchOnReturnedExpression/beforeChangeFunctionReturnTypeToMatchReturnTypeOfReturnedLiteral.kt b/idea/testData/quickfix/typeMismatch/typeMismatchOnReturnedExpression/beforeChangeFunctionReturnTypeToMatchReturnTypeOfReturnedLiteral.kt new file mode 100644 index 00000000000..44c4c565685 --- /dev/null +++ b/idea/testData/quickfix/typeMismatch/typeMismatchOnReturnedExpression/beforeChangeFunctionReturnTypeToMatchReturnTypeOfReturnedLiteral.kt @@ -0,0 +1,4 @@ +// "Change 'foo' function return type to '() -> Any'" "true" +fun foo(x: Any): () -> Int { + return {x} +} \ No newline at end of file diff --git a/idea/testData/quickfix/typeMismatch/typeMismatchOnReturnedExpression/beforeReturnedExpresionCantEvaluateToExpresionThatTypeMismatch.kt b/idea/testData/quickfix/typeMismatch/typeMismatchOnReturnedExpression/beforeReturnedExpresionCantEvaluateToExpresionThatTypeMismatch.kt new file mode 100644 index 00000000000..8161c29c287 --- /dev/null +++ b/idea/testData/quickfix/typeMismatch/typeMismatchOnReturnedExpression/beforeReturnedExpresionCantEvaluateToExpresionThatTypeMismatch.kt @@ -0,0 +1,6 @@ +// "Change function 'foo' return type to 'String'" "false" +// ERROR: Type mismatch.
Required:jet.Int
Found:jet.String
+// ACTION: Disable 'Replace 'if' with 'when'' +// ACTION: Edit intention settings +// ACTION: Replace 'if' with 'when' +fun foo(): Int = if (true) "": Int else 4 \ No newline at end of file diff --git a/idea/testData/quickfix/typeMismatch/typeMismatchOnReturnedExpression/beforeReturnedExpressionTypeMismatchFunctionParameterType.kt b/idea/testData/quickfix/typeMismatch/typeMismatchOnReturnedExpression/beforeReturnedExpressionTypeMismatchFunctionParameterType.kt new file mode 100644 index 00000000000..cb39787a072 --- /dev/null +++ b/idea/testData/quickfix/typeMismatch/typeMismatchOnReturnedExpression/beforeReturnedExpressionTypeMismatchFunctionParameterType.kt @@ -0,0 +1,6 @@ +// "Change parameter 'f' type of function 'foo' to '() -> String'" "true" +fun foo(f: () -> Int) { + foo { + "" + } +} \ No newline at end of file diff --git a/idea/testData/quickfix/typeMismatch/typeMismatchOnReturnedExpression/beforeTypeMismatchInIfStatementReturnedByFunction.kt b/idea/testData/quickfix/typeMismatch/typeMismatchOnReturnedExpression/beforeTypeMismatchInIfStatementReturnedByFunction.kt new file mode 100644 index 00000000000..8a4869a7439 --- /dev/null +++ b/idea/testData/quickfix/typeMismatch/typeMismatchOnReturnedExpression/beforeTypeMismatchInIfStatementReturnedByFunction.kt @@ -0,0 +1,7 @@ +// "Change 'boo' function return type to 'String'" "true" +fun boo(): Int { + return ((if (true) { + val a = "" + a + } else "")) +} \ No newline at end of file diff --git a/idea/testData/quickfix/typeMismatch/typeMismatchOnReturnedExpression/beforeTypeMismatchInIfStatementReturnedByLiteral.kt b/idea/testData/quickfix/typeMismatch/typeMismatchOnReturnedExpression/beforeTypeMismatchInIfStatementReturnedByLiteral.kt new file mode 100644 index 00000000000..ae1c5c6a142 --- /dev/null +++ b/idea/testData/quickfix/typeMismatch/typeMismatchOnReturnedExpression/beforeTypeMismatchInIfStatementReturnedByLiteral.kt @@ -0,0 +1,12 @@ +// "Change 'f' type to '(Int, Int) -> (String) -> Int'" "true" +fun foo() { + val f: () -> Long = { + (a: Int, b: Int): Long -> + val x = {(s: String) -> 42} + if (true) x + else if (true) x else { + var y = 42 + if (true) x else x + } + } +} \ No newline at end of file diff --git a/idea/tests/org/jetbrains/jet/plugin/quickfix/QuickFixTestGenerated.java b/idea/tests/org/jetbrains/jet/plugin/quickfix/QuickFixTestGenerated.java index 810c38bc41d..7dbabee2862 100644 --- a/idea/tests/org/jetbrains/jet/plugin/quickfix/QuickFixTestGenerated.java +++ b/idea/tests/org/jetbrains/jet/plugin/quickfix/QuickFixTestGenerated.java @@ -1421,16 +1421,51 @@ public class QuickFixTestGenerated extends AbstractQuickFixTest { doTest("idea/testData/quickfix/typeMismatch/typeMismatchOnReturnedExpression/beforeAssignmentTypeMismatch.kt"); } + @TestMetadata("beforeChangeFunctionLiteralTypeWithoutChangingFunctionParameterType.kt") + public void testChangeFunctionLiteralTypeWithoutChangingFunctionParameterType() throws Exception { + doTest("idea/testData/quickfix/typeMismatch/typeMismatchOnReturnedExpression/beforeChangeFunctionLiteralTypeWithoutChangingFunctionParameterType.kt"); + } + + @TestMetadata("beforeChangeFunctionLiteralTypeWithoutChangingPropertyType.kt") + public void testChangeFunctionLiteralTypeWithoutChangingPropertyType() throws Exception { + doTest("idea/testData/quickfix/typeMismatch/typeMismatchOnReturnedExpression/beforeChangeFunctionLiteralTypeWithoutChangingPropertyType.kt"); + } + @TestMetadata("beforeChangeFunctionReturnTypeToFunctionType.kt") public void testChangeFunctionReturnTypeToFunctionType() throws Exception { doTest("idea/testData/quickfix/typeMismatch/typeMismatchOnReturnedExpression/beforeChangeFunctionReturnTypeToFunctionType.kt"); } + @TestMetadata("beforeChangeFunctionReturnTypeToMatchReturnTypeOfReturnedLiteral.kt") + public void testChangeFunctionReturnTypeToMatchReturnTypeOfReturnedLiteral() throws Exception { + doTest("idea/testData/quickfix/typeMismatch/typeMismatchOnReturnedExpression/beforeChangeFunctionReturnTypeToMatchReturnTypeOfReturnedLiteral.kt"); + } + @TestMetadata("beforeExpectedTypeMismatch.kt") public void testExpectedTypeMismatch() throws Exception { doTest("idea/testData/quickfix/typeMismatch/typeMismatchOnReturnedExpression/beforeExpectedTypeMismatch.kt"); } + @TestMetadata("beforeReturnedExpresionCantEvaluateToExpresionThatTypeMismatch.kt") + public void testReturnedExpresionCantEvaluateToExpresionThatTypeMismatch() throws Exception { + doTest("idea/testData/quickfix/typeMismatch/typeMismatchOnReturnedExpression/beforeReturnedExpresionCantEvaluateToExpresionThatTypeMismatch.kt"); + } + + @TestMetadata("beforeReturnedExpressionTypeMismatchFunctionParameterType.kt") + public void testReturnedExpressionTypeMismatchFunctionParameterType() throws Exception { + doTest("idea/testData/quickfix/typeMismatch/typeMismatchOnReturnedExpression/beforeReturnedExpressionTypeMismatchFunctionParameterType.kt"); + } + + @TestMetadata("beforeTypeMismatchInIfStatementReturnedByFunction.kt") + public void testTypeMismatchInIfStatementReturnedByFunction() throws Exception { + doTest("idea/testData/quickfix/typeMismatch/typeMismatchOnReturnedExpression/beforeTypeMismatchInIfStatementReturnedByFunction.kt"); + } + + @TestMetadata("beforeTypeMismatchInIfStatementReturnedByLiteral.kt") + public void testTypeMismatchInIfStatementReturnedByLiteral() throws Exception { + doTest("idea/testData/quickfix/typeMismatch/typeMismatchOnReturnedExpression/beforeTypeMismatchInIfStatementReturnedByLiteral.kt"); + } + @TestMetadata("beforeTypeMismatchInInitializer.kt") public void testTypeMismatchInInitializer() throws Exception { doTest("idea/testData/quickfix/typeMismatch/typeMismatchOnReturnedExpression/beforeTypeMismatchInInitializer.kt"); From d3492d8e6f708d861641aeea0b2fce33f67cbc91 Mon Sep 17 00:00:00 2001 From: Wojciech Lopata Date: Thu, 9 May 2013 22:24:15 +0200 Subject: [PATCH 159/249] QuickFix: change property type to match it's initializer type --- .../quickfix/QuickFixFactoryForTypeMismatchError.java | 6 ++++++ .../quickfix/typeMismatch/afterPropertyTypeMismatch.kt | 4 ++++ .../quickfix/typeMismatch/beforePropertyTypeMismatch.kt | 4 ++++ .../jet/plugin/quickfix/QuickFixTestGenerated.java | 5 +++++ 4 files changed, 19 insertions(+) create mode 100644 idea/testData/quickfix/typeMismatch/afterPropertyTypeMismatch.kt create mode 100644 idea/testData/quickfix/typeMismatch/beforePropertyTypeMismatch.kt diff --git a/idea/src/org/jetbrains/jet/plugin/quickfix/QuickFixFactoryForTypeMismatchError.java b/idea/src/org/jetbrains/jet/plugin/quickfix/QuickFixFactoryForTypeMismatchError.java index 1f0ae66d09b..7ba9769d05e 100644 --- a/idea/src/org/jetbrains/jet/plugin/quickfix/QuickFixFactoryForTypeMismatchError.java +++ b/idea/src/org/jetbrains/jet/plugin/quickfix/QuickFixFactoryForTypeMismatchError.java @@ -50,6 +50,12 @@ public class QuickFixFactoryForTypeMismatchError implements JetIntentionActionsF actions.add(new CastExpressionFix(expression, expectedType)); } + // Property initializer type mismatch property type: + JetProperty property = PsiTreeUtil.getParentOfType(expression, JetProperty.class); + if (property != null && QuickFixUtil.canEvaluateTo(property.getInitializer(), expression)) { + actions.add(new ChangeVariableTypeFix(property, expressionType)); + } + // Mismatch in returned expression: JetFunction function = PsiTreeUtil.getParentOfType(expression, JetFunction.class, true); if (function != null && QuickFixUtil.canFunctionReturnExpression(function, expression)) { diff --git a/idea/testData/quickfix/typeMismatch/afterPropertyTypeMismatch.kt b/idea/testData/quickfix/typeMismatch/afterPropertyTypeMismatch.kt new file mode 100644 index 00000000000..4302b75770c --- /dev/null +++ b/idea/testData/quickfix/typeMismatch/afterPropertyTypeMismatch.kt @@ -0,0 +1,4 @@ +// "Change 'f' type to '(Long) -> Unit'" "true" +fun foo() { + var f: (Long) -> Unit = if (true) { (x: Long) -> } else { (x: Long) -> } +} \ No newline at end of file diff --git a/idea/testData/quickfix/typeMismatch/beforePropertyTypeMismatch.kt b/idea/testData/quickfix/typeMismatch/beforePropertyTypeMismatch.kt new file mode 100644 index 00000000000..a1ffc07759c --- /dev/null +++ b/idea/testData/quickfix/typeMismatch/beforePropertyTypeMismatch.kt @@ -0,0 +1,4 @@ +// "Change 'f' type to '(Long) -> Unit'" "true" +fun foo() { + var f: Int = if (true) { (x: Long) -> } else { (x: Long) -> } +} \ No newline at end of file diff --git a/idea/tests/org/jetbrains/jet/plugin/quickfix/QuickFixTestGenerated.java b/idea/tests/org/jetbrains/jet/plugin/quickfix/QuickFixTestGenerated.java index 7dbabee2862..034c2451009 100644 --- a/idea/tests/org/jetbrains/jet/plugin/quickfix/QuickFixTestGenerated.java +++ b/idea/tests/org/jetbrains/jet/plugin/quickfix/QuickFixTestGenerated.java @@ -1286,6 +1286,11 @@ public class QuickFixTestGenerated extends AbstractQuickFixTest { doTest("idea/testData/quickfix/typeMismatch/beforeNoReturnInFunctionWithBlockBody.kt"); } + @TestMetadata("beforePropertyTypeMismatch.kt") + public void testPropertyTypeMismatch() throws Exception { + doTest("idea/testData/quickfix/typeMismatch/beforePropertyTypeMismatch.kt"); + } + @TestMetadata("beforeReturnTypeMismatch.kt") public void testReturnTypeMismatch() throws Exception { doTest("idea/testData/quickfix/typeMismatch/beforeReturnTypeMismatch.kt"); From 76e648ded30e392d39be09065fcb2de6fea3ed66 Mon Sep 17 00:00:00 2001 From: Wojciech Lopata Date: Fri, 10 May 2013 00:42:40 +0200 Subject: [PATCH 160/249] QuickFix: change overloaded operator parameter type or return type --- .../QuickFixFactoryForTypeMismatchError.java | 29 +++++++++++++++++++ .../afterChangeNotFunctionReturnType.kt | 7 +++++ .../afterChangePlusFunctionReturnType.kt | 8 +++++ .../afterChangeTimesFunctionParameterType.kt | 6 ++++ .../beforeChangeNotFunctionReturnType.kt | 7 +++++ .../beforeChangePlusFunctionReturnType.kt | 8 +++++ .../beforeChangeTimesFunctionParameterType.kt | 6 ++++ .../quickfix/QuickFixTestGenerated.java | 26 ++++++++++++++++- 8 files changed, 96 insertions(+), 1 deletion(-) create mode 100644 idea/testData/quickfix/typeMismatch/fixOverloadedOperator/afterChangeNotFunctionReturnType.kt create mode 100644 idea/testData/quickfix/typeMismatch/fixOverloadedOperator/afterChangePlusFunctionReturnType.kt create mode 100644 idea/testData/quickfix/typeMismatch/fixOverloadedOperator/afterChangeTimesFunctionParameterType.kt create mode 100644 idea/testData/quickfix/typeMismatch/fixOverloadedOperator/beforeChangeNotFunctionReturnType.kt create mode 100644 idea/testData/quickfix/typeMismatch/fixOverloadedOperator/beforeChangePlusFunctionReturnType.kt create mode 100644 idea/testData/quickfix/typeMismatch/fixOverloadedOperator/beforeChangeTimesFunctionParameterType.kt diff --git a/idea/src/org/jetbrains/jet/plugin/quickfix/QuickFixFactoryForTypeMismatchError.java b/idea/src/org/jetbrains/jet/plugin/quickfix/QuickFixFactoryForTypeMismatchError.java index 7ba9769d05e..613136a1bd3 100644 --- a/idea/src/org/jetbrains/jet/plugin/quickfix/QuickFixFactoryForTypeMismatchError.java +++ b/idea/src/org/jetbrains/jet/plugin/quickfix/QuickFixFactoryForTypeMismatchError.java @@ -17,13 +17,17 @@ package org.jetbrains.jet.plugin.quickfix; import com.intellij.codeInsight.intention.IntentionAction; +import com.intellij.psi.PsiElement; import com.intellij.psi.util.PsiTreeUtil; import org.jetbrains.annotations.NotNull; +import org.jetbrains.jet.lang.descriptors.CallableDescriptor; import org.jetbrains.jet.lang.diagnostics.Diagnostic; import org.jetbrains.jet.lang.diagnostics.DiagnosticWithParameters2; import org.jetbrains.jet.lang.diagnostics.Errors; import org.jetbrains.jet.lang.psi.*; import org.jetbrains.jet.lang.resolve.BindingContext; +import org.jetbrains.jet.lang.resolve.BindingContextUtils; +import org.jetbrains.jet.lang.resolve.calls.model.ResolvedCall; import org.jetbrains.jet.lang.types.JetType; import org.jetbrains.jet.plugin.project.AnalyzerFacadeWithCache; @@ -62,6 +66,31 @@ public class QuickFixFactoryForTypeMismatchError implements JetIntentionActionsF actions.add(new ChangeFunctionReturnTypeFix(function, expressionType)); } + // Fixing overloaded operators: + if (expression instanceof JetOperationExpression) { + ResolvedCall resolvedCall = + context.get(BindingContext.RESOLVED_CALL, ((JetOperationExpression) expression).getOperationReference()); + if (resolvedCall != null) { + PsiElement declaration = BindingContextUtils.descriptorToDeclaration(context, resolvedCall.getResultingDescriptor()); + if (declaration instanceof JetFunction) { + actions.add(new ChangeFunctionReturnTypeFix((JetFunction) declaration, expectedType)); + } + } + } + if (expression.getParent() instanceof JetBinaryExpression) { + JetBinaryExpression parentBinary = (JetBinaryExpression) expression.getParent(); + if (parentBinary.getRight() == expression) { + ResolvedCall resolvedCall = context.get(BindingContext.RESOLVED_CALL, parentBinary.getOperationReference()); + if (resolvedCall != null) { + PsiElement declaration = BindingContextUtils.descriptorToDeclaration(context, resolvedCall.getResultingDescriptor()); + if (declaration instanceof JetFunction) { + JetParameter binaryOperatorParameter = ((JetFunction) declaration).getValueParameterList().getParameters().get(0); + actions.add(new ChangeFunctionParameterTypeFix(binaryOperatorParameter, expressionType)); + } + } + } + } + // Change type of a function parameter in case TYPE_MISMATCH is reported on expression passed as value argument of call. // 1) When an argument is a dangling function literal: JetFunctionLiteralExpression functionLiteralExpression = diff --git a/idea/testData/quickfix/typeMismatch/fixOverloadedOperator/afterChangeNotFunctionReturnType.kt b/idea/testData/quickfix/typeMismatch/fixOverloadedOperator/afterChangeNotFunctionReturnType.kt new file mode 100644 index 00000000000..2e02e549264 --- /dev/null +++ b/idea/testData/quickfix/typeMismatch/fixOverloadedOperator/afterChangeNotFunctionReturnType.kt @@ -0,0 +1,7 @@ +// "Change 'A.not' function return type to 'A'" "true" +trait A { + fun not(): A + fun times(a: A): A +} + +fun foo(a: A): A = a * !(if (true) a else a) \ No newline at end of file diff --git a/idea/testData/quickfix/typeMismatch/fixOverloadedOperator/afterChangePlusFunctionReturnType.kt b/idea/testData/quickfix/typeMismatch/fixOverloadedOperator/afterChangePlusFunctionReturnType.kt new file mode 100644 index 00000000000..5f841fe38b4 --- /dev/null +++ b/idea/testData/quickfix/typeMismatch/fixOverloadedOperator/afterChangePlusFunctionReturnType.kt @@ -0,0 +1,8 @@ +// "Change 'A.plus' function return type to '() -> Int'" "true" +trait A { + fun plus(a: A): () -> Int +} + +fun foo(a: A): () -> Int { + return a + a +} \ No newline at end of file diff --git a/idea/testData/quickfix/typeMismatch/fixOverloadedOperator/afterChangeTimesFunctionParameterType.kt b/idea/testData/quickfix/typeMismatch/fixOverloadedOperator/afterChangeTimesFunctionParameterType.kt new file mode 100644 index 00000000000..a0178c297d5 --- /dev/null +++ b/idea/testData/quickfix/typeMismatch/fixOverloadedOperator/afterChangeTimesFunctionParameterType.kt @@ -0,0 +1,6 @@ +// "Change parameter 'a' type of function 'A.times' to 'String'" "true" +trait A { + fun times(a: String): A +} + +fun foo(a: A): A = a * "" \ No newline at end of file diff --git a/idea/testData/quickfix/typeMismatch/fixOverloadedOperator/beforeChangeNotFunctionReturnType.kt b/idea/testData/quickfix/typeMismatch/fixOverloadedOperator/beforeChangeNotFunctionReturnType.kt new file mode 100644 index 00000000000..3fcbddff06c --- /dev/null +++ b/idea/testData/quickfix/typeMismatch/fixOverloadedOperator/beforeChangeNotFunctionReturnType.kt @@ -0,0 +1,7 @@ +// "Change 'A.not' function return type to 'A'" "true" +trait A { + fun not(): String + fun times(a: A): A +} + +fun foo(a: A): A = a * !(if (true) a else a) \ No newline at end of file diff --git a/idea/testData/quickfix/typeMismatch/fixOverloadedOperator/beforeChangePlusFunctionReturnType.kt b/idea/testData/quickfix/typeMismatch/fixOverloadedOperator/beforeChangePlusFunctionReturnType.kt new file mode 100644 index 00000000000..c83d83f0c41 --- /dev/null +++ b/idea/testData/quickfix/typeMismatch/fixOverloadedOperator/beforeChangePlusFunctionReturnType.kt @@ -0,0 +1,8 @@ +// "Change 'A.plus' function return type to '() -> Int'" "true" +trait A { + fun plus(a: A): String +} + +fun foo(a: A): () -> Int { + return a + a +} \ No newline at end of file diff --git a/idea/testData/quickfix/typeMismatch/fixOverloadedOperator/beforeChangeTimesFunctionParameterType.kt b/idea/testData/quickfix/typeMismatch/fixOverloadedOperator/beforeChangeTimesFunctionParameterType.kt new file mode 100644 index 00000000000..837fc7af446 --- /dev/null +++ b/idea/testData/quickfix/typeMismatch/fixOverloadedOperator/beforeChangeTimesFunctionParameterType.kt @@ -0,0 +1,6 @@ +// "Change parameter 'a' type of function 'A.times' to 'String'" "true" +trait A { + fun times(a: A): A +} + +fun foo(a: A): A = a * "" \ No newline at end of file diff --git a/idea/tests/org/jetbrains/jet/plugin/quickfix/QuickFixTestGenerated.java b/idea/tests/org/jetbrains/jet/plugin/quickfix/QuickFixTestGenerated.java index 034c2451009..a4eb2f2f42a 100644 --- a/idea/tests/org/jetbrains/jet/plugin/quickfix/QuickFixTestGenerated.java +++ b/idea/tests/org/jetbrains/jet/plugin/quickfix/QuickFixTestGenerated.java @@ -1240,7 +1240,7 @@ public class QuickFixTestGenerated extends AbstractQuickFixTest { } @TestMetadata("idea/testData/quickfix/typeMismatch") - @InnerTestClasses({TypeMismatch.Casts.class, TypeMismatch.ComponentFunctionReturnTypeMismatch.class, TypeMismatch.FunctionParameterTypeMismatch.class, TypeMismatch.TypeMismatchOnReturnedExpression.class}) + @InnerTestClasses({TypeMismatch.Casts.class, TypeMismatch.ComponentFunctionReturnTypeMismatch.class, TypeMismatch.FixOverloadedOperator.class, TypeMismatch.FunctionParameterTypeMismatch.class, TypeMismatch.TypeMismatchOnReturnedExpression.class}) public static class TypeMismatch extends AbstractQuickFixTest { public void testAllFilesPresentInTypeMismatch() throws Exception { JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.GenerateTests", new File("idea/testData/quickfix/typeMismatch"), Pattern.compile("^before(\\w+)\\.kt$"), true); @@ -1382,6 +1382,29 @@ public class QuickFixTestGenerated extends AbstractQuickFixTest { } + @TestMetadata("idea/testData/quickfix/typeMismatch/fixOverloadedOperator") + public static class FixOverloadedOperator extends AbstractQuickFixTest { + public void testAllFilesPresentInFixOverloadedOperator() throws Exception { + JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.GenerateTests", new File("idea/testData/quickfix/typeMismatch/fixOverloadedOperator"), Pattern.compile("^before(\\w+)\\.kt$"), true); + } + + @TestMetadata("beforeChangeNotFunctionReturnType.kt") + public void testChangeNotFunctionReturnType() throws Exception { + doTest("idea/testData/quickfix/typeMismatch/fixOverloadedOperator/beforeChangeNotFunctionReturnType.kt"); + } + + @TestMetadata("beforeChangePlusFunctionReturnType.kt") + public void testChangePlusFunctionReturnType() throws Exception { + doTest("idea/testData/quickfix/typeMismatch/fixOverloadedOperator/beforeChangePlusFunctionReturnType.kt"); + } + + @TestMetadata("beforeChangeTimesFunctionParameterType.kt") + public void testChangeTimesFunctionParameterType() throws Exception { + doTest("idea/testData/quickfix/typeMismatch/fixOverloadedOperator/beforeChangeTimesFunctionParameterType.kt"); + } + + } + @TestMetadata("idea/testData/quickfix/typeMismatch/functionParameterTypeMismatch") public static class FunctionParameterTypeMismatch extends AbstractQuickFixTest { public void testAllFilesPresentInFunctionParameterTypeMismatch() throws Exception { @@ -1488,6 +1511,7 @@ public class QuickFixTestGenerated extends AbstractQuickFixTest { suite.addTestSuite(TypeMismatch.class); suite.addTestSuite(Casts.class); suite.addTestSuite(ComponentFunctionReturnTypeMismatch.class); + suite.addTestSuite(FixOverloadedOperator.class); suite.addTestSuite(FunctionParameterTypeMismatch.class); suite.addTestSuite(TypeMismatchOnReturnedExpression.class); return suite; From 1a5d5159727ec0c6f33331787f8e10582b45681b Mon Sep 17 00:00:00 2001 From: Wojciech Lopata Date: Fri, 10 May 2013 00:57:45 +0200 Subject: [PATCH 161/249] QuickFix: change function return type to match expexted type of call --- .../QuickFixFactoryForTypeMismatchError.java | 12 ++++++++++++ ...ngeFunctionReturnTypeToMatchExpectedTypeOfCall.kt | 3 +++ ...ngeFunctionReturnTypeToMatchExpectedTypeOfCall.kt | 3 +++ .../jet/plugin/quickfix/QuickFixTestGenerated.java | 5 +++++ 4 files changed, 23 insertions(+) create mode 100644 idea/testData/quickfix/typeMismatch/afterChangeFunctionReturnTypeToMatchExpectedTypeOfCall.kt create mode 100644 idea/testData/quickfix/typeMismatch/beforeChangeFunctionReturnTypeToMatchExpectedTypeOfCall.kt diff --git a/idea/src/org/jetbrains/jet/plugin/quickfix/QuickFixFactoryForTypeMismatchError.java b/idea/src/org/jetbrains/jet/plugin/quickfix/QuickFixFactoryForTypeMismatchError.java index 613136a1bd3..70c1c6632b0 100644 --- a/idea/src/org/jetbrains/jet/plugin/quickfix/QuickFixFactoryForTypeMismatchError.java +++ b/idea/src/org/jetbrains/jet/plugin/quickfix/QuickFixFactoryForTypeMismatchError.java @@ -91,6 +91,18 @@ public class QuickFixFactoryForTypeMismatchError implements JetIntentionActionsF } } + // Change function return type when TYPE_MISMATCH is reported on call expression: + if (expression instanceof JetCallExpression) { + ResolvedCall resolvedCall = + context.get(BindingContext.RESOLVED_CALL, ((JetCallExpression) expression).getCalleeExpression()); + if (resolvedCall != null) { + PsiElement declaration = BindingContextUtils.descriptorToDeclaration(context, resolvedCall.getResultingDescriptor()); + if (declaration instanceof JetFunction) { + actions.add(new ChangeFunctionReturnTypeFix((JetFunction) declaration, expectedType)); + } + } + } + // Change type of a function parameter in case TYPE_MISMATCH is reported on expression passed as value argument of call. // 1) When an argument is a dangling function literal: JetFunctionLiteralExpression functionLiteralExpression = diff --git a/idea/testData/quickfix/typeMismatch/afterChangeFunctionReturnTypeToMatchExpectedTypeOfCall.kt b/idea/testData/quickfix/typeMismatch/afterChangeFunctionReturnTypeToMatchExpectedTypeOfCall.kt new file mode 100644 index 00000000000..e043c28dd7b --- /dev/null +++ b/idea/testData/quickfix/typeMismatch/afterChangeFunctionReturnTypeToMatchExpectedTypeOfCall.kt @@ -0,0 +1,3 @@ +// "Change 'bar' function return type to 'String'" "true" +fun bar(): String = "" +fun foo(): String = bar() \ No newline at end of file diff --git a/idea/testData/quickfix/typeMismatch/beforeChangeFunctionReturnTypeToMatchExpectedTypeOfCall.kt b/idea/testData/quickfix/typeMismatch/beforeChangeFunctionReturnTypeToMatchExpectedTypeOfCall.kt new file mode 100644 index 00000000000..dcd7a090c5b --- /dev/null +++ b/idea/testData/quickfix/typeMismatch/beforeChangeFunctionReturnTypeToMatchExpectedTypeOfCall.kt @@ -0,0 +1,3 @@ +// "Change 'bar' function return type to 'String'" "true" +fun bar(): Any = "" +fun foo(): String = bar() \ No newline at end of file diff --git a/idea/tests/org/jetbrains/jet/plugin/quickfix/QuickFixTestGenerated.java b/idea/tests/org/jetbrains/jet/plugin/quickfix/QuickFixTestGenerated.java index a4eb2f2f42a..a7a0898cffe 100644 --- a/idea/tests/org/jetbrains/jet/plugin/quickfix/QuickFixTestGenerated.java +++ b/idea/tests/org/jetbrains/jet/plugin/quickfix/QuickFixTestGenerated.java @@ -1251,6 +1251,11 @@ public class QuickFixTestGenerated extends AbstractQuickFixTest { doTest("idea/testData/quickfix/typeMismatch/beforeChangeFunctionLiteralParameterTypeToFunctionType.kt"); } + @TestMetadata("beforeChangeFunctionReturnTypeToMatchExpectedTypeOfCall.kt") + public void testChangeFunctionReturnTypeToMatchExpectedTypeOfCall() throws Exception { + doTest("idea/testData/quickfix/typeMismatch/beforeChangeFunctionReturnTypeToMatchExpectedTypeOfCall.kt"); + } + @TestMetadata("beforeChangeReturnTypeWhenFunctionNameIsMissing.kt") public void testChangeReturnTypeWhenFunctionNameIsMissing() throws Exception { doTest("idea/testData/quickfix/typeMismatch/beforeChangeReturnTypeWhenFunctionNameIsMissing.kt"); From 0d65a1b7895ed6bdc68f47cf4f6e5c90de251bc2 Mon Sep 17 00:00:00 2001 From: Wojciech Lopata Date: Wed, 15 May 2013 20:25:34 +0200 Subject: [PATCH 162/249] Better text for ChangeVariableTypeFix --- .../jet/plugin/quickfix/ChangeVariableTypeFix.java | 7 ++++++- .../afterChangeOverridingPropertyTypeToFunctionType.kt | 2 +- .../afterPropertyReturnTypeMismatchOnOverride.kt | 2 +- .../afterPropertyTypeMismatchOnOverrideIntLong.kt | 2 +- .../afterPropertyTypeMismatchOnOverrideIntUnit.kt | 2 +- .../beforeChangeOverridingPropertyTypeToFunctionType.kt | 2 +- .../beforePropertyReturnTypeMismatchOnOverride.kt | 2 +- .../beforePropertyTypeMismatchOnOverrideIntLong.kt | 2 +- .../beforePropertyTypeMismatchOnOverrideIntUnit.kt | 2 +- 9 files changed, 14 insertions(+), 9 deletions(-) diff --git a/idea/src/org/jetbrains/jet/plugin/quickfix/ChangeVariableTypeFix.java b/idea/src/org/jetbrains/jet/plugin/quickfix/ChangeVariableTypeFix.java index c70d024f7a6..4df5e245e88 100644 --- a/idea/src/org/jetbrains/jet/plugin/quickfix/ChangeVariableTypeFix.java +++ b/idea/src/org/jetbrains/jet/plugin/quickfix/ChangeVariableTypeFix.java @@ -30,6 +30,7 @@ import org.jetbrains.jet.lang.psi.*; import org.jetbrains.jet.lang.resolve.BindingContext; import org.jetbrains.jet.lang.resolve.BindingContextUtils; import org.jetbrains.jet.lang.resolve.calls.model.ResolvedCall; +import org.jetbrains.jet.lang.resolve.name.FqName; import org.jetbrains.jet.lang.types.JetType; import org.jetbrains.jet.plugin.JetBundle; import org.jetbrains.jet.plugin.caches.resolve.KotlinCacheManagerUtil; @@ -48,7 +49,11 @@ public class ChangeVariableTypeFix extends JetIntentionAction Int'" "true" +// "Change 'B.x' type to '(String) -> Int'" "true" trait A { var x: (String) -> Int } diff --git a/idea/testData/quickfix/override/typeMismatchOnOverride/afterPropertyReturnTypeMismatchOnOverride.kt b/idea/testData/quickfix/override/typeMismatchOnOverride/afterPropertyReturnTypeMismatchOnOverride.kt index 9dbb3cbe563..0f79cd40f9d 100644 --- a/idea/testData/quickfix/override/typeMismatchOnOverride/afterPropertyReturnTypeMismatchOnOverride.kt +++ b/idea/testData/quickfix/override/typeMismatchOnOverride/afterPropertyReturnTypeMismatchOnOverride.kt @@ -1,4 +1,4 @@ -// "Change 'x' type to 'Int'" "true" +// "Change 'A.x' type to 'Int'" "true" trait X { val x: Int } diff --git a/idea/testData/quickfix/override/typeMismatchOnOverride/afterPropertyTypeMismatchOnOverrideIntLong.kt b/idea/testData/quickfix/override/typeMismatchOnOverride/afterPropertyTypeMismatchOnOverrideIntLong.kt index e810c22a1ee..80d3b2e6a05 100644 --- a/idea/testData/quickfix/override/typeMismatchOnOverride/afterPropertyTypeMismatchOnOverrideIntLong.kt +++ b/idea/testData/quickfix/override/typeMismatchOnOverride/afterPropertyTypeMismatchOnOverrideIntLong.kt @@ -1,4 +1,4 @@ -// "Change 'x' type to 'Int'" "true" +// "Change 'B.x' type to 'Int'" "true" abstract class A { abstract var x : Int } diff --git a/idea/testData/quickfix/override/typeMismatchOnOverride/afterPropertyTypeMismatchOnOverrideIntUnit.kt b/idea/testData/quickfix/override/typeMismatchOnOverride/afterPropertyTypeMismatchOnOverrideIntUnit.kt index 8296b837504..f37ab4f9ff0 100644 --- a/idea/testData/quickfix/override/typeMismatchOnOverride/afterPropertyTypeMismatchOnOverrideIntUnit.kt +++ b/idea/testData/quickfix/override/typeMismatchOnOverride/afterPropertyTypeMismatchOnOverrideIntUnit.kt @@ -1,4 +1,4 @@ -// "Change 'x' type to 'Int'" "true" +// "Change 'B.x' type to 'Int'" "true" abstract class A { abstract var x : Int } diff --git a/idea/testData/quickfix/override/typeMismatchOnOverride/beforeChangeOverridingPropertyTypeToFunctionType.kt b/idea/testData/quickfix/override/typeMismatchOnOverride/beforeChangeOverridingPropertyTypeToFunctionType.kt index 86cf8bd43da..6a6b1155d01 100644 --- a/idea/testData/quickfix/override/typeMismatchOnOverride/beforeChangeOverridingPropertyTypeToFunctionType.kt +++ b/idea/testData/quickfix/override/typeMismatchOnOverride/beforeChangeOverridingPropertyTypeToFunctionType.kt @@ -1,4 +1,4 @@ -// "Change 'x' type to '(String) -> Int'" "true" +// "Change 'B.x' type to '(String) -> Int'" "true" trait A { var x: (String) -> Int } diff --git a/idea/testData/quickfix/override/typeMismatchOnOverride/beforePropertyReturnTypeMismatchOnOverride.kt b/idea/testData/quickfix/override/typeMismatchOnOverride/beforePropertyReturnTypeMismatchOnOverride.kt index afd321e5cfa..4378d809f4a 100644 --- a/idea/testData/quickfix/override/typeMismatchOnOverride/beforePropertyReturnTypeMismatchOnOverride.kt +++ b/idea/testData/quickfix/override/typeMismatchOnOverride/beforePropertyReturnTypeMismatchOnOverride.kt @@ -1,4 +1,4 @@ -// "Change 'x' type to 'Int'" "true" +// "Change 'A.x' type to 'Int'" "true" trait X { val x: Int } diff --git a/idea/testData/quickfix/override/typeMismatchOnOverride/beforePropertyTypeMismatchOnOverrideIntLong.kt b/idea/testData/quickfix/override/typeMismatchOnOverride/beforePropertyTypeMismatchOnOverrideIntLong.kt index db0eabb5856..a70d8d74a05 100644 --- a/idea/testData/quickfix/override/typeMismatchOnOverride/beforePropertyTypeMismatchOnOverrideIntLong.kt +++ b/idea/testData/quickfix/override/typeMismatchOnOverride/beforePropertyTypeMismatchOnOverrideIntLong.kt @@ -1,4 +1,4 @@ -// "Change 'x' type to 'Int'" "true" +// "Change 'B.x' type to 'Int'" "true" abstract class A { abstract var x : Int } diff --git a/idea/testData/quickfix/override/typeMismatchOnOverride/beforePropertyTypeMismatchOnOverrideIntUnit.kt b/idea/testData/quickfix/override/typeMismatchOnOverride/beforePropertyTypeMismatchOnOverrideIntUnit.kt index 39289180da2..469a62099b0 100644 --- a/idea/testData/quickfix/override/typeMismatchOnOverride/beforePropertyTypeMismatchOnOverrideIntUnit.kt +++ b/idea/testData/quickfix/override/typeMismatchOnOverride/beforePropertyTypeMismatchOnOverrideIntUnit.kt @@ -1,4 +1,4 @@ -// "Change 'x' type to 'Int'" "true" +// "Change 'B.x' type to 'Int'" "true" abstract class A { abstract var x : Int } From 9fdbd01660c21f21091c53cdf2a3eca2565bd4e4 Mon Sep 17 00:00:00 2001 From: Wojciech Lopata Date: Wed, 15 May 2013 21:16:41 +0200 Subject: [PATCH 163/249] QuickFix: change type of overridden property to type of overridding property --- .../quickfix/ChangeVariableTypeFix.java | 48 +++++++++++++++---- .../jet/plugin/quickfix/QuickFixes.java | 2 +- .../afterChangeOverriddenPropertyType.kt | 12 +++++ ...ChangeMultipleOverriddenPropertiesTypes.kt | 14 ++++++ .../beforeChangeOverriddenPropertyType.kt | 12 +++++ .../quickfix/QuickFixTestGenerated.java | 10 ++++ 6 files changed, 89 insertions(+), 9 deletions(-) create mode 100644 idea/testData/quickfix/override/typeMismatchOnOverride/afterChangeOverriddenPropertyType.kt create mode 100644 idea/testData/quickfix/override/typeMismatchOnOverride/beforeCantChangeMultipleOverriddenPropertiesTypes.kt create mode 100644 idea/testData/quickfix/override/typeMismatchOnOverride/beforeChangeOverriddenPropertyType.kt diff --git a/idea/src/org/jetbrains/jet/plugin/quickfix/ChangeVariableTypeFix.java b/idea/src/org/jetbrains/jet/plugin/quickfix/ChangeVariableTypeFix.java index 4df5e245e88..e30cd47a574 100644 --- a/idea/src/org/jetbrains/jet/plugin/quickfix/ChangeVariableTypeFix.java +++ b/idea/src/org/jetbrains/jet/plugin/quickfix/ChangeVariableTypeFix.java @@ -25,6 +25,7 @@ import com.intellij.util.IncorrectOperationException; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.jet.lang.descriptors.FunctionDescriptor; +import org.jetbrains.jet.lang.descriptors.PropertyDescriptor; import org.jetbrains.jet.lang.diagnostics.Diagnostic; import org.jetbrains.jet.lang.psi.*; import org.jetbrains.jet.lang.resolve.BindingContext; @@ -32,12 +33,16 @@ import org.jetbrains.jet.lang.resolve.BindingContextUtils; import org.jetbrains.jet.lang.resolve.calls.model.ResolvedCall; import org.jetbrains.jet.lang.resolve.name.FqName; import org.jetbrains.jet.lang.types.JetType; +import org.jetbrains.jet.lang.types.checker.JetTypeChecker; import org.jetbrains.jet.plugin.JetBundle; import org.jetbrains.jet.plugin.caches.resolve.KotlinCacheManagerUtil; import org.jetbrains.jet.plugin.intentions.SpecifyTypeExplicitlyAction; import org.jetbrains.jet.plugin.project.AnalyzerFacadeWithCache; import org.jetbrains.jet.renderer.DescriptorRenderer; +import java.util.LinkedList; +import java.util.List; + public class ChangeVariableTypeFix extends JetIntentionAction { private final String renderedType; @@ -90,16 +95,43 @@ public class ChangeVariableTypeFix extends JetIntentionAction createActions(Diagnostic diagnostic) { + List actions = new LinkedList(); + JetProperty property = QuickFixUtil.getParentElementOfType(diagnostic, JetProperty.class); - if (property == null) return null; - BindingContext context = KotlinCacheManagerUtil.getDeclarationsBindingContext(property); - JetType type = QuickFixUtil.findLowerBoundOfOverriddenCallablesReturnTypes(context, property); - return type == null ? null : new ChangeVariableTypeFix(property, type); + if (property != null) { + BindingContext context = KotlinCacheManagerUtil.getDeclarationsBindingContext(property); + JetType lowerBoundOfOverriddenPropertiesTypes = QuickFixUtil.findLowerBoundOfOverriddenCallablesReturnTypes(context, property); + if (lowerBoundOfOverriddenPropertiesTypes != null) { + actions.add(new ChangeVariableTypeFix(property, lowerBoundOfOverriddenPropertiesTypes)); + } + + PropertyDescriptor descriptor = (PropertyDescriptor) context.get(BindingContext.DECLARATION_TO_DESCRIPTOR, property); + assert descriptor != null : "Descriptor of property not available in binding context"; + JetType propertyType = descriptor.getReturnType(); + assert propertyType != null : "Property type cannot be null if it mismatch something"; + + List overriddenMismatchingProperties = new LinkedList(); + for (PropertyDescriptor overriddenProperty: descriptor.getOverriddenDescriptors()) { + JetType overriddenPropertyType = overriddenProperty.getReturnType(); + if (overriddenPropertyType != null && !JetTypeChecker.INSTANCE.isSubtypeOf(propertyType, overriddenPropertyType)) { + overriddenMismatchingProperties.add(overriddenProperty); + } + } + + if (overriddenMismatchingProperties.size() == 1) { + JetProperty overriddenProperty = + (JetProperty) BindingContextUtils.descriptorToDeclaration(context, overriddenMismatchingProperties.get(0)); + if (overriddenProperty != null) { + actions.add(new ChangeVariableTypeFix(overriddenProperty, propertyType)); + } + } + } + return actions; } }; } diff --git a/idea/src/org/jetbrains/jet/plugin/quickfix/QuickFixes.java b/idea/src/org/jetbrains/jet/plugin/quickfix/QuickFixes.java index ad2eb561f5a..63f87c80c17 100644 --- a/idea/src/org/jetbrains/jet/plugin/quickfix/QuickFixes.java +++ b/idea/src/org/jetbrains/jet/plugin/quickfix/QuickFixes.java @@ -214,7 +214,7 @@ public class QuickFixes { factories.put(DANGLING_FUNCTION_LITERAL_ARGUMENT_SUSPECTED, AddSemicolonAfterFunctionCallFix.createFactory()); - JetSingleIntentionActionFactory changeVariableTypeFix = ChangeVariableTypeFix.createFactoryForPropertyOrReturnTypeMismatchOnOverride(); + JetIntentionActionsFactory changeVariableTypeFix = ChangeVariableTypeFix.createFactoryForPropertyOrReturnTypeMismatchOnOverride(); factories.put(RETURN_TYPE_MISMATCH_ON_OVERRIDE, changeVariableTypeFix); factories.put(PROPERTY_TYPE_MISMATCH_ON_OVERRIDE, changeVariableTypeFix); factories.put(COMPONENT_FUNCTION_RETURN_TYPE_MISMATCH, ChangeVariableTypeFix.createFactoryForComponentFunctionReturnTypeMismatch()); diff --git a/idea/testData/quickfix/override/typeMismatchOnOverride/afterChangeOverriddenPropertyType.kt b/idea/testData/quickfix/override/typeMismatchOnOverride/afterChangeOverriddenPropertyType.kt new file mode 100644 index 00000000000..6a3586ed492 --- /dev/null +++ b/idea/testData/quickfix/override/typeMismatchOnOverride/afterChangeOverriddenPropertyType.kt @@ -0,0 +1,12 @@ +// "Change 'B.x' type to '(Int) -> Int'" "true" +trait A { + val x: (Int) -> Int +} + +trait B { + val x: (Int) -> Int +} + +trait C : A, B { + override val x: (Int) -> Int +} \ No newline at end of file diff --git a/idea/testData/quickfix/override/typeMismatchOnOverride/beforeCantChangeMultipleOverriddenPropertiesTypes.kt b/idea/testData/quickfix/override/typeMismatchOnOverride/beforeCantChangeMultipleOverriddenPropertiesTypes.kt new file mode 100644 index 00000000000..9fe0b5a6264 --- /dev/null +++ b/idea/testData/quickfix/override/typeMismatchOnOverride/beforeCantChangeMultipleOverriddenPropertiesTypes.kt @@ -0,0 +1,14 @@ +// "Change 'A.x' type to '(Int) -> Int'" "false" +// ACTION: Change 'C.x' type to '(String) -> Int' +// ERROR: Return type is '(jet.Int) → jet.Int', which is not a subtype of overridden
internal abstract val x: (jet.String) → jet.Int defined in A +trait A { + val x: (String) -> Int +} + +trait B { + val x: (String) -> Any +} + +trait C : A, B { + override val x: (Int) -> Int +} \ No newline at end of file diff --git a/idea/testData/quickfix/override/typeMismatchOnOverride/beforeChangeOverriddenPropertyType.kt b/idea/testData/quickfix/override/typeMismatchOnOverride/beforeChangeOverriddenPropertyType.kt new file mode 100644 index 00000000000..9216f429193 --- /dev/null +++ b/idea/testData/quickfix/override/typeMismatchOnOverride/beforeChangeOverriddenPropertyType.kt @@ -0,0 +1,12 @@ +// "Change 'B.x' type to '(Int) -> Int'" "true" +trait A { + val x: (Int) -> Int +} + +trait B { + val x: (String) -> Any +} + +trait C : A, B { + override val x: (Int) -> Int +} \ No newline at end of file diff --git a/idea/tests/org/jetbrains/jet/plugin/quickfix/QuickFixTestGenerated.java b/idea/tests/org/jetbrains/jet/plugin/quickfix/QuickFixTestGenerated.java index a7a0898cffe..19755e455eb 100644 --- a/idea/tests/org/jetbrains/jet/plugin/quickfix/QuickFixTestGenerated.java +++ b/idea/tests/org/jetbrains/jet/plugin/quickfix/QuickFixTestGenerated.java @@ -1018,6 +1018,16 @@ public class QuickFixTestGenerated extends AbstractQuickFixTest { JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.GenerateTests", new File("idea/testData/quickfix/override/typeMismatchOnOverride"), Pattern.compile("^before(\\w+)\\.kt$"), true); } + @TestMetadata("beforeCantChangeMultipleOverriddenPropertiesTypes.kt") + public void testCantChangeMultipleOverriddenPropertiesTypes() throws Exception { + doTest("idea/testData/quickfix/override/typeMismatchOnOverride/beforeCantChangeMultipleOverriddenPropertiesTypes.kt"); + } + + @TestMetadata("beforeChangeOverriddenPropertyType.kt") + public void testChangeOverriddenPropertyType() throws Exception { + doTest("idea/testData/quickfix/override/typeMismatchOnOverride/beforeChangeOverriddenPropertyType.kt"); + } + @TestMetadata("beforeChangeOverridingPropertyTypeToFunctionType.kt") public void testChangeOverridingPropertyTypeToFunctionType() throws Exception { doTest("idea/testData/quickfix/override/typeMismatchOnOverride/beforeChangeOverridingPropertyTypeToFunctionType.kt"); From e08d9ee8da49df82f6f6e5d3f92700745a1a8363 Mon Sep 17 00:00:00 2001 From: Wojciech Lopata Date: Wed, 15 May 2013 21:43:37 +0200 Subject: [PATCH 164/249] Fix quickFix for PROPERTY_TYPE_MISMATCH_ON_OVERRIDE --- .../quickfix/ChangeVariableTypeFix.java | 30 ++++++++++++------- ... => afterChangeOverriddenPropertyType1.kt} | 0 .../afterChangeOverriddenPropertyType2.kt | 12 ++++++++ ...enPropertyTypeToMatchOverridingProperty.kt | 13 ++++++++ ...ePropertyTypeToMatchOverridenProperties.kt | 13 ++++++++ ...=> beforeChangeOverriddenPropertyType1.kt} | 0 .../beforeChangeOverriddenPropertyType2.kt | 12 ++++++++ .../quickfix/QuickFixTestGenerated.java | 21 +++++++++++-- 8 files changed, 88 insertions(+), 13 deletions(-) rename idea/testData/quickfix/override/typeMismatchOnOverride/{afterChangeOverriddenPropertyType.kt => afterChangeOverriddenPropertyType1.kt} (100%) create mode 100644 idea/testData/quickfix/override/typeMismatchOnOverride/afterChangeOverriddenPropertyType2.kt create mode 100644 idea/testData/quickfix/override/typeMismatchOnOverride/beforeCantChangeOverriddenPropertyTypeToMatchOverridingProperty.kt create mode 100644 idea/testData/quickfix/override/typeMismatchOnOverride/beforeCantChangePropertyTypeToMatchOverridenProperties.kt rename idea/testData/quickfix/override/typeMismatchOnOverride/{beforeChangeOverriddenPropertyType.kt => beforeChangeOverriddenPropertyType1.kt} (100%) create mode 100644 idea/testData/quickfix/override/typeMismatchOnOverride/beforeChangeOverriddenPropertyType2.kt diff --git a/idea/src/org/jetbrains/jet/plugin/quickfix/ChangeVariableTypeFix.java b/idea/src/org/jetbrains/jet/plugin/quickfix/ChangeVariableTypeFix.java index e30cd47a574..9d9f5cdfd9f 100644 --- a/idea/src/org/jetbrains/jet/plugin/quickfix/ChangeVariableTypeFix.java +++ b/idea/src/org/jetbrains/jet/plugin/quickfix/ChangeVariableTypeFix.java @@ -106,9 +106,6 @@ public class ChangeVariableTypeFix extends JetIntentionAction overriddenMismatchingProperties = new LinkedList(); + boolean canChangeOverriddenPropertyType = true; for (PropertyDescriptor overriddenProperty: descriptor.getOverriddenDescriptors()) { JetType overriddenPropertyType = overriddenProperty.getReturnType(); - if (overriddenPropertyType != null && !JetTypeChecker.INSTANCE.isSubtypeOf(propertyType, overriddenPropertyType)) { - overriddenMismatchingProperties.add(overriddenProperty); + if (overriddenPropertyType != null) { + if (!JetTypeChecker.INSTANCE.isSubtypeOf(propertyType, overriddenPropertyType)) { + overriddenMismatchingProperties.add(overriddenProperty); + } + else if (overriddenProperty.isVar() && !JetTypeChecker.INSTANCE.equalTypes(overriddenPropertyType, propertyType)) { + canChangeOverriddenPropertyType = false; + } + if (overriddenProperty.isVar() && lowerBoundOfOverriddenPropertiesTypes != null && + !JetTypeChecker.INSTANCE.equalTypes(lowerBoundOfOverriddenPropertiesTypes, overriddenPropertyType)) { + lowerBoundOfOverriddenPropertiesTypes = null; + } } } - if (overriddenMismatchingProperties.size() == 1) { - JetProperty overriddenProperty = - (JetProperty) BindingContextUtils.descriptorToDeclaration(context, overriddenMismatchingProperties.get(0)); - if (overriddenProperty != null) { - actions.add(new ChangeVariableTypeFix(overriddenProperty, propertyType)); + if (lowerBoundOfOverriddenPropertiesTypes != null) { + actions.add(new ChangeVariableTypeFix(property, lowerBoundOfOverriddenPropertiesTypes)); + } + + if (overriddenMismatchingProperties.size() == 1 && canChangeOverriddenPropertyType) { + PsiElement overriddenProperty = BindingContextUtils.descriptorToDeclaration(context, overriddenMismatchingProperties.get(0)); + if (overriddenProperty instanceof JetProperty) { + actions.add(new ChangeVariableTypeFix((JetProperty) overriddenProperty, propertyType)); } } } diff --git a/idea/testData/quickfix/override/typeMismatchOnOverride/afterChangeOverriddenPropertyType.kt b/idea/testData/quickfix/override/typeMismatchOnOverride/afterChangeOverriddenPropertyType1.kt similarity index 100% rename from idea/testData/quickfix/override/typeMismatchOnOverride/afterChangeOverriddenPropertyType.kt rename to idea/testData/quickfix/override/typeMismatchOnOverride/afterChangeOverriddenPropertyType1.kt diff --git a/idea/testData/quickfix/override/typeMismatchOnOverride/afterChangeOverriddenPropertyType2.kt b/idea/testData/quickfix/override/typeMismatchOnOverride/afterChangeOverriddenPropertyType2.kt new file mode 100644 index 00000000000..fd1e09a06ce --- /dev/null +++ b/idea/testData/quickfix/override/typeMismatchOnOverride/afterChangeOverriddenPropertyType2.kt @@ -0,0 +1,12 @@ +// "Change 'A.x' type to 'String'" "true" +trait A { + var x: String +} + +trait B { + var x: String +} + +trait C : A, B { + override var x: String +} \ No newline at end of file diff --git a/idea/testData/quickfix/override/typeMismatchOnOverride/beforeCantChangeOverriddenPropertyTypeToMatchOverridingProperty.kt b/idea/testData/quickfix/override/typeMismatchOnOverride/beforeCantChangeOverriddenPropertyTypeToMatchOverridingProperty.kt new file mode 100644 index 00000000000..1a7149f1ca8 --- /dev/null +++ b/idea/testData/quickfix/override/typeMismatchOnOverride/beforeCantChangeOverriddenPropertyTypeToMatchOverridingProperty.kt @@ -0,0 +1,13 @@ +// "Change 'A.x' type to 'String'" "false" +// ERROR: Var-property type is 'jet.String', which is not a type of overridden
internal abstract var x: jet.Int defined in A +trait A { + var x: Int +} + +trait B { + var x: Any +} + +trait C : A, B { + override var x: String +} \ No newline at end of file diff --git a/idea/testData/quickfix/override/typeMismatchOnOverride/beforeCantChangePropertyTypeToMatchOverridenProperties.kt b/idea/testData/quickfix/override/typeMismatchOnOverride/beforeCantChangePropertyTypeToMatchOverridenProperties.kt new file mode 100644 index 00000000000..c47babf6e69 --- /dev/null +++ b/idea/testData/quickfix/override/typeMismatchOnOverride/beforeCantChangePropertyTypeToMatchOverridenProperties.kt @@ -0,0 +1,13 @@ +// "Change 'C.x' type to 'String'" "false" +// ERROR: Var-property type is 'jet.Int', which is not a type of overridden
internal abstract var x: jet.String defined in A +trait A { + var x: String +} + +trait B { + var x: Any +} + +trait C : A, B { + override var x: Int +} \ No newline at end of file diff --git a/idea/testData/quickfix/override/typeMismatchOnOverride/beforeChangeOverriddenPropertyType.kt b/idea/testData/quickfix/override/typeMismatchOnOverride/beforeChangeOverriddenPropertyType1.kt similarity index 100% rename from idea/testData/quickfix/override/typeMismatchOnOverride/beforeChangeOverriddenPropertyType.kt rename to idea/testData/quickfix/override/typeMismatchOnOverride/beforeChangeOverriddenPropertyType1.kt diff --git a/idea/testData/quickfix/override/typeMismatchOnOverride/beforeChangeOverriddenPropertyType2.kt b/idea/testData/quickfix/override/typeMismatchOnOverride/beforeChangeOverriddenPropertyType2.kt new file mode 100644 index 00000000000..df144be7ce6 --- /dev/null +++ b/idea/testData/quickfix/override/typeMismatchOnOverride/beforeChangeOverriddenPropertyType2.kt @@ -0,0 +1,12 @@ +// "Change 'A.x' type to 'String'" "true" +trait A { + var x: Int +} + +trait B { + var x: String +} + +trait C : A, B { + override var x: String +} \ No newline at end of file diff --git a/idea/tests/org/jetbrains/jet/plugin/quickfix/QuickFixTestGenerated.java b/idea/tests/org/jetbrains/jet/plugin/quickfix/QuickFixTestGenerated.java index 19755e455eb..9b22cc5d85a 100644 --- a/idea/tests/org/jetbrains/jet/plugin/quickfix/QuickFixTestGenerated.java +++ b/idea/tests/org/jetbrains/jet/plugin/quickfix/QuickFixTestGenerated.java @@ -1023,9 +1023,24 @@ public class QuickFixTestGenerated extends AbstractQuickFixTest { doTest("idea/testData/quickfix/override/typeMismatchOnOverride/beforeCantChangeMultipleOverriddenPropertiesTypes.kt"); } - @TestMetadata("beforeChangeOverriddenPropertyType.kt") - public void testChangeOverriddenPropertyType() throws Exception { - doTest("idea/testData/quickfix/override/typeMismatchOnOverride/beforeChangeOverriddenPropertyType.kt"); + @TestMetadata("beforeCantChangeOverriddenPropertyTypeToMatchOverridingProperty.kt") + public void testCantChangeOverriddenPropertyTypeToMatchOverridingProperty() throws Exception { + doTest("idea/testData/quickfix/override/typeMismatchOnOverride/beforeCantChangeOverriddenPropertyTypeToMatchOverridingProperty.kt"); + } + + @TestMetadata("beforeCantChangePropertyTypeToMatchOverridenProperties.kt") + public void testCantChangePropertyTypeToMatchOverridenProperties() throws Exception { + doTest("idea/testData/quickfix/override/typeMismatchOnOverride/beforeCantChangePropertyTypeToMatchOverridenProperties.kt"); + } + + @TestMetadata("beforeChangeOverriddenPropertyType1.kt") + public void testChangeOverriddenPropertyType1() throws Exception { + doTest("idea/testData/quickfix/override/typeMismatchOnOverride/beforeChangeOverriddenPropertyType1.kt"); + } + + @TestMetadata("beforeChangeOverriddenPropertyType2.kt") + public void testChangeOverriddenPropertyType2() throws Exception { + doTest("idea/testData/quickfix/override/typeMismatchOnOverride/beforeChangeOverriddenPropertyType2.kt"); } @TestMetadata("beforeChangeOverridingPropertyTypeToFunctionType.kt") From 16d9abf5466979d7f0a5c5824ac560e80e95e2c0 Mon Sep 17 00:00:00 2001 From: Wojciech Lopata Date: Wed, 15 May 2013 23:02:36 +0200 Subject: [PATCH 165/249] QuickFix: change type of overridden function to type of overridding function --- .../quickfix/ChangeFunctionReturnTypeFix.java | 51 +++++++++++++++---- ...terChangeReturnTypeOfOverriddenFunction.kt | 12 +++++ ...antChangeReturnTypeOfOverriddenFunction.kt | 13 +++++ ...oreChangeReturnTypeOfOverriddenFunction.kt | 12 +++++ .../quickfix/QuickFixTestGenerated.java | 10 ++++ 5 files changed, 89 insertions(+), 9 deletions(-) create mode 100644 idea/testData/quickfix/override/typeMismatchOnOverride/afterChangeReturnTypeOfOverriddenFunction.kt create mode 100644 idea/testData/quickfix/override/typeMismatchOnOverride/beforeCantChangeReturnTypeOfOverriddenFunction.kt create mode 100644 idea/testData/quickfix/override/typeMismatchOnOverride/beforeChangeReturnTypeOfOverriddenFunction.kt diff --git a/idea/src/org/jetbrains/jet/plugin/quickfix/ChangeFunctionReturnTypeFix.java b/idea/src/org/jetbrains/jet/plugin/quickfix/ChangeFunctionReturnTypeFix.java index b9483a3e818..c9a974790aa 100644 --- a/idea/src/org/jetbrains/jet/plugin/quickfix/ChangeFunctionReturnTypeFix.java +++ b/idea/src/org/jetbrains/jet/plugin/quickfix/ChangeFunctionReturnTypeFix.java @@ -28,6 +28,7 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.jet.lang.descriptors.CallableDescriptor; import org.jetbrains.jet.lang.descriptors.FunctionDescriptor; +import org.jetbrains.jet.lang.descriptors.SimpleFunctionDescriptor; import org.jetbrains.jet.lang.diagnostics.Diagnostic; import org.jetbrains.jet.lang.diagnostics.DiagnosticWithParameters3; import org.jetbrains.jet.lang.psi.*; @@ -38,6 +39,7 @@ import org.jetbrains.jet.lang.resolve.calls.model.ResolvedCall; import org.jetbrains.jet.lang.resolve.name.FqName; import org.jetbrains.jet.lang.resolve.name.Name; import org.jetbrains.jet.lang.types.JetType; +import org.jetbrains.jet.lang.types.checker.JetTypeChecker; import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns; import org.jetbrains.jet.plugin.JetBundle; import org.jetbrains.jet.plugin.caches.resolve.KotlinCacheManagerUtil; @@ -45,6 +47,9 @@ import org.jetbrains.jet.plugin.intentions.SpecifyTypeExplicitlyAction; import org.jetbrains.jet.plugin.project.AnalyzerFacadeWithCache; import org.jetbrains.jet.renderer.DescriptorRenderer; +import java.util.LinkedList; +import java.util.List; + public class ChangeFunctionReturnTypeFix extends JetIntentionAction { private final JetType type; private final String renderedType; @@ -175,7 +180,8 @@ public class ChangeFunctionReturnTypeFix extends JetIntentionAction JetBinaryExpression expression = QuickFixUtil.getParentElementOfType(diagnostic, JetBinaryExpression.class); assert expression != null : "COMPARE_TO_TYPE_MISMATCH reported on element that is not within any expression"; BindingContext context = AnalyzerFacadeWithCache.analyzeFileWithCache((JetFile) expression.getContainingFile()).getBindingContext(); - ResolvedCall resolvedCall = context.get(BindingContext.RESOLVED_CALL, expression.getOperationReference()); + ResolvedCall resolvedCall = context.get(BindingContext.RESOLVED_CALL, + expression.getOperationReference()); if (resolvedCall == null) return null; PsiElement compareTo = BindingContextUtils.descriptorToDeclaration(context, resolvedCall.getCandidateDescriptor()); if (!(compareTo instanceof JetFunction)) return null; @@ -185,16 +191,43 @@ public class ChangeFunctionReturnTypeFix extends JetIntentionAction } @NotNull - public static JetSingleIntentionActionFactory createFactoryForReturnTypeMismatchOnOverride() { - return new JetSingleIntentionActionFactory() { - @Nullable + public static JetIntentionActionsFactory createFactoryForReturnTypeMismatchOnOverride() { + return new JetIntentionActionsFactory() { + @NotNull @Override - public IntentionAction createAction(Diagnostic diagnostic) { + public List createActions(Diagnostic diagnostic) { + List actions = new LinkedList(); + JetFunction function = QuickFixUtil.getParentElementOfType(diagnostic, JetFunction.class); - if (function == null) return null; - BindingContext context = KotlinCacheManagerUtil.getDeclarationsBindingContext(function); - JetType matchingReturnType = QuickFixUtil.findLowerBoundOfOverriddenCallablesReturnTypes(context, function); - return matchingReturnType == null ? null : new ChangeFunctionReturnTypeFix(function, matchingReturnType); + if (function != null) { + BindingContext context = KotlinCacheManagerUtil.getDeclarationsBindingContext(function); + JetType matchingReturnType = QuickFixUtil.findLowerBoundOfOverriddenCallablesReturnTypes(context, function); + if (matchingReturnType != null) { + actions.add(new ChangeFunctionReturnTypeFix(function, matchingReturnType)); + } + + SimpleFunctionDescriptor descriptor = context.get(BindingContext.FUNCTION, function); + if (descriptor == null) return actions; + JetType functionType = descriptor.getReturnType(); + if (functionType == null) return actions; + + List overriddenMismatchingFunctions = new LinkedList(); + for (FunctionDescriptor overriddenFunction: descriptor.getOverriddenDescriptors()) { + JetType overriddenFunctionType = overriddenFunction.getReturnType(); + if (overriddenFunctionType == null) continue; + if (!JetTypeChecker.INSTANCE.isSubtypeOf(functionType, overriddenFunctionType)) { + overriddenMismatchingFunctions.add(overriddenFunction); + } + } + + if (overriddenMismatchingFunctions.size() == 1) { + PsiElement overriddenFunction = BindingContextUtils.descriptorToDeclaration(context, overriddenMismatchingFunctions.get(0)); + if (overriddenFunction instanceof JetFunction) { + actions.add(new ChangeFunctionReturnTypeFix((JetFunction) overriddenFunction, functionType)); + } + } + } + return actions; } }; } diff --git a/idea/testData/quickfix/override/typeMismatchOnOverride/afterChangeReturnTypeOfOverriddenFunction.kt b/idea/testData/quickfix/override/typeMismatchOnOverride/afterChangeReturnTypeOfOverriddenFunction.kt new file mode 100644 index 00000000000..0efefb16139 --- /dev/null +++ b/idea/testData/quickfix/override/typeMismatchOnOverride/afterChangeReturnTypeOfOverriddenFunction.kt @@ -0,0 +1,12 @@ +// "Change 'A.foo' function return type to 'Long'" "true" +trait A { + fun foo(): Long +} + +trait B { + fun foo(): Number +} + +trait C : A, B { + override fun foo(): Long +} \ No newline at end of file diff --git a/idea/testData/quickfix/override/typeMismatchOnOverride/beforeCantChangeReturnTypeOfOverriddenFunction.kt b/idea/testData/quickfix/override/typeMismatchOnOverride/beforeCantChangeReturnTypeOfOverriddenFunction.kt new file mode 100644 index 00000000000..302ed8d5be4 --- /dev/null +++ b/idea/testData/quickfix/override/typeMismatchOnOverride/beforeCantChangeReturnTypeOfOverriddenFunction.kt @@ -0,0 +1,13 @@ +// "Change 'A.foo' function return type to 'Long'" "false" +// ERROR: Return type is 'jet.Long', which is not a subtype of overridden
internal abstract fun foo(): jet.Int defined in A +trait A { + fun foo(): Int +} + +trait B { + fun foo(): String +} + +trait C : A, B { + override fun foo(): Long +} \ No newline at end of file diff --git a/idea/testData/quickfix/override/typeMismatchOnOverride/beforeChangeReturnTypeOfOverriddenFunction.kt b/idea/testData/quickfix/override/typeMismatchOnOverride/beforeChangeReturnTypeOfOverriddenFunction.kt new file mode 100644 index 00000000000..a8ccbc2551c --- /dev/null +++ b/idea/testData/quickfix/override/typeMismatchOnOverride/beforeChangeReturnTypeOfOverriddenFunction.kt @@ -0,0 +1,12 @@ +// "Change 'A.foo' function return type to 'Long'" "true" +trait A { + fun foo(): Int +} + +trait B { + fun foo(): Number +} + +trait C : A, B { + override fun foo(): Long +} \ No newline at end of file diff --git a/idea/tests/org/jetbrains/jet/plugin/quickfix/QuickFixTestGenerated.java b/idea/tests/org/jetbrains/jet/plugin/quickfix/QuickFixTestGenerated.java index 9b22cc5d85a..8e766d00b3a 100644 --- a/idea/tests/org/jetbrains/jet/plugin/quickfix/QuickFixTestGenerated.java +++ b/idea/tests/org/jetbrains/jet/plugin/quickfix/QuickFixTestGenerated.java @@ -1033,6 +1033,11 @@ public class QuickFixTestGenerated extends AbstractQuickFixTest { doTest("idea/testData/quickfix/override/typeMismatchOnOverride/beforeCantChangePropertyTypeToMatchOverridenProperties.kt"); } + @TestMetadata("beforeCantChangeReturnTypeOfOverriddenFunction.kt") + public void testCantChangeReturnTypeOfOverriddenFunction() throws Exception { + doTest("idea/testData/quickfix/override/typeMismatchOnOverride/beforeCantChangeReturnTypeOfOverriddenFunction.kt"); + } + @TestMetadata("beforeChangeOverriddenPropertyType1.kt") public void testChangeOverriddenPropertyType1() throws Exception { doTest("idea/testData/quickfix/override/typeMismatchOnOverride/beforeChangeOverriddenPropertyType1.kt"); @@ -1048,6 +1053,11 @@ public class QuickFixTestGenerated extends AbstractQuickFixTest { doTest("idea/testData/quickfix/override/typeMismatchOnOverride/beforeChangeOverridingPropertyTypeToFunctionType.kt"); } + @TestMetadata("beforeChangeReturnTypeOfOverriddenFunction.kt") + public void testChangeReturnTypeOfOverriddenFunction() throws Exception { + doTest("idea/testData/quickfix/override/typeMismatchOnOverride/beforeChangeReturnTypeOfOverriddenFunction.kt"); + } + @TestMetadata("beforePropertyReturnTypeMismatchOnOverride.kt") public void testPropertyReturnTypeMismatchOnOverride() throws Exception { doTest("idea/testData/quickfix/override/typeMismatchOnOverride/beforePropertyReturnTypeMismatchOnOverride.kt"); From 0a541373a504da242f484aebe0ccc5369d2c00b9 Mon Sep 17 00:00:00 2001 From: Wojciech Lopata Date: Wed, 15 May 2013 23:48:49 +0200 Subject: [PATCH 166/249] QuickFix: change property type to match expression returned by getter --- .../ChangeFunctionLiteralReturnTypeFix.java | 2 +- .../plugin/quickfix/ChangeVariableTypeFix.java | 15 +++++++++++++++ .../QuickFixFactoryForTypeMismatchError.java | 10 +++++++--- .../jet/plugin/quickfix/QuickFixUtil.java | 8 ++++---- .../afterPropertyGetterInitializerTypeMismatch.kt | 6 ++++++ ...beforePropertyGetterInitializerTypeMismatch.kt | 6 ++++++ .../plugin/quickfix/QuickFixTestGenerated.java | 5 +++++ 7 files changed, 44 insertions(+), 8 deletions(-) create mode 100644 idea/testData/quickfix/typeMismatch/typeMismatchOnReturnedExpression/afterPropertyGetterInitializerTypeMismatch.kt create mode 100644 idea/testData/quickfix/typeMismatch/typeMismatchOnReturnedExpression/beforePropertyGetterInitializerTypeMismatch.kt diff --git a/idea/src/org/jetbrains/jet/plugin/quickfix/ChangeFunctionLiteralReturnTypeFix.java b/idea/src/org/jetbrains/jet/plugin/quickfix/ChangeFunctionLiteralReturnTypeFix.java index b257b99cfdc..c7ac17cd164 100644 --- a/idea/src/org/jetbrains/jet/plugin/quickfix/ChangeFunctionLiteralReturnTypeFix.java +++ b/idea/src/org/jetbrains/jet/plugin/quickfix/ChangeFunctionLiteralReturnTypeFix.java @@ -85,7 +85,7 @@ public class ChangeFunctionLiteralReturnTypeFix extends JetIntentionAction typeWhiteSpaceAndColon = JetPsiFactory.createTypeWhiteSpaceAndColon(project, renderedType); element.addRangeAfter(typeWhiteSpaceAndColon.first, typeWhiteSpaceAndColon.second, nameIdentifier); + + if (element instanceof JetProperty) { + JetPropertyAccessor getter = ((JetProperty) element).getGetter(); + JetTypeReference getterReturnTypeRef = getter == null ? null : getter.getReturnTypeReference(); + if (getterReturnTypeRef != null) { + getterReturnTypeRef.replace(JetPsiFactory.createType(project, renderedType)); + } + + JetPropertyAccessor setter = ((JetProperty) element).getSetter(); + JetParameter setterParameter = setter == null ? null : setter.getParameter(); + JetTypeReference setterParameterTypeRef = setterParameter == null ? null : setterParameter.getTypeReference(); + if (setterParameterTypeRef != null) { + setterParameterTypeRef.replace(JetPsiFactory.createType(project, renderedType)); + } + } } @NotNull diff --git a/idea/src/org/jetbrains/jet/plugin/quickfix/QuickFixFactoryForTypeMismatchError.java b/idea/src/org/jetbrains/jet/plugin/quickfix/QuickFixFactoryForTypeMismatchError.java index 70c1c6632b0..ec304583cb9 100644 --- a/idea/src/org/jetbrains/jet/plugin/quickfix/QuickFixFactoryForTypeMismatchError.java +++ b/idea/src/org/jetbrains/jet/plugin/quickfix/QuickFixFactoryForTypeMismatchError.java @@ -56,13 +56,17 @@ public class QuickFixFactoryForTypeMismatchError implements JetIntentionActionsF // Property initializer type mismatch property type: JetProperty property = PsiTreeUtil.getParentOfType(expression, JetProperty.class); - if (property != null && QuickFixUtil.canEvaluateTo(property.getInitializer(), expression)) { - actions.add(new ChangeVariableTypeFix(property, expressionType)); + if (property != null) { + JetPropertyAccessor getter = property.getGetter(); + if (QuickFixUtil.canEvaluateTo(property.getInitializer(), expression) || + (getter != null && QuickFixUtil.canFunctionOrGetterReturnExpression(property.getGetter(), expression))) { + actions.add(new ChangeVariableTypeFix(property, expressionType)); + } } // Mismatch in returned expression: JetFunction function = PsiTreeUtil.getParentOfType(expression, JetFunction.class, true); - if (function != null && QuickFixUtil.canFunctionReturnExpression(function, expression)) { + if (function != null && QuickFixUtil.canFunctionOrGetterReturnExpression(function, expression)) { actions.add(new ChangeFunctionReturnTypeFix(function, expressionType)); } diff --git a/idea/src/org/jetbrains/jet/plugin/quickfix/QuickFixUtil.java b/idea/src/org/jetbrains/jet/plugin/quickfix/QuickFixUtil.java index a7217ba7006..c7d003be348 100644 --- a/idea/src/org/jetbrains/jet/plugin/quickfix/QuickFixUtil.java +++ b/idea/src/org/jetbrains/jet/plugin/quickfix/QuickFixUtil.java @@ -175,14 +175,14 @@ public class QuickFixUtil { return true; } - public static boolean canFunctionReturnExpression(@NotNull JetFunction function, @NotNull JetExpression expression) { - if (function instanceof JetFunctionLiteral) { - JetBlockExpression functionLiteralBody = ((JetFunctionLiteral) function).getBodyExpression(); + public static boolean canFunctionOrGetterReturnExpression(@NotNull JetDeclaration functionOrGetter, @NotNull JetExpression expression) { + if (functionOrGetter instanceof JetFunctionLiteral) { + JetBlockExpression functionLiteralBody = ((JetFunctionLiteral) functionOrGetter).getBodyExpression(); PsiElement returnedElement = functionLiteralBody == null ? null : functionLiteralBody.getLastChild(); return returnedElement instanceof JetExpression && canEvaluateTo((JetExpression) returnedElement, expression); } else { - if (function instanceof JetWithExpressionInitializer && canEvaluateTo(((JetWithExpressionInitializer) function).getInitializer(), expression)) { + if (functionOrGetter instanceof JetWithExpressionInitializer && canEvaluateTo(((JetWithExpressionInitializer) functionOrGetter).getInitializer(), expression)) { return true; } JetReturnExpression returnExpression = PsiTreeUtil.getParentOfType(expression, JetReturnExpression.class); diff --git a/idea/testData/quickfix/typeMismatch/typeMismatchOnReturnedExpression/afterPropertyGetterInitializerTypeMismatch.kt b/idea/testData/quickfix/typeMismatch/typeMismatchOnReturnedExpression/afterPropertyGetterInitializerTypeMismatch.kt new file mode 100644 index 00000000000..e22fc7027ef --- /dev/null +++ b/idea/testData/quickfix/typeMismatch/typeMismatchOnReturnedExpression/afterPropertyGetterInitializerTypeMismatch.kt @@ -0,0 +1,6 @@ +// "Change 'A.x' type to '() -> Int'" "true" +class A { + var x: () -> Int + get(): () -> Int = if (true) { {42} } else { {24} } + set(i: () -> Int) {} +} \ No newline at end of file diff --git a/idea/testData/quickfix/typeMismatch/typeMismatchOnReturnedExpression/beforePropertyGetterInitializerTypeMismatch.kt b/idea/testData/quickfix/typeMismatch/typeMismatchOnReturnedExpression/beforePropertyGetterInitializerTypeMismatch.kt new file mode 100644 index 00000000000..c9196877276 --- /dev/null +++ b/idea/testData/quickfix/typeMismatch/typeMismatchOnReturnedExpression/beforePropertyGetterInitializerTypeMismatch.kt @@ -0,0 +1,6 @@ +// "Change 'A.x' type to '() -> Int'" "true" +class A { + var x: Int + get(): Int = if (true) { {42} } else { {24} } + set(i: Int) {} +} \ No newline at end of file diff --git a/idea/tests/org/jetbrains/jet/plugin/quickfix/QuickFixTestGenerated.java b/idea/tests/org/jetbrains/jet/plugin/quickfix/QuickFixTestGenerated.java index 8e766d00b3a..66801905864 100644 --- a/idea/tests/org/jetbrains/jet/plugin/quickfix/QuickFixTestGenerated.java +++ b/idea/tests/org/jetbrains/jet/plugin/quickfix/QuickFixTestGenerated.java @@ -1514,6 +1514,11 @@ public class QuickFixTestGenerated extends AbstractQuickFixTest { doTest("idea/testData/quickfix/typeMismatch/typeMismatchOnReturnedExpression/beforeExpectedTypeMismatch.kt"); } + @TestMetadata("beforePropertyGetterInitializerTypeMismatch.kt") + public void testPropertyGetterInitializerTypeMismatch() throws Exception { + doTest("idea/testData/quickfix/typeMismatch/typeMismatchOnReturnedExpression/beforePropertyGetterInitializerTypeMismatch.kt"); + } + @TestMetadata("beforeReturnedExpresionCantEvaluateToExpresionThatTypeMismatch.kt") public void testReturnedExpresionCantEvaluateToExpresionThatTypeMismatch() throws Exception { doTest("idea/testData/quickfix/typeMismatch/typeMismatchOnReturnedExpression/beforeReturnedExpresionCantEvaluateToExpresionThatTypeMismatch.kt"); From c6a378f4fbfd5ee3a878ea091eb8fc9f58581fbf Mon Sep 17 00:00:00 2001 From: Wojciech Lopata Date: Thu, 16 May 2013 00:44:23 +0200 Subject: [PATCH 167/249] Rename directory with tests --- .../afterChangeFunctionParameterType1.kt | 0 .../afterChangeFunctionParameterType2.kt | 0 .../afterChangeFunctionParameterType3.kt | 0 .../beforeChangeFunctionParameterType1.kt | 0 .../beforeChangeFunctionParameterType2.kt | 0 .../beforeChangeFunctionParameterType3.kt | 0 .../beforeChangeFunctionParameterType4.kt | 0 .../beforeChangeFunctionParameterType5.kt | 0 .../quickfix/QuickFixTestGenerated.java | 22 +++++++++---------- 9 files changed, 11 insertions(+), 11 deletions(-) rename idea/testData/quickfix/typeMismatch/{functionParameterTypeMismatch => parameterTypeMismatch}/afterChangeFunctionParameterType1.kt (100%) rename idea/testData/quickfix/typeMismatch/{functionParameterTypeMismatch => parameterTypeMismatch}/afterChangeFunctionParameterType2.kt (100%) rename idea/testData/quickfix/typeMismatch/{functionParameterTypeMismatch => parameterTypeMismatch}/afterChangeFunctionParameterType3.kt (100%) rename idea/testData/quickfix/typeMismatch/{functionParameterTypeMismatch => parameterTypeMismatch}/beforeChangeFunctionParameterType1.kt (100%) rename idea/testData/quickfix/typeMismatch/{functionParameterTypeMismatch => parameterTypeMismatch}/beforeChangeFunctionParameterType2.kt (100%) rename idea/testData/quickfix/typeMismatch/{functionParameterTypeMismatch => parameterTypeMismatch}/beforeChangeFunctionParameterType3.kt (100%) rename idea/testData/quickfix/typeMismatch/{functionParameterTypeMismatch => parameterTypeMismatch}/beforeChangeFunctionParameterType4.kt (100%) rename idea/testData/quickfix/typeMismatch/{functionParameterTypeMismatch => parameterTypeMismatch}/beforeChangeFunctionParameterType5.kt (100%) diff --git a/idea/testData/quickfix/typeMismatch/functionParameterTypeMismatch/afterChangeFunctionParameterType1.kt b/idea/testData/quickfix/typeMismatch/parameterTypeMismatch/afterChangeFunctionParameterType1.kt similarity index 100% rename from idea/testData/quickfix/typeMismatch/functionParameterTypeMismatch/afterChangeFunctionParameterType1.kt rename to idea/testData/quickfix/typeMismatch/parameterTypeMismatch/afterChangeFunctionParameterType1.kt diff --git a/idea/testData/quickfix/typeMismatch/functionParameterTypeMismatch/afterChangeFunctionParameterType2.kt b/idea/testData/quickfix/typeMismatch/parameterTypeMismatch/afterChangeFunctionParameterType2.kt similarity index 100% rename from idea/testData/quickfix/typeMismatch/functionParameterTypeMismatch/afterChangeFunctionParameterType2.kt rename to idea/testData/quickfix/typeMismatch/parameterTypeMismatch/afterChangeFunctionParameterType2.kt diff --git a/idea/testData/quickfix/typeMismatch/functionParameterTypeMismatch/afterChangeFunctionParameterType3.kt b/idea/testData/quickfix/typeMismatch/parameterTypeMismatch/afterChangeFunctionParameterType3.kt similarity index 100% rename from idea/testData/quickfix/typeMismatch/functionParameterTypeMismatch/afterChangeFunctionParameterType3.kt rename to idea/testData/quickfix/typeMismatch/parameterTypeMismatch/afterChangeFunctionParameterType3.kt diff --git a/idea/testData/quickfix/typeMismatch/functionParameterTypeMismatch/beforeChangeFunctionParameterType1.kt b/idea/testData/quickfix/typeMismatch/parameterTypeMismatch/beforeChangeFunctionParameterType1.kt similarity index 100% rename from idea/testData/quickfix/typeMismatch/functionParameterTypeMismatch/beforeChangeFunctionParameterType1.kt rename to idea/testData/quickfix/typeMismatch/parameterTypeMismatch/beforeChangeFunctionParameterType1.kt diff --git a/idea/testData/quickfix/typeMismatch/functionParameterTypeMismatch/beforeChangeFunctionParameterType2.kt b/idea/testData/quickfix/typeMismatch/parameterTypeMismatch/beforeChangeFunctionParameterType2.kt similarity index 100% rename from idea/testData/quickfix/typeMismatch/functionParameterTypeMismatch/beforeChangeFunctionParameterType2.kt rename to idea/testData/quickfix/typeMismatch/parameterTypeMismatch/beforeChangeFunctionParameterType2.kt diff --git a/idea/testData/quickfix/typeMismatch/functionParameterTypeMismatch/beforeChangeFunctionParameterType3.kt b/idea/testData/quickfix/typeMismatch/parameterTypeMismatch/beforeChangeFunctionParameterType3.kt similarity index 100% rename from idea/testData/quickfix/typeMismatch/functionParameterTypeMismatch/beforeChangeFunctionParameterType3.kt rename to idea/testData/quickfix/typeMismatch/parameterTypeMismatch/beforeChangeFunctionParameterType3.kt diff --git a/idea/testData/quickfix/typeMismatch/functionParameterTypeMismatch/beforeChangeFunctionParameterType4.kt b/idea/testData/quickfix/typeMismatch/parameterTypeMismatch/beforeChangeFunctionParameterType4.kt similarity index 100% rename from idea/testData/quickfix/typeMismatch/functionParameterTypeMismatch/beforeChangeFunctionParameterType4.kt rename to idea/testData/quickfix/typeMismatch/parameterTypeMismatch/beforeChangeFunctionParameterType4.kt diff --git a/idea/testData/quickfix/typeMismatch/functionParameterTypeMismatch/beforeChangeFunctionParameterType5.kt b/idea/testData/quickfix/typeMismatch/parameterTypeMismatch/beforeChangeFunctionParameterType5.kt similarity index 100% rename from idea/testData/quickfix/typeMismatch/functionParameterTypeMismatch/beforeChangeFunctionParameterType5.kt rename to idea/testData/quickfix/typeMismatch/parameterTypeMismatch/beforeChangeFunctionParameterType5.kt diff --git a/idea/tests/org/jetbrains/jet/plugin/quickfix/QuickFixTestGenerated.java b/idea/tests/org/jetbrains/jet/plugin/quickfix/QuickFixTestGenerated.java index 66801905864..5ad88c7a44e 100644 --- a/idea/tests/org/jetbrains/jet/plugin/quickfix/QuickFixTestGenerated.java +++ b/idea/tests/org/jetbrains/jet/plugin/quickfix/QuickFixTestGenerated.java @@ -1275,7 +1275,7 @@ public class QuickFixTestGenerated extends AbstractQuickFixTest { } @TestMetadata("idea/testData/quickfix/typeMismatch") - @InnerTestClasses({TypeMismatch.Casts.class, TypeMismatch.ComponentFunctionReturnTypeMismatch.class, TypeMismatch.FixOverloadedOperator.class, TypeMismatch.FunctionParameterTypeMismatch.class, TypeMismatch.TypeMismatchOnReturnedExpression.class}) + @InnerTestClasses({TypeMismatch.Casts.class, TypeMismatch.ComponentFunctionReturnTypeMismatch.class, TypeMismatch.FixOverloadedOperator.class, TypeMismatch.ParameterTypeMismatch.class, TypeMismatch.TypeMismatchOnReturnedExpression.class}) public static class TypeMismatch extends AbstractQuickFixTest { public void testAllFilesPresentInTypeMismatch() throws Exception { JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.GenerateTests", new File("idea/testData/quickfix/typeMismatch"), Pattern.compile("^before(\\w+)\\.kt$"), true); @@ -1445,35 +1445,35 @@ public class QuickFixTestGenerated extends AbstractQuickFixTest { } - @TestMetadata("idea/testData/quickfix/typeMismatch/functionParameterTypeMismatch") - public static class FunctionParameterTypeMismatch extends AbstractQuickFixTest { - public void testAllFilesPresentInFunctionParameterTypeMismatch() throws Exception { - JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.GenerateTests", new File("idea/testData/quickfix/typeMismatch/functionParameterTypeMismatch"), Pattern.compile("^before(\\w+)\\.kt$"), true); + @TestMetadata("idea/testData/quickfix/typeMismatch/parameterTypeMismatch") + public static class ParameterTypeMismatch extends AbstractQuickFixTest { + public void testAllFilesPresentInParameterTypeMismatch() throws Exception { + JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.GenerateTests", new File("idea/testData/quickfix/typeMismatch/parameterTypeMismatch"), Pattern.compile("^before(\\w+)\\.kt$"), true); } @TestMetadata("beforeChangeFunctionParameterType1.kt") public void testChangeFunctionParameterType1() throws Exception { - doTest("idea/testData/quickfix/typeMismatch/functionParameterTypeMismatch/beforeChangeFunctionParameterType1.kt"); + doTest("idea/testData/quickfix/typeMismatch/parameterTypeMismatch/beforeChangeFunctionParameterType1.kt"); } @TestMetadata("beforeChangeFunctionParameterType2.kt") public void testChangeFunctionParameterType2() throws Exception { - doTest("idea/testData/quickfix/typeMismatch/functionParameterTypeMismatch/beforeChangeFunctionParameterType2.kt"); + doTest("idea/testData/quickfix/typeMismatch/parameterTypeMismatch/beforeChangeFunctionParameterType2.kt"); } @TestMetadata("beforeChangeFunctionParameterType3.kt") public void testChangeFunctionParameterType3() throws Exception { - doTest("idea/testData/quickfix/typeMismatch/functionParameterTypeMismatch/beforeChangeFunctionParameterType3.kt"); + doTest("idea/testData/quickfix/typeMismatch/parameterTypeMismatch/beforeChangeFunctionParameterType3.kt"); } @TestMetadata("beforeChangeFunctionParameterType4.kt") public void testChangeFunctionParameterType4() throws Exception { - doTest("idea/testData/quickfix/typeMismatch/functionParameterTypeMismatch/beforeChangeFunctionParameterType4.kt"); + doTest("idea/testData/quickfix/typeMismatch/parameterTypeMismatch/beforeChangeFunctionParameterType4.kt"); } @TestMetadata("beforeChangeFunctionParameterType5.kt") public void testChangeFunctionParameterType5() throws Exception { - doTest("idea/testData/quickfix/typeMismatch/functionParameterTypeMismatch/beforeChangeFunctionParameterType5.kt"); + doTest("idea/testData/quickfix/typeMismatch/parameterTypeMismatch/beforeChangeFunctionParameterType5.kt"); } } @@ -1557,7 +1557,7 @@ public class QuickFixTestGenerated extends AbstractQuickFixTest { suite.addTestSuite(Casts.class); suite.addTestSuite(ComponentFunctionReturnTypeMismatch.class); suite.addTestSuite(FixOverloadedOperator.class); - suite.addTestSuite(FunctionParameterTypeMismatch.class); + suite.addTestSuite(ParameterTypeMismatch.class); suite.addTestSuite(TypeMismatchOnReturnedExpression.class); return suite; } From 2a97617880e0b164017f64ce887bfa3faa1a210e Mon Sep 17 00:00:00 2001 From: Wojciech Lopata Date: Thu, 16 May 2013 00:43:26 +0200 Subject: [PATCH 168/249] QuickFix: change type of constructor parameter to match value argument in invocation --- .../jetbrains/jet/plugin/JetBundle.properties | 1 + .../ChangeFunctionLiteralReturnTypeFix.java | 4 ++-- ...peFix.java => ChangeParameterTypeFix.java} | 20 +++++++++++-------- .../QuickFixFactoryForTypeMismatchError.java | 12 +++++------ .../jet/plugin/quickfix/QuickFixUtil.java | 19 ++++++++++-------- ...erChangePrimaryConstructorParameterType.kt | 5 +++++ ...reChangePrimaryConstructorParameterType.kt | 5 +++++ .../quickfix/QuickFixTestGenerated.java | 5 +++++ 8 files changed, 47 insertions(+), 24 deletions(-) rename idea/src/org/jetbrains/jet/plugin/quickfix/{ChangeFunctionParameterTypeFix.java => ChangeParameterTypeFix.java} (67%) create mode 100644 idea/testData/quickfix/typeMismatch/parameterTypeMismatch/afterChangePrimaryConstructorParameterType.kt create mode 100644 idea/testData/quickfix/typeMismatch/parameterTypeMismatch/beforeChangePrimaryConstructorParameterType.kt diff --git a/idea/src/org/jetbrains/jet/plugin/JetBundle.properties b/idea/src/org/jetbrains/jet/plugin/JetBundle.properties index 6f7ebde6deb..a68d3edbb91 100644 --- a/idea/src/org/jetbrains/jet/plugin/JetBundle.properties +++ b/idea/src/org/jetbrains/jet/plugin/JetBundle.properties @@ -64,6 +64,7 @@ remove.function.return.type=Remove explicitly specified return type in ''{0}'' f remove.no.name.function.return.type=Remove explicitly specified function return type change.element.type=Change ''{0}'' type to ''{1}'' change.function.parameter.type=Change parameter ''{0}'' type of function ''{1}'' to ''{2}'' +change.primary.constructor.parameter.type=Change parameter ''{0}'' type of primary constructor of class ''{1}'' to ''{2}'' change.type=Change type from ''{0}'' to ''{1}'' change.type.family=Change Type add.parameters.to.function=Add parameter{0} to function ''{1}'' diff --git a/idea/src/org/jetbrains/jet/plugin/quickfix/ChangeFunctionLiteralReturnTypeFix.java b/idea/src/org/jetbrains/jet/plugin/quickfix/ChangeFunctionLiteralReturnTypeFix.java index c7ac17cd164..3027cba79c4 100644 --- a/idea/src/org/jetbrains/jet/plugin/quickfix/ChangeFunctionLiteralReturnTypeFix.java +++ b/idea/src/org/jetbrains/jet/plugin/quickfix/ChangeFunctionLiteralReturnTypeFix.java @@ -74,12 +74,12 @@ public class ChangeFunctionLiteralReturnTypeFix extends JetIntentionAction { +public class ChangeParameterTypeFix extends JetIntentionAction { private final String renderedType; - private final String containingFunctionName; + private final String containingDeclarationName; + private final boolean isPrimaryConstructorParameter; - public ChangeFunctionParameterTypeFix(@NotNull JetParameter element, @NotNull JetType type) { + public ChangeParameterTypeFix(@NotNull JetParameter element, @NotNull JetType type) { super(element); renderedType = DescriptorRenderer.SHORT_NAMES_IN_TYPES.renderType(type); - JetFunction function = PsiTreeUtil.getParentOfType(element, JetFunction.class); - FqName functionFQName = function == null ? null : JetPsiUtil.getFQName(function); - containingFunctionName = functionFQName == null ? null : functionFQName.getFqName(); + JetNamedDeclaration declaration = PsiTreeUtil.getParentOfType(element, JetNamedDeclaration.class); + isPrimaryConstructorParameter = declaration instanceof JetClass; + FqName declarationFQName = declaration == null ? null : JetPsiUtil.getFQName(declaration); + containingDeclarationName = declarationFQName == null ? null : declarationFQName.asString(); } @Override public boolean isAvailable(@NotNull Project project, Editor editor, PsiFile file) { - return super.isAvailable(project, editor, file) && containingFunctionName != null; + return super.isAvailable(project, editor, file) && containingDeclarationName != null; } @NotNull @Override public String getText() { - return JetBundle.message("change.function.parameter.type", element.getName(), containingFunctionName, renderedType); + return isPrimaryConstructorParameter ? + JetBundle.message("change.primary.constructor.parameter.type", element.getName(), containingDeclarationName, renderedType) : + JetBundle.message("change.function.parameter.type", element.getName(), containingDeclarationName, renderedType); } @NotNull diff --git a/idea/src/org/jetbrains/jet/plugin/quickfix/QuickFixFactoryForTypeMismatchError.java b/idea/src/org/jetbrains/jet/plugin/quickfix/QuickFixFactoryForTypeMismatchError.java index ec304583cb9..9eb2dd5314b 100644 --- a/idea/src/org/jetbrains/jet/plugin/quickfix/QuickFixFactoryForTypeMismatchError.java +++ b/idea/src/org/jetbrains/jet/plugin/quickfix/QuickFixFactoryForTypeMismatchError.java @@ -89,7 +89,7 @@ public class QuickFixFactoryForTypeMismatchError implements JetIntentionActionsF PsiElement declaration = BindingContextUtils.descriptorToDeclaration(context, resolvedCall.getResultingDescriptor()); if (declaration instanceof JetFunction) { JetParameter binaryOperatorParameter = ((JetFunction) declaration).getValueParameterList().getParameters().get(0); - actions.add(new ChangeFunctionParameterTypeFix(binaryOperatorParameter, expressionType)); + actions.add(new ChangeParameterTypeFix(binaryOperatorParameter, expressionType)); } } } @@ -113,20 +113,20 @@ public class QuickFixFactoryForTypeMismatchError implements JetIntentionActionsF QuickFixUtil.getParentElementOfType(diagnostic, JetFunctionLiteralExpression.class); if (functionLiteralExpression != null && functionLiteralExpression.getBodyExpression() == expression) { JetParameter correspondingParameter = - QuickFixUtil.getFunctionParameterCorrespondingToFunctionLiteralPassedOutsideArgumentList(functionLiteralExpression); + QuickFixUtil.getParameterCorrespondingToFunctionLiteralPassedOutsideArgumentList(functionLiteralExpression); JetType functionLiteralExpressionType = context.get(BindingContext.EXPRESSION_TYPE, functionLiteralExpression); if (correspondingParameter != null && functionLiteralExpressionType != null) { - actions.add(new ChangeFunctionParameterTypeFix(correspondingParameter, functionLiteralExpressionType)); + actions.add(new ChangeParameterTypeFix(correspondingParameter, functionLiteralExpressionType)); } } // 2) When an argument is passed inside value argument list: else { JetValueArgument valueArgument = QuickFixUtil.getParentElementOfType(diagnostic, JetValueArgument.class); - if (valueArgument != null && valueArgument.getArgumentExpression() == expression) { - JetParameter correspondingParameter = QuickFixUtil.getFunctionParameterCorrespondingToValueArgumentPassedInCall(valueArgument); + if (valueArgument != null && QuickFixUtil.canEvaluateTo(valueArgument.getArgumentExpression(), expression)) { + JetParameter correspondingParameter = QuickFixUtil.getParameterCorrespondingToValueArgumentPassedInCall(valueArgument); JetType valueArgumentType = context.get(BindingContext.EXPRESSION_TYPE, valueArgument.getArgumentExpression()); if (correspondingParameter != null && valueArgumentType != null) { - actions.add(new ChangeFunctionParameterTypeFix(correspondingParameter, valueArgumentType)); + actions.add(new ChangeParameterTypeFix(correspondingParameter, valueArgumentType)); } } } diff --git a/idea/src/org/jetbrains/jet/plugin/quickfix/QuickFixUtil.java b/idea/src/org/jetbrains/jet/plugin/quickfix/QuickFixUtil.java index c7d003be348..11380a56cc4 100644 --- a/idea/src/org/jetbrains/jet/plugin/quickfix/QuickFixUtil.java +++ b/idea/src/org/jetbrains/jet/plugin/quickfix/QuickFixUtil.java @@ -95,30 +95,33 @@ public class QuickFixUtil { } @Nullable - public static JetParameterList getParameterListOfCalledFunction(@NotNull JetCallExpression callExpression) { + public static JetParameterList getParameterListOfCallee(@NotNull JetCallExpression callExpression) { BindingContext context = AnalyzerFacadeWithCache.analyzeFileWithCache((JetFile) callExpression.getContainingFile()).getBindingContext(); ResolvedCall resolvedCall = context.get(BindingContext.RESOLVED_CALL, callExpression.getCalleeExpression()); if (resolvedCall == null) return null; - PsiElement functionDeclaration = BindingContextUtils.descriptorToDeclaration(context, resolvedCall.getCandidateDescriptor()); - if (functionDeclaration instanceof JetFunction) { - return ((JetFunction) functionDeclaration).getValueParameterList(); + PsiElement declaration = BindingContextUtils.descriptorToDeclaration(context, resolvedCall.getCandidateDescriptor()); + if (declaration instanceof JetFunction) { + return ((JetFunction) declaration).getValueParameterList(); + } + if (declaration instanceof JetClass) { + return ((JetClass) declaration).getPrimaryConstructorParameterList(); } return null; } @Nullable - public static JetParameter getFunctionParameterCorrespondingToFunctionLiteralPassedOutsideArgumentList(@NotNull JetFunctionLiteralExpression functionLiteralExpression) { + public static JetParameter getParameterCorrespondingToFunctionLiteralPassedOutsideArgumentList(@NotNull JetFunctionLiteralExpression functionLiteralExpression) { if (!(functionLiteralExpression.getParent() instanceof JetCallExpression)) { return null; } JetCallExpression callExpression = (JetCallExpression) functionLiteralExpression.getParent(); - JetParameterList parameterList = getParameterListOfCalledFunction(callExpression); + JetParameterList parameterList = getParameterListOfCallee(callExpression); if (parameterList == null) return null; return parameterList.getParameters().get(parameterList.getParameters().size() - 1); } @Nullable - public static JetParameter getFunctionParameterCorrespondingToValueArgumentPassedInCall(@NotNull JetValueArgument valueArgument) { + public static JetParameter getParameterCorrespondingToValueArgumentPassedInCall(@NotNull JetValueArgument valueArgument) { if (!(valueArgument.getParent() instanceof JetValueArgumentList)) { return null; } @@ -127,7 +130,7 @@ public class QuickFixUtil { return null; } JetCallExpression callExpression = (JetCallExpression) valueArgumentList.getParent(); - JetParameterList parameterList = getParameterListOfCalledFunction(callExpression); + JetParameterList parameterList = getParameterListOfCallee(callExpression); if (parameterList == null) return null; int position = valueArgumentList.getArguments().indexOf(valueArgument); if (position == -1) return null; diff --git a/idea/testData/quickfix/typeMismatch/parameterTypeMismatch/afterChangePrimaryConstructorParameterType.kt b/idea/testData/quickfix/typeMismatch/parameterTypeMismatch/afterChangePrimaryConstructorParameterType.kt new file mode 100644 index 00000000000..9acd1ad0389 --- /dev/null +++ b/idea/testData/quickfix/typeMismatch/parameterTypeMismatch/afterChangePrimaryConstructorParameterType.kt @@ -0,0 +1,5 @@ +// "Change parameter 'a' type of primary constructor of class 'B' to 'String'" "true" +class B(val a: String) +fun foo() { + B(if (true) "" else "") +} diff --git a/idea/testData/quickfix/typeMismatch/parameterTypeMismatch/beforeChangePrimaryConstructorParameterType.kt b/idea/testData/quickfix/typeMismatch/parameterTypeMismatch/beforeChangePrimaryConstructorParameterType.kt new file mode 100644 index 00000000000..7e39c54a4a1 --- /dev/null +++ b/idea/testData/quickfix/typeMismatch/parameterTypeMismatch/beforeChangePrimaryConstructorParameterType.kt @@ -0,0 +1,5 @@ +// "Change parameter 'a' type of primary constructor of class 'B' to 'String'" "true" +class B(val a: Int) +fun foo() { + B(if (true) "" else "") +} diff --git a/idea/tests/org/jetbrains/jet/plugin/quickfix/QuickFixTestGenerated.java b/idea/tests/org/jetbrains/jet/plugin/quickfix/QuickFixTestGenerated.java index 5ad88c7a44e..fe3b3c67a02 100644 --- a/idea/tests/org/jetbrains/jet/plugin/quickfix/QuickFixTestGenerated.java +++ b/idea/tests/org/jetbrains/jet/plugin/quickfix/QuickFixTestGenerated.java @@ -1476,6 +1476,11 @@ public class QuickFixTestGenerated extends AbstractQuickFixTest { doTest("idea/testData/quickfix/typeMismatch/parameterTypeMismatch/beforeChangeFunctionParameterType5.kt"); } + @TestMetadata("beforeChangePrimaryConstructorParameterType.kt") + public void testChangePrimaryConstructorParameterType() throws Exception { + doTest("idea/testData/quickfix/typeMismatch/parameterTypeMismatch/beforeChangePrimaryConstructorParameterType.kt"); + } + } @TestMetadata("idea/testData/quickfix/typeMismatch/typeMismatchOnReturnedExpression") From 4bf7151e473cf3cf78c89379943b895b936703e9 Mon Sep 17 00:00:00 2001 From: Wojciech Lopata Date: Wed, 29 May 2013 13:52:27 +0200 Subject: [PATCH 169/249] Make "type mismatch" quickfixes not available in case of error types --- .../plugin/quickfix/ChangeFunctionReturnTypeFix.java | 7 +++++++ .../jet/plugin/quickfix/ChangeVariableTypeFix.java | 9 +++++++++ ...eforeDontChangeOverriddenPropertyTypeToErrorType.kt | 10 ++++++++++ .../beforeDontChangeFunctionReturnTypeToErrorType.kt | 6 ++++++ .../jet/plugin/quickfix/QuickFixTestGenerated.java | 10 ++++++++++ 5 files changed, 42 insertions(+) create mode 100644 idea/testData/quickfix/typeMismatch/beforeDontChangeOverriddenPropertyTypeToErrorType.kt create mode 100644 idea/testData/quickfix/typeMismatch/typeMismatchOnReturnedExpression/beforeDontChangeFunctionReturnTypeToErrorType.kt diff --git a/idea/src/org/jetbrains/jet/plugin/quickfix/ChangeFunctionReturnTypeFix.java b/idea/src/org/jetbrains/jet/plugin/quickfix/ChangeFunctionReturnTypeFix.java index c9a974790aa..cf22d69bf9c 100644 --- a/idea/src/org/jetbrains/jet/plugin/quickfix/ChangeFunctionReturnTypeFix.java +++ b/idea/src/org/jetbrains/jet/plugin/quickfix/ChangeFunctionReturnTypeFix.java @@ -22,6 +22,7 @@ import com.intellij.openapi.project.Project; import com.intellij.openapi.util.Pair; import com.intellij.psi.PsiElement; import com.intellij.psi.PsiErrorElement; +import com.intellij.psi.PsiFile; import com.intellij.psi.util.PsiTreeUtil; import com.intellij.util.IncorrectOperationException; import org.jetbrains.annotations.NotNull; @@ -38,6 +39,7 @@ import org.jetbrains.jet.lang.resolve.DescriptorResolver; import org.jetbrains.jet.lang.resolve.calls.model.ResolvedCall; import org.jetbrains.jet.lang.resolve.name.FqName; import org.jetbrains.jet.lang.resolve.name.Name; +import org.jetbrains.jet.lang.types.ErrorUtils; import org.jetbrains.jet.lang.types.JetType; import org.jetbrains.jet.lang.types.checker.JetTypeChecker; import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns; @@ -96,6 +98,11 @@ public class ChangeFunctionReturnTypeFix extends JetIntentionAction return JetBundle.message("change.type.family"); } + @Override + public boolean isAvailable(@NotNull Project project, @Nullable Editor editor, @Nullable PsiFile file) { + return super.isAvailable(project, editor, file) && !ErrorUtils.containsErrorType(type); + } + @Override public void invoke(@NotNull Project project, @Nullable Editor editor, @Nullable JetFile file) throws IncorrectOperationException { if (changeFunctionLiteralReturnTypeFix != null) { diff --git a/idea/src/org/jetbrains/jet/plugin/quickfix/ChangeVariableTypeFix.java b/idea/src/org/jetbrains/jet/plugin/quickfix/ChangeVariableTypeFix.java index c80f8d356dd..bcb408900ba 100644 --- a/idea/src/org/jetbrains/jet/plugin/quickfix/ChangeVariableTypeFix.java +++ b/idea/src/org/jetbrains/jet/plugin/quickfix/ChangeVariableTypeFix.java @@ -21,6 +21,7 @@ import com.intellij.openapi.editor.Editor; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.Pair; import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiFile; import com.intellij.util.IncorrectOperationException; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -32,6 +33,7 @@ import org.jetbrains.jet.lang.resolve.BindingContext; import org.jetbrains.jet.lang.resolve.BindingContextUtils; import org.jetbrains.jet.lang.resolve.calls.model.ResolvedCall; import org.jetbrains.jet.lang.resolve.name.FqName; +import org.jetbrains.jet.lang.types.ErrorUtils; import org.jetbrains.jet.lang.types.JetType; import org.jetbrains.jet.lang.types.checker.JetTypeChecker; import org.jetbrains.jet.plugin.JetBundle; @@ -45,10 +47,12 @@ import java.util.List; public class ChangeVariableTypeFix extends JetIntentionAction { private final String renderedType; + private final JetType type; public ChangeVariableTypeFix(@NotNull JetVariableDeclaration element, @NotNull JetType type) { super(element); renderedType = DescriptorRenderer.SHORT_NAMES_IN_TYPES.renderType(type); + this.type = type; } @NotNull @@ -67,6 +71,11 @@ public class ChangeVariableTypeFix extends JetIntentionAction [ERROR : Ay]'" "false" +// ACTION: Change 'A.x' type to '(Int) -> Int' +// ERROR: Return type is '(jet.Int) → jet.Int', which is not a subtype of overridden
internal abstract val x: (jet.String) → [ERROR : Ay] defined in A +// ERROR: Unresolved reference: Ay +trait A { + val x: (String) -> Ay +} +trait B : A { + override val x: (Int) -> Int +} \ No newline at end of file diff --git a/idea/testData/quickfix/typeMismatch/typeMismatchOnReturnedExpression/beforeDontChangeFunctionReturnTypeToErrorType.kt b/idea/testData/quickfix/typeMismatch/typeMismatchOnReturnedExpression/beforeDontChangeFunctionReturnTypeToErrorType.kt new file mode 100644 index 00000000000..ff1d6c75cf7 --- /dev/null +++ b/idea/testData/quickfix/typeMismatch/typeMismatchOnReturnedExpression/beforeDontChangeFunctionReturnTypeToErrorType.kt @@ -0,0 +1,6 @@ +// "Change 'foo' function return type to '([ERROR : NoSuchType]) -> Int'" "false" +// ERROR: Type mismatch.
Required:jet.Int
Found:([ERROR : NoSuchType]) → jet.Int
+// ERROR: Unresolved reference: NoSuchType +fun foo(): Int { + return { (x: NoSuchType) -> 42 } +} \ No newline at end of file diff --git a/idea/tests/org/jetbrains/jet/plugin/quickfix/QuickFixTestGenerated.java b/idea/tests/org/jetbrains/jet/plugin/quickfix/QuickFixTestGenerated.java index fe3b3c67a02..f4226698736 100644 --- a/idea/tests/org/jetbrains/jet/plugin/quickfix/QuickFixTestGenerated.java +++ b/idea/tests/org/jetbrains/jet/plugin/quickfix/QuickFixTestGenerated.java @@ -1306,6 +1306,11 @@ public class QuickFixTestGenerated extends AbstractQuickFixTest { doTest("idea/testData/quickfix/typeMismatch/beforeCompareToTypeMismatch.kt"); } + @TestMetadata("beforeDontChangeOverriddenPropertyTypeToErrorType.kt") + public void testDontChangeOverriddenPropertyTypeToErrorType() throws Exception { + doTest("idea/testData/quickfix/typeMismatch/beforeDontChangeOverriddenPropertyTypeToErrorType.kt"); + } + @TestMetadata("beforeExpectedParameterTypeMismatch.kt") public void testExpectedParameterTypeMismatch() throws Exception { doTest("idea/testData/quickfix/typeMismatch/beforeExpectedParameterTypeMismatch.kt"); @@ -1514,6 +1519,11 @@ public class QuickFixTestGenerated extends AbstractQuickFixTest { doTest("idea/testData/quickfix/typeMismatch/typeMismatchOnReturnedExpression/beforeChangeFunctionReturnTypeToMatchReturnTypeOfReturnedLiteral.kt"); } + @TestMetadata("beforeDontChangeFunctionReturnTypeToErrorType.kt") + public void testDontChangeFunctionReturnTypeToErrorType() throws Exception { + doTest("idea/testData/quickfix/typeMismatch/typeMismatchOnReturnedExpression/beforeDontChangeFunctionReturnTypeToErrorType.kt"); + } + @TestMetadata("beforeExpectedTypeMismatch.kt") public void testExpectedTypeMismatch() throws Exception { doTest("idea/testData/quickfix/typeMismatch/typeMismatchOnReturnedExpression/beforeExpectedTypeMismatch.kt"); From 6465abe7eb02304bc9a4698031bb9c45a3095391 Mon Sep 17 00:00:00 2001 From: Andrey Breslav Date: Wed, 29 May 2013 21:07:54 +0400 Subject: [PATCH 170/249] Do not fail on circular dependencies + better message --- .../jet/jps/build/KotlinBuilder.java | 20 ++++++++++++++++--- .../jet/jps/build/KotlinJpsBuildTestCase.java | 4 ++++ .../kotlinProject.iml | 14 +++++++++++++ .../kotlinProject.ipr | 15 ++++++++++++++ .../module2/module2.iml | 14 +++++++++++++ .../module2/src/JSecond.java | 5 +++++ .../src/JFirst.java | 11 ++++++++++ 7 files changed, 80 insertions(+), 3 deletions(-) create mode 100644 jps-plugin/testData/CircularDependenciesNoKotlinFiles/kotlinProject.iml create mode 100644 jps-plugin/testData/CircularDependenciesNoKotlinFiles/kotlinProject.ipr create mode 100644 jps-plugin/testData/CircularDependenciesNoKotlinFiles/module2/module2.iml create mode 100644 jps-plugin/testData/CircularDependenciesNoKotlinFiles/module2/src/JSecond.java create mode 100644 jps-plugin/testData/CircularDependenciesNoKotlinFiles/src/JFirst.java diff --git a/jps-plugin/src/org/jetbrains/jet/jps/build/KotlinBuilder.java b/jps-plugin/src/org/jetbrains/jet/jps/build/KotlinBuilder.java index 2f0eb7bb58f..0d88d6e635b 100644 --- a/jps-plugin/src/org/jetbrains/jet/jps/build/KotlinBuilder.java +++ b/jps-plugin/src/org/jetbrains/jet/jps/build/KotlinBuilder.java @@ -16,6 +16,8 @@ package org.jetbrains.jet.jps.build; +import com.intellij.openapi.util.text.StringUtil; +import com.intellij.util.Function; import com.intellij.util.containers.ContainerUtil; import org.jetbrains.annotations.NotNull; import org.jetbrains.jet.cli.common.messages.CompilerMessageLocation; @@ -29,19 +31,27 @@ import org.jetbrains.jps.builders.java.JavaSourceRootDescriptor; import org.jetbrains.jps.incremental.*; import org.jetbrains.jps.incremental.messages.BuildMessage; import org.jetbrains.jps.incremental.messages.CompilerMessage; +import org.jetbrains.jps.model.module.JpsModule; import java.io.File; import java.io.IOException; import java.util.Collection; import java.util.List; -import static org.jetbrains.jet.cli.common.messages.CompilerMessageSeverity.ERROR; import static org.jetbrains.jet.cli.common.messages.CompilerMessageSeverity.EXCEPTION; +import static org.jetbrains.jet.cli.common.messages.CompilerMessageSeverity.WARNING; public class KotlinBuilder extends ModuleLevelBuilder { private static final String KOTLIN_BUILDER_NAME = "Kotlin Builder"; + private static final Function MODULE_NAME = new Function() { + @Override + public String fun(JpsModule module) { + return module.getName(); + } + }; + protected KotlinBuilder() { super(BuilderCategory.SOURCE_PROCESSOR); } @@ -63,10 +73,14 @@ public class KotlinBuilder extends ModuleLevelBuilder { MessageCollector messageCollector = new MessageCollectorAdapter(context); if (chunk.getModules().size() > 1) { + // We do not support circular dependencies, but if they are present, we should not break the build, + // so we simply yield a warning and report NOTHING_DONE messageCollector.report( - ERROR, "Circular dependencies are not supported: " + chunk.getModules(), + WARNING, "Circular dependencies are not supported. " + + "The following modules depend on each other: " + StringUtil.join(chunk.getModules(), MODULE_NAME, ", ") + ". " + + "Kotlin is not compiled for these modules", CompilerMessageLocation.NO_LOCATION); - return ExitCode.ABORT; + return ExitCode.NOTHING_DONE; } ModuleBuildTarget representativeTarget = chunk.representativeTarget(); diff --git a/jps-plugin/test/org/jetbrains/jet/jps/build/KotlinJpsBuildTestCase.java b/jps-plugin/test/org/jetbrains/jet/jps/build/KotlinJpsBuildTestCase.java index 7461afc3328..72c20c11c83 100644 --- a/jps-plugin/test/org/jetbrains/jet/jps/build/KotlinJpsBuildTestCase.java +++ b/jps-plugin/test/org/jetbrains/jet/jps/build/KotlinJpsBuildTestCase.java @@ -82,6 +82,10 @@ public class KotlinJpsBuildTestCase extends AbstractKotlinJpsBuildTestCase { doTestWithRuntime(); } + public void testCircularDependenciesNoKotlinFiles() { + doTest(); + } + public void testTestDependencyLibrary() throws Throwable { initProject(); addKotlinRuntimeDependency(JpsJavaDependencyScope.TEST); diff --git a/jps-plugin/testData/CircularDependenciesNoKotlinFiles/kotlinProject.iml b/jps-plugin/testData/CircularDependenciesNoKotlinFiles/kotlinProject.iml new file mode 100644 index 00000000000..5559c7ad919 --- /dev/null +++ b/jps-plugin/testData/CircularDependenciesNoKotlinFiles/kotlinProject.iml @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + diff --git a/jps-plugin/testData/CircularDependenciesNoKotlinFiles/kotlinProject.ipr b/jps-plugin/testData/CircularDependenciesNoKotlinFiles/kotlinProject.ipr new file mode 100644 index 00000000000..809737b0b76 --- /dev/null +++ b/jps-plugin/testData/CircularDependenciesNoKotlinFiles/kotlinProject.ipr @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + diff --git a/jps-plugin/testData/CircularDependenciesNoKotlinFiles/module2/module2.iml b/jps-plugin/testData/CircularDependenciesNoKotlinFiles/module2/module2.iml new file mode 100644 index 00000000000..eace69878a2 --- /dev/null +++ b/jps-plugin/testData/CircularDependenciesNoKotlinFiles/module2/module2.iml @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + diff --git a/jps-plugin/testData/CircularDependenciesNoKotlinFiles/module2/src/JSecond.java b/jps-plugin/testData/CircularDependenciesNoKotlinFiles/module2/src/JSecond.java new file mode 100644 index 00000000000..e034bf38792 --- /dev/null +++ b/jps-plugin/testData/CircularDependenciesNoKotlinFiles/module2/src/JSecond.java @@ -0,0 +1,5 @@ +public class JSecond { + public static void main(String[] args) { + new JFirst().foo(); + } +} diff --git a/jps-plugin/testData/CircularDependenciesNoKotlinFiles/src/JFirst.java b/jps-plugin/testData/CircularDependenciesNoKotlinFiles/src/JFirst.java new file mode 100644 index 00000000000..12140d2a7e4 --- /dev/null +++ b/jps-plugin/testData/CircularDependenciesNoKotlinFiles/src/JFirst.java @@ -0,0 +1,11 @@ +public class JFirst { + JSecond s = null; + + public void foo() { + + } + + public static void main(String[] args) { + System.out.println(1); + } +} \ No newline at end of file From 7ff1885e8ea65c95ab42cc2e5721f2b6ef4ba9ce Mon Sep 17 00:00:00 2001 From: Andrey Breslav Date: Wed, 29 May 2013 21:28:26 +0400 Subject: [PATCH 171/249] The error message now tells the user about jps.kotlin.home For TeamCity users --- compiler/util/src/org/jetbrains/jet/utils/PathUtil.java | 4 +++- .../jetbrains/jet/compiler/runner/CompilerEnvironment.java | 4 +++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/compiler/util/src/org/jetbrains/jet/utils/PathUtil.java b/compiler/util/src/org/jetbrains/jet/utils/PathUtil.java index cbafebff153..0c7f7924327 100644 --- a/compiler/util/src/org/jetbrains/jet/utils/PathUtil.java +++ b/compiler/util/src/org/jetbrains/jet/utils/PathUtil.java @@ -27,6 +27,8 @@ import java.io.File; public class PathUtil { + public static final String JPS_KOTLIN_HOME_PROPERTY = "jps.kotlin.home"; + public static final String JS_LIB_JAR_NAME = "kotlin-jslib.jar"; public static final String JS_LIB_JS_NAME = "kotlinEcma3.js"; public static final String JDK_ANNOTATIONS_JAR = "kotlin-jdk-annotations.jar"; @@ -46,7 +48,7 @@ public class PathUtil { public static KotlinPaths getKotlinPathsForJpsPlugin() { // When JPS is run on TeamCity, it can not rely on Kotlin plugin layout, // so the path to Kotlin is specified in a system property - String jpsKotlinHome = System.getProperty("jps.kotlin.home"); + String jpsKotlinHome = System.getProperty(JPS_KOTLIN_HOME_PROPERTY); if (jpsKotlinHome != null) { return new KotlinPathsFromHomeDir(new File(jpsKotlinHome)); } diff --git a/ide-compiler-runner/src/org/jetbrains/jet/compiler/runner/CompilerEnvironment.java b/ide-compiler-runner/src/org/jetbrains/jet/compiler/runner/CompilerEnvironment.java index c2bc4431392..a633c4f5f24 100644 --- a/ide-compiler-runner/src/org/jetbrains/jet/compiler/runner/CompilerEnvironment.java +++ b/ide-compiler-runner/src/org/jetbrains/jet/compiler/runner/CompilerEnvironment.java @@ -20,6 +20,7 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.jet.cli.common.messages.MessageCollector; import org.jetbrains.jet.utils.KotlinPaths; +import org.jetbrains.jet.utils.PathUtil; import java.io.File; @@ -61,7 +62,8 @@ public final class CompilerEnvironment { messageCollector.report(ERROR, "[Internal Error] No output directory", NO_LOCATION); } if (!kotlinPaths.getHomePath().exists()) { - messageCollector.report(ERROR, "Cannot find kotlinc home: " + kotlinPaths.getHomePath() + ". Make sure plugin is properly installed", NO_LOCATION); + messageCollector.report(ERROR, "Cannot find kotlinc home: " + kotlinPaths.getHomePath() + ". Make sure plugin is properly installed, " + + "or specify " + PathUtil.JPS_KOTLIN_HOME_PROPERTY + " system property", NO_LOCATION); } } From b08751f50107ebdcea6fbb2689af7f290ad9200e Mon Sep 17 00:00:00 2001 From: Evgeny Gerashchenko Date: Thu, 30 May 2013 12:53:26 +0400 Subject: [PATCH 172/249] Fixed starting in profiler. --- compiler/util/src/org/jetbrains/jet/utils/Profiler.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/util/src/org/jetbrains/jet/utils/Profiler.java b/compiler/util/src/org/jetbrains/jet/utils/Profiler.java index 06f4a68dde2..0c4a4f73084 100644 --- a/compiler/util/src/org/jetbrains/jet/utils/Profiler.java +++ b/compiler/util/src/org/jetbrains/jet/utils/Profiler.java @@ -116,7 +116,7 @@ public class Profiler { } public Profiler start() { - if (!paused) { + if (paused) { start = System.nanoTime(); paused = false; } From aa1998fa20ce0e636f3de8c7fd9788a46cb83896 Mon Sep 17 00:00:00 2001 From: "Natalia.Ukhorskaya" Date: Wed, 29 May 2013 15:30:03 +0400 Subject: [PATCH 173/249] Check not null annotations for parameters in IdeaJdkAnnotationsReflectedTest --- .../IdeaJdkAnnotationsReflectedTest.java | 57 ++++++++++++++----- 1 file changed, 43 insertions(+), 14 deletions(-) diff --git a/compiler/tests/org/jetbrains/jet/jvm/compiler/IdeaJdkAnnotationsReflectedTest.java b/compiler/tests/org/jetbrains/jet/jvm/compiler/IdeaJdkAnnotationsReflectedTest.java index e1df228e34e..d65fe3c89e0 100644 --- a/compiler/tests/org/jetbrains/jet/jvm/compiler/IdeaJdkAnnotationsReflectedTest.java +++ b/compiler/tests/org/jetbrains/jet/jvm/compiler/IdeaJdkAnnotationsReflectedTest.java @@ -87,14 +87,14 @@ public class IdeaJdkAnnotationsReflectedTest extends KotlinTestWithEnvironment { public void visitMethod(PsiMethod method) { super.visitMethod(method); if (method.getReturnType() != null) { // disabled for constructors - check(method, method); + checkAndReport(method); } } @Override public void visitField(PsiField field) { super.visitField(field); - check(field, field); + checkAndReport(field); } @Override @@ -103,22 +103,39 @@ public class IdeaJdkAnnotationsReflectedTest extends KotlinTestWithEnvironment { PsiMethod method = PsiTreeUtil.getParentOfType(parameter, PsiMethod.class); assert method != null; if (method.getReturnType() != null) { // disabled for constructors - check(parameter, method); + if (!check(parameter, method, AnnotationsKind.KOTLIN_SIGNATURE) && + !check(parameter, parameter, AnnotationsKind.NOT_NULL)) { + declarationsWithMissingAnnotations.add(parameter); + } } } - private void check(@NotNull PsiModifierListOwner ideaOwner, @NotNull PsiModifierListOwner kotlinOwner) { - if (hasAnnotation(ideaFakeAnnotationsManager, ideaOwner, AnnotationUtil.NOT_NULL)) { - boolean kotlinHasNotNull = hasAnnotation(kotlinFakeAnnotationsManager, kotlinOwner, AnnotationUtil.NOT_NULL); - boolean kotlinHasKotlinSignature = hasAnnotation(kotlinFakeAnnotationsManager, kotlinOwner, - JvmStdlibNames.KOTLIN_SIGNATURE.getFqName().asString()); - if (kotlinOwner == ideaOwner && kotlinHasNotNull || kotlinHasKotlinSignature) { - // good - } - else { - declarationsWithMissingAnnotations.add(kotlinOwner); + private void checkAndReport(@NotNull PsiModifierListOwner annotationOwner) { + if (!check(annotationOwner, annotationOwner, AnnotationsKind.ANY)) { + declarationsWithMissingAnnotations.add(annotationOwner); + } + } + + private boolean check( + @NotNull PsiModifierListOwner ideaOwner, + @NotNull PsiModifierListOwner kotlinOwner, + @NotNull AnnotationsKind annotationsKind + ) + { + return !hasAnnotationInIdea(ideaOwner) || hasAnnotationInKotlin(kotlinOwner, annotationsKind); + } + + private boolean hasAnnotationInIdea(@NotNull PsiModifierListOwner owner) { + return hasAnnotation(ideaFakeAnnotationsManager, owner, AnnotationUtil.NOT_NULL); + } + + private boolean hasAnnotationInKotlin(@NotNull PsiModifierListOwner owner, @NotNull AnnotationsKind annotationsKind) { + for (String name : annotationsKind.annotationNames) { + if (hasAnnotation(kotlinFakeAnnotationsManager, owner, name)) { + return true; } } + return false; } private boolean hasAnnotation( @@ -134,9 +151,21 @@ public class IdeaJdkAnnotationsReflectedTest extends KotlinTestWithEnvironment { if (!declarationsWithMissingAnnotations.isEmpty()) { StringBuilder builder = new StringBuilder("Annotations missing for JDK items:\n"); for (PsiModifierListOwner declaration : declarationsWithMissingAnnotations) { - builder.append(PsiFormatUtil.getExternalName(declaration)).append("\n"); + builder.append(PsiFormatUtil.getExternalName(declaration) + " " + declaration.getText()).append("\n"); } fail(builder.toString()); } } + + private enum AnnotationsKind { + KOTLIN_SIGNATURE(JvmStdlibNames.KOTLIN_SIGNATURE.getFqName().asString()), + NOT_NULL(AnnotationUtil.NOT_NULL), + ANY(AnnotationUtil.NOT_NULL, JvmStdlibNames.KOTLIN_SIGNATURE.getFqName().asString()); + + public final String[] annotationNames; + + private AnnotationsKind(@NotNull String... annotationNames) { + this.annotationNames = annotationNames; + } + } } From 7e58d8312194639da1328caa0618206748f86e77 Mon Sep 17 00:00:00 2001 From: Nikita Skvortsov Date: Sun, 26 May 2013 22:06:10 +0400 Subject: [PATCH 174/249] rename module --- libraries/pom.xml | 2 +- .../.gitignore | 0 .../gradle_api_jar/.gitignore | 0 .../gradle_api_jar/README.txt | 14 +-- .../gradle_api_jar/build.gradle | 0 .../gradle/wrapper/gradle-wrapper.jar | Bin .../gradle/wrapper/gradle-wrapper.properties | 0 .../gradle_api_jar/gradlew | 0 .../gradle_api_jar/gradlew.bat | 0 .../gradle_api_jar/pom.xml | 102 +++++++++--------- .../gradle_api_jar/settings.gradle | 0 .../com/google/common/base/annotations.xml | 0 .../com/google/common/io/annotations.xml | 8 +- .../org/apache/commons/io/annotations.xml | 8 +- .../org/gradle/api/annotations.xml | 0 .../org/gradle/api/file/annotations.xml | 0 .../api/initialization/dsl/annotations.xml | 0 .../org/gradle/api/internal/annotations.xml | 0 .../api/internal/project/annotations.xml | 0 .../org/gradle/api/logging/annotations.xml | 8 +- .../org/gradle/api/plugins/annotations.xml | 0 .../org/gradle/api/tasks/annotations.xml | 0 .../gradle/api/tasks/compile/annotations.xml | 0 .../pom.xml | 2 +- .../kotlin/gradle/internal/KotlinSourceSet.kt | 0 .../kotlin/gradle/plugin/KotlinPlugin.kt | 0 .../jetbrains/kotlin/gradle/tasks/Tasks.kt | 0 .../META-INF/gradle-plugins/kotlin.properties | 0 .../kotlin/gradle/KotlinGradlePluginIT.kt | 0 .../resources/testProject/alfa/build.gradle | 0 .../com/google/common/base/annotations.xml | 0 .../alfa/gradle/wrapper/gradle-wrapper.jar | Bin .../gradle/wrapper/gradle-wrapper.properties | 0 .../test/resources/testProject/alfa/gradlew | 0 .../resources/testProject/alfa/gradlew.bat | 0 .../alfa/src/deploy/kotlin/kotlinSrc.kt | 0 .../alfa/src/main/java/demo/Greeter.java | 0 .../alfa/src/main/java/demo/HelloWorld.java | 0 .../alfa/src/main/kotlin/helloWorld.kt | 0 .../testProject/alfa/src/test/kotlin/tests.kt | 0 40 files changed, 72 insertions(+), 72 deletions(-) rename libraries/tools/{kotlin-gradle-plugin => kotlin-gradle-plugin-core}/.gitignore (100%) rename libraries/tools/{kotlin-gradle-plugin => kotlin-gradle-plugin-core}/gradle_api_jar/.gitignore (100%) rename libraries/tools/{kotlin-gradle-plugin => kotlin-gradle-plugin-core}/gradle_api_jar/README.txt (96%) rename libraries/tools/{kotlin-gradle-plugin => kotlin-gradle-plugin-core}/gradle_api_jar/build.gradle (100%) rename libraries/tools/{kotlin-gradle-plugin => kotlin-gradle-plugin-core}/gradle_api_jar/gradle/wrapper/gradle-wrapper.jar (100%) rename libraries/tools/{kotlin-gradle-plugin => kotlin-gradle-plugin-core}/gradle_api_jar/gradle/wrapper/gradle-wrapper.properties (100%) rename libraries/tools/{kotlin-gradle-plugin => kotlin-gradle-plugin-core}/gradle_api_jar/gradlew (100%) rename libraries/tools/{kotlin-gradle-plugin => kotlin-gradle-plugin-core}/gradle_api_jar/gradlew.bat (100%) rename libraries/tools/{kotlin-gradle-plugin => kotlin-gradle-plugin-core}/gradle_api_jar/pom.xml (97%) rename libraries/tools/{kotlin-gradle-plugin => kotlin-gradle-plugin-core}/gradle_api_jar/settings.gradle (100%) rename libraries/tools/{kotlin-gradle-plugin => kotlin-gradle-plugin-core}/kotlinAnnotation/com/google/common/base/annotations.xml (100%) rename libraries/tools/{kotlin-gradle-plugin => kotlin-gradle-plugin-core}/kotlinAnnotation/com/google/common/io/annotations.xml (97%) rename libraries/tools/{kotlin-gradle-plugin => kotlin-gradle-plugin-core}/kotlinAnnotation/org/apache/commons/io/annotations.xml (97%) rename libraries/tools/{kotlin-gradle-plugin => kotlin-gradle-plugin-core}/kotlinAnnotation/org/gradle/api/annotations.xml (100%) rename libraries/tools/{kotlin-gradle-plugin => kotlin-gradle-plugin-core}/kotlinAnnotation/org/gradle/api/file/annotations.xml (100%) rename libraries/tools/{kotlin-gradle-plugin => kotlin-gradle-plugin-core}/kotlinAnnotation/org/gradle/api/initialization/dsl/annotations.xml (100%) rename libraries/tools/{kotlin-gradle-plugin => kotlin-gradle-plugin-core}/kotlinAnnotation/org/gradle/api/internal/annotations.xml (100%) rename libraries/tools/{kotlin-gradle-plugin => kotlin-gradle-plugin-core}/kotlinAnnotation/org/gradle/api/internal/project/annotations.xml (100%) rename libraries/tools/{kotlin-gradle-plugin => kotlin-gradle-plugin-core}/kotlinAnnotation/org/gradle/api/logging/annotations.xml (97%) rename libraries/tools/{kotlin-gradle-plugin => kotlin-gradle-plugin-core}/kotlinAnnotation/org/gradle/api/plugins/annotations.xml (100%) rename libraries/tools/{kotlin-gradle-plugin => kotlin-gradle-plugin-core}/kotlinAnnotation/org/gradle/api/tasks/annotations.xml (100%) rename libraries/tools/{kotlin-gradle-plugin => kotlin-gradle-plugin-core}/kotlinAnnotation/org/gradle/api/tasks/compile/annotations.xml (100%) rename libraries/tools/{kotlin-gradle-plugin => kotlin-gradle-plugin-core}/pom.xml (99%) rename libraries/tools/{kotlin-gradle-plugin => kotlin-gradle-plugin-core}/src/main/kotlin/org/jetbrains/kotlin/gradle/internal/KotlinSourceSet.kt (100%) rename libraries/tools/{kotlin-gradle-plugin => kotlin-gradle-plugin-core}/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/KotlinPlugin.kt (100%) rename libraries/tools/{kotlin-gradle-plugin => kotlin-gradle-plugin-core}/src/main/kotlin/org/jetbrains/kotlin/gradle/tasks/Tasks.kt (100%) rename libraries/tools/{kotlin-gradle-plugin => kotlin-gradle-plugin-core}/src/main/resources/META-INF/gradle-plugins/kotlin.properties (100%) rename libraries/tools/{kotlin-gradle-plugin => kotlin-gradle-plugin-core}/src/test/kotlin/org/jetbrains/kotlin/gradle/KotlinGradlePluginIT.kt (100%) rename libraries/tools/{kotlin-gradle-plugin => kotlin-gradle-plugin-core}/src/test/resources/testProject/alfa/build.gradle (100%) rename libraries/tools/{kotlin-gradle-plugin => kotlin-gradle-plugin-core}/src/test/resources/testProject/alfa/externalAnnotations/com/google/common/base/annotations.xml (100%) rename libraries/tools/{kotlin-gradle-plugin => kotlin-gradle-plugin-core}/src/test/resources/testProject/alfa/gradle/wrapper/gradle-wrapper.jar (100%) rename libraries/tools/{kotlin-gradle-plugin => kotlin-gradle-plugin-core}/src/test/resources/testProject/alfa/gradle/wrapper/gradle-wrapper.properties (100%) rename libraries/tools/{kotlin-gradle-plugin => kotlin-gradle-plugin-core}/src/test/resources/testProject/alfa/gradlew (100%) rename libraries/tools/{kotlin-gradle-plugin => kotlin-gradle-plugin-core}/src/test/resources/testProject/alfa/gradlew.bat (100%) rename libraries/tools/{kotlin-gradle-plugin => kotlin-gradle-plugin-core}/src/test/resources/testProject/alfa/src/deploy/kotlin/kotlinSrc.kt (100%) rename libraries/tools/{kotlin-gradle-plugin => kotlin-gradle-plugin-core}/src/test/resources/testProject/alfa/src/main/java/demo/Greeter.java (100%) rename libraries/tools/{kotlin-gradle-plugin => kotlin-gradle-plugin-core}/src/test/resources/testProject/alfa/src/main/java/demo/HelloWorld.java (100%) rename libraries/tools/{kotlin-gradle-plugin => kotlin-gradle-plugin-core}/src/test/resources/testProject/alfa/src/main/kotlin/helloWorld.kt (100%) rename libraries/tools/{kotlin-gradle-plugin => kotlin-gradle-plugin-core}/src/test/resources/testProject/alfa/src/test/kotlin/tests.kt (100%) diff --git a/libraries/pom.xml b/libraries/pom.xml index b3e31788884..560c1a1e5e6 100644 --- a/libraries/pom.xml +++ b/libraries/pom.xml @@ -56,7 +56,7 @@ tools/kotlin-compiler tools/kotlin-jdk-annotations tools/runtime - tools/kotlin-gradle-plugin + tools/kotlin-gradle-plugin-core tools/kotlin-maven-plugin tools/kotlin-js-library tools/kotlin-js-tests diff --git a/libraries/tools/kotlin-gradle-plugin/.gitignore b/libraries/tools/kotlin-gradle-plugin-core/.gitignore similarity index 100% rename from libraries/tools/kotlin-gradle-plugin/.gitignore rename to libraries/tools/kotlin-gradle-plugin-core/.gitignore diff --git a/libraries/tools/kotlin-gradle-plugin/gradle_api_jar/.gitignore b/libraries/tools/kotlin-gradle-plugin-core/gradle_api_jar/.gitignore similarity index 100% rename from libraries/tools/kotlin-gradle-plugin/gradle_api_jar/.gitignore rename to libraries/tools/kotlin-gradle-plugin-core/gradle_api_jar/.gitignore diff --git a/libraries/tools/kotlin-gradle-plugin/gradle_api_jar/README.txt b/libraries/tools/kotlin-gradle-plugin-core/gradle_api_jar/README.txt similarity index 96% rename from libraries/tools/kotlin-gradle-plugin/gradle_api_jar/README.txt rename to libraries/tools/kotlin-gradle-plugin-core/gradle_api_jar/README.txt index c9045e657f0..df08dc77e0d 100644 --- a/libraries/tools/kotlin-gradle-plugin/gradle_api_jar/README.txt +++ b/libraries/tools/kotlin-gradle-plugin-core/gradle_api_jar/README.txt @@ -1,7 +1,7 @@ -Deploying gradle api to maven - - * gradlew build - -> build/libs/gradle-api-1.4.jar - - * mvn deploy - build/libs/gradle-api-1.4.jar -> http://repository.jetbrains.com/utils +Deploying gradle api to maven + + * gradlew build + -> build/libs/gradle-api-1.4.jar + + * mvn deploy + build/libs/gradle-api-1.4.jar -> http://repository.jetbrains.com/utils diff --git a/libraries/tools/kotlin-gradle-plugin/gradle_api_jar/build.gradle b/libraries/tools/kotlin-gradle-plugin-core/gradle_api_jar/build.gradle similarity index 100% rename from libraries/tools/kotlin-gradle-plugin/gradle_api_jar/build.gradle rename to libraries/tools/kotlin-gradle-plugin-core/gradle_api_jar/build.gradle diff --git a/libraries/tools/kotlin-gradle-plugin/gradle_api_jar/gradle/wrapper/gradle-wrapper.jar b/libraries/tools/kotlin-gradle-plugin-core/gradle_api_jar/gradle/wrapper/gradle-wrapper.jar similarity index 100% rename from libraries/tools/kotlin-gradle-plugin/gradle_api_jar/gradle/wrapper/gradle-wrapper.jar rename to libraries/tools/kotlin-gradle-plugin-core/gradle_api_jar/gradle/wrapper/gradle-wrapper.jar diff --git a/libraries/tools/kotlin-gradle-plugin/gradle_api_jar/gradle/wrapper/gradle-wrapper.properties b/libraries/tools/kotlin-gradle-plugin-core/gradle_api_jar/gradle/wrapper/gradle-wrapper.properties similarity index 100% rename from libraries/tools/kotlin-gradle-plugin/gradle_api_jar/gradle/wrapper/gradle-wrapper.properties rename to libraries/tools/kotlin-gradle-plugin-core/gradle_api_jar/gradle/wrapper/gradle-wrapper.properties diff --git a/libraries/tools/kotlin-gradle-plugin/gradle_api_jar/gradlew b/libraries/tools/kotlin-gradle-plugin-core/gradle_api_jar/gradlew similarity index 100% rename from libraries/tools/kotlin-gradle-plugin/gradle_api_jar/gradlew rename to libraries/tools/kotlin-gradle-plugin-core/gradle_api_jar/gradlew diff --git a/libraries/tools/kotlin-gradle-plugin/gradle_api_jar/gradlew.bat b/libraries/tools/kotlin-gradle-plugin-core/gradle_api_jar/gradlew.bat similarity index 100% rename from libraries/tools/kotlin-gradle-plugin/gradle_api_jar/gradlew.bat rename to libraries/tools/kotlin-gradle-plugin-core/gradle_api_jar/gradlew.bat diff --git a/libraries/tools/kotlin-gradle-plugin/gradle_api_jar/pom.xml b/libraries/tools/kotlin-gradle-plugin-core/gradle_api_jar/pom.xml similarity index 97% rename from libraries/tools/kotlin-gradle-plugin/gradle_api_jar/pom.xml rename to libraries/tools/kotlin-gradle-plugin-core/gradle_api_jar/pom.xml index b5e367c2c68..ab208885125 100644 --- a/libraries/tools/kotlin-gradle-plugin/gradle_api_jar/pom.xml +++ b/libraries/tools/kotlin-gradle-plugin-core/gradle_api_jar/pom.xml @@ -1,51 +1,51 @@ - - - - 4.0.0 - - 1.4.1 - 3.0.4 - - - org.jetbrains.kotlin - gradle-api - pom - 1.4 - - - - - org.codehaus.mojo - build-helper-maven-plugin - 1.7 - - - attach-artifacts - compile - - attach-artifact - - - - - build/libs/gradle-api-1.4.jar - jar - - - - - - - - - - - - utils - http://repository.jetbrains.com/utils - - - - + + + + 4.0.0 + + 1.4.1 + 3.0.4 + + + org.jetbrains.kotlin + gradle-api + pom + 1.4 + + + + + org.codehaus.mojo + build-helper-maven-plugin + 1.7 + + + attach-artifacts + compile + + attach-artifact + + + + + build/libs/gradle-api-1.4.jar + jar + + + + + + + + + + + + utils + http://repository.jetbrains.com/utils + + + + diff --git a/libraries/tools/kotlin-gradle-plugin/gradle_api_jar/settings.gradle b/libraries/tools/kotlin-gradle-plugin-core/gradle_api_jar/settings.gradle similarity index 100% rename from libraries/tools/kotlin-gradle-plugin/gradle_api_jar/settings.gradle rename to libraries/tools/kotlin-gradle-plugin-core/gradle_api_jar/settings.gradle diff --git a/libraries/tools/kotlin-gradle-plugin/kotlinAnnotation/com/google/common/base/annotations.xml b/libraries/tools/kotlin-gradle-plugin-core/kotlinAnnotation/com/google/common/base/annotations.xml similarity index 100% rename from libraries/tools/kotlin-gradle-plugin/kotlinAnnotation/com/google/common/base/annotations.xml rename to libraries/tools/kotlin-gradle-plugin-core/kotlinAnnotation/com/google/common/base/annotations.xml diff --git a/libraries/tools/kotlin-gradle-plugin/kotlinAnnotation/com/google/common/io/annotations.xml b/libraries/tools/kotlin-gradle-plugin-core/kotlinAnnotation/com/google/common/io/annotations.xml similarity index 97% rename from libraries/tools/kotlin-gradle-plugin/kotlinAnnotation/com/google/common/io/annotations.xml rename to libraries/tools/kotlin-gradle-plugin-core/kotlinAnnotation/com/google/common/io/annotations.xml index b7f0b110ddc..64ac65dcca1 100644 --- a/libraries/tools/kotlin-gradle-plugin/kotlinAnnotation/com/google/common/io/annotations.xml +++ b/libraries/tools/kotlin-gradle-plugin-core/kotlinAnnotation/com/google/common/io/annotations.xml @@ -1,5 +1,5 @@ - - - - + + + + \ No newline at end of file diff --git a/libraries/tools/kotlin-gradle-plugin/kotlinAnnotation/org/apache/commons/io/annotations.xml b/libraries/tools/kotlin-gradle-plugin-core/kotlinAnnotation/org/apache/commons/io/annotations.xml similarity index 97% rename from libraries/tools/kotlin-gradle-plugin/kotlinAnnotation/org/apache/commons/io/annotations.xml rename to libraries/tools/kotlin-gradle-plugin-core/kotlinAnnotation/org/apache/commons/io/annotations.xml index 86f130b880e..0aee42a6e6a 100644 --- a/libraries/tools/kotlin-gradle-plugin/kotlinAnnotation/org/apache/commons/io/annotations.xml +++ b/libraries/tools/kotlin-gradle-plugin-core/kotlinAnnotation/org/apache/commons/io/annotations.xml @@ -1,5 +1,5 @@ - - - - + + + + \ No newline at end of file diff --git a/libraries/tools/kotlin-gradle-plugin/kotlinAnnotation/org/gradle/api/annotations.xml b/libraries/tools/kotlin-gradle-plugin-core/kotlinAnnotation/org/gradle/api/annotations.xml similarity index 100% rename from libraries/tools/kotlin-gradle-plugin/kotlinAnnotation/org/gradle/api/annotations.xml rename to libraries/tools/kotlin-gradle-plugin-core/kotlinAnnotation/org/gradle/api/annotations.xml diff --git a/libraries/tools/kotlin-gradle-plugin/kotlinAnnotation/org/gradle/api/file/annotations.xml b/libraries/tools/kotlin-gradle-plugin-core/kotlinAnnotation/org/gradle/api/file/annotations.xml similarity index 100% rename from libraries/tools/kotlin-gradle-plugin/kotlinAnnotation/org/gradle/api/file/annotations.xml rename to libraries/tools/kotlin-gradle-plugin-core/kotlinAnnotation/org/gradle/api/file/annotations.xml diff --git a/libraries/tools/kotlin-gradle-plugin/kotlinAnnotation/org/gradle/api/initialization/dsl/annotations.xml b/libraries/tools/kotlin-gradle-plugin-core/kotlinAnnotation/org/gradle/api/initialization/dsl/annotations.xml similarity index 100% rename from libraries/tools/kotlin-gradle-plugin/kotlinAnnotation/org/gradle/api/initialization/dsl/annotations.xml rename to libraries/tools/kotlin-gradle-plugin-core/kotlinAnnotation/org/gradle/api/initialization/dsl/annotations.xml diff --git a/libraries/tools/kotlin-gradle-plugin/kotlinAnnotation/org/gradle/api/internal/annotations.xml b/libraries/tools/kotlin-gradle-plugin-core/kotlinAnnotation/org/gradle/api/internal/annotations.xml similarity index 100% rename from libraries/tools/kotlin-gradle-plugin/kotlinAnnotation/org/gradle/api/internal/annotations.xml rename to libraries/tools/kotlin-gradle-plugin-core/kotlinAnnotation/org/gradle/api/internal/annotations.xml diff --git a/libraries/tools/kotlin-gradle-plugin/kotlinAnnotation/org/gradle/api/internal/project/annotations.xml b/libraries/tools/kotlin-gradle-plugin-core/kotlinAnnotation/org/gradle/api/internal/project/annotations.xml similarity index 100% rename from libraries/tools/kotlin-gradle-plugin/kotlinAnnotation/org/gradle/api/internal/project/annotations.xml rename to libraries/tools/kotlin-gradle-plugin-core/kotlinAnnotation/org/gradle/api/internal/project/annotations.xml diff --git a/libraries/tools/kotlin-gradle-plugin/kotlinAnnotation/org/gradle/api/logging/annotations.xml b/libraries/tools/kotlin-gradle-plugin-core/kotlinAnnotation/org/gradle/api/logging/annotations.xml similarity index 97% rename from libraries/tools/kotlin-gradle-plugin/kotlinAnnotation/org/gradle/api/logging/annotations.xml rename to libraries/tools/kotlin-gradle-plugin-core/kotlinAnnotation/org/gradle/api/logging/annotations.xml index 7ee1ff08665..87c8bc5da18 100644 --- a/libraries/tools/kotlin-gradle-plugin/kotlinAnnotation/org/gradle/api/logging/annotations.xml +++ b/libraries/tools/kotlin-gradle-plugin-core/kotlinAnnotation/org/gradle/api/logging/annotations.xml @@ -1,5 +1,5 @@ - - - - + + + + \ No newline at end of file diff --git a/libraries/tools/kotlin-gradle-plugin/kotlinAnnotation/org/gradle/api/plugins/annotations.xml b/libraries/tools/kotlin-gradle-plugin-core/kotlinAnnotation/org/gradle/api/plugins/annotations.xml similarity index 100% rename from libraries/tools/kotlin-gradle-plugin/kotlinAnnotation/org/gradle/api/plugins/annotations.xml rename to libraries/tools/kotlin-gradle-plugin-core/kotlinAnnotation/org/gradle/api/plugins/annotations.xml diff --git a/libraries/tools/kotlin-gradle-plugin/kotlinAnnotation/org/gradle/api/tasks/annotations.xml b/libraries/tools/kotlin-gradle-plugin-core/kotlinAnnotation/org/gradle/api/tasks/annotations.xml similarity index 100% rename from libraries/tools/kotlin-gradle-plugin/kotlinAnnotation/org/gradle/api/tasks/annotations.xml rename to libraries/tools/kotlin-gradle-plugin-core/kotlinAnnotation/org/gradle/api/tasks/annotations.xml diff --git a/libraries/tools/kotlin-gradle-plugin/kotlinAnnotation/org/gradle/api/tasks/compile/annotations.xml b/libraries/tools/kotlin-gradle-plugin-core/kotlinAnnotation/org/gradle/api/tasks/compile/annotations.xml similarity index 100% rename from libraries/tools/kotlin-gradle-plugin/kotlinAnnotation/org/gradle/api/tasks/compile/annotations.xml rename to libraries/tools/kotlin-gradle-plugin-core/kotlinAnnotation/org/gradle/api/tasks/compile/annotations.xml diff --git a/libraries/tools/kotlin-gradle-plugin/pom.xml b/libraries/tools/kotlin-gradle-plugin-core/pom.xml similarity index 99% rename from libraries/tools/kotlin-gradle-plugin/pom.xml rename to libraries/tools/kotlin-gradle-plugin-core/pom.xml index f3602e2ce62..2c558ae18e8 100644 --- a/libraries/tools/kotlin-gradle-plugin/pom.xml +++ b/libraries/tools/kotlin-gradle-plugin-core/pom.xml @@ -16,7 +16,7 @@ ../../pom.xml - kotlin-gradle-plugin + kotlin-gradle-plugin-core jar diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/internal/KotlinSourceSet.kt b/libraries/tools/kotlin-gradle-plugin-core/src/main/kotlin/org/jetbrains/kotlin/gradle/internal/KotlinSourceSet.kt similarity index 100% rename from libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/internal/KotlinSourceSet.kt rename to libraries/tools/kotlin-gradle-plugin-core/src/main/kotlin/org/jetbrains/kotlin/gradle/internal/KotlinSourceSet.kt diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/KotlinPlugin.kt b/libraries/tools/kotlin-gradle-plugin-core/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/KotlinPlugin.kt similarity index 100% rename from libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/KotlinPlugin.kt rename to libraries/tools/kotlin-gradle-plugin-core/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/KotlinPlugin.kt diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/tasks/Tasks.kt b/libraries/tools/kotlin-gradle-plugin-core/src/main/kotlin/org/jetbrains/kotlin/gradle/tasks/Tasks.kt similarity index 100% rename from libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/tasks/Tasks.kt rename to libraries/tools/kotlin-gradle-plugin-core/src/main/kotlin/org/jetbrains/kotlin/gradle/tasks/Tasks.kt diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/resources/META-INF/gradle-plugins/kotlin.properties b/libraries/tools/kotlin-gradle-plugin-core/src/main/resources/META-INF/gradle-plugins/kotlin.properties similarity index 100% rename from libraries/tools/kotlin-gradle-plugin/src/main/resources/META-INF/gradle-plugins/kotlin.properties rename to libraries/tools/kotlin-gradle-plugin-core/src/main/resources/META-INF/gradle-plugins/kotlin.properties diff --git a/libraries/tools/kotlin-gradle-plugin/src/test/kotlin/org/jetbrains/kotlin/gradle/KotlinGradlePluginIT.kt b/libraries/tools/kotlin-gradle-plugin-core/src/test/kotlin/org/jetbrains/kotlin/gradle/KotlinGradlePluginIT.kt similarity index 100% rename from libraries/tools/kotlin-gradle-plugin/src/test/kotlin/org/jetbrains/kotlin/gradle/KotlinGradlePluginIT.kt rename to libraries/tools/kotlin-gradle-plugin-core/src/test/kotlin/org/jetbrains/kotlin/gradle/KotlinGradlePluginIT.kt diff --git a/libraries/tools/kotlin-gradle-plugin/src/test/resources/testProject/alfa/build.gradle b/libraries/tools/kotlin-gradle-plugin-core/src/test/resources/testProject/alfa/build.gradle similarity index 100% rename from libraries/tools/kotlin-gradle-plugin/src/test/resources/testProject/alfa/build.gradle rename to libraries/tools/kotlin-gradle-plugin-core/src/test/resources/testProject/alfa/build.gradle diff --git a/libraries/tools/kotlin-gradle-plugin/src/test/resources/testProject/alfa/externalAnnotations/com/google/common/base/annotations.xml b/libraries/tools/kotlin-gradle-plugin-core/src/test/resources/testProject/alfa/externalAnnotations/com/google/common/base/annotations.xml similarity index 100% rename from libraries/tools/kotlin-gradle-plugin/src/test/resources/testProject/alfa/externalAnnotations/com/google/common/base/annotations.xml rename to libraries/tools/kotlin-gradle-plugin-core/src/test/resources/testProject/alfa/externalAnnotations/com/google/common/base/annotations.xml diff --git a/libraries/tools/kotlin-gradle-plugin/src/test/resources/testProject/alfa/gradle/wrapper/gradle-wrapper.jar b/libraries/tools/kotlin-gradle-plugin-core/src/test/resources/testProject/alfa/gradle/wrapper/gradle-wrapper.jar similarity index 100% rename from libraries/tools/kotlin-gradle-plugin/src/test/resources/testProject/alfa/gradle/wrapper/gradle-wrapper.jar rename to libraries/tools/kotlin-gradle-plugin-core/src/test/resources/testProject/alfa/gradle/wrapper/gradle-wrapper.jar diff --git a/libraries/tools/kotlin-gradle-plugin/src/test/resources/testProject/alfa/gradle/wrapper/gradle-wrapper.properties b/libraries/tools/kotlin-gradle-plugin-core/src/test/resources/testProject/alfa/gradle/wrapper/gradle-wrapper.properties similarity index 100% rename from libraries/tools/kotlin-gradle-plugin/src/test/resources/testProject/alfa/gradle/wrapper/gradle-wrapper.properties rename to libraries/tools/kotlin-gradle-plugin-core/src/test/resources/testProject/alfa/gradle/wrapper/gradle-wrapper.properties diff --git a/libraries/tools/kotlin-gradle-plugin/src/test/resources/testProject/alfa/gradlew b/libraries/tools/kotlin-gradle-plugin-core/src/test/resources/testProject/alfa/gradlew similarity index 100% rename from libraries/tools/kotlin-gradle-plugin/src/test/resources/testProject/alfa/gradlew rename to libraries/tools/kotlin-gradle-plugin-core/src/test/resources/testProject/alfa/gradlew diff --git a/libraries/tools/kotlin-gradle-plugin/src/test/resources/testProject/alfa/gradlew.bat b/libraries/tools/kotlin-gradle-plugin-core/src/test/resources/testProject/alfa/gradlew.bat similarity index 100% rename from libraries/tools/kotlin-gradle-plugin/src/test/resources/testProject/alfa/gradlew.bat rename to libraries/tools/kotlin-gradle-plugin-core/src/test/resources/testProject/alfa/gradlew.bat diff --git a/libraries/tools/kotlin-gradle-plugin/src/test/resources/testProject/alfa/src/deploy/kotlin/kotlinSrc.kt b/libraries/tools/kotlin-gradle-plugin-core/src/test/resources/testProject/alfa/src/deploy/kotlin/kotlinSrc.kt similarity index 100% rename from libraries/tools/kotlin-gradle-plugin/src/test/resources/testProject/alfa/src/deploy/kotlin/kotlinSrc.kt rename to libraries/tools/kotlin-gradle-plugin-core/src/test/resources/testProject/alfa/src/deploy/kotlin/kotlinSrc.kt diff --git a/libraries/tools/kotlin-gradle-plugin/src/test/resources/testProject/alfa/src/main/java/demo/Greeter.java b/libraries/tools/kotlin-gradle-plugin-core/src/test/resources/testProject/alfa/src/main/java/demo/Greeter.java similarity index 100% rename from libraries/tools/kotlin-gradle-plugin/src/test/resources/testProject/alfa/src/main/java/demo/Greeter.java rename to libraries/tools/kotlin-gradle-plugin-core/src/test/resources/testProject/alfa/src/main/java/demo/Greeter.java diff --git a/libraries/tools/kotlin-gradle-plugin/src/test/resources/testProject/alfa/src/main/java/demo/HelloWorld.java b/libraries/tools/kotlin-gradle-plugin-core/src/test/resources/testProject/alfa/src/main/java/demo/HelloWorld.java similarity index 100% rename from libraries/tools/kotlin-gradle-plugin/src/test/resources/testProject/alfa/src/main/java/demo/HelloWorld.java rename to libraries/tools/kotlin-gradle-plugin-core/src/test/resources/testProject/alfa/src/main/java/demo/HelloWorld.java diff --git a/libraries/tools/kotlin-gradle-plugin/src/test/resources/testProject/alfa/src/main/kotlin/helloWorld.kt b/libraries/tools/kotlin-gradle-plugin-core/src/test/resources/testProject/alfa/src/main/kotlin/helloWorld.kt similarity index 100% rename from libraries/tools/kotlin-gradle-plugin/src/test/resources/testProject/alfa/src/main/kotlin/helloWorld.kt rename to libraries/tools/kotlin-gradle-plugin-core/src/test/resources/testProject/alfa/src/main/kotlin/helloWorld.kt diff --git a/libraries/tools/kotlin-gradle-plugin/src/test/resources/testProject/alfa/src/test/kotlin/tests.kt b/libraries/tools/kotlin-gradle-plugin-core/src/test/resources/testProject/alfa/src/test/kotlin/tests.kt similarity index 100% rename from libraries/tools/kotlin-gradle-plugin/src/test/resources/testProject/alfa/src/test/kotlin/tests.kt rename to libraries/tools/kotlin-gradle-plugin-core/src/test/resources/testProject/alfa/src/test/kotlin/tests.kt From 7e36547b3861bf9e59bd10fe4e87e19d2b95a9b8 Mon Sep 17 00:00:00 2001 From: Nikita Skvortsov Date: Wed, 29 May 2013 19:47:42 +0400 Subject: [PATCH 175/249] Added wrapper module for gradle plugin --- libraries/pom.xml | 1 + .../org/gradle/api/annotations.xml | 18 +++ .../org/gradle/api/file/annotations.xml | 5 + .../api/initialization/dsl/annotations.xml | 7 ++ .../org/gradle/api/internal/annotations.xml | 15 +++ .../api/internal/project/annotations.xml | 5 + .../org/gradle/api/logging/annotations.xml | 5 + .../org/gradle/api/plugins/annotations.xml | 22 ++++ .../org/gradle/api/tasks/annotations.xml | 7 ++ .../gradle/api/tasks/compile/annotations.xml | 5 + libraries/tools/kotlin-gradle-plugin/pom.xml | 107 ++++++++++++++++++ .../ParentLastURLClassLoader.java | 74 ++++++++++++ .../gradle/plugin/KotlinPluginWrapper.kt | 13 +++ .../META-INF/gradle-plugins/kotlin.properties | 2 +- 14 files changed, 285 insertions(+), 1 deletion(-) create mode 100644 libraries/tools/kotlin-gradle-plugin/kotlinAnnotation/org/gradle/api/annotations.xml create mode 100644 libraries/tools/kotlin-gradle-plugin/kotlinAnnotation/org/gradle/api/file/annotations.xml create mode 100644 libraries/tools/kotlin-gradle-plugin/kotlinAnnotation/org/gradle/api/initialization/dsl/annotations.xml create mode 100644 libraries/tools/kotlin-gradle-plugin/kotlinAnnotation/org/gradle/api/internal/annotations.xml create mode 100644 libraries/tools/kotlin-gradle-plugin/kotlinAnnotation/org/gradle/api/internal/project/annotations.xml create mode 100644 libraries/tools/kotlin-gradle-plugin/kotlinAnnotation/org/gradle/api/logging/annotations.xml create mode 100644 libraries/tools/kotlin-gradle-plugin/kotlinAnnotation/org/gradle/api/plugins/annotations.xml create mode 100644 libraries/tools/kotlin-gradle-plugin/kotlinAnnotation/org/gradle/api/tasks/annotations.xml create mode 100644 libraries/tools/kotlin-gradle-plugin/kotlinAnnotation/org/gradle/api/tasks/compile/annotations.xml create mode 100644 libraries/tools/kotlin-gradle-plugin/pom.xml create mode 100644 libraries/tools/kotlin-gradle-plugin/src/main/java/org/jetbrains/kotlin/gradle/classloaders/ParentLastURLClassLoader.java create mode 100644 libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/KotlinPluginWrapper.kt rename libraries/tools/{kotlin-gradle-plugin-core => kotlin-gradle-plugin}/src/main/resources/META-INF/gradle-plugins/kotlin.properties (85%) diff --git a/libraries/pom.xml b/libraries/pom.xml index 560c1a1e5e6..48652d81263 100644 --- a/libraries/pom.xml +++ b/libraries/pom.xml @@ -56,6 +56,7 @@ tools/kotlin-compiler tools/kotlin-jdk-annotations tools/runtime + tools/kotlin-gradle-plugin tools/kotlin-gradle-plugin-core tools/kotlin-maven-plugin tools/kotlin-js-library diff --git a/libraries/tools/kotlin-gradle-plugin/kotlinAnnotation/org/gradle/api/annotations.xml b/libraries/tools/kotlin-gradle-plugin/kotlinAnnotation/org/gradle/api/annotations.xml new file mode 100644 index 00000000000..dc5cd1bbcbe --- /dev/null +++ b/libraries/tools/kotlin-gradle-plugin/kotlinAnnotation/org/gradle/api/annotations.xml @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/libraries/tools/kotlin-gradle-plugin/kotlinAnnotation/org/gradle/api/file/annotations.xml b/libraries/tools/kotlin-gradle-plugin/kotlinAnnotation/org/gradle/api/file/annotations.xml new file mode 100644 index 00000000000..dea5cec6774 --- /dev/null +++ b/libraries/tools/kotlin-gradle-plugin/kotlinAnnotation/org/gradle/api/file/annotations.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/libraries/tools/kotlin-gradle-plugin/kotlinAnnotation/org/gradle/api/initialization/dsl/annotations.xml b/libraries/tools/kotlin-gradle-plugin/kotlinAnnotation/org/gradle/api/initialization/dsl/annotations.xml new file mode 100644 index 00000000000..a33a584b9ed --- /dev/null +++ b/libraries/tools/kotlin-gradle-plugin/kotlinAnnotation/org/gradle/api/initialization/dsl/annotations.xml @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff --git a/libraries/tools/kotlin-gradle-plugin/kotlinAnnotation/org/gradle/api/internal/annotations.xml b/libraries/tools/kotlin-gradle-plugin/kotlinAnnotation/org/gradle/api/internal/annotations.xml new file mode 100644 index 00000000000..c14ebed20ae --- /dev/null +++ b/libraries/tools/kotlin-gradle-plugin/kotlinAnnotation/org/gradle/api/internal/annotations.xml @@ -0,0 +1,15 @@ + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/libraries/tools/kotlin-gradle-plugin/kotlinAnnotation/org/gradle/api/internal/project/annotations.xml b/libraries/tools/kotlin-gradle-plugin/kotlinAnnotation/org/gradle/api/internal/project/annotations.xml new file mode 100644 index 00000000000..6595499a4a1 --- /dev/null +++ b/libraries/tools/kotlin-gradle-plugin/kotlinAnnotation/org/gradle/api/internal/project/annotations.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/libraries/tools/kotlin-gradle-plugin/kotlinAnnotation/org/gradle/api/logging/annotations.xml b/libraries/tools/kotlin-gradle-plugin/kotlinAnnotation/org/gradle/api/logging/annotations.xml new file mode 100644 index 00000000000..87c8bc5da18 --- /dev/null +++ b/libraries/tools/kotlin-gradle-plugin/kotlinAnnotation/org/gradle/api/logging/annotations.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/libraries/tools/kotlin-gradle-plugin/kotlinAnnotation/org/gradle/api/plugins/annotations.xml b/libraries/tools/kotlin-gradle-plugin/kotlinAnnotation/org/gradle/api/plugins/annotations.xml new file mode 100644 index 00000000000..5859b33807e --- /dev/null +++ b/libraries/tools/kotlin-gradle-plugin/kotlinAnnotation/org/gradle/api/plugins/annotations.xml @@ -0,0 +1,22 @@ + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/libraries/tools/kotlin-gradle-plugin/kotlinAnnotation/org/gradle/api/tasks/annotations.xml b/libraries/tools/kotlin-gradle-plugin/kotlinAnnotation/org/gradle/api/tasks/annotations.xml new file mode 100644 index 00000000000..67bc433ea20 --- /dev/null +++ b/libraries/tools/kotlin-gradle-plugin/kotlinAnnotation/org/gradle/api/tasks/annotations.xml @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff --git a/libraries/tools/kotlin-gradle-plugin/kotlinAnnotation/org/gradle/api/tasks/compile/annotations.xml b/libraries/tools/kotlin-gradle-plugin/kotlinAnnotation/org/gradle/api/tasks/compile/annotations.xml new file mode 100644 index 00000000000..812dfa500fa --- /dev/null +++ b/libraries/tools/kotlin-gradle-plugin/kotlinAnnotation/org/gradle/api/tasks/compile/annotations.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/libraries/tools/kotlin-gradle-plugin/pom.xml b/libraries/tools/kotlin-gradle-plugin/pom.xml new file mode 100644 index 00000000000..543601c16bb --- /dev/null +++ b/libraries/tools/kotlin-gradle-plugin/pom.xml @@ -0,0 +1,107 @@ + + + + + 4.0.0 + + 3.0.4 + + + + org.jetbrains.kotlin + kotlin-project + 0.1-SNAPSHOT + ../../pom.xml + + + kotlin-gradle-plugin-core + jar + + + + org.jetbrains.kotlin + gradle-api + 1.4 + provided + + + + + + ${project.basedir}/src/main/kotlin + ${project.basedir}/src/test/kotlin + + + + ${project.basedir}/src/main/resources + + + + + + kotlin-maven-plugin + org.jetbrains.kotlin + ${project.version} + + + ${basedir}/kotlinAnnotation + + + + + + compile + compile + compile + + + + test-compile + test-compile + test-compile + + + + + + maven-invoker-plugin + 1.8 + + ${project.build.directory}/it + local-repo + verify + + + + create_local + pre-integration-test + + install + + + + + + maven-failsafe-plugin + 2.6 + + + + integration-test + verify + + + + + + + + + + jetbrains-utils + http://repository.jetbrains.com/utils + + + \ No newline at end of file diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/java/org/jetbrains/kotlin/gradle/classloaders/ParentLastURLClassLoader.java b/libraries/tools/kotlin-gradle-plugin/src/main/java/org/jetbrains/kotlin/gradle/classloaders/ParentLastURLClassLoader.java new file mode 100644 index 00000000000..d71acde71e3 --- /dev/null +++ b/libraries/tools/kotlin-gradle-plugin/src/main/java/org/jetbrains/kotlin/gradle/classloaders/ParentLastURLClassLoader.java @@ -0,0 +1,74 @@ +package org.jetbrains.kotlin.gradle.classloaders; + + +import java.net.URL; +import java.net.URLClassLoader; +import java.util.List; + +/** + * A parent-last classloader that will try the child classloader first and then the parent. + * This takes a fair bit of doing because java really prefers parent-first. + *

+ * For those not familiar with class loading trickery, be wary + */ +public class ParentLastURLClassLoader extends ClassLoader { + private ChildURLClassLoader childClassLoader; + + public ParentLastURLClassLoader(List classpath, ClassLoader parent) { + super(Thread.currentThread().getContextClassLoader()); + + URL[] urls = classpath.toArray(new URL[classpath.size()]); + + childClassLoader = new ChildURLClassLoader(urls, new FindClassClassLoader(parent)); + } + + @Override + protected synchronized Class loadClass(String name, boolean resolve) throws ClassNotFoundException { + try { + // first we try to find a class inside the child classloader + return childClassLoader.findClass(name); + } catch (ClassNotFoundException e) { + // didn't find it, try the parent + return super.loadClass(name, resolve); + } + } + + /** + * This class allows me to call findClass on a classloader + */ + private static class FindClassClassLoader extends ClassLoader { + public FindClassClassLoader(ClassLoader parent) { + super(parent); + } + + @Override + public Class findClass(String name) throws ClassNotFoundException { + return super.findClass(name); + } + } + + /** + * This class delegates (child then parent) for the findClass method for a URLClassLoader. + * We need this because findClass is protected in URLClassLoader + */ + private static class ChildURLClassLoader extends URLClassLoader { + private FindClassClassLoader realParent; + + public ChildURLClassLoader(URL[] urls, FindClassClassLoader realParent) { + super(urls, null); + + this.realParent = realParent; + } + + @Override + public Class findClass(String name) throws ClassNotFoundException { + try { + // first try to use the URLClassLoader findClass + return super.findClass(name); + } catch (ClassNotFoundException e) { + // if that fails, we ask our real parent classloader to load the class (we give up) + return realParent.loadClass(name); + } + } + } +} diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/KotlinPluginWrapper.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/KotlinPluginWrapper.kt new file mode 100644 index 00000000000..611f34ad2aa --- /dev/null +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/KotlinPluginWrapper.kt @@ -0,0 +1,13 @@ +package org.jetbrains.kotlin.gradle.plugin + +import org.gradle.api.Plugin +import org.gradle.api.Project +import org.gradle.api.artifacts.dsl.DependencyHandler + +open class KotlinPluginWrapper: Plugin { + public override fun apply(project: Project) { + val dependencyHandler : DependencyHandler = project.getDependencies() + dependencyHandler.create("org.jetbrains.kotlin:kotlin-gradle-plugin-core:0.1-SNAPSHOT") + + } +} \ No newline at end of file diff --git a/libraries/tools/kotlin-gradle-plugin-core/src/main/resources/META-INF/gradle-plugins/kotlin.properties b/libraries/tools/kotlin-gradle-plugin/src/main/resources/META-INF/gradle-plugins/kotlin.properties similarity index 85% rename from libraries/tools/kotlin-gradle-plugin-core/src/main/resources/META-INF/gradle-plugins/kotlin.properties rename to libraries/tools/kotlin-gradle-plugin/src/main/resources/META-INF/gradle-plugins/kotlin.properties index 4f8cd030af6..3a22596804f 100644 --- a/libraries/tools/kotlin-gradle-plugin-core/src/main/resources/META-INF/gradle-plugins/kotlin.properties +++ b/libraries/tools/kotlin-gradle-plugin/src/main/resources/META-INF/gradle-plugins/kotlin.properties @@ -1 +1 @@ -implementation-class=org.jetbrains.kotlin.gradle.plugin.KotlinPlugin \ No newline at end of file +implementation-class=org.jetbrains.kotlin.gradle.plugin.KotlinPluginWrapper \ No newline at end of file From 308c12f45c2cd1001dfac0512f0e6c237b20a5e7 Mon Sep 17 00:00:00 2001 From: Nikita Skvortsov Date: Wed, 29 May 2013 20:15:32 +0400 Subject: [PATCH 176/249] first class loader wrapper implementation --- .../gradle/api/artifacts/dsl/annotations.xml | 5 ++++ libraries/tools/kotlin-gradle-plugin/pom.xml | 5 ++++ .../gradle/plugin/KotlinPluginWrapper.kt | 27 ++++++++++++++++--- .../plugin}/ParentLastURLClassLoader.java | 2 +- 4 files changed, 35 insertions(+), 4 deletions(-) create mode 100644 libraries/tools/kotlin-gradle-plugin/kotlinAnnotation/org/gradle/api/artifacts/dsl/annotations.xml rename libraries/tools/kotlin-gradle-plugin/src/main/{java/org/jetbrains/kotlin/gradle/classloaders => kotlin/org/jetbrains/kotlin/gradle/plugin}/ParentLastURLClassLoader.java (98%) diff --git a/libraries/tools/kotlin-gradle-plugin/kotlinAnnotation/org/gradle/api/artifacts/dsl/annotations.xml b/libraries/tools/kotlin-gradle-plugin/kotlinAnnotation/org/gradle/api/artifacts/dsl/annotations.xml new file mode 100644 index 00000000000..0402ed182e0 --- /dev/null +++ b/libraries/tools/kotlin-gradle-plugin/kotlinAnnotation/org/gradle/api/artifacts/dsl/annotations.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/libraries/tools/kotlin-gradle-plugin/pom.xml b/libraries/tools/kotlin-gradle-plugin/pom.xml index 543601c16bb..b4eb77b2478 100644 --- a/libraries/tools/kotlin-gradle-plugin/pom.xml +++ b/libraries/tools/kotlin-gradle-plugin/pom.xml @@ -20,6 +20,11 @@ jar + + org.jetbrains.kotlin + kotlin-stdlib + ${project.version} + org.jetbrains.kotlin gradle-api diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/KotlinPluginWrapper.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/KotlinPluginWrapper.kt index 611f34ad2aa..a32bdb94c3d 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/KotlinPluginWrapper.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/KotlinPluginWrapper.kt @@ -3,11 +3,32 @@ package org.jetbrains.kotlin.gradle.plugin import org.gradle.api.Plugin import org.gradle.api.Project import org.gradle.api.artifacts.dsl.DependencyHandler +import org.gradle.api.artifacts.ConfigurationContainer +import org.gradle.api.artifacts.Dependency +import org.gradle.api.specs.Spec +import java.io.File +import java.net.URL open class KotlinPluginWrapper: Plugin { public override fun apply(project: Project) { - val dependencyHandler : DependencyHandler = project.getDependencies() - dependencyHandler.create("org.jetbrains.kotlin:kotlin-gradle-plugin-core:0.1-SNAPSHOT") + val dependencyHandler : DependencyHandler = project.getDependencies()!! + val configurationsContainer : ConfigurationContainer = project.getConfigurations()!! + val dependency = dependencyHandler.create("org.jetbrains.kotlin:kotlin-gradle-plugin-core:0.1-SNAPSHOT") + val configuration = configurationsContainer.detachedConfiguration(dependency)!! + + val kotlinPluginDependencies : List = configuration.getResolvedConfiguration()!!.getFiles(KSpec({ dep -> true }))!!.map({(f: File):URL -> f.toURI().toURL() }) + val kotlinPluginClassloader = ParentLastURLClassLoader(kotlinPluginDependencies, getClass().getClassLoader()) + val cls = Class.forName("org.jetbrains.kotlin.gradle.plugin.KotlinPlugin", true, kotlinPluginClassloader) + val pluginInstance = cls.newInstance() + val applyMethod = cls.getMethod("apply", javaClass()) + + applyMethod.invoke(pluginInstance, project); } -} \ No newline at end of file +} + +open class KSpec(val predicate: (T) -> Boolean): Spec { + public override fun isSatisfiedBy(p0: T?): Boolean { + return p0 != null && predicate(p0) + } +} diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/java/org/jetbrains/kotlin/gradle/classloaders/ParentLastURLClassLoader.java b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/ParentLastURLClassLoader.java similarity index 98% rename from libraries/tools/kotlin-gradle-plugin/src/main/java/org/jetbrains/kotlin/gradle/classloaders/ParentLastURLClassLoader.java rename to libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/ParentLastURLClassLoader.java index d71acde71e3..dec931c3baa 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/main/java/org/jetbrains/kotlin/gradle/classloaders/ParentLastURLClassLoader.java +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/ParentLastURLClassLoader.java @@ -1,4 +1,4 @@ -package org.jetbrains.kotlin.gradle.classloaders; +package org.jetbrains.kotlin.gradle.plugin; import java.net.URL; From 9f0acd0e98e74f88fcaa8adb1cefc3a96fc9843f Mon Sep 17 00:00:00 2001 From: Nikita Skvortsov Date: Thu, 30 May 2013 15:00:18 +0400 Subject: [PATCH 177/249] fix tests --- .../src/test/resources/testProject/alfa/build.gradle | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libraries/tools/kotlin-gradle-plugin-core/src/test/resources/testProject/alfa/build.gradle b/libraries/tools/kotlin-gradle-plugin-core/src/test/resources/testProject/alfa/build.gradle index dbee1e21015..14bf8d494aa 100644 --- a/libraries/tools/kotlin-gradle-plugin-core/src/test/resources/testProject/alfa/build.gradle +++ b/libraries/tools/kotlin-gradle-plugin-core/src/test/resources/testProject/alfa/build.gradle @@ -6,11 +6,11 @@ buildscript { } } dependencies { - classpath 'org.jetbrains.kotlin:kotlin-gradle-plugin:0.1-SNAPSHOT' + classpath 'org.jetbrains.kotlin:kotlin-gradle-plugin-core:0.1-SNAPSHOT' } } -apply plugin: "kotlin" +apply plugin: org.jetbrains.kotlin.gradle.plugin.KotlinPlugin sourceSets { deploy From 5429c1333edcbee4b20c0f1b20733c066ef71feb Mon Sep 17 00:00:00 2001 From: Nikita Skvortsov Date: Thu, 30 May 2013 15:20:14 +0400 Subject: [PATCH 178/249] Tests for wrapped plugin, some polishing --- .../com/google/common/base/annotations.xml | 5 + .../com/google/common/io/annotations.xml | 5 + .../org/gradle/api/artifacts/annotations.xml | 5 + .../api/initialization/dsl/annotations.xml | 5 + libraries/tools/kotlin-gradle-plugin/pom.xml | 28 ++- .../gradle/plugin/KotlinPluginWrapper.kt | 42 ++++- .../src/main/resources/project.properties | 1 + .../kotlin/gradle/KotlinGradlePluginIT.kt | 126 ++++++++++++++ .../resources/testProject/alfa/build.gradle | 52 ++++++ .../com/google/common/base/annotations.xml | 18 ++ .../alfa/gradle/wrapper/gradle-wrapper.jar | Bin 0 -> 46735 bytes .../gradle/wrapper/gradle-wrapper.properties | 6 + .../test/resources/testProject/alfa/gradlew | 164 ++++++++++++++++++ .../resources/testProject/alfa/gradlew.bat | 90 ++++++++++ .../alfa/src/deploy/kotlin/kotlinSrc.kt | 12 ++ .../alfa/src/main/java/demo/Greeter.java | 17 ++ .../alfa/src/main/java/demo/HelloWorld.java | 18 ++ .../alfa/src/main/kotlin/helloWorld.kt | 20 +++ .../testProject/alfa/src/test/kotlin/tests.kt | 21 +++ 19 files changed, 621 insertions(+), 14 deletions(-) create mode 100644 libraries/tools/kotlin-gradle-plugin/kotlinAnnotation/com/google/common/base/annotations.xml create mode 100644 libraries/tools/kotlin-gradle-plugin/kotlinAnnotation/com/google/common/io/annotations.xml create mode 100644 libraries/tools/kotlin-gradle-plugin/kotlinAnnotation/org/gradle/api/artifacts/annotations.xml create mode 100644 libraries/tools/kotlin-gradle-plugin/src/main/resources/project.properties create mode 100644 libraries/tools/kotlin-gradle-plugin/src/test/kotlin/org/jetbrains/kotlin/gradle/KotlinGradlePluginIT.kt create mode 100644 libraries/tools/kotlin-gradle-plugin/src/test/resources/testProject/alfa/build.gradle create mode 100644 libraries/tools/kotlin-gradle-plugin/src/test/resources/testProject/alfa/externalAnnotations/com/google/common/base/annotations.xml create mode 100644 libraries/tools/kotlin-gradle-plugin/src/test/resources/testProject/alfa/gradle/wrapper/gradle-wrapper.jar create mode 100644 libraries/tools/kotlin-gradle-plugin/src/test/resources/testProject/alfa/gradle/wrapper/gradle-wrapper.properties create mode 100644 libraries/tools/kotlin-gradle-plugin/src/test/resources/testProject/alfa/gradlew create mode 100644 libraries/tools/kotlin-gradle-plugin/src/test/resources/testProject/alfa/gradlew.bat create mode 100644 libraries/tools/kotlin-gradle-plugin/src/test/resources/testProject/alfa/src/deploy/kotlin/kotlinSrc.kt create mode 100644 libraries/tools/kotlin-gradle-plugin/src/test/resources/testProject/alfa/src/main/java/demo/Greeter.java create mode 100644 libraries/tools/kotlin-gradle-plugin/src/test/resources/testProject/alfa/src/main/java/demo/HelloWorld.java create mode 100644 libraries/tools/kotlin-gradle-plugin/src/test/resources/testProject/alfa/src/main/kotlin/helloWorld.kt create mode 100644 libraries/tools/kotlin-gradle-plugin/src/test/resources/testProject/alfa/src/test/kotlin/tests.kt diff --git a/libraries/tools/kotlin-gradle-plugin/kotlinAnnotation/com/google/common/base/annotations.xml b/libraries/tools/kotlin-gradle-plugin/kotlinAnnotation/com/google/common/base/annotations.xml new file mode 100644 index 00000000000..69ed1be5713 --- /dev/null +++ b/libraries/tools/kotlin-gradle-plugin/kotlinAnnotation/com/google/common/base/annotations.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/libraries/tools/kotlin-gradle-plugin/kotlinAnnotation/com/google/common/io/annotations.xml b/libraries/tools/kotlin-gradle-plugin/kotlinAnnotation/com/google/common/io/annotations.xml new file mode 100644 index 00000000000..64ac65dcca1 --- /dev/null +++ b/libraries/tools/kotlin-gradle-plugin/kotlinAnnotation/com/google/common/io/annotations.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/libraries/tools/kotlin-gradle-plugin/kotlinAnnotation/org/gradle/api/artifacts/annotations.xml b/libraries/tools/kotlin-gradle-plugin/kotlinAnnotation/org/gradle/api/artifacts/annotations.xml new file mode 100644 index 00000000000..885acfdd4ab --- /dev/null +++ b/libraries/tools/kotlin-gradle-plugin/kotlinAnnotation/org/gradle/api/artifacts/annotations.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/libraries/tools/kotlin-gradle-plugin/kotlinAnnotation/org/gradle/api/initialization/dsl/annotations.xml b/libraries/tools/kotlin-gradle-plugin/kotlinAnnotation/org/gradle/api/initialization/dsl/annotations.xml index a33a584b9ed..4005fe3c2c3 100644 --- a/libraries/tools/kotlin-gradle-plugin/kotlinAnnotation/org/gradle/api/initialization/dsl/annotations.xml +++ b/libraries/tools/kotlin-gradle-plugin/kotlinAnnotation/org/gradle/api/initialization/dsl/annotations.xml @@ -4,4 +4,9 @@ + + + + + \ No newline at end of file diff --git a/libraries/tools/kotlin-gradle-plugin/pom.xml b/libraries/tools/kotlin-gradle-plugin/pom.xml index b4eb77b2478..717f6ce83d6 100644 --- a/libraries/tools/kotlin-gradle-plugin/pom.xml +++ b/libraries/tools/kotlin-gradle-plugin/pom.xml @@ -16,20 +16,31 @@ ../../pom.xml - kotlin-gradle-plugin-core + kotlin-gradle-plugin jar - org.jetbrains.kotlin - kotlin-stdlib - ${project.version} + org.jetbrains.kotlin + kotlin-stdlib + ${project.version} - org.jetbrains.kotlin - gradle-api - 1.4 - provided + org.jetbrains.kotlin + kotlin-jdk-annotations + ${project.version} + + + org.jetbrains.kotlin + gradle-api + 1.4 + provided + + + org.jetbrains.kotlin + kotlin-gradle-plugin-core + ${project.version} + provided @@ -41,6 +52,7 @@ ${project.basedir}/src/main/resources + true diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/KotlinPluginWrapper.kt b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/KotlinPluginWrapper.kt index a32bdb94c3d..f2891244fc9 100644 --- a/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/KotlinPluginWrapper.kt +++ b/libraries/tools/kotlin-gradle-plugin/src/main/kotlin/org/jetbrains/kotlin/gradle/plugin/KotlinPluginWrapper.kt @@ -8,22 +8,52 @@ import org.gradle.api.artifacts.Dependency import org.gradle.api.specs.Spec import java.io.File import java.net.URL +import org.gradle.api.logging.Logging +import java.util.Properties +import java.io.FileNotFoundException open class KotlinPluginWrapper: Plugin { - public override fun apply(project: Project) { - val dependencyHandler : DependencyHandler = project.getDependencies()!! - val configurationsContainer : ConfigurationContainer = project.getConfigurations()!! - val dependency = dependencyHandler.create("org.jetbrains.kotlin:kotlin-gradle-plugin-core:0.1-SNAPSHOT") + val log = Logging.getLogger(getClass())!! + + public override fun apply(project: Project) { + val dependencyHandler : DependencyHandler = project.getBuildscript().getDependencies() + val configurationsContainer : ConfigurationContainer = project.getBuildscript().getConfigurations() + + log.debug("Loading version information") + val props = Properties() + val propFileName = "project.properties" + val inputStream = getClass().getClassLoader()!!.getResourceAsStream(propFileName) + + if (inputStream == null) { + throw FileNotFoundException("property file '" + propFileName + "' not found in the classpath") + } + + props.load(inputStream); + + val projectVersion = props.get("project.version") + log.debug("Found project version [" + projectVersion + "]") + + log.debug("Creating configuration and dependency") + val kotlinPluginCoreCoordinates = "org.jetbrains.kotlin:kotlin-gradle-plugin-core:" + projectVersion + val dependency = dependencyHandler.create(kotlinPluginCoreCoordinates) val configuration = configurationsContainer.detachedConfiguration(dependency)!! - val kotlinPluginDependencies : List = configuration.getResolvedConfiguration()!!.getFiles(KSpec({ dep -> true }))!!.map({(f: File):URL -> f.toURI().toURL() }) + log.debug("Resolving [" + kotlinPluginCoreCoordinates + "]") + val kotlinPluginDependencies : List = configuration.getResolvedConfiguration().getFiles(KSpec({ dep -> true }))!!.map({(f: File):URL -> f.toURI().toURL() }) + log.debug("Resolved files: [" + kotlinPluginDependencies.toString() + "]") + log.debug("Load plugin in parent-last URL classloader") val kotlinPluginClassloader = ParentLastURLClassLoader(kotlinPluginDependencies, getClass().getClassLoader()) + log.debug("Class loader created") val cls = Class.forName("org.jetbrains.kotlin.gradle.plugin.KotlinPlugin", true, kotlinPluginClassloader) + log.debug("Plugin class loaded") val pluginInstance = cls.newInstance() - val applyMethod = cls.getMethod("apply", javaClass()) + log.debug("Plugin class instantiated") + val applyMethod = cls.getMethod("apply", javaClass()) + log.debug("'apply' method found, invoking...") applyMethod.invoke(pluginInstance, project); + log.debug("'apply' method invoked successfully") } } diff --git a/libraries/tools/kotlin-gradle-plugin/src/main/resources/project.properties b/libraries/tools/kotlin-gradle-plugin/src/main/resources/project.properties new file mode 100644 index 00000000000..e362614406a --- /dev/null +++ b/libraries/tools/kotlin-gradle-plugin/src/main/resources/project.properties @@ -0,0 +1 @@ +project.version=${project.version} \ No newline at end of file diff --git a/libraries/tools/kotlin-gradle-plugin/src/test/kotlin/org/jetbrains/kotlin/gradle/KotlinGradlePluginIT.kt b/libraries/tools/kotlin-gradle-plugin/src/test/kotlin/org/jetbrains/kotlin/gradle/KotlinGradlePluginIT.kt new file mode 100644 index 00000000000..68f085a6eae --- /dev/null +++ b/libraries/tools/kotlin-gradle-plugin/src/test/kotlin/org/jetbrains/kotlin/gradle/KotlinGradlePluginIT.kt @@ -0,0 +1,126 @@ +package org.jetbrains.kotlin.gradle + +import com.google.common.io.Files +import com.intellij.openapi.util.SystemInfo +import java.io.File +import java.util.Arrays +import java.util.Scanner +import org.junit.Before +import org.junit.After +import org.junit.Test +import kotlin.test.assertTrue +import kotlin.test.assertEquals +import kotlin.test.fail + +class BasicKotlinGradleIT { + + var workingDir: File = File(".") + + Before fun setUp() { + workingDir = Files.createTempDir() + workingDir.mkdirs() + copyRecursively(File("src/test/resources/testProject/alfa"), workingDir) + } + + + After fun tearDown() { + deleteRecursively(workingDir) + } + + Test fun testSimpleCompile() { + val projectDir = File(workingDir, "alfa") + + val pathToKotlinPluginWrapper = "-PpathToKotlinPluginWrapper=" + File("local-repo").getAbsolutePath() + val pathToKotlinPlugin = "-PpathToKotlinPlugin=" + File("../kotlin-gradle-plugin-core/local-repo").getAbsolutePath() + val cmd = if (SystemInfo.isWindows) + listOf("cmd", "/C", "gradlew.bat", "compileDeployKotlin", "build", pathToKotlinPluginWrapper, pathToKotlinPlugin, "--no-daemon", "--debug") + else + listOf("/bin/bash", "./gradlew", "compileDeployKotlin", "build", pathToKotlinPluginWrapper, pathToKotlinPlugin, "--no-daemon", "--debug") + + val builder = ProcessBuilder(cmd) + builder.directory(projectDir) + builder.redirectErrorStream(true) + val process = builder.start() + + val s = Scanner(process.getInputStream()!!) + val text = StringBuilder() + while (s.hasNextLine()) { + text append s.nextLine() + text append "\n" + } + s.close() + + val result = process.waitFor() + val buildOutput = text.toString() + + println(buildOutput) + + assertEquals(result, 0) + assertTrue(buildOutput.contains(":compileKotlin"), "Should contain ':compileKotlin'") + assertTrue(buildOutput.contains(":compileTestKotlin"), "Should contain ':compileTestKotlin'") + assertTrue(buildOutput.contains(":compileDeployKotlin"), "Should contain ':compileDeployKotlin'") + assertTrue(File(projectDir, "build/reports/tests/demo.TestSource.html").exists(), "Test report does not exist. Were tests executed?") + + // Run the build second time, assert everything is up-to-date + + val up2dateBuilder = ProcessBuilder(cmd) + up2dateBuilder.directory(projectDir) + up2dateBuilder.redirectErrorStream(true) + val up2dateProcess = up2dateBuilder.start() + + val up2dateProcessScanner = Scanner(up2dateProcess.getInputStream()!!) + val up2dateText = StringBuilder() + while (up2dateProcessScanner.hasNextLine()) { + up2dateText append up2dateProcessScanner.nextLine() + up2dateText append "\n" + } + up2dateProcessScanner.close() + + val up2dateResult = up2dateProcess.waitFor() + val up2dateBuildOutput = up2dateText.toString() + + println(up2dateBuildOutput) + + assertEquals(up2dateResult, 0) + assertTrue(up2dateBuildOutput.contains(":compileKotlin UP-TO-DATE"), "Should contain ':compileKotlin UP-TO-DATE'") + assertTrue(up2dateBuildOutput.contains(":compileTestKotlin UP-TO-DATE"), "Should contain ':compileTestKotlin UP-TO-DATE'") + assertTrue(up2dateBuildOutput.contains(":compileDeployKotlin UP-TO-DATE"), "Should contain ':compileDeployKotlin UP-TO-DATE'") + assertTrue(up2dateBuildOutput.contains(":compileJava UP-TO-DATE"), "Should contain ':compileJava UP-TO-DATE'") + } + + + fun copyRecursively(source: File, target: File) { + assertTrue(target.isDirectory()) + val targetFile = File(target, source.getName()) + if (source.isDirectory()) { + targetFile.mkdir() + val array = source.listFiles() + if (array != null) { + for (child in array) { + copyRecursively(child, targetFile) + } + } + } else { + Files.copy(source, targetFile) + } + } + + + fun deleteRecursively(f: File): Unit { + if (f.isDirectory()) { + val children = f.listFiles() + if (children != null) { + for (child in children) { + deleteRecursively(child) + } + } + val shouldBeEmpty = f.listFiles() + if (shouldBeEmpty != null) { + assertTrue(shouldBeEmpty.isEmpty()) + } else { + fail("Error listing directory content") + } + } + f.delete() + } +} \ No newline at end of file diff --git a/libraries/tools/kotlin-gradle-plugin/src/test/resources/testProject/alfa/build.gradle b/libraries/tools/kotlin-gradle-plugin/src/test/resources/testProject/alfa/build.gradle new file mode 100644 index 00000000000..451ac3de6c0 --- /dev/null +++ b/libraries/tools/kotlin-gradle-plugin/src/test/resources/testProject/alfa/build.gradle @@ -0,0 +1,52 @@ +buildscript { + repositories { + mavenCentral() + maven { + url 'file://' + pathToKotlinPlugin + } + maven { + url 'file://' + pathToKotlinPluginWrapper + } + } + dependencies { + classpath 'org.jetbrains.kotlin:kotlin-gradle-plugin:0.1-SNAPSHOT' + } +} + +apply plugin: "kotlin" + +sourceSets { + deploy +} + +repositories { + maven { + url 'file://' + pathToKotlinPlugin + } + mavenCentral() +} + +dependencies { + compile 'com.google.guava:guava:12.0' + deployCompile 'com.google.guava:guava:12.0' + testCompile 'org.testng:testng:6.8' + testRuntime 'org.jetbrains.kotlin:kotlin-stdlib:0.1-SNAPSHOT' +} + +test { + useTestNG() +} + +task show << { + buildscript.configurations.classpath.each { println it } +} + + +compileKotlin { + kotlinOptions.annotations = "externalAnnotations" +} + + +task wrapper(type: Wrapper) { + gradleVersion="1.4" +} \ No newline at end of file diff --git a/libraries/tools/kotlin-gradle-plugin/src/test/resources/testProject/alfa/externalAnnotations/com/google/common/base/annotations.xml b/libraries/tools/kotlin-gradle-plugin/src/test/resources/testProject/alfa/externalAnnotations/com/google/common/base/annotations.xml new file mode 100644 index 00000000000..be8ddab04a3 --- /dev/null +++ b/libraries/tools/kotlin-gradle-plugin/src/test/resources/testProject/alfa/externalAnnotations/com/google/common/base/annotations.xml @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/libraries/tools/kotlin-gradle-plugin/src/test/resources/testProject/alfa/gradle/wrapper/gradle-wrapper.jar b/libraries/tools/kotlin-gradle-plugin/src/test/resources/testProject/alfa/gradle/wrapper/gradle-wrapper.jar new file mode 100644 index 0000000000000000000000000000000000000000..42d9b0e9c5872910311a1d035995ab8ec466e7ac GIT binary patch literal 46735 zcmagF1C%G-vM*R&wr$(CZQK5r?W(RW+qP|V*|u%lt}eX3bMCzRzB6ZLa;=@2D_88b zk%3=C>`;^e0fhzvf`kN0C*u_c`g;NY*X{2G^|#51sS43a$%`|904e^1@P>(hmhUft z>feU?e-g?G$xDfgsi@M+i9g6qPRPp8(a*uj&{0oM&NM1BF0$+%-A~euN=?a4(MZw$ zfIbf~O*t&mrfS6?D>*DO9wi2_?H%nO0skMvrTyEyK>rSB?_}|hDg8SQ%zx8ZI2oDR znEii}qWqK8-O0$o!OZFZ(Zw>r)V%O7>C)du@}Iki+PmA?*c+LWGSQpZ7&$xpM#(|< zGa?4>Sh8u;xG@C4tc2wB5jYUh^9tFB*g#21Rdi*-AnfK3qB>si9`oT(`qaK0KoN@c z_hK3g`~2oeo$xIuGiqND?klq9{`pwezyPNf#GP9BnlRPNcHG+l$n$Gh=R8MB) z=g-P0AYms)@%Cu+Z5ahg9_*EVO22khW_!p7fjAc|L_VKVf}mMqSYdHYaDve20XSDW zJl}uY>o_w{N+bI4VhkOWVm zrZjs`45Hg*h7B;)+3v!N+^1uBSfvtOqat7;H`kG2rkv{&>c7Nb3wQ6qEjtT9Ij5YaLN0GT-Tso4-6)3G85e$o7K8&jc8;MukUR=X}zac3J z@dn*5K-6M26k9@2MS%Z@^RSb(oW zp&dvFT`7NjK@mn1%}|dBtb#e|7YQ2=9tje4m1}F2^q7=rKNbEm<~@rx?((B+ZI-ia z)trI3&`-y~$Le_!?SgEX6n#|m-wKF-WaVMCv=avmK`;Q#;!t&t!8X8Lha-p7Vr(hj zA+J0e$Y*s2Ur8Oj zZ}?L4*_^^;?+PrFqU>_%k60dP9+UlCdDiQa|1ve6|RH&`-Tj zy&xg|3TVjK6d)7N$WJt;lPK4WFoF%nS#>OwgBnSQG`EbElG4>J5cnp%eVOXZUV?<0 zKD4GTMEW%|lZrzqlOU~l)YMMo#yI3r77 zj`UO_`W+?!Ni{K%+S)|>v#~B&R%3fZiK;*mCYfe%q{}%CHF}I};+a3%pTlGW#78hb zLEa@?-!Hd>3_B)WFrU|a{rsLi(Z9Y<9t?n%=VXb4Lmhdg_nFueJpyu((|+NPq{MAF zCI!)s)RP>l)bpZD)M)y}?0LeXg*54N&Hl8-Z?16l{qv^O);<$g-nnn@Q9n@aR)5A- zvg9|)*lep)GeT#d>+S_UV1ubyfu~Bt)`c2m)#*IE(@s}8q2Om>7z(@atHLx_3okP_ zVW#{{dHEp6VjX=g&?;pQO($BfA_@Dqz2i!ps_S)^X;>Fa$1kNz;H^QD1?Dcfkcl?l zKGEM-Dh)HLvJ+*``UE)B3?Ho~VKD0yosBbiDp?|CgWiC4*tdwQrbye+T(_wG^nnh& z0V;gZ1nt|*wQDY2LrCR?rQ!)Cvv%ioHr_SlF+Aw9Ge6lL2^Nr@UnRC4#qs#XPM&Qt z#5Rjm**H%~OXkI@LLUCy-52_k5Q#G-vPxz%r-D@B|rd zGh9q=vP@ZEOQ6f3sUc=QV{yLgvogu|b3!7uD-+R$@fLUkIU&?mOp9!tf+7RFHH@^C zChrW|18RH8&|TVcPM+!;G}f&lu%CqQu_B#v8Uw`4*bT;7$P*ZvhOKV`JIHEnr;b;z z$&UNcWf}H*GahmXS?y+;_L%BwB1%)NzWEysS22C%Da%JO*03?-KM0J2zsQvzH4=M) z=STg`WlCipwR$&aJp;NI<$wNUOLFlvP%iXo!yLDvO!eUs;j;8-@)Ij%nP*AB363=k zo-9^q{eX&h7KKR<|Ke949h`}$G)*{3dwj|0$$j4~)ysFqV$wcABnm?{GA(~~)pk~O ziLP21s{jkWW$Pvya{#F%5{)ma6NC9l{5(Q<7F4T?1sww)V6S{m=&^7E?}>p9^#n|H zW^J!HS&_RZy^Cg!$TP>G#90d(K2GRKCMg7moGfIgGP#Z!_l9_g-mT^@+mkA|oJ`n4 z)dlNxfxEyw3O=-n1467HN2xpL4jmT+doKvp5ObqO2!(aXG-MO=qwQG0HH1exP6|s@ zBVbc4PrLt4Y%&catj82DHoBCkC5x*swRDq2<1cfA+)146OJ$ zmB5=oyNP%Iktpx!fU?ymoO;~!p1H_*;5o@z>-m0rU;qleYYcIVD)SH#!4qfA8ZL|A zV0$Hdhyq75xo4zzN1-NHlP&j<86b}WbyTlmlA4xs(hrO|Bc!+Vz+sucG$z^ZD;C!s z?nvmQVBldWzOiOxq><7czztH(u@?oFLMw@&fd&RCF>4QmJ|Dnafc6o2&Qh#1n`{~s zrRSr`avrvc$SPstu`4Qp8%a7LUN|A2stUMf+K>`Oj$ukgjt3hVH4Q=ur!&)w&vCNB z*Htl9z(F69SM7Taa-b=OehwL_!CZ+B14xKZCWX17#&E63iVa7@UImn(IpY}>p#_b* zNL0&C(}k6lFxDNrzMUT48ta z)zJ!*0c)3l)@76J!x5U1V+|Ztt5?gGKo^v;GSHkVA3G}j8L!1F1Fy_rkqm`nVll$9 zo6e8jE5&$7_qAf;IT;lDQM09BS*{PLFcETl#`6V=$gXulAn{Al1LF3}>h>Dv!cjBJr;uVwzhl~VTWtdBoaL=o9ZV7?Q6>uaS zN{xDvxJ5LiH0Mb|Ocx@Hy~fUB+?c0)_a@f&{Gz?V!RD;G{Q_}#oWdsP)VmRo zRSx@c?ms9o*$22b@UhEP{mat$j#5xGd*odqIAn689|&IxpDPcPKc;bdpKL_IMy%5W z5=AZ#YVq!C;UlsXiXc299MoFhc{K7ruEP-$z!*2rdU|)78^8sye%-N^u{`2tonDU>{`y{Le)P-T4DyLhnPaa9_ce#h zEbD3m$l&Xo8SCK7@l~#Vl>tUTSQT7O>K}--Q6K*ZcZaSP@6yYU>4nk$R2a>bu*RQx zf)M`2>$WrWOR+a~`_ekJUYR(XPBXH3DHyJr-u-oBvc>h!2S?NS}N*5~GVP z$mCRlgbX~Ta2dM!T16&+8{y4pQ5J!(lP+SbDcZpuqB`n`QJ~8X>6GLVIj@%A>)Zq? zfm6g_1d>N+#IduVEo|qMW1KknmImA*V5n{Krdp^|`e!W~jOMIYc1NOqd}u4r(N)Oz zzri3Hd0QxK2p}LwcpxD1|Ex0=ja)2+oSn^VjsLf%OjdvM#?e6IGm*hI0P|D-g(UGaw+pOrEgPzA!hx3-R9!w{!DpKkJo0Xcufl~f~r*BdY1Au&t z5`b;;u%wu}%5Es+ZnM8^d2hF!Y^DGFKH260n%*@)jwxt`u&AdN8gLC4pK(yxFQFAa zF$<)yCeBGF%pav8kFBD#xyFMcw!6KTvs)Ikk>m_hka>j_;E6mbc&!SXk@CRLjok-> zV%R6k>6|RoA@1(|#2~{Rq1p728cY@QA&aP$J{?*qc;&|V8JKC`Fr(r5sExX_|Fxmy zLlJQ!{fgf`!)YgR7f9(h%3~kdO0wGzW=GE9DJ5vL-|i$Lm5SPxmO}>Nb=T?NWfEey7GcLgNhX0- zXYXZxes{U5YrE22P>w2n-dUV+Af8Ug%aIY^U6!osgybo^!1gD=e_3=Vz<)MPiLmh# zC8I{3`^ao5OC?2ydc@)uCZhaq(*Sm@5HK^CR7@~0v)3QEU?QSe zo?6zlNzks#C=-C`0=tkI{^4)_bsF)T+>rY2`qJ0m8QfIgWpcjNxEeYxY`|wPi^G$V zP;vLG%WSD3sUTx6qQVS@^B7C(Ji^54S)6<4HSKa>0*4)@>FB%+=vRzqS)a9=ubAEg zRfMJ;4Z%GoUOGo1AoMmB=%|Sn6`p@;&9*4C~(ivC?nlCNBr3E*Z3$}KiUHo z59wjzoVYtE*?B#?N7@4l54~Y#^;30@LQK~tWg#}Rk0e{akX#fJ09McL8lxZ8fd=n8 zn?A@_bnywgQtGD)cyHtT2zL z56}h`3u0xA2eoJ@+1p?!YGUrCNWcWNN#h^X;mMqS872xbguah&Rsc2+SE^+UaeS!| zUjy3tU8D8D4Jq_rG^g*~@c6Sv!A8)|5WCwKE%1s>+1@tDU&p6;Z8d*uKTBq@!zK84 z)x*SrW#uW<6h3;cM9BMq#s)Mx`*_RjUQvk9|@1CyxD6MT^g$MIRLNL#;NRK`$DjUbiII zsN?t@n=y^ZhIUz7;7i$Q>unfnYZF?{b6#s7VY9bu+`zJlRbF7y=$1tK8x>nV8!( zx_+;*9z*}T#2iBeq|tq@Z7r$2F{#0szM`n5 zBjmg_QqVynsy3L`B+W^w`S#Cbtas@1-E^PkiXLwq#e6%(9|&sB-@ylwME&>q)caR= z(DF9NEwde%JW^cTt~*aYzH1E2Ag@G-1M0wj1?G75rMbGfI(lN!D zhQl{vN51RfSZ{A@ByNYHXu^acHJ|xp4&RX1df5hZ0lh&9gYMj9=l6al=+&OJpR|uI zU}Ii`11`*pb^}Rj>Gx~$v?GwNd^CE^WqO+Z3#cSfB8s}zqb|Oj{1(C8jvueJv;5|y zi4jNvUmIcMJE9Zj)a<*{>sr_KeI1e-ceCWBLn}U)uwy(!+CM#XPGUFhg}D`^_43M6 zsUQ^Qle^{}j9A!;uuwl>%dWqyU+XHlz3P?eXM|n}{^^k%&kvlf{I#sBctAje|Jk}q z**Uuy+1UImu8^$>(K}Kn9@fW)$1?VUqu%bg&2Vd9@|91 zHvLR?YrdfZ`y~%2;FPF)FMgovD03@=@Wps;t zvotCInB4e%+notca!!6uce(f6E~M%c6~KKUC1amW9JvViie=PRJdQlF0lq{t1k}zh z9xbT(q<+>UNbe|~X5N3o1b-=$MR(H%_9Sc@K%DB_fBv5Qh-TfPDy@9n0{X0${mz#D zsqn2R^ewrQ*!&YY=DSLG`-SEd;*nwg!y4=}?n^F%0PJ)`_~}OYHWBDk!v9O9{kwSf zC&cMb)OUmA-?QK4O)-AdJhevgP<+Qgsg##0?akS9T4$=BFgrE(>emVSrH|Zb+ry}rXImS5i|(f$ z3Ldw!eYe;7B6}d8BM|KfS0)wLJmtCbJO%A+YfPu4vew8r=vVdCMTI)kMtm8}z@6Dt zi1i9ON;?hpCK9kEL%tLk9|RDnDpdG5*9^DoQ!M`u+h>wq?P;3W;MA` zB>&}Aj$K{R88fMYvux&Jm6$YkLsDaNW-4tG#)mdM^e`hMEjK@RE8~7i%=kd?&hrw} z`S4XL!!CA(M|~co1-ucmTZwqRT@(Tn?HmnBaOCIKc-d?Dbfs97k#s9`XsI=~N( zy7iS+P}$VAF+V-G6p5%ZqV#OaeJVuivBg$OSYNrIpC6#GGMK$?Qk}}d5d*fgD&jQHKFy*Ae=YJXjBmNG(QL9DheUHr~s)b&sjB|4_wIzMOm9wq4<@AE}ofrO_7=H`yG3)Oc>UN%exgNuH59nf2!`NJ5Ukx2pty^t54@1S(<{QZ zh}N7W_lTkq9_sq-f5q??+#z`h9Vl4}3rG;Cy_OBXL==p?w)VdOswNDhMtQmB%^!JZ531#&PKaR8E5`izF9f`tPD>7`qk>`LDehcPr z>LzOAN3D-G9c{=)oJNq~sE)Ifvk(JOyUO1#=L8oQHI*aO5*|+CzZNYO!EvJgUD$nm zNPx)`4uJFICHlf%_DE2$e2jdQ!FD<#UFcd-qo@``?!Q#Lv{))8552n<70yjrFT4B1 zUE(Cq`MtV)njk2Q$5Q>+7Z}x{-$q?G9SEh!dR2cCh0z+qWF5)o0rR0u^pKiaTD4m{>Qzwdzf55j_Qlz0T zL6bL)h=#TTTY%KGQopB$neC=tWiAXR`4G-_og0zukrdb_^bngYUY5wURODFHa$P=H z{(zW@N%q$;mr>BX2PQO$M?|(wi(&wqA5E^>t5Gz;UJKyE%@5VOw9Bgc&g26=dS@)Q za2u7*(gAi?y!IXix<}@Kg6vX3Dqsn%wgS6HM^gUI+u|zu0^o!7CnlHIX9sCa#blHzSjF2g$4`oJ(N#DT{Y!_YeD2zx zfgHlPV2L3rqb(KnfUo4baap&S4pepX5@wD5*=QR>?k{utDS-txrC_!-8RO-+O|#0$ zw0que$RH4Ic*l`KHO6Op5E+&ZXoM$bC7~KL+h~|njO$T7Kj4^bDv}n|E<{vD;mh&P z4M`)S40&#G+V5UGAm3|II>qtIvD!*iIV5%mVO?=0uGL5^s4ex*?G0M@gE2yjy=V%c z)Pbo`8{VN~qM0r~HS}$#{KWLj=pj7RZvS*YV4`}QhuQ&8g~IdTMngwog=ZWU!{e4s z1*5Qq>wD#VZ(4waN(_;r2qpO@^acM5`m4!fbgM4Ch#?I=90uCCLWTt_hwaf1LI#+- zWN$Nj?OXLS#zemKMg;FiNmKnYX0P3OZLoT8mxcLJ?2P!uX#-VWJdG_tVAS* zT$?d5qsW%D&(*lR764AhL%cxL<~pl*zwkO zKg?9RRc+HB4Qy+r_Yh5rk+5}?my55iQ!z#;7@pfQex5hBsq^7Bl5SQNM2F|VD_L?8 zU_*|N4L~i%WYWS+j+0xu4-@Rs-bQ)_uRB(RzM_f}7d#kncYL6Abe@1wo!@*1exq;8 zROs0Fu+%8j6FG8$QJdG!=$9Sc5MOW!8NCX}bn_-I1O0?JBl00CIV7ekLb^ktV>#T3 zEpdU!XpsN;@Ng)ia7GQ6GOd_bIk{3^#jAkU*MLPWpfGYQi5KrTgbN^PY?6FWW@&0| zhn|9^OD{gJ5oBZ(VH-#V05Zzj(Icx_R3QSeDng?YmJN5I=>pw>`-wO&Z&XEh?`s5| z85w0bT$5L*Ps-buf8sNb*UmzhIJ-!B(WJL8=6MCHkExbE+L?PLFV;lxh7(D`s!z^Z zDbU4ZSEUuR4PexCrAW9%#wB~2E?Ju)Qf{h{qrhQhH)POe7P^uwU3@aA9E8=n-ilde z6d%v9K}`5+log9Mr5CH`+kph|$CKOVO5{j8x--JdN&37N%EYHG(~DC zanu%WZOVJUx}EQRHl@bS^XC*X3W&OQV0uNN|8l43N}dKzF$n4movX~#y7da$2KV(( zgYBR7=HY`@O};N&eS;^IIcj{A_rgt4y+dvC!ll%kM(>K;2Ju!GS@!O$jaqgJ+749% z!~PE1zLDlp5XeI?)RiXyc82rmN-t%4Fq(X2dO#ZObzUA|^hGlO+qvdC7i6?Y!%WRB z+_+tv-FcQS-C5Dn*3rKB86s@kT#VB(PCAP-6Tgg2+acVNJbP@O&*6>*zY8f)~;40?6&_@MYm&UuaWC@t1z zBka}@vd{Q~gQ8ZKkmT#UI*_Dzw5g^~Ykm0$;oZWrBX!(8tCY>NcW2Mc6#g8;@&@+` zH@#4gM0lG|ro#fDps|MgWGG^vO1!t zp=dkWE_h{YXXhEadM0s8z<_T4Qq2)h11i->$Nl1Qzk?{fn5d1f4i3jy|ziIhG5d~n@6&A!M z`EH*5rmAN&8jX4)Y?A6$W;OEqv{w2V<}7+=Lcho?57E9zFq3yXI=yzq+E1AAvhw@7 zQ_e+LSXJ+(sGkfT^|IW-vwnEs7jZ8>n(fk{FM8t6H?U>F^_=1Jk=?7vYfqQv6$3fT zL}tQXz2a`)Y}7YAC0kg!Hbz!2C*%B}N1c%GS=>?H85;3Ppd_pwqpAmoCrSbW6B88q zp&5ZZ>;GsUGN8@09ae-<%r2x0Qf9vCL^!fU>ogF`cX2A#zF*Nvc2PrTH)izFCF*=8 z`i%swfYtqs3m4loIj_U38~xa#mrtS`4Kat6%(7b+`s6*M)TKF39cWT#77_zeXkZQh zZg$+wHUHzWJ{~wj3p=-X6c!7khL7Ts!pXvpCr(IG5e=;j`iTNE-8%lUTJn|0aFV|0 z0@T3-mB-$w+l5M(9ZqUM&Y^qIH&f2%>1!<`R|dkhUO^^m}&*x)@R?rF;TzlNvyifrya1S znS3YT40WI+qFzTj|Fm$VG;=kZyp_`zJv5xthewEAWpR!Lj8lYsV>0Et*iG(Km3q+7 z;L&&FE*t|iXNCEdeA;h;e>%kyo7jW>f75iy|L>W1VS9TQXP3X}cR3?~or;T*lgt0) z=(Kb;)Dijm8_ZP6{I!r11+##L%29n?B)u zuVf4|F$OfcOKv_fe9wCCJ0>Tyxh#&ik&(eoS&h{CGooB=Bwu@DN!=g9 z5Hfu{E=NL{`TIwZ`R_!ICg`v<;u7M}cQa>Ur*cqtp(K{U!c@#Npe!S-!F8rBTGE;; z?9ND`2B(rLYAaKQU&Qh)Z!Ecf#J2*>jIm_oE@+<@m0zCI&^jzK+@?#W5-PBubee6< zqhW53UzG*zJy^OcuPd4K*qG~sYyslto5_~uHsT9wt$`BF%&7UzG4()ea9kGVP!mJr z1HjmNR{>T??@55w%if&%C0%;E3V?Wjo_D{Yn~g1*e#w4lW6(MhlqFTU42=V1}XJ=0yiq+mcs| z6GRJmHRCF5&W<|H6@}XB3|y;Ka~G3@!Hf)fLWRLuj1TG&Q=Fv%PtX`g_^3e+dVM^t zbi4ChFlWYm^qNwN)9IW2U*i zW5k5;{{-cf=2)tkDfFq}LR#{p?Ch);OG|R9-eU1H5Yd$UqVKG+bwo9wd_^{(@(8I7 zPsQ56(?`jqBXj0M3gFA zcF5A?;7(SAMdqkoXk)G8c}=vqlX?+L?Gbas)kFaL_&rl9W`78)iA7v%TT`u=pE(eJ zf59)HuT}n5VAeUzET3|v)<(b7PB(BlXf$oUHXf>Wujt$FnLO#2r#+eHB_Yk1hkBN! z(utI`1T=_UX`T8*(5% zL!TJw%q*E>cl) zQEvhKzes--S;Re8<1pYh;mWt598(8h6!>z0hfhJ)r;*`bfCdj_Ip?Dq-K&9uz(2w@ z5D<^@^A0jrx6UAmhIdFhBiPONATzvK4byc>sgsD!*Id)hM<s`KMt%R%(>10{`NCoKw=KdMLaQgYwM)`4nV?fcG z0IN%f#4o;r)c(y`EeH_|77vA#Z8ZKSryYw-B=4Hg9|C!e8GpA=ykvrl;!+cAvrSeV z`USMr>)nLR)wz&F%N@Q8)^jk}_UGRsgyuRMcS3*9D>S160a5FTYsgxtLg*H-yLCn@2S!-1+QjUQKo4I?d&vE0qs?DD17$;cMzn){gxjdY z#<*2vN10|Gk+Am3d$#?)EwC?;V;dqKp*}lQJU0nz`H0(eJ1?WR+lbo~J1-NrzYzH; zcM!%LIK#X}Uh7Uj!fv-Q#35qB)L57^lh;0pcnQ%3FbA_{c_}H}$1V$ncu|KvIWhYO z?tMvvVuNq*5b@#mP>6h(gA~S|=Lqp(Od8{SwYziU_fCa*V`d_fX29;=7`<-6lpy?l^Uu1@jR(=oAduc-v6%y8D3 z8=9GQ)}%PC)3vr5;P^@n%dHKz+2`>@f_>LDHHz9dB^O4yQ|B3ZOzHG5m#Sd#uqQXx zI`t5bTHDDomsqH5`-ybpSXnxvq`)rTWvv@b=I50GT_&}~@uTOM&OLhYa@+GZ1Cw#( zeyM=Dye+T!Yj)b0l4gUx-zmy8)RnyPIXS*w%nC-TNTtbbSQfR*Bs(&z4!1gxtnY3i*n zDvNZB+VWGeg0;lO8x^0ey9l9pda+C@xqF)+?wBu9xNgKk^zF(^p;KGhdXiJ&EaHuZ zZ>iB~;OV?1lRilkNS4y%xMq~d{b{o4A;$-#?alAoDXIN4;p#jbOLbBy?4*SUe+G5}Wygbtfh#&AS8M9(`1* z*ADz}(*Km0z2LOro<*RCpvV_=h;1mUvtAJ!^qqej=r3N($biwAJzg_k(``iBs)-@* z`p58j}o8T;Xsa^J}QHwKH81oFP^5Ps&+Z?K4u2%0;yiz3> z`-m-wt8Wyi}Qns1qXCgXmzANC%-M&o{{ z!=KZ*$O%Pub;;CZ3M-3k$HE7CA2*hVMy+?S3Uyp$*9=KLelS^h?5FI0ablRl%2`*yQdF>Fc%c5ku7epjU1 zd)WM0qGP6asNg)Ibx&GskdcOdsZeup4AwvIVcFcT-IT?ld9trC$fD_CPi;!#M-8gz zzI007H!HO+FRS3!2yfL5N_wkry0%Me;)$x7z?^==xDJ;{d7v|<=(ZFup>?+3qf(b) z3O`JuM{AS3=Hf45{=IPnV_&vE(ONH<d(PS%wo)JL?D z6?+N_S?w_Gm-Rn_DEIY0mUCd9&*{_>o#cyy!GV9Y@nL**BTmU0*l+)1L3c} znjz>%6aPw~nhL}duhAC$>8IrGr!!rIKg)8u6h0SAVWVafo}$+}ClfR)Z};TK?ntiu z5Hn;W53Sg}z)nACPV%B=@~wE$%X7pG;n@xvHD|daca0>j@HTgr=?<6^I5z%8bMvz}bvWE&JMD42z+PPJoZA#PVN}K;tzpkQPVwC1z)(3$J_Os%>8i zncN6sE$UssC$a#hZ9e98#^^K_4iz0Mhu76k&+^VM^6oDM)7x0r+g9#3vKIDJM69-u zoH@BiUfa|;wUCnqZ}HxMJ8jP+2N&P#K`PuC37{#>D41D)7_8k$2khlUbCABB(Ji^t zA+jJ(mYSjB!<(X@2?vzlyLK)-oY@MXcKyt!t72M%z=>&2h#ez+@{Z;SlxowmidDy1 z_RKNJov3ezHgJxBGZM`U`~heRp=*&(SmRBjR$vxOo=xp2t-(1rux9(<2wT|^euK?r z5A{XH=vtu+by;V$U5)|g#=Jk$76^zgB=N7X>#@dTxZG)3cUoC|kO9o9A?F z_Zb6aD2-Xfbk}##+p31;oP?7x5k&XHv23soD)Mc?vk~$tp-n>T>UJDUy=8f=(Ml~1 z&}a`~&K%G$pkU?DXj(#fJ|Ag^G8!>gd1-7BG*(y!HF#XHcHgv1g2dkWXn~=+d;NL` z@}L>Srq9sCSo`nMUuIi>X-dATPvu)=0U2!XNPE}r+FuX_K^)>(Osmh8akD1W#XH*4 zf*O(af#z46nO;zG_lL3HZ;18|^_GD=RR~|zINd8~i-SyU$xuC*Ume88GSo(AP1FW4 zA1TK~2fKq(a%K;Y1EVCi?a_`J4i?59!p&9|J`A zvgxbfB5*G4Z$X>UZ(lptm*>@wEtJi2=l^_K_@__q?QZBt_7{f2|AnE{{~3l#{9pAu z{|!d}%P;@$l(hzg2hI_e-?!%7*h%BTsJxAZRuE~*(I9bE+?;h0*4(K&Ck2mZCromhldNAV%NR+VY0M|w1Z!BEvhrosY$gvwT& zMri(mU3|0+$J&U-)|uGYaTbDyg9B)OqR`x=%$JEN2-3nopRY-#j{pJuzdmXCJz&je zIX2Vun@fPdb|1z=vJd0)HG%iTOrV=Mda$~7{L7kc@#_M*JKq?y^z*gkvgc@|#q1mJ zS4z&d@7!HqphOLJ^fT-;J{G|R9$&+EuVSsB;Vt)PE56kES@~$1E!n(E2iUU4JRTMn zALBfam&5(2;7yUBUQ7D)y4QNn?B6n%4~)4Nc!k!YC2!=jpe~I(>P04^-3#^u-a2E( zc=izI^1={TMS%=fQh1gU3JMn*qLU%9T)ym4Xd5in>hjT~;*mu0!=Pdd<`A^D@pODA z3lT43xy^1=?_W##1Ch;6MHkDcZ){#RFlA!XpY3FdH_D`wqurwOyLP_A%xwUQs486~ zMcRcXZ{#A|(VX#hajPOxLD1{FtZYf~cv7}+@vhQiB=#ZJyj@@3^{S~X2+DOw8BX7 zLHkKe{K)v~$9tHlm_81Tr>n-i#}ITc z)sTUZ@n-4LTH5!*EF}?3r1U)Ki>;w1BZ*;&Kg06Hwx6bBW<_@tSUXO-5!J-yQPl-$ zPy^%KsB+HC=;D@Jj;XzJxWe^ORq2h!;;b^*A_`Dd)J7LF7EZrACJWc+bcwMD*o?)A zO;Sg3pN}Xn^h%=_#Qsd7F5Tbce{X`SkKk(AJ=W?c`ROGThDhla62+)s%kKw;P-Q9J z>cQ;{ys#C;E#HECD2l+3uzf%ZsNbT%2@K7EE_;{?<SzPT@a@as$pC%?mn2 z016|~$bB$ zQEAg*%ABv+gyg{Cvs4=**~PK(di*^Zi+SMctU80;_dK=sOkXnDxe6jt%VPYS{Co(S zs$K|%rnq%EERlMHmP2Dani{wuo*$Pz5MHWI5;;poM0m9LAZh+k?UQYeR2^X4Y>D2Q z#2Yb&E6cNnJ82%Jxv$wD27z+se0!rT8cDA02p5?p@ip(fWgc^au5CF@F6ODHyvEif z%4F#j)m{UjSi_;Nb(E_@o5F@S*3D~cAk?E`8qcets-GR?uFnx8nLlD)83YH+GZ%IM z`onUVFYhbXk-xgJ;Ddw3TlsgA?%9-jc`E{4~7jZ};ENu>i$CvPNm1Ao>O z`}(-h84g6?rSFagWOYG3n0(*NF4f^0IKMaZm5#^iLWyWQc7dj9W-- zTB(@br@SyMt~Ga+K6{*&N4UX#<~%scQNy>$M&1*R;Ja$KcA0Z-7`WKv%1PsYVOvJN z-%OpiI*I(E@>|Nzd=b8l#{W1C*PKrhBm6iO>X=1Z5;ZJ}bFs%v zUqsEj*4}RC<&9h))3Qwb)ed}a@fW+oC4yCD2^oS%H(F+7^;Phy&zP(Ur#C$1XBQ%# zBZ-qN>4(~iVhTaf_hQn!)m^*Z?NSB_zQioseWKeOn7(^^gzI3S0O3Mk_c76 zJ9WUXsEiajOUH>P6F`gcITzI!@9;;O_giCSiP8LF6Uo+j(46>g|N9*9tePi4b&unkLkmu=U04Hbv(45kb??0SA5d z%a2IIAW^iQRP2jUiV;w zG+Bdn$$v0vWk{;4DBAFg+25!}Z)yp|(ipUQgp!VRcoo|nv4-3hh2(t9BjTV&&x1PW zxHZnePpk@oC8FqpB8;t$B6b8Wh(Itq(4rP*-wAvcEihXY`3hDyUE*bSnJWTcs@^qC zr)y*S@_wv)$=$7Yts}y-{hPL}g(<2aCcYzE-|Kg-BaRu3w?-}uK!I`1I;Vu z-TapP*nvWXp?`NnO6I2IN>(@+UuP%?yd(q1rm$qW$(TIt{NqrYkDt)dHJ(=_ekQ zqA-2{(?VblSOO6g@~cDY%)E@+RVAyMR=+wsk>P;ltFly9!J7;)e`Dc)vycT1gGl5v zfvQpu7hK(v-zCgAPSfx99(hxHt$>L2?1|oZQ;Om6wFV;r3a;BM_KKoky7iH zGvk;rjS<+GHsRu6xfVWQFZfoc+3$Okz6a08dOOXa_h|R;+T|%orgFhou&&H`6u?<| zfO}63&8@1*ZG-CC2`T|!gUd^$Iq!&%p{lFuC?!GDomU8Euy{x2qt(z;u-6cidZ)(a zBR8^g7ftw)Tb{#s_4jKgxBgIzOJ~Rm+u+ghhVpepk?!0r9^B5-Eg#&@%56vpf#qv{ z1cz&9FhTiieMD}Vht3aFOsEOuY0+&Ly*=tvIXx#nCCOQy)7&ZeZsYN|#;RM7;BsRwgjdu^Dzq?5y{;6T#luqo(~qas2VN{ge;0qA$* zm-9`Tvs^XAw7SN}xr9kA;|kR@lxgQ<-R&1Ei^-3wv%|w~VOWnyE^{OAc{lWZn3(jb z$XBq?d`Jqv#csnRTb7Ak{K?g2AG`d+u&J}V0h=hP8SUQ%d4>{Xx-uUBi?Mf%u54?! zg{vwRR_v8z#kP%#ZQHh;RK>RKq+;8)ZQFLf?DL*;?>_rI-)Z;9Xlu2$=8rko9FO|w zPk*kGj|7Nj(||k)BR_Z~=0=TxThq=rLbCg`6dE+fiWV%^vx-^LTBAWZ2F>K_vXjmG z%(|}KRim6cWNc580kN|d)J@%N)wtwQbZz$ePp-VbFr^|H2ul=_Q0ZS2a`b5i4~b7> z7{xj>a}-;4$qqFl4_t;Q5;zOAl0enqXobU^SHLPt5yTA)D&tHBqdOcmd35KBg(0L0 z;#j!oYEbiiB2>KF)TSUO-NFy$bd*$7RsTqqq(YUH4HqZGos}!;E;^Y93#X0Zhv%Qh z#3Inom0s3Cp+`GGWA*y|eq+_qk$~Mv(vd>rs$i9iQ^ea*x{?Rs>6t*mYL^x~d;Lh1 za%(Bx)&%M3q)~hw?yR`N1nKB=2P+>^M2sc(GTwZ61Ua#%D%|1D!dDN4q5DIXt(I_m z-H!EMv@H$x9@c@*8a_b>cTL;F4Mkp#+4!3ujJs1?ah1{Lham`qik@m%QKRLibz`pH zQYREQ<0Zm5`lHHzKe+y`2Pj5vbxB^Up`&_{oWcsQ%EQE=oH_bdd`VWl}5qsz7|(o7c|>a+8W@&5mTu997WNBNccp z&}(rhr-dUE$Ivzwr;hzv`&ny}^piv@`IC9gEg;H`5!uAatmaGt^WYP6*fRN6Iy{)PG zRnEl9fQ8x|cJAhHNowZX%<*Tedu(D;wN?eajk0gEqaX{lq@bEiB021YCf60RBnRiLh?be5F_sdo>}|YueXz$)bfGVBI&j=QcLW|?jGHy97iCKq`~vl| z`ZtO|!%I}6cm#7$E0an@3EuAnMow^a}Q8al#hk0Mxbe7!2 zee8byy!+DP9b2p`9NDvWjy`SCK$us8M(zBf)aj04vk(Junw~ z(uM6zuOUs+7qcAjRDK(+A@^{TK-bE!Gj7q-nZR7Nop~ETX7l|L=-bI+S*d=5Tvz#5 z=SPHeqW(6QK-5f<7+y-eaQQUz=smP1x#ACE;aC=fO=67L=s?wq2>~a&w2;$nR@9)= z1bNzNl0q3mViKn5jbhKB-wp(I7;;CQI^@7GF!>`H#yGJOS*G~;0J)?2Nm}rEzGG&v zii*OP1!tF-h#844vRb+{OK1~ttxZdpXhZjY>8V>Yop=y%vMV3&gA|uuv^S20euea{ z;^=2ckBpKpWnuCMU-q1l`q|3)Y9ArGVva0-&PVcZ&Un?BbV5`>sWDv#K-9kfgPEh3 zj`~CDGZ6o^{u0*tmt+ssf9mj1{fCl{&1W|#wax$0nvowLlO`JzRTL4G92p&<92%Y2 zk-Hz8kiQfgm8Y$ip{1>&|B5dTYPm~?AUrhQg5?Ur-72g5JJI2lX+E}i#$L?~*t_yxCxRO%hO$MjZ zz76qN&KMOIyZ4^u1WQavaZ=br%iMR4>kE zB>nh#dflxQDNZv32MfalLru+!c1Op@_sWQBXh4Z9vO$=RVn6A8WBqs?Ogrb+$P8(Q zU=^UxK0susR-$keUd%WGJ#S4((>SRpDWQGCbl#z*cpk$bxww|G&NgqEc*9+2=*gfS za2=mui43h?#&YX3Py2(Tu3o<+rDny9S+Qh1_N=~Ce$C0DWsugBZDDC>!vm8=RH0ZY z)NmMePU8nZyC$2G^c)|5U064E(`9L&MCO&|naTndRE)w3?tXCA7qj7Dvj)dhUE3%b zoM@0O{&n7>eD0NO{nP}!#^H)~ljmUl`cfxkb?Dr{0^L7S0|nbR{0Boad(f#zymmga zZIOC5XYDz!w$Kzk256l1AT8(Mu)B!1hqw-b6UvTAxMJir_a}i`b>S0?PFOuMec@iNIscffq1#hTPvFXc;kQf9~t&pEB zRBUa(CirRrm(4*85pT@Ykfc18w6hSsfZaa05Vr>Itnb0oO0vt%RRp zJ_Dp_Ao;5@a6#q_B682@f~!50Z=g1prZMHpIR}oJt=Li2(H=o;(?YZ~LHV3|;DoMe zr3UfTIhwuW;34TKSgWUYk-id3XooKy)rN4c@Yb@MRIV=CqGE)xS_Jp;oYn#vEcnil zYiGS!ifq#9B9N#dm@E3xx9nYY!YahI=ucM}e%~1y?1!|ZW3;3-J_dGq2Au?B9?J+q zTa*tE%v5*%MnAs(cO#?MHjFIzw3frq^$*U?Uq<#fYmw2lvp2N+FA*{SFy6mJ!~{P~ z>ePNX?KKCP^H0bie;4dR>UAojGW{lcXG6{TD-cm$quGZ0h6l%J{p8K%+aP=(1iyga zp@mibre#@D<)Gw>nC7|p7>Oxx#gX75hIZqS51@Q<+_^RvhiBxMUlm_eN{JH6H@AJ@ z8jtWZ$XTssEZ!jkh<6mtC#o5|lfRWikoO@XddvpmVSEU>@h!{)4Bb8RIs6sojw;#X zA3hYyr=>Xi(?dLfefh%q?;hgcpH+CYWhVw%xLV2I4bcps5#T2U4v6}Li5ZeMON>kB%^u=v)32`MJ@A4fdeOYT@Wfql zS|tB?n%!1~s2 zB-DGWMrrT66SeII=F(FJxYBvu$^Fh1D9@XlM=CYyfVl>&t-43~nj@5or$(`%LUYJ& zn=C6JOIf6;1+;DM&?QZ}U!E)jRQjxBxO1m%O6E#W#woNK4h>q(F6_)xISOWbdXgT- z^BhPrQp?Su2!5_RhgBBWb*bLo<;l@YzBiS}?z?nxgv6AzAKrNou-4FY%5KPJ>fIHi_-nVGxo94MI*0p_@vJgibOj>VO9!hwvb*kudS?^&P z5G>=;5M8J_p4r?2Kl0w=v-gX_(Re#Xf zLBD+YOCRwcvGm`!{=fFT{3ps}W&HW8jqa!9*MDi}r7Q4$21?|2BMw7d%WQlFK?+h7 zs4~iYh!{kCQ$0S5-tYW54cQXIF@}k!R>9t&QtOu0t|ncr z*I)MAtUFw1Xby0=zmjf8|Nc6PPCJ{UuO!^{WgtyW0(e6%Szn~jD;%6{J!e;{6ONaV zx@5G8;;c*$tw<%zZH{#+a^b&NMMkgTXx_d4natkHMuEF0Ohm17LQ^g*L2-`!QC{`s z-wN)$Lr27nAZQDr^3X=K%0G5RN{xvLnuIwbgAdR_+DgMYAOd3?X^D64G6dzyYuT<@A-uW5@S+{2 zmLzx8Y*_)v^4K4KNWv(IO}qpLN(RpJp(=cjrme^6tFlh^nDiaGb&za!DPr0XM*d@Z z>wvwFw1OXfYI<~G4)UQ}S{JEV!BzS4aQEFT0yDHzC(!#x2pEir%7;UCCSoefFw^6N z;xj&vr-0grT@&=2I%&`)<-9@Z+AobE2t`f!t~osy@VTs&89ahv9lysndT>j?TVrIP~{}@qBace{Bgw32oB=Omk6`4WBvfR{q`z6w03%X z4o0n9qZCCR=rIx<4(Asq^C!;jrZA`zk($>Wcla?$jb7-ZIy_**(<`mZUdyIIz#(+? zb(cWefngbC#Wj^x#RzbRPb-R{nM#CT7F7H3cBbU{)d{PQ(V)=!_$KkFt^8G*55f5Q-ek4{}9$G`O*w8jqC$S0zF+>L$W zXwB5Q0GH<8OK>1Y(b>@uspNS!Nzv4EOb#oqsvHoYm|SCZ8`iqM=5*i^vMRlpVYS>) z>8rZ*ZGT*MU!gCcuF z%#n*PixC||wP9u1eNj`v`iK!D5O{qgJFQ8rDy@00Pn<1H;rG%ev02nZMPzvA@P-rVb>EqHv12}`sMuMr?o$!9rJI0#h@qe&T)@@$!e~mpCJ0{jQdlq;w7=Rv6%d zcT>ez{R<|Eo-@QGYx2l;F`Bpr4_E$*@uV^SZ`s%syz|Y!WuF;#a+^I>FeRr%^Cm*f z|KN==yWn62EUJCOyr3(CoLMl7W^qnb&SE56QmP-d;z$N8NGj`S%U89eC}WcAQccjv zjY{bNSF~!@yx#J}b3oZsl&JJI<(%P6#(nnVCC47zBJqYD#EeT6T=6JmbQvKmNP|YS zlpB~9wg=^=GZ?^qI4Pkj@U_9|@U}|7e1E_DfREa%YH;UOx2^U~JZp8h{`^R9J>4GF z{)%Zgl@(vL^Q;L5e&3Iu=HwLX({f1$>a54ZUjbRFZKKs-X_c43tS;)0{<k(>1wbBJk{I}1rJbYM7&aIJRxqe_V_ zdZ;2!m>_fT*<&j^f}(S5KI_#iPiBt4@wuJ# zmhF-@N)WBpeD_|;)9i$6Q7XqSqsfK>P>;1ByIN5J^l2F|96;U54DZ!>1^vZ%&^eC4 zO_}gH!Qhd%L_1%mX*WGhu`k;hDJDnjBR8RLXXmefZOJNKw(_!on>=umAAL6oub0Th zCpVG-r1P5?fGN%tMbu02htx|FV3om1>PyyUNbQAU4```b2MFkI$w&1e6(LFM*SLT+ z1Q}N;at5N>VmKp>ODWKKuloA_0JOBzuEc zKgtUTE``zTYK|U0RF49q*$M#6YFQ3#_pdtUJ*I3PC#aTIbkfo-+u(hKj9GlW!Y8B? zTXaHCl~6rbqG!U?=IotE5WK!cskeOQW;H=&%IY*6zQEh*c2BeJ;9w>r8R;uhF3LdCiN1Od{l{D3gwY8nJ7jUApQXJ?o{dEaqcMV^m1?bk znr9LM;Aoqbqyp%McTi9%^Bqp+qoS z8iMtXqb;a6n(`H#EzAe%glvD<<78Sdlu8TJ>hrX6qZ*C;=~ zt{}=K#ZQiCb0s0s(eQTq_z6-5yHM(>^2J=ly5Q@@_bdn$;m-?l8Xl^#Q1-0o1RY$v zL-S2>PXeBY1M)8zk6)T^lvY?o8D#29Qkn|cz%~NKy4z$-PG^vD5QmauUd$ zdj1@*fLVu1s6VnvQ4xfD0VXQR^g?y_0;muSn(CV9(_zwhD7Krz@U>)=wWyGLj0^^I z_K%51=BO4f!}Qy@?p40?^+RaUhY1^o?+5{)KDf{lsZkXobc^JViu!U_e8iMz+HfIY z%)F^Lrom9s8+MtTAyv==)OS*e)5)?zXLMwi?f0ba$6*ThIl}w$r=SkXHDhUXGuo}& z7&$#}9g*R8sDxX-E|b+xYv9p21}u^w>Y?X3qbXNkpyR8;enIcIyoAg{^dH9wrsO@j zz9ri}fM2g-Amq+H`L;bSk!mK%DjajsVl3<@FG4bA(iVht1qWT7IasajHJks7Eo?ZS zqwyru0PrBPodIWyqraP)9~vG@nAdRV0M|X!M*QOnpNYxycLu;s3NO>4b=&2O1(>+5 z&tNi*WDK&nZ=|e9tC%_EDBvWmM&gSJB5@F{@IC7_w-?mRJG-xXt&|M5yg~@H;XOi` z2#IL!WTZu$mkg8=?epIVAAiBrTfZ_~H$Lse>N6GQ`G2t!MJx0FB@u2@6qiPlMSef8 zok=+QlK-<04L_%rKRYfk1UEz=7m^n#4zxv_10Y<;V8E{U?(@;-PsoXgW+nNlb%x1e zb?b~ikuD|XA5%}gnr45|bntTCw856{_4xK#>T+691nFwqFhVxRpug>Hq=?C#_Td6uP2>jyp)LCh6vAD8RrD2dLWi5|p(9o*A)##$PACdag zd$t{7dZM^00`$nh>(%tdYq}2W*klV`5waSymt4upb=iU+q4kJcIv|_BLL#izSuSW8 z%qomzU?wrCcpPQtcUdBnvt7eCtdm=wT^sP2neGcs`_?euWFF!P5A7~3iD|WIN zlz*86X4W#5uHW24Kx#=nfm-Mk34Ef9=(V*Euip`OHl=m!JQC}WQZg^t@&ioETQ zXD<0#9!E-JzE)X5nrFXc<*9JL5Ntw4(nC4Aur5+mh1Fg?Uv3z^ z)n`ExJgfVBbYTVRmi;m{cshr>ecNl66MHAC#gpwFQ;p17>`p`hhy07YI3w^eIe4{V zA*fFo%>vxtL~A37>oc8*mi>nw%um0>FxLl0C9LtQU~c%f@`EGF8OTSO_Ve%=WoA`Q z92#j)4zzD0r<*E%gWiPRtmyS0)efd0@+Jy_l)a@K2URv63Z*1_ZFZ6t5Ljf%R4&T^ zYlS|bL&vrMDmQDZ||46FEXJg!c2el4!917aIxFPj&U(t zU9nyx;vrU#NtQjdskU*|@MC&3?S75nl&Dt{zU?Rc9(bv$v=g)5W*v~l{#Q&@9{HtvIS1}*1q^^vljJ^g!hZOTwPoYyBMS+%3&!Q|5 zYK}Z4N24@bCSNIVmoW@Te`K(opNO*^YF$R-S)>Vy=2%wF{WMwkO!CaXe9i#qCS)-6 z6d7mRcpB$+_uk;9c-pzp_6E76ZV%PxF;X1uoBF*(ecI!JX0@fy){_1c`v;_lkKj{X z-uBG*^Ud-Q!=|_75O>?#S!qvdu!MZWIT(Q;o6@izOLx~wczLJ*^zvW^{Q|?)7Nj(Ce50~Wx>@o zm$lve9GHO@m=MMT9a%~7-G0U)Cd3`u+O zT0uS*j26^$3XL%n*Ee1EWk!OR`KD^vs~DU8hSo|3E)1I<8}rh!x?sgNx1pNfKDnHC zsD_gsfiB)GL%W`9>urwCH3Tu{Zu!kRPYe@zzQNXgKP`XWUS3mpu?ShpmL((Cu>A6D zGD;G}OI_y&l`NF=Ycfcg*YBttza_P7s;FWT*T~g_(iZa=S@O}iZ`9yR%V;oj;*|hQ zBYA%1A|aH9$#ogjvSK-F*3vZGVZ`d>Aa9@5(G%&x4NxdGCGC-uow`IRH?8C)A5v-} zcWDd|j%x{L*H-`l!Egk;Q=d&(eR46dcY*^D*xW-Z_O3C%QCXh=u`qXA+6uSOr*C_& z@9m9F)h~f?@7g4(A`=yy$e;sd&)cYm&iYgIDyxIt>FUZ$MVl0|@C>aFqu0!UjfZjh zE>cecoY7#CRwg;8K%I&9L7sTmMbLzy7q5W@ zQZOuK+v7n+qTgY!trw2pv6t{ZX4aXQKLH|WEyUjR0x1C;sjRI zm#6LG>-p&ysp#XEG;^$z=oy%7V^)q(`;0IwWqRYlyt~*`o7J)eXxNs-d0r{CrGwaY-OzetW$}_4yIfPyHP6!-tg7>_u6&h01(Bt17OT?6TzwPWbzn#QrV=##G z0HLB7fH~FJPIB{gZ~|$`Ajpt}wbFTzW3CfEAIgj45WRD4dYhn~OySrpu+X_+p1XOK z{;tH-pK}{C`ehD?--aNE*@M!&P3~O4+7gkP)Ni@E$x{j7>`aqRxyr+P|Bv|zk&V}%9Y@?)m$ z$)p|G*#7y|_=5b972b#-y;>DeDD9p%D`5b9`&x6b`{_>vB^OM{KpQvcTzf(>B=cB&=AM7n&PV+CSDOZhZjgzEgZOXQD7?}{66|y!V zzR6EyAE;=~M`qE0vq2*zBN8I%H)&7u+pbThsbXslWRQwT&5h0ZD%XR?dDG3o#f9;g zz{hO@Ur8KlX0A9+3kCz}{FwbPJoztoqrZ`NrI%A)2G1F>E^~6esQh zbBgQ1vw(el!E9z0J(F?A!|YMohXU!cW){`wvLYOcX^dNcdT6w{eS(j1-=Gp&69AQ> zN~W4EH}ZZ6Nky^2KL2tMc_zNDUmy^S_Ed?)9B2NFI88S^`tH%qG1J&9lfenaZ;CiXHHGA)+d+xNfz)(7MTJWk zN>}soV_X^vYqWsy(T#s$>fepY6v@c(1v{11H9 z;BUD2f5PC(=FXoS)3w}%!JV%DZiwCQx$wS*csAIzMD_Z55VOB5)HKNbBp1Zv24VoSz)!*W(mv_}`t}(Bvw67_|?%Nn*h|ICl_UiUC+|Qd1 zGTJWK4u&(|KQ=xdS87(^H$us7o`0yf(dmk;ZCW5bAb+7cR zZb;4^$t>vJl5H;SQ96Ql5;2}HOPpGNq4|%AlWQqWnkH(FP%GZkNVP;LlFKmIj-b-6E80;X2jvPY-Vh#QAM)Jaxl=c0qT#EDWDxjM9i~T zq*ju5%Wr%pBjtJoN<((SC>Fzv=vYpY1FZ6lf#6c)L0FYH1rP})1;sy%B@X;lMq;=laY2*os>QMDJB(L`xp?Oh zoY#xLFV;U6mYFS-mv98(fesmAppGz+--9iFiWPC%QuXjQR28&s_ivYLj$E9N{+uK_ zj8wKL+hEoVl;Pms@!w-Z~n zfN$-D2CCLr>a<$k2<0b8V=|PXf`kbbj;WYd86^xe8XSCWQDHnFZ0fG9F+n39y)mlN z>K)S22VLs)SCl!2;$}cU_=8e9n^oGT(F|4KZX<{!IxCl76@F?WTmDTaJ$gbsk|bPj zPQ%}P-{`irVO{72V=EGDah-jk15Cqmxt!g8A5T2au)5ExfmL$=yOqxlG)TZ}kM2NvH#?bBkiy#yyv*hXO>^9pstUr{V2 zoHKF$Q=D8^@Zkh~Ko|IO$pyUFjtS{FWc__{{7CWM&%GkkIeO|NTPkRC*`0QzzkaGK z_F!FcTPR+iI-Y7A%-Er>5tgkdI19aGpzgLlWzftwhEqK?|L_Rl7@}VChNe= z$Pp+>kPHjg3qcmUDD4&zl}br19mpPJM^$Z;bYKGRw%wnke75851L2}I9jy!ITuX>) zeHK+$RA~=)+J8ZDyv<1^aJ0)(r{=%fMVg(nl{CCQrfJ&2h-Yn}|Kf#T1kT<~F zd-z_ne9ce9RxryL*Yb^N`#pKe7*sx;xn}BcnC$kP3rFm z#Vs^23*#_t^d@7lpy;3}%-1Euh;nx}%@-4Z8KAcWhalP~7yTK`^^K19jm24bT(t3@ zP&-CMyXDL7gRf@i{e|B<>8>kdjj(Jn1?@+AFY94MfEef~|`Cd`)8 z3xq6Yi2(q(gTM)aXeNwz_uG{RtX&h=YHZh+GJI4$2&frfvX+7R z+McI%)8S7Y9^h32t#lMsfE6|DlEE-@#&@(#+e*#V92I&eVOep9Gk6;1Gex4lFM#nP zXv!nYBJim`aqJupP!hVG*k^WOgyS#iYg17zTy?8!wDE@HRxLp$yVuiW6FrG18brZL z2Fh^yD?%Ec23eU9y;G{}XSzSPf6DS6xhcWS_5eD2k}QYGv)L2}yi*Xh(Qv%|wYs~7 zkRg2A7_~)CSVtyodZq z(}&&1q?V}wFWL!%mRa2Oj3oN_=AP=3jQA8C+eX|&;6ydBg2#)-IzHkh+d}15lsQA; z?vGD2g~nH_MMDNDZ!V^7-0}Ut$IVb)CJT?xoax7B&cy!j73b%4K{G>rhyOcn@NXgX zAMC>P7;)+DpUD0bpx*^Ncw~BVPCLJ2AUW<3$c9nm5TZZub0pAN210{Ceuya(Q@?)w zoSuMOOt&boLwSCb#TMJK7c^q&QU_;?$Ox9V`hObz%Sga?5XHrbQyyoXX$IUQ5GV?V3GkURSv!I)=eN?mGjXNE^OF$e$IpL%!1XxhKVzR zbJ4m;pR3LATflj3Bh7LI4VE_8wSohPG`rFWFx@5+ynH~X7AWjOmHN`2<#zyFsF4`i z0Z~u#R8R2(+8SpSx9?}rw00v7v-_^YIXi@>>m4Lz+Rf}o7)nLoJ&F90WIGqd)hsM{ zP6io`c=%KE8w(bo^78GaWWDMT{O&18Z(;pBog`v>R#Y-@=vS1L=}ld8ir|*^FX$3Y zQ#MX?3L*^emSfha`X}M`evb#q95KhWss%KfJPa$V^3`%N`lxOq5ceX$A~;!clZc@X z5R)C7j`MAUE>k~~xwo>ah#=r>&y22AIC6i|Qa$1XQZZB4z6(SSL^C}ba6NJ;ikQyL zGMocP3oCgfz~Spetct;nxCb}69-E6NX)gE4fzcq|NcvV8Ksn2R2bsHzm%U?96MqcQ z8!K}bv5<_z$sA3phU)s971vJC=hdmh!#{t`$e^dVPHd-}Pgx#QI0b~(=yB|&pD5Z7 zFWUdAcMCGTH*8E;e9OacSADttL}sIeAD-HXk|3fV%1H$xhmV86gI6LbR@o=ETks2@ z>jQBy?Fzku_l^yf-4;oqi-R$w#T#($l}brZ(eV#POO8?!e&T2DzWND!{qM-vzxM2Z zk`&e4brj~3KRkyJ|-cZ1c=rdz(I{2YgWXTwH+zXRd^SdyhCUA0@enIB{EkSrP(b3i8Fl zpY8kGaAH3Pu%;LxkCRBUvks42B$xtnl5+GjC18dbndHk;j?4=1Ng0arN1?^?iEA8Y zcRa-sUw!w^GhGbm0BeTQTxO!r-42t#%)D(H5 z;p6iLh5+gWMPAc+gF1|Q(kXMFYNew_YSNQA=MrK}hf}$*6+f?aBFrNv!)|Ie#aKyR zHsK|k@(3$7>2PN7J&)o1!o6>r^&&0Az;6&?V^@vw7NN=YmPfmxy0<8@3Vf`=5 zh;JZ9(-K56DHbTB)(n>B_N(>VPK+pP#wdu8!)t3zFVx7R>!=%;(x;Ivp=c?hD`HLs zqjC8|f^jZgqVv?K5)Vn|$O`qsmZ>>wbMpq7H3I5t?($00>2*v^0<<&9Y$PeQ^69>7 zvn3m0!h<@#bEzU~pf@QNBkWm@9m%!VyIRAYqp6Ehznj((CBz$ZSfCA!>rd$(lEZ!f zn3PtnVX06-I10UN8=29Hda~?Q)Hi0*F|02f(yO!)MW33Vil;;;%`GB@G8ZtdA%?4$ zAI_N%**611iS8SO;Z&k)uf8qeC2fr!xMotIAeiHt-X%pClljBu2x}}&3FI==aRK%i zRVRv+en&ghTZJtfIgjRie50CjVXRY+}e$IAjeB`z;vy#51uer2Yx6w)u{VaFPl(p%ws56WB_~r^7z!DJvpr9H(w8D#N3F>+EUW^ zG7(a0hV^afYY_&?LHexeIL^e+ZBh1^)A>giZlwiex@#yG&!71l z%qyq4Tw5AM>fm55i&nqrz{3QvZ$~8v36$uOq|Zy!BYD!5LcSHyJ-7q87#R217}ay? z@yXZBVdx6)ldE_u2&jbc5Y?{~1XniQ;aF7E(eMrU#7ioe(CVGkC8zBI{sE7%~!uX0!@>3zv^j}O&;rWgMy^}BV*db z9Z|NxUR-kgyhR{*WuJg3!ODCPal&78?3fvJnQW_YBOcp9;*X=gfxHY=_AB1@TprxVZtHRg%LYrUaRg+#5|LOZ1iXYuG#kL zCq~eqn}pA&ccXqQ?}i3={P`t(zfHGW8A7$e=dR01)2s1|c{ivRx=FcR0`Et9jc$U8 zlVbd`&Y<#~?&x)Zp5(dw?ZZv;1X&nFou^S4%DxWI#e>D&h|fS>huIXLyR71DIlaEb z&7h2;U!UM=2&JqVXO`41FF&@N?Z&E6|4y(%JRn$s$nHL66?0nSC5jalfAYcf}zpI}m^Qc^YMX3|Q*{?c;bjW*J_Nc^Qn*;0+=|zo&+_-hVs<_y4FiZeU-H;##yUufM-`F_|`U>`!fz zoB>kWRm)X&otSVJpH^oGa2g8j+=Cu_V$!B3lIZrvK8O}$E0Po#m z+uk`gXauW5)qnGlxXpLs&=muZBiaTAyX=1%0S<=&QscZriN}W=PLX##_M7eI?Pz<+ zYQD9GsOwk3eT4%1q$E{eoF2I@9lmGKGU1fWR)|Iio%{+|oHY^?Y7#VpA(Be$nGmQ_N1sy9xpyJ&|oI6i4cecVGSPebcS@&ids65Dr#Ur*>& zrzX=O1{>eV-N7u=B1r4MUgipLJ>WLRYZE;pe>`5>_k*Xm^Kn7{zFs=c@4EPtx5p8A zw)Uz9f+O5n+f4V^lJQgL`!a-2BnLG2$mcxoTALLNj|hSuqJe`e&`w=P>6AI@YPs6N zxo}(oC$|NN;fUNg{#^4bhytv@u$wYmrpgFQq^7cgKPHZk6Lzk7PbE`8Rsl$stN16P z@+PrFR)y^5K55-!+5%685$4UJ2BJVk(h+jM9@g$VcQz#@?__U}<{Sk&DlP%-gy?W< z=sivSq;FPYNi(O` z5HEqY$GWbRrxmQ0==N~A9?&<F_j%2W3=4!$TnmYqE#YOX1Y|PG#iTJ>ljw-iK%Akl7$?#+}$Gn99fBPc+Yz}>~*#0XuWBiWE5OPd$;50Ytdgro83^flX4-+Y)J71fIEKeNGw zBr+5C^rJ#(s5;=j4kY8oMcO_iy4z5veevksijBXuKP9?{CVhqByJ9OZ@!hT#4tsd? zSiD9(-hlU;-|vT!dv}pKl#p&Ohc+W;S;%6N`qBum-l>S3&LXyG2fN- z!Wp=`hPH}Jw2f_zP~Qcvl3(m(y`nk~<2*ILd~r@JqLiuP8U2o_$LxXfP}K&0W6OiR zd5A!qnle+Ayj3oTmME25%W#Q{?L*Bhf1`U2AzNZ)%p}s3eOrWD5i`TTdL`v%9hL9~ zCd`KRvxGBTAM2?~WxaFZ(lP#+s9gfv&H;Tx=X@-|`HI9PPPO@`SIEF+;q6nVA#Q*6 zvyoPPGsFYyfb^!i>7;5GApS}%{esoQap&je_B@xuwhXM5sp=~G;aE;yP#;2d<3em- zEbDnS>6%zcFz~vKu2fEDL84Mc65jMkZ@dD~wHy&ZnG&X_30WVh%jH{Lx3oYT0^^5h zRQiL+MKT-wqY3zn}!{jhC_iqCBb z(86TZ7Vq_QRVvZf!`i}rasWX_Dw(cgW`w0fH9{yp1m-A37}LV40F9wWY-%W0b`qm&KyLR?{4&M8XH zQ7kQFfez>`KIsi2eno5^dr`ye`UCS4#G-qHqp&JrdA6p}B_00Qm~++`Hv+9^!-ghp z3iFmqT>IPu$y@lxthe|R_m4`fAp64&y^C)va4I`k`Ox5UdHxx)N;s;kS|6*+)5O~O z*5|&5r4_eS*7qDN6+E6d0Rxk3ic_&tU%U_GgTgwuJpvIS%f?;41o|x_MzmbQg=NS+pUb)3e|5WOmax^E z3q;OUcWs&dx-X&Y?5A8xetLg7s*si#2cGQCBevsC;J#>5fT)4KU>rkIh9KCGac`j znyYHBzbxub^4wrJKu>n-SO6bmZxT5c6lh4@X+>!}#@TQzvcwOJf05oRd|=(n=XDHs zgngh~DqT{EH$-*tWVSl=*gZJ}e(NdwgV1Bvtq1)lY6Z$A4I#(-TMu`m(3{e#{68k^ zoQe%=0-<3)^KP8NoXQN-`P7yPnB%AbhdAcHF~{*40!OyL?M>T$vvcG}c}S1&;&wDl z1l!v^LB(u+ecg-qdSq&vAEWG7j9$2BZ_+^Vx7DAIy)&&zJG|*ie?sanp5{;Ah-2Vd zke6N(?!^dsG_W^oo4oG)F3HT}j-I&PFKE7b~BIqW-8;GhOz{dDRp|+9(9l9nS!v*0QBg}tzE+rvawlW zj+@M)%>;o3*)R7{PuxeSk7oDOg?&@IhQTM%2{&-;OSfDqUeH4<7(i9ZFH4v;NTero7PZXYg20xjZGYt&I3C>tzg2z?5 zVcq+FMRyRn`ykO33$Oh~sW%_ER$XhX#;9i;_uXz>l#pRKpHh8+{?K(u+vOHrn&V<8 z+F8f6o;Sg_S?=g*C|c773TYU{a>$`ENfH|z;jM+v6WTplc8r3iEeoP?7V;+&w>-6c zbwZ3!F&%IkZz-Zt(^RKaTf6O2*ZiFJ?c-2h1cWcTS)?-_G6$GqJTm&p;hCXjM;TNs zhISR#h3?gp6bs~fxj*_u&IeW=Y8g){wqNOFo3#-k>Uhi>p&~qBjp8$ifS(x?aX4w1 zNkR|hXqK5q@u9hUx&5lt(;!7PzM=4=kQI4>(;)BOqV`y(YqMN z)-tR}C)uciq1>GtxghGhn(`lGY`7|6l?s< z8AG;RHz)>p>JtGY^j|&o-yZmHw&(A=^YYtLz%fjo5wr>#ux3vTWxSW-G_3*E(p|rH z{9ELgZlNHaqHe22n>!}VwQZyyUO9;pBpGT&+O)Fs5QCdK3rZa;o0>u?sTw@`lUD5~ zJ8%$=Enz4{sUBIt{o+(^iojREeNSLl{3K|z7FkjGl|_RoPjTDeQ!Z-B>wdm_gRJ@t zB)yubCL67F3UXG`E!^0+!qXBDrU5_hRkNy4A=DVg_C|4hI;dn5yzg+_3+9c}w}s~B zs$*f$rIolL_5MKXx7%Byj_5WIP_(8ODOzM=dT8s?l=~APJ^2`OmPnj(;fC?12O!JN z;n26)ukq9UhuOP&{HR9aBdaexvVDS?FOQkcYOzIbiRl>5kmb!YFWfUXjqxMc>Sd}1*`%Ic&(IR!` zuhPZLKERkUdFw{9DEzi_5d||ygjt4x)QF@muamSO+X{7pD>l5!K^3VZHn?Y)QBpji z<3(Kr?%X?w#^V5R8Nc)~!mk@>$JIjQ#emBuDGD4M*TvrbhbqV4?4ac<%_$QIVV*)t zpe-e<1jU6eMV4 zRFk#wZ4A#@dd+FfsN)jxCDzMSTxUukcPt9ygtb^LAmwYp$8JIcR+W3c?!4k-iO`Mi z+z#QVdCuz0cD^IwLn}!(DXlgENx_-s@*}1C({C9yWh{hxa`1fX5p9*GM>Rt8O$1&K zl^{GLK@-_*QsPsWmkhMBCR6($l?>f&JJ7eNQs)_{2?}~SW4ABMUuiBReJibC+39*k zbRaF*xx^S^qN-U;*gCSmSE}`>E}r89Syqn%^Xx~#ZQcQe)Px-PMTFG>f=Kh|l$Ko? z9t~w11pDIHdx||a{AjG*@zMloK}yx)GD}!93mN_f!!HqEIu9|5e(p9|LMkKDblkqg z(@RV|+;ywuE-m(mDPF3drtgkcd<#V-r^zET`tHqxr1%Q4SEDTboA#)hp95l?Z8O=b zqu%s-%pD0=x*Z70a{7znAu#994?D4SB;?WFnvDr6-O$^3`3bCtj$?qbn06J?j(Z@; z9U0zI9|XOh-jd?-8D%Fzcl)LxhO_0d|5bTk1a(2a_De+ml-=yD*-ZBZ5-mGX@sgLX zBX%C%3^j1|DRkZo4x*%EOw1+aZ#Mvzb$6*#TRS8&8qG8fuC!EEwZl9#_8-U)NWdW(xa_c>KmK4iv35%M`X;Hxw`&nG`<1>Wl<`zS);_|gm{ zPc8QBrJHD}@kpdOs$c0UfVlBq@#-cyEaNmUavMntqq~{jSEgZGtUp_z&J)(AspexhlJ=MEW_7vHqzHn4hyk@Ub~nM z3{eV4Sdv}VlWug+3PC#_tzhrAOhjtP47r48bqW27*6rIIE8S4KF2gH@)lz%<+jlvb zhz<$sA*U+WPDZnM`9-79RYIZ%OKxYTs_e_QgYT}(z$MYNs z)QLRUD-*hLweYa`J$e6d zC-IF)s~Y92NZv?yyytQ}-2H9r+>taN2;QxLE?Ik#xjxqolDA91oN^ns8nyK{_Oeqp zVdIT{IOq|Pw$p4O37uXv$!i|LE?9)z?Wfh~KoMeB_fIsl3^NS*a@l0whQq1W*0UFn zChrO(sYz=F;**C0T&lijLp?2q2l4<#{b7o~c$lEufe7Bf7F{N$m}}f~j-%&0uCF=_sq|%JWF<+x_|d*FB&V(V1|*2lWQ09VYNw^4uvT~9c~J#!__R`zu~Z*` zgnZMb*W6l}FRP^IAa?$PcaF06TUzi&4swgGR?i}`VU2r?S7{fGK;fg1qM%i#Opti< zO)XVE7VSv|boKJLk+aGe*d9Zs=C`>FMz#2{ zx8RT=Q>z|%hR6q@5h2fBqIR7~NZUNEPSrIXB0$K=owG6hS{+7+Tidwlr9aHz4Ml*@ zHdVg;bX%ee|4aCo6=5kdg;ZWa0>!;p)&1CxiTUxW0U^J~EXtMD38m)rl`RKOA*x3l zr%W`R{PNU9rcPHPxbd6CoC}7Sc!pS-@8@bF~pgX!w z+)^Hvhi5~J)j;b0cwP@wQL;%I@gPteor@n04{&*szq`1BF^uum>mWzdI+n%DG)Eyl z`LH90pXe6hSj_ZT2Nlu#ytj4{r%Mt0ku-})*<2CJP@BQ9+iet#SZYqf7$(ZkKzkw^ z!3*||;I%Lc4)S^#VuBA{b1a6gcy>kt?Q)c0f{zOkUhpr9(e%IS#k7CE5j<7V#6cW& z3gd))uPdN14tNW40cX_z2O$zZN2ra#x2^4;Q~>f7HG#uV=scC0HQNrwSgDWwbgB4z zL{bsM(Xc?eqWCO1CSDIKx7BbeYuDb5hbAx4@3tX91cO09%;iXHOI1@bGi-nQ=g;Gq z*Cls)=Z-%E&bM$9lR=~*VyK)!u6(cpF1?Fge{KH44;!O@c=Swx@dMt1&WlQM=fQL9lDm5 zI31@V*NWa0b1qg>Hd1((KH)ZWX{WZdPTrv$o4j5hDz^tOIvw!jLbV=c={=H%y)$5dcsrGi z0;St5Su6krw-$f8edJBzo;!8)YQu}`{#=%lO?;Z^R_q5SIn51(oD_1;jF3Q;@uAS` zoR(0@wt$cs6~*E#JwgJM9?x#|0d9e<*yerlzJO#y+%2qVQ%Bsjfp%xt`z#EvMxt() znSs|6Nn2(c5;Fr_P;_E%Xl?h(nc1gjxiC%or)U~&td~zextFwHV96TXKqFtBkSp=r zus=_+#h$q*(9Sx$-wJCrqW+Lx`QW8d=}e}Bdx0H;R9wov45^)dbi~yF_^u3%M*-fc zgG8u<`t;$-Ai-F3rh6_|qxG~gy88&pzIGKNjL9XT3h0rG7RjQ>(g<LQ*hZ`x0v%PBxv4Og5ZKk(DyB9RvvL{a_M8VF<|yS<;mIB1OzS!!da=4ubzFBl z5%ym+iiy{;8_a{TnInSsXj-_h;c5?kbiS1?%+1O^Rn!!SD643u$=c&6ypP)-9mE>g zk6wS2m32P|v1cJ1*h0|qi{&m+SWO;XYG1uYw)AL`->N2FgHUMjG?dq>dfJKJI2?m6 zFJ^-8aSB3Up#`Z5yu|jjsZq`&B=d69rW&Oh#LVm{)F&l5QM6A=@*@d1-rB29`S2XS zK80Cs^Y&#hz5%M=6*xKeSJGen28Iu941`T=Z0+Rjb-y>!w{>@$(p#GmVa$_pr4l}+ zMr&*FY2WyTutV%N(mOcv)1X!STO;_xoF6H;nz1HtlK1#1Z;*ea-H_x;?Zf<1$b3BV zX+wY^F)C6@AevNH#c&j$EK+x{;!Ri!v@?uzd|)D*T%fd?)y1`QXTX22>g!); zpgfkFZ!uw4F2_8|nx{3EgUU6pKDwW>0@iHGl;yR>AR8ZK2Wj`_MNi|=(Fj$`^09B#oi@9 zixr=<3ENGq-GwvlnJ=}=AkmUtvJZ5UDKNy4%janbH14)GLy(gmJvJ@pikTUwhxU=I zyji@eVql0x?3hO7oki(aJ@>4ynmQP@TK4!uWI7u{!*amG%_( z!Q}eH!YSHeLo0;14XpbyC198<$fqT(ZiLeB@r#3xfIN!fgfUTumROd%07;zq4$0y5 zK6t0(>1Ewuh~DEn=(=LAycM!)*$bw z249wDj6EUbe%!!NMiVUNLH;%_^f;)KZbdF2D;2aDb+;CmPAEjeV@Z%Img>Hc6B7A= zBLTExY&!!JKNeBSp1D0<9S4ncndG4@4#f9MR~=z>6p+g zEB`IQRv(-&Y#cdynK$n7L?hv#TNESw^Ww^0*NGdS-n?sqp2OFwn#jC2aN3txUFT6( zf2r}3c?=0!Fqt`Ks;YP2Wpk_)Arg;nZi<0x`qN*+cq@83L{p}Xh~_2dFalgSZ6f7% zYy&w3s8v{`T3;p>J#LguzCKfiK*(jRc7quSN;357)~pCA9-`*Eno$CgK!@sk@?-(G zF0&FC=psLK>#7n-85%zdwG)OseN@2_=H*;bQsJ)RLP=$7C8=}IfUf9@gc1$vp@NE2 zS6aY+L!_Y~f_U}(yD#4GVz7=JAM9-U~Xmm}S zdQGqRh5;7X_DMIGu^xHs$~%x%R{h7a$7~I$arAby2z@kZTsg+TCtaEva_)VzEwxh^ z@9xA>F%Nj4IV%AJ71PBg{b^wS?g@Nh1{x*bWI4i%?zTK>y_vyst&EoseR>cCA&|GE z^n=F`6_pK)%zZk~=D!N~HH@_j?E*2yAGdm3=&*Ob365j3AbbZ6IQ^wVhZ#?v~v zcf#-(NmsEpoJx$_jhbS^PANwx2S3(^}Ro^ z_QY{Fn}V_j&9`of=XgB%^d^zQcA74l`AOgH58>QFD_B#Ndmm}sq{0)$o$o$ni@$^~CKkG|YRcis`ToM`BXE zf44;BcWL51$t8C`$VTA%jd)FF|Ie@bUb3_W$#tgrx-wC@wvESj##2>f9jZ*Y(r^pi zp>l~{dAN9E2BPnj?W;Jl7=Zt-)U6l0Z5C#gAIg?^j~ke1bOQn1e`D{w_(=V4H|t;K z89RV|AN|xqoxO@khMMF=9phLYqRE{``|rQ>V_PLHRLl=K9h zM20IOn+4>&cN5!Ke8*(hs;!JnRqpiuL#t(a4Clmlf6_v&Ou$xC&R(yp)XX+%39ZpitwCH zQr3BfX4%%e*Q&TM6vJ%pVv|c#W+&z_Ug>DAd)W}LvB;TMc9XjY*}MXTuMmq5@hmKw@Y~P_Adt};v2E_`s$lLw0r z9v2ajLFB`>)17zVmN+Z99y{`2QiQWOy)d8RvS}N*G=(y)dil9I_NC~uxoey_gw?k? zG(ScVB-V-~26}~%JU+5IVi))5YGd(fmqvEz-C|!8c8_iAZuB9yx&(iv!<^1oq^}yi z*+B`(B8XIjoKpbLI1@+to|xsWSIZbfBAE3QoEUAmhw|V6+&8ZTvm1#`WP6=7R6y|` z{5*d0p7#ef+ae{e#GRe=5Cm>w;Qp@V4xD=a|J8A4EM{Vov2s9_Wnf}pS)-=x9uSAn zQB|x`Q}=fjE*^ufoLvnE-hIkuwK6hwm3U+&16YSBQ`TAFY^_ zFmP`7*JL}4_Xp1mB?`cedG^ciSBB@=Qu3c<5I!j}VIg@1I*9Pk2(d84z(Du?IwOt+ zzMm<<{wW2pVEQRV-S-sVb=d!u@YauXaA#EOzb5=Hqknsu&u`Fw33T=Q9Ip+xyqN$}PZ9!#^dEr0XNG4h z)^9O^b6a*$bMxP$iOk}+HUs64x=^)Kpx>hLKYVC+7DmA8EaodB+`eT%EHl@&1eQTe{YFDX(Pi@!74MJ zQ>APE1=Y7o`>*PPm9;x3>CyQMl0S>w!IlVC2ke{-N&in|KX0kRV#2E9oMQ@^{0Z}W zgM5Sj_Qy{J2$Vb8sub6#@%Z_eL$SFjGJ=a{ok{~Hr@(ft%Q)3CmM=LEw6e?jnbFZKHp zz&cf(6VwD>Aowv#{EcZ6wj{7V3+F_w5f_LqJg$Fw-C*~D&yl;ME+Aign7%>(epeW_ z5U|^C=T!B;0_fj+^8Xl1VYigdVfo_!1pB?i_`?PhYyn^`&*x0uNf(%4r|3V`-G3Aa z)*5 \(.*\)$'` + if expr "$link" : '/.*' > /dev/null; then + PRG="$link" + else + PRG=`dirname "$PRG"`"/$link" + fi +done +SAVED="`pwd`" +cd "`dirname \"$PRG\"`/" >&- +APP_HOME="`pwd -P`" +cd "$SAVED" >&- + +CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar + +# Determine the Java command to use to start the JVM. +if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD="$JAVA_HOME/jre/sh/java" + else + JAVACMD="$JAVA_HOME/bin/java" + fi + if [ ! -x "$JAVACMD" ] ; then + die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +else + JAVACMD="java" + which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." +fi + +# Increase the maximum file descriptors if we can. +if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then + MAX_FD_LIMIT=`ulimit -H -n` + if [ $? -eq 0 ] ; then + if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then + MAX_FD="$MAX_FD_LIMIT" + fi + ulimit -n $MAX_FD + if [ $? -ne 0 ] ; then + warn "Could not set maximum file descriptor limit: $MAX_FD" + fi + else + warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" + fi +fi + +# For Darwin, add options to specify how the application appears in the dock +if $darwin; then + GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" +fi + +# For Cygwin, switch paths to Windows format before running java +if $cygwin ; then + APP_HOME=`cygpath --path --mixed "$APP_HOME"` + CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` + + # We build the pattern for arguments to be converted via cygpath + ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` + SEP="" + for dir in $ROOTDIRSRAW ; do + ROOTDIRS="$ROOTDIRS$SEP$dir" + SEP="|" + done + OURCYGPATTERN="(^($ROOTDIRS))" + # Add a user-defined pattern to the cygpath arguments + if [ "$GRADLE_CYGPATTERN" != "" ] ; then + OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" + fi + # Now convert the arguments - kludge to limit ourselves to /bin/sh + i=0 + for arg in "$@" ; do + CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` + CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option + + if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition + eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` + else + eval `echo args$i`="\"$arg\"" + fi + i=$((i+1)) + done + case $i in + (0) set -- ;; + (1) set -- "$args0" ;; + (2) set -- "$args0" "$args1" ;; + (3) set -- "$args0" "$args1" "$args2" ;; + (4) set -- "$args0" "$args1" "$args2" "$args3" ;; + (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; + (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; + (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; + (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; + (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; + esac +fi + +# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules +function splitJvmOpts() { + JVM_OPTS=("$@") +} +eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS +JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME" + +exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@" diff --git a/libraries/tools/kotlin-gradle-plugin/src/test/resources/testProject/alfa/gradlew.bat b/libraries/tools/kotlin-gradle-plugin/src/test/resources/testProject/alfa/gradlew.bat new file mode 100644 index 00000000000..8a0b282aa68 --- /dev/null +++ b/libraries/tools/kotlin-gradle-plugin/src/test/resources/testProject/alfa/gradlew.bat @@ -0,0 +1,90 @@ +@if "%DEBUG%" == "" @echo off +@rem ########################################################################## +@rem +@rem Gradle startup script for Windows +@rem +@rem ########################################################################## + +@rem Set local scope for the variables with windows NT shell +if "%OS%"=="Windows_NT" setlocal + +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS= + +set DIRNAME=%~dp0 +if "%DIRNAME%" == "" set DIRNAME=. +set APP_BASE_NAME=%~n0 +set APP_HOME=%DIRNAME% + +@rem Find java.exe +if defined JAVA_HOME goto findJavaFromJavaHome + +set JAVA_EXE=java.exe +%JAVA_EXE% -version >NUL 2>&1 +if "%ERRORLEVEL%" == "0" goto init + +echo. +echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:findJavaFromJavaHome +set JAVA_HOME=%JAVA_HOME:"=% +set JAVA_EXE=%JAVA_HOME%/bin/java.exe + +if exist "%JAVA_EXE%" goto init + +echo. +echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% +echo. +echo Please set the JAVA_HOME variable in your environment to match the +echo location of your Java installation. + +goto fail + +:init +@rem Get command-line arguments, handling Windowz variants + +if not "%OS%" == "Windows_NT" goto win9xME_args +if "%@eval[2+2]" == "4" goto 4NT_args + +:win9xME_args +@rem Slurp the command line arguments. +set CMD_LINE_ARGS= +set _SKIP=2 + +:win9xME_args_slurp +if "x%~1" == "x" goto execute + +set CMD_LINE_ARGS=%* +goto execute + +:4NT_args +@rem Get arguments from the 4NT Shell from JP Software +set CMD_LINE_ARGS=%$ + +:execute +@rem Setup the command line + +set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar + +@rem Execute Gradle +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% + +:end +@rem End local scope for the variables with windows NT shell +if "%ERRORLEVEL%"=="0" goto mainEnd + +:fail +rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of +rem the _cmd.exe /c_ return code! +if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 +exit /b 1 + +:mainEnd +if "%OS%"=="Windows_NT" endlocal + +:omega diff --git a/libraries/tools/kotlin-gradle-plugin/src/test/resources/testProject/alfa/src/deploy/kotlin/kotlinSrc.kt b/libraries/tools/kotlin-gradle-plugin/src/test/resources/testProject/alfa/src/deploy/kotlin/kotlinSrc.kt new file mode 100644 index 00000000000..eec86b34406 --- /dev/null +++ b/libraries/tools/kotlin-gradle-plugin/src/test/resources/testProject/alfa/src/deploy/kotlin/kotlinSrc.kt @@ -0,0 +1,12 @@ +package demo + +import com.google.common.primitives.Ints +import com.google.common.base.Joiner + +class ExampleSource(param : Int) { + val property = param + fun f() : String? { + return "Hello World" + } +} + diff --git a/libraries/tools/kotlin-gradle-plugin/src/test/resources/testProject/alfa/src/main/java/demo/Greeter.java b/libraries/tools/kotlin-gradle-plugin/src/test/resources/testProject/alfa/src/main/java/demo/Greeter.java new file mode 100644 index 00000000000..ec2831d8d21 --- /dev/null +++ b/libraries/tools/kotlin-gradle-plugin/src/test/resources/testProject/alfa/src/main/java/demo/Greeter.java @@ -0,0 +1,17 @@ +package demo; + +/** + * Created by Nikita.Skvortsov + * Date: 3/1/13, 10:53 AM + */ +public class Greeter { + private final String myGreeting; + + public Greeter(String greeting) { + myGreeting = greeting; + } + + public String getGreeting() { + return myGreeting; + } +} diff --git a/libraries/tools/kotlin-gradle-plugin/src/test/resources/testProject/alfa/src/main/java/demo/HelloWorld.java b/libraries/tools/kotlin-gradle-plugin/src/test/resources/testProject/alfa/src/main/java/demo/HelloWorld.java new file mode 100644 index 00000000000..2bc6463319b --- /dev/null +++ b/libraries/tools/kotlin-gradle-plugin/src/test/resources/testProject/alfa/src/main/java/demo/HelloWorld.java @@ -0,0 +1,18 @@ +package demo; + +/** + * Created by Nikita.Skvortsov + * Date: 3/1/13, 10:50 AM + */ +public class HelloWorld { + public static void main(String[] args) { + final KotlinGreetingJoiner example = new KotlinGreetingJoiner(new Greeter("Hi")); + + example.addName("Harry"); + example.addName("Ron"); + example.addName(null); + example.addName("Hermione"); + + System.out.println(example.getJoinedGreeting()); + } +} diff --git a/libraries/tools/kotlin-gradle-plugin/src/test/resources/testProject/alfa/src/main/kotlin/helloWorld.kt b/libraries/tools/kotlin-gradle-plugin/src/test/resources/testProject/alfa/src/main/kotlin/helloWorld.kt new file mode 100644 index 00000000000..b3e99bbdd59 --- /dev/null +++ b/libraries/tools/kotlin-gradle-plugin/src/test/resources/testProject/alfa/src/main/kotlin/helloWorld.kt @@ -0,0 +1,20 @@ +package demo + +import com.google.common.primitives.Ints +import com.google.common.base.Joiner +import java.util.ArrayList + +class KotlinGreetingJoiner(val greeter : Greeter) { + + val names = ArrayList() + + fun addName(name : String?): Unit{ + names.add(name) + } + + fun getJoinedGreeting() : String? { + val joiner = Joiner.on(" and ").skipNulls(); + return "${greeter.getGreeting()} ${joiner.join(names)}" + } +} + diff --git a/libraries/tools/kotlin-gradle-plugin/src/test/resources/testProject/alfa/src/test/kotlin/tests.kt b/libraries/tools/kotlin-gradle-plugin/src/test/resources/testProject/alfa/src/test/kotlin/tests.kt new file mode 100644 index 00000000000..e631927f0ff --- /dev/null +++ b/libraries/tools/kotlin-gradle-plugin/src/test/resources/testProject/alfa/src/test/kotlin/tests.kt @@ -0,0 +1,21 @@ +package demo + +import com.google.common.primitives.Ints +import com.google.common.base.Joiner +import org.testng.Assert.* +import org.testng.annotations.AfterMethod +import org.testng.annotations.BeforeMethod +import org.testng.annotations.Test as test + +class TestSource() { + test fun f() { + val example : KotlinGreetingJoiner = KotlinGreetingJoiner(Greeter("Hi")) + example.addName("Harry") + example.addName("Ron") + example.addName(null) + example.addName("Hermione") + + assertEquals(example.getJoinedGreeting(), "Hi Harry and Ron and Hermione") + } +} + From 0514ddc719d50ae79f64749fe4d6e3bc86d02f60 Mon Sep 17 00:00:00 2001 From: Erokhin Stanislav Date: Thu, 30 May 2013 17:09:31 +0400 Subject: [PATCH 179/249] fix Iterable.toSortedList --- libraries/stdlib/src/kotlin/IterablesSpecial.kt | 10 ++++++++++ libraries/stdlib/src/kotlin/JUtil.kt | 2 +- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/libraries/stdlib/src/kotlin/IterablesSpecial.kt b/libraries/stdlib/src/kotlin/IterablesSpecial.kt index 62aff9516be..92abbab4362 100644 --- a/libraries/stdlib/src/kotlin/IterablesSpecial.kt +++ b/libraries/stdlib/src/kotlin/IterablesSpecial.kt @@ -75,3 +75,13 @@ public inline fun Iterable.sort(comparator: java.util.Comparator) : Li java.util.Collections.sort(list, comparator) return list } + +public inline fun Iterable.sort(compare: (T, T) -> Int): List { + return sort( + object : java.util.Comparator { + public override fun compare(o1: T, o2: T): Int { + return compare.invoke(o1, o2) + } + } + ) +} \ No newline at end of file diff --git a/libraries/stdlib/src/kotlin/JUtil.kt b/libraries/stdlib/src/kotlin/JUtil.kt index fc015040ae4..400fb43963c 100644 --- a/libraries/stdlib/src/kotlin/JUtil.kt +++ b/libraries/stdlib/src/kotlin/JUtil.kt @@ -27,7 +27,7 @@ public inline fun Collection?.orEmpty() : Collection /** TODO these functions don't work when they generate the Array versions when they are in JLIterables */ public inline fun > Iterable.toSortedList() : List = toCollection(ArrayList()).sort() -public inline fun > Iterable.toSortedList(comparator: java.util.Comparator) : List = toList().sort(comparator) +public inline fun Iterable.toSortedList(compare: (T, T) -> Int) : List = toList().sort(compare) // List APIs From 58914cdf33be43ddb74fb330c673d0ae96f2ac75 Mon Sep 17 00:00:00 2001 From: Maxim Shafirov Date: Thu, 30 May 2013 17:54:27 +0400 Subject: [PATCH 180/249] Delegate properties stdlib, take 2. --- .../src/kotlin/properties/Delegation.kt | 175 ++++++++++++++++++ .../src/kotlin/properties/Properties.kt | 5 +- .../properties/delegation/Delegation.kt | 118 ------------ .../properties/delegation/lazy/LazyValues.kt | 75 -------- .../properties/delegation/DelegationTest.kt | 8 +- .../delegation/MapDelegationTest.kt | 91 ++++----- .../delegation/lazy/LazyValuesTest.kt | 20 +- 7 files changed, 236 insertions(+), 256 deletions(-) create mode 100644 libraries/stdlib/src/kotlin/properties/Delegation.kt delete mode 100644 libraries/stdlib/src/kotlin/properties/delegation/Delegation.kt delete mode 100644 libraries/stdlib/src/kotlin/properties/delegation/lazy/LazyValues.kt diff --git a/libraries/stdlib/src/kotlin/properties/Delegation.kt b/libraries/stdlib/src/kotlin/properties/Delegation.kt new file mode 100644 index 00000000000..a56b98b2a78 --- /dev/null +++ b/libraries/stdlib/src/kotlin/properties/Delegation.kt @@ -0,0 +1,175 @@ +package kotlin.properties + +public trait ReadOnlyProperty { + public fun get(thisRef: R, desc: PropertyMetadata): T +} + +public trait ReadWriteProperty { + public fun get(thisRef: R, desc: PropertyMetadata): T + public fun set(thisRef: R, desc: PropertyMetadata, value: T) +} + +public object Delegates { + public fun notNull(): ReadWriteProperty = NotNullVar() + + public fun lazy(initializer: () -> T): ReadOnlyProperty = LazyVal(initializer) + public fun blockingLazy(lock: Any? = null, initializer: () -> T): ReadOnlyProperty = BlockingLazyVal(lock, initializer) + + public fun observable(initial: T, onChange: (desc: PropertyMetadata, oldValue: T, newValue: T) -> Unit): ReadWriteProperty { + return ObservableProperty(initial) { (desc, old, new) -> + onChange(desc, old, new) + true + } + } + + public fun vetoable(initial: T, onChange: (desc: PropertyMetadata, oldValue: T, newValue: T) -> Boolean): ReadWriteProperty { + return ObservableProperty(initial, onChange) + } + + public fun mapVar(map: MutableMap, + default: (thisRef: Any?, desc: String) -> T = defaultValueProvider): ReadWriteProperty { + return FixedMapVar(map, defaultKeyProvider, default) + } + + public fun mapVal(map: Map, + default: (thisRef: Any?, desc: String) -> T = defaultValueProvider): ReadOnlyProperty { + return FixedMapVal(map, defaultKeyProvider, default) + } +} + + +private class NotNullVar() : ReadWriteProperty { + private var value: T? = null + + public override fun get(thisRef: Any?, desc: PropertyMetadata): T { + return value ?: throw IllegalStateException("Property ${desc.name} should be initialized before get") + } + + public override fun set(thisRef: Any?, desc: PropertyMetadata, value: T) { + this.value = value + } +} + +class ObservableProperty(initialValue: T, val onChange: (name: jet.PropertyMetadata, oldValue: T, newValue: T) -> Boolean): ReadWriteProperty { + private var value = initialValue + + public override fun get(thisRef: Any?, desc: PropertyMetadata): T { + return value + } + + public override fun set(thisRef: Any?, desc: PropertyMetadata, value: T) { + if (onChange(desc, this.value, value)) { + this.value = value + } + } +} + +private val NULL_VALUE: Any = Any() + +private fun escape(value: Any?): Any { + return value ?: NULL_VALUE +} + +private fun unescape(value: Any?): Any? { + return if (value == NULL_VALUE) null else value +} + +private class LazyVal(private val initializer: () -> T) : ReadOnlyProperty { + private var value: Any? = null + + public override fun get(thisRef: Any?, desc: PropertyMetadata): T { + if (value == null) { + value = escape(initializer()) + } + return unescape(value) as T + } +} + +private class BlockingLazyVal(lock: Any?, private val initializer: () -> T) : ReadOnlyProperty { + private val lock = lock ?: this + private volatile var value: Any? = null + + public override fun get(thisRef: Any?, desc: PropertyMetadata): T { + val _v1 = value + if (_v1 != null) { + return unescape(_v1) as T + } + + return synchronized(lock) { + val _v2 = value + if (_v2 != null) { + unescape(_v2) as T + } + else { + val typedValue = initializer() + value = escape(typedValue) + typedValue + } + } + } +} + +public class KeyMissingException(message: String): RuntimeException(message) + +public abstract class MapVal() : ReadOnlyProperty { + protected abstract fun map(ref: T): Map + protected abstract fun key(desc: PropertyMetadata): K + + protected open fun default(ref: T, desc: PropertyMetadata): V { + throw KeyMissingException("Key $desc is missing in $ref") + } + + public override fun get(thisRef: T, desc: PropertyMetadata) : V { + val map = map(thisRef) + val key = key(desc) + if (!map.containsKey(key)) { + return default(thisRef, desc) + } + + return map[key] as V + } +} + +public abstract class MapVar() : MapVal(), ReadWriteProperty { + protected abstract override fun map(ref: T): MutableMap + + public override fun set(thisRef: T, desc: PropertyMetadata, value: V) { + val map = map(thisRef) + map.put(key(desc), value) + } +} + +private val defaultKeyProvider:(PropertyMetadata) -> String = {it.name} +private val defaultValueProvider:(Any?, Any?) -> Nothing = {(thisRef, key) -> throw KeyMissingException("$key is missing from $thisRef")} + +public open class FixedMapVal(private val map: Map, + private val key: (PropertyMetadata) -> K, + private val default: (ref: T, key: K) -> V = defaultValueProvider) : MapVal() { + protected override fun map(ref: T): Map { + return map + } + + protected override fun key(desc: PropertyMetadata): K { + return (key)(desc) + } + + protected override fun default(ref: T, desc: PropertyMetadata): V { + return (default)(ref, key(desc)) + } +} + +public open class FixedMapVar(private val map: MutableMap, + private val key: (PropertyMetadata) -> K, + private val default: (ref: T, key: K) -> V = defaultValueProvider) : MapVar() { + protected override fun map(ref: T): MutableMap { + return map + } + + protected override fun key(desc: PropertyMetadata): K { + return (key)(desc) + } + + protected override fun default(ref: T, desc: PropertyMetadata): V { + return (default)(ref, key(desc)) + } +} diff --git a/libraries/stdlib/src/kotlin/properties/Properties.kt b/libraries/stdlib/src/kotlin/properties/Properties.kt index e045c5993c6..78dc550e692 100644 --- a/libraries/stdlib/src/kotlin/properties/Properties.kt +++ b/libraries/stdlib/src/kotlin/properties/Properties.kt @@ -2,7 +2,6 @@ package kotlin.properties import java.util.HashMap import java.util.ArrayList -import kotlin.properties.delegation.ObservableProperty public class ChangeEvent(val source: Any, val name: String, val oldValue: Any?, val newValue: Any?) { var propogationId: Any? = null @@ -65,8 +64,8 @@ public abstract class ChangeSupport { } } - protected fun property(init: T): ObservableProperty { - return ObservableProperty(init) { name, oldValue, newValue -> changeProperty(name, oldValue, newValue) } + protected fun property(init: T): ReadWriteProperty { + return Delegates.observable(init) { desc, oldValue, newValue -> changeProperty(desc.name, oldValue, newValue) } } public fun onPropertyChange(fn: (ChangeEvent) -> Unit) { diff --git a/libraries/stdlib/src/kotlin/properties/delegation/Delegation.kt b/libraries/stdlib/src/kotlin/properties/delegation/Delegation.kt deleted file mode 100644 index fe4dbb05a6d..00000000000 --- a/libraries/stdlib/src/kotlin/properties/delegation/Delegation.kt +++ /dev/null @@ -1,118 +0,0 @@ -package kotlin.properties.delegation - -import kotlin.properties.ChangeSupport - -public class NotNullVar { - private var value: T? = null - - public fun get(thisRef: Any?, desc: PropertyMetadata): T { - return value ?: throw IllegalStateException("Property ${desc.name} should be initialized before get") - } - - public fun set(thisRef: Any?, desc: PropertyMetadata, value: T) { - this.value = value - } -} - -public class SynchronizedVar(private val initValue: T, private val lock: Any) { - private var value: T = initValue - - public fun get(thisRef: Any?, desc: PropertyMetadata): T { - return synchronized(lock) { value } - } - - public fun set(thisRef: Any?, desc: PropertyMetadata, newValue: T) { - synchronized(lock) { - value = newValue - } - } -} - -class ObservableProperty(initialValue: T, val changeSupport: (name: String, oldValue: T, newValue: T) -> Unit) { - private var value = initialValue - - public fun get(thisRef: Any?, desc: PropertyMetadata): T { - return value - } - - public fun set(thisRef: Any?, desc: PropertyMetadata, newValue: T) { - changeSupport(desc.name, value, newValue) - value = newValue - } -} - -public class KeyMissingException(message: String): RuntimeException(message) - -public abstract class MapVal { - public abstract fun getMap(thisRef: T): Map<*, *> - public abstract fun getKey(desc: PropertyMetadata): Any? - - public open fun getDefaultValue(desc: PropertyMetadata, key: Any?): V { - throw KeyMissingException("Key $key is missing") - } - - public fun get(thisRef: T, desc: PropertyMetadata): V { - val key = getKey(desc) - val map = getMap(thisRef) - if (!map.containsKey(key)) { - return getDefaultValue(desc, key) - } - return map[key] as V - } -} - -public abstract class MapVar: MapVal() { - - public fun set(thisRef: T, desc: PropertyMetadata, newValue: V) { - val map = getMap(thisRef) as MutableMap - map[getKey(desc)] = newValue - } -} - -public fun Map.readOnlyProperty(default: (() -> V)? = null): MapVal { - return object: MapVal() { - override fun getMap(thisRef: Any?) = this@readOnlyProperty - override fun getKey(desc: PropertyMetadata) = desc.name - override fun getDefaultValue(desc: PropertyMetadata, key: Any?) = if (default == null) super.getDefaultValue(desc, key) else default() - } -} - -public fun Map<*, *>.readOnlyProperty(default: (() -> V)? = null, key: Any?): MapVal { - return object: MapVal() { - override fun getMap(thisRef: Any?) = this@readOnlyProperty - override fun getKey(desc: PropertyMetadata) = key - override fun getDefaultValue(desc: PropertyMetadata, key: Any?) = if (default == null) super.getDefaultValue(desc, key) else default() - } -} - -public fun Map<*, *>.readOnlyProperty(default: (() -> V)? = null, key: (desc: PropertyMetadata) -> Any?): MapVal { - return object: MapVal() { - override fun getMap(thisRef: Any?) = this@readOnlyProperty - override fun getKey(desc: PropertyMetadata) = key(desc) - override fun getDefaultValue(desc: PropertyMetadata, key: Any?) = if (default == null) super.getDefaultValue(desc, key) else default() - } -} - -public fun MutableMap.property(default: (() -> V)? = null): MapVar { - return object: MapVar() { - override fun getMap(thisRef: Any?) = this@property - override fun getKey(desc: PropertyMetadata) = desc.name - override fun getDefaultValue(desc: PropertyMetadata, key: Any?) = if (default == null) super.getDefaultValue(desc, key) else default() - } -} - -public fun MutableMap<*, *>.property(default: (() -> V)? = null, key: Any?): MapVar { - return object: MapVar() { - override fun getMap(thisRef: Any?) = this@property - override fun getKey(desc: PropertyMetadata) = key - override fun getDefaultValue(desc: PropertyMetadata, key: Any?) = if (default == null) super.getDefaultValue(desc, key) else default() - } -} - -public fun MutableMap<*, *>.property(default: (() -> V)? = null, key: (desc: PropertyMetadata) -> Any?): MapVar { - return object: MapVar() { - override fun getMap(thisRef: Any?) = this@property - override fun getKey(desc: PropertyMetadata) = key(desc) - override fun getDefaultValue(desc: PropertyMetadata, key: Any?) = if (default == null) super.getDefaultValue(desc, key) else default() - } -} \ No newline at end of file diff --git a/libraries/stdlib/src/kotlin/properties/delegation/lazy/LazyValues.kt b/libraries/stdlib/src/kotlin/properties/delegation/lazy/LazyValues.kt deleted file mode 100644 index 2d0767446d3..00000000000 --- a/libraries/stdlib/src/kotlin/properties/delegation/lazy/LazyValues.kt +++ /dev/null @@ -1,75 +0,0 @@ -package kotlin.properties.delegation.lazy - -private val NULL_VALUE: Any = Any() - -private fun escape(value: T): Any { - return if (value == null) NULL_VALUE else value -} - -private fun unescape(value: Any): T? { - return if (value == NULL_VALUE) null else value as T -} - -public open class LazyVal(initializer: () -> T): NullableLazyVal(initializer) { - override fun get(thisRef: Any?, desc: PropertyMetadata): T { - return super.get(thisRef, desc)!! - } -} - -public open class NullableLazyVal(private val initializer: () -> T?) { - private var value: Any? = null - - public open fun get(thisRef: Any?, desc: PropertyMetadata): T? { - if (value == null) { - value = escape(initializer()) - } - return unescape(value!!) - } -} - -public open class VolatileLazyVal(initializer: () -> T): VolatileNullableLazyVal(initializer) { - override fun get(thisRef: Any?, desc: PropertyMetadata): T { - return super.get(thisRef, desc)!! - } -} - -public open class VolatileNullableLazyVal(private val initializer: () -> T?) { - private volatile var value: Any? = null - - public open fun get(thisRef: Any?, desc: PropertyMetadata): T? { - if (value == null) { - value = escape(initializer()) - } - return unescape(value!!) - } -} - -public open class AtomicLazyVal(lock: Any? = null, initializer: () -> T): AtomicNullableLazyVal(lock, initializer) { - override fun get(thisRef: Any?, desc: PropertyMetadata): T { - return super.get(thisRef, desc)!! - } -} - -public open class AtomicNullableLazyVal(lock: Any? = null, private val initializer: () -> T?) { - private val lock = lock ?: this - private volatile var value: Any? = null - - public open fun get(thisRef: Any?, desc: PropertyMetadata): T? { - val _v1 = value - if (_v1 != null) { - return unescape(_v1) - } - - return synchronized(lock) { - val _v2 = value - if (_v2 != null) { - unescape(_v2) - } - else { - val typedValue = initializer() - value = escape(typedValue) - typedValue - } - } - } -} \ No newline at end of file diff --git a/libraries/stdlib/test/properties/delegation/DelegationTest.kt b/libraries/stdlib/test/properties/delegation/DelegationTest.kt index cceeeaf6af1..4098956d993 100644 --- a/libraries/stdlib/test/properties/delegation/DelegationTest.kt +++ b/libraries/stdlib/test/properties/delegation/DelegationTest.kt @@ -3,8 +3,6 @@ package test.properties.delegation import junit.framework.TestCase import kotlin.test.* import kotlin.properties.* -import kotlin.properties.delegation.* -import kotlin.properties.delegation.lazy.* trait WithBox { fun box(): String @@ -27,8 +25,8 @@ class DelegationTest(): DelegationTestBase() { } public class TestNotNullVar(val a1: String, val b1: T): WithBox { - var a: String by NotNullVar() - var b by NotNullVar() + var a: String by Delegates.notNull() + var b by Delegates.notNull() override fun box(): String { a = a1 @@ -61,4 +59,4 @@ class TestObservableProperty: WithBox, ChangeSupport() { if (!result) return "fail: result should be true" return "OK" } -} \ No newline at end of file +} diff --git a/libraries/stdlib/test/properties/delegation/MapDelegationTest.kt b/libraries/stdlib/test/properties/delegation/MapDelegationTest.kt index 9bc21c81c20..b6df3fc21fb 100644 --- a/libraries/stdlib/test/properties/delegation/MapDelegationTest.kt +++ b/libraries/stdlib/test/properties/delegation/MapDelegationTest.kt @@ -1,7 +1,7 @@ package test.properties.delegation import java.util.HashMap -import kotlin.properties.delegation.* +import kotlin.properties.* class MapDelegationTest(): DelegationTestBase() { @@ -48,10 +48,10 @@ class MapDelegationTest(): DelegationTestBase() { class TestMapValWithDifferentTypes(): WithBox { val map = hashMapOf("a" to "a", "b" to 1, "c" to A(1), "d" to null) - val a by map.readOnlyProperty() - val b by map.readOnlyProperty() - val c by map.readOnlyProperty() - val d by map.readOnlyProperty() + val a by Delegates.mapVal(map) + val b by Delegates.mapVal(map) + val c by Delegates.mapVal(map) + val d by Delegates.mapVal(map) override fun box(): String { if (a != "a") return "fail at 'a'" @@ -66,10 +66,10 @@ class TestMapValWithDifferentTypes(): WithBox { class TestMapVarWithDifferentTypes(): WithBox { val map: HashMap = hashMapOf("a" to "a", "b" to 1, "c" to A(1), "d" to "d") - var a by map.property() - var b by map.property() - var c by map.property() - var d by map.property() + var a by Delegates.mapVar(map) + var b by Delegates.mapVar(map) + var c by Delegates.mapVar(map) + var d by Delegates.mapVar(map) override fun box(): String { a = "aa" @@ -87,8 +87,8 @@ class TestMapVarWithDifferentTypes(): WithBox { } class TestNullableKey: WithBox { - val map = hashMapOf(null to "null") - var a by map.property { desc -> null } + val map = hashMapOf(null:Any? to "null": Any?) + var a by FixedMapVar(map, key = { desc -> null }, default = {ref, desc -> null}) override fun box(): String { if (a != "null") return "fail at 'a'" @@ -99,10 +99,10 @@ class TestNullableKey: WithBox { } class TestMapPropertyString(): WithBox { - val map = hashMapOf("a" to "a", "b" to "b", "c" to "c") - val a by map.readOnlyProperty() - var b by map.property() - val c by map.property() + val map = hashMapOf("a" to "a", "b" to "b", "c" to "c":Any?) + val a by Delegates.mapVal(map) + var b by Delegates.mapVar(map) + val c by Delegates.mapVal(map) override fun box(): String { b = "newB" @@ -115,9 +115,9 @@ class TestMapPropertyString(): WithBox { class TestMapValWithDefault(): WithBox { val map = hashMapOf() - val a by map.readOnlyProperty(default = { "aDefault" }) - val b by map.readOnlyProperty(default = { "bDefault" }, key = "b") - val c by map.readOnlyProperty(default = { "cDefault" }, key = { desc -> desc.name }) + val a by Delegates.mapVal(map, default = { ref, desc -> "aDefault" }) + val b by FixedMapVal(map, default = { ref, desc -> "bDefault" }, key = {"b"}) + val c by FixedMapVal(map, default = { ref, desc -> "cDefault" }, key = { desc -> desc.name }) override fun box(): String { if (a != "aDefault") return "fail at 'a'" @@ -128,10 +128,10 @@ class TestMapValWithDefault(): WithBox { } class TestMapVarWithDefault(): WithBox { - val map = hashMapOf() - var a by map.property(default = { "aDefault" }) - var b by map.property(default = { "bDefault" }, key = "b") - var c by map.property(default = { "cDefault" }, key = { desc -> desc.name }) + val map = hashMapOf() + var a: String by Delegates.mapVar(map, default = {ref, desc -> "aDefault" }) + var b: String by FixedMapVar(map, default = {ref, desc -> "bDefault" }, key = {"b"}) + var c: String by FixedMapVar(map, default = {ref, desc -> "cDefault" }, key = { desc -> desc.name }) override fun box(): String { if (a != "aDefault") return "fail at 'a'" @@ -148,9 +148,9 @@ class TestMapVarWithDefault(): WithBox { } class TestMapPropertyKey(): WithBox { - val map = hashMapOf("a" to "a", "b" to "b") - val a by map.readOnlyProperty(key = "a") - var b by map.property(key = "b") + val map = hashMapOf("a" to "a", "b" to "b" : Any?) + val a by FixedMapVal(map, key = {"a"}) + var b by FixedMapVar(map, key = {"b"}) override fun box(): String { b = "c" @@ -161,9 +161,9 @@ class TestMapPropertyKey(): WithBox { } class TestMapPropertyFunction(): WithBox { - val map = hashMapOf("aDesc" to "a", "bDesc" to "b") - val a by map.readOnlyProperty { desc -> "${desc.name}Desc" } - var b by map.property { desc -> "${desc.name}Desc" } + val map = hashMapOf("aDesc" to "a", "bDesc" to "b": Any?) + val a by FixedMapVal(map, { desc -> "${desc.name}Desc" }) + var b by FixedMapVar(map, { desc -> "${desc.name}Desc" }) override fun box(): String { b = "c" @@ -173,17 +173,18 @@ class TestMapPropertyFunction(): WithBox { } } -val mapVal = object : MapVal() { - override fun getMap(thisRef: TestMapPropertyCustom) = thisRef.map - override fun getKey(desc: PropertyMetadata) = "${desc.name}Desc" +val mapVal = object: MapVal() { + override fun map(ref: TestMapPropertyCustom) = ref.map + override fun key(desc: PropertyMetadata) = "${desc.name}Desc" } -val mapVar = object : MapVar() { - override fun getMap(thisRef: TestMapPropertyCustom) = thisRef.map - override fun getKey(desc: PropertyMetadata) = "${desc.name}Desc" + +val mapVar = object : MapVar() { + override fun map(ref: TestMapPropertyCustom) = ref.map + override fun key(desc: PropertyMetadata) = "${desc.name}Desc" } class TestMapPropertyCustom(): WithBox { - val map = hashMapOf("aDesc" to "a", "bDesc" to "b") + val map = hashMapOf("aDesc" to "a", "bDesc" to "b":Any?) val a by mapVal var b by mapVar @@ -195,22 +196,22 @@ class TestMapPropertyCustom(): WithBox { } } -val mapValWithDefault = object : MapVal() { - override fun getMap(thisRef: TestMapPropertyCustomWithDefault) = thisRef.map - override fun getKey(desc: PropertyMetadata) = desc.name +val mapValWithDefault = object : MapVal() { + override fun map(ref: TestMapPropertyCustomWithDefault) = ref.map + override fun key(desc: PropertyMetadata) = desc.name - override fun getDefaultValue(desc: PropertyMetadata, key: Any?) = "default" + override fun default(ref: TestMapPropertyCustomWithDefault, key: PropertyMetadata) = "default" } -val mapVarWithDefault = object : MapVar() { - override fun getMap(thisRef: TestMapPropertyCustomWithDefault) = thisRef.map - override fun getKey(desc: PropertyMetadata) = desc.name +val mapVarWithDefault = object : MapVar() { + override fun map(ref: TestMapPropertyCustomWithDefault) = ref.map + override fun key(desc: PropertyMetadata) = desc.name - override fun getDefaultValue(desc: PropertyMetadata, key: Any?) = "default" + override fun default(ref: TestMapPropertyCustomWithDefault, key: PropertyMetadata) = "default" } class TestMapPropertyCustomWithDefault(): WithBox { - val map = hashMapOf() + val map = hashMapOf() val a by mapValWithDefault var b by mapVarWithDefault @@ -221,4 +222,4 @@ class TestMapPropertyCustomWithDefault(): WithBox { if (b != "c") return "fail at 'b' after set" return "OK" } -} \ No newline at end of file +} diff --git a/libraries/stdlib/test/properties/delegation/lazy/LazyValuesTest.kt b/libraries/stdlib/test/properties/delegation/lazy/LazyValuesTest.kt index 6a3a4cac847..31fe609bf2d 100644 --- a/libraries/stdlib/test/properties/delegation/lazy/LazyValuesTest.kt +++ b/libraries/stdlib/test/properties/delegation/lazy/LazyValuesTest.kt @@ -1,8 +1,8 @@ package test.properties.delegation.lazy -import kotlin.properties.delegation.lazy.* import test.properties.delegation.WithBox import test.properties.delegation.DelegationTestBase +import kotlin.properties.* class LazyValuesTest(): DelegationTestBase() { @@ -33,7 +33,7 @@ class LazyValuesTest(): DelegationTestBase() { class TestLazyVal: WithBox { var result = 0 - val a by LazyVal { + val a by Delegates.lazy { ++result } @@ -48,8 +48,8 @@ class TestNullableLazyVal: WithBox { var resultA = 0 var resultB = 0 - val a: Int? by NullableLazyVal { resultA++; null} - val b by NullableLazyVal { foo() } + val a: Int? by Delegates.lazy { resultA++; null} + val b by Delegates.lazy { foo() } override fun box(): String { a @@ -70,7 +70,7 @@ class TestNullableLazyVal: WithBox { class TestAtomicLazyVal: WithBox { var result = 0 - val a by AtomicLazyVal { + val a by Delegates.blockingLazy { ++result } @@ -85,8 +85,8 @@ class TestVolatileNullableLazyVal: WithBox { var resultA = 0 var resultB = 0 - val a: Int? by VolatileNullableLazyVal { resultA++; null} - val b by VolatileNullableLazyVal { foo() } + val a: Int? by Delegates.blockingLazy { resultA++; null} + val b by Delegates.blockingLazy { foo() } override fun box(): String { a @@ -107,7 +107,7 @@ class TestVolatileNullableLazyVal: WithBox { class TestVolatileLazyVal: WithBox { var result = 0 - val a by VolatileLazyVal { + val a by Delegates.blockingLazy { ++result } @@ -122,8 +122,8 @@ class TestAtomicNullableLazyVal: WithBox { var resultA = 0 var resultB = 0 - val a: Int? by AtomicNullableLazyVal { resultA++; null} - val b by AtomicNullableLazyVal { foo() } + val a: Int? by Delegates.blockingLazy { resultA++; null} + val b by Delegates.blockingLazy { foo() } override fun box(): String { a From 868bf90de226bf8e4828bbfb7c24a462f5cf1007 Mon Sep 17 00:00:00 2001 From: Maxim Shafirov Date: Fri, 31 May 2013 11:35:11 +0400 Subject: [PATCH 181/249] Rollback 0514ddc719d50ae79f64749fe4d6e3bc86d02f60 due to failing tests --- libraries/stdlib/src/kotlin/IterablesSpecial.kt | 10 ---------- libraries/stdlib/src/kotlin/JUtil.kt | 2 +- 2 files changed, 1 insertion(+), 11 deletions(-) diff --git a/libraries/stdlib/src/kotlin/IterablesSpecial.kt b/libraries/stdlib/src/kotlin/IterablesSpecial.kt index 92abbab4362..62aff9516be 100644 --- a/libraries/stdlib/src/kotlin/IterablesSpecial.kt +++ b/libraries/stdlib/src/kotlin/IterablesSpecial.kt @@ -75,13 +75,3 @@ public inline fun Iterable.sort(comparator: java.util.Comparator) : Li java.util.Collections.sort(list, comparator) return list } - -public inline fun Iterable.sort(compare: (T, T) -> Int): List { - return sort( - object : java.util.Comparator { - public override fun compare(o1: T, o2: T): Int { - return compare.invoke(o1, o2) - } - } - ) -} \ No newline at end of file diff --git a/libraries/stdlib/src/kotlin/JUtil.kt b/libraries/stdlib/src/kotlin/JUtil.kt index 400fb43963c..fc015040ae4 100644 --- a/libraries/stdlib/src/kotlin/JUtil.kt +++ b/libraries/stdlib/src/kotlin/JUtil.kt @@ -27,7 +27,7 @@ public inline fun Collection?.orEmpty() : Collection /** TODO these functions don't work when they generate the Array versions when they are in JLIterables */ public inline fun > Iterable.toSortedList() : List = toCollection(ArrayList()).sort() -public inline fun Iterable.toSortedList(compare: (T, T) -> Int) : List = toList().sort(compare) +public inline fun > Iterable.toSortedList(comparator: java.util.Comparator) : List = toList().sort(comparator) // List APIs From f05f616230ed0d61a2777b94e3de047774a092d2 Mon Sep 17 00:00:00 2001 From: Svetlana Isakova Date: Wed, 22 May 2013 16:40:29 +0400 Subject: [PATCH 182/249] KT-2422 Invalid warning "Condition is always true" #KT-2422 fixed --- .../calls/autocasts/DataFlowValueFactory.java | 170 ++++++++++++++---- .../diagnostics/tests/smartCasts/kt2422.kt | 23 +++ .../noErrorCheckForPackageLevelVal.kt | 25 +++ .../tests/smartCasts/thisWithLabel.kt | 36 ++++ .../smartCasts/thisWithLabelAsReceiverPart.kt | 39 ++++ .../checkers/JetDiagnosticsTestGenerated.java | 20 +++ 6 files changed, 280 insertions(+), 33 deletions(-) create mode 100644 compiler/testData/diagnostics/tests/smartCasts/kt2422.kt create mode 100644 compiler/testData/diagnostics/tests/smartCasts/noErrorCheckForPackageLevelVal.kt create mode 100644 compiler/testData/diagnostics/tests/smartCasts/thisWithLabel.kt create mode 100644 compiler/testData/diagnostics/tests/smartCasts/thisWithLabelAsReceiverPart.kt diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/autocasts/DataFlowValueFactory.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/autocasts/DataFlowValueFactory.java index b1edec00e93..d8793b33b33 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/autocasts/DataFlowValueFactory.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/autocasts/DataFlowValueFactory.java @@ -18,17 +18,20 @@ package org.jetbrains.jet.lang.resolve.calls.autocasts; import com.intellij.openapi.util.Pair; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import org.jetbrains.jet.JetNodeTypes; import org.jetbrains.jet.lang.descriptors.*; import org.jetbrains.jet.lang.psi.*; import org.jetbrains.jet.lang.resolve.BindingContext; import org.jetbrains.jet.lang.resolve.JetModuleUtil; +import org.jetbrains.jet.lang.resolve.calls.model.ResolvedCall; import org.jetbrains.jet.lang.resolve.scopes.receivers.*; import org.jetbrains.jet.lang.types.JetType; import org.jetbrains.jet.lang.types.TypeUtils; import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns; import static org.jetbrains.jet.lang.resolve.BindingContext.REFERENCE_TARGET; +import static org.jetbrains.jet.lang.resolve.BindingContext.RESOLVED_CALL; public class DataFlowValueFactory { public static final DataFlowValueFactory INSTANCE = new DataFlowValueFactory(); @@ -42,8 +45,8 @@ public class DataFlowValueFactory { if (constantExpression.getNode().getElementType() == JetNodeTypes.NULL) return DataFlowValue.NULL; } if (TypeUtils.equalTypes(type, KotlinBuiltIns.getInstance().getNullableNothingType())) return DataFlowValue.NULL; // 'null' is the only inhabitant of 'Nothing?' - Pair result = getIdForStableIdentifier(expression, bindingContext, false); - return new DataFlowValue(result.first == null ? expression : result.first, type, result.second, getImmanentNullability(type)); + IdentifierInfo result = getIdForStableIdentifier(expression, bindingContext, false); + return new DataFlowValue(result.id == null ? expression : result.id, type, result.isStable, getImmanentNullability(type)); } @NotNull @@ -104,55 +107,156 @@ public class DataFlowValueFactory { return type.isNullable() || TypeUtils.hasNullableSuperType(type) ? Nullability.UNKNOWN : Nullability.NOT_NULL; } + private static class IdentifierInfo { + public final Object id; + public final boolean isStable; + public final boolean isNamespace; + + private IdentifierInfo(Object id, boolean isStable, boolean isNamespace) { + this.id = id; + this.isStable = isStable; + this.isNamespace = isNamespace; + } + } + + private static final IdentifierInfo ERROR_IDENTIFIER_INFO = new IdentifierInfo(null, false, false); + @NotNull - private static Pair getIdForStableIdentifier(@NotNull JetExpression expression, @NotNull BindingContext bindingContext, boolean allowNamespaces) { + private static IdentifierInfo createInfo(Object id, boolean isStable) { + return new IdentifierInfo(id, isStable, false); + } + + @NotNull + private static IdentifierInfo createNamespaceInfo(Object id, boolean isStable) { + return new IdentifierInfo(id, isStable, true); + } + + @NotNull + private static IdentifierInfo combineInfo(@Nullable IdentifierInfo receiverInfo, @NotNull IdentifierInfo selectorInfo) { + if (receiverInfo == null || receiverInfo == ERROR_IDENTIFIER_INFO || receiverInfo.isNamespace) { + return selectorInfo; + } + return createInfo(Pair.create(receiverInfo.id, selectorInfo.id), receiverInfo.isStable && selectorInfo.isStable); + } + + @NotNull + private static IdentifierInfo getIdForStableIdentifier( + @Nullable JetExpression expression, + @NotNull BindingContext bindingContext, + boolean allowNamespaces + ) { if (expression instanceof JetParenthesizedExpression) { JetParenthesizedExpression parenthesizedExpression = (JetParenthesizedExpression) expression; JetExpression innerExpression = parenthesizedExpression.getExpression(); - if (innerExpression == null) { - return Pair.create(null, false); - } + return getIdForStableIdentifier(innerExpression, bindingContext, allowNamespaces); } else if (expression instanceof JetQualifiedExpression) { JetQualifiedExpression qualifiedExpression = (JetQualifiedExpression) expression; + JetExpression receiverExpression = qualifiedExpression.getReceiverExpression(); JetExpression selectorExpression = qualifiedExpression.getSelectorExpression(); - if (selectorExpression == null) { - return Pair.create(null, false); - } - Pair receiverId = getIdForStableIdentifier(qualifiedExpression.getReceiverExpression(), bindingContext, true); - Pair selectorId = getIdForStableIdentifier(selectorExpression, bindingContext, allowNamespaces); - return receiverId.second ? selectorId : Pair.create(receiverId.first, false); + IdentifierInfo receiverId = getIdForStableIdentifier(receiverExpression, bindingContext, true); + IdentifierInfo selectorId = getIdForStableIdentifier(selectorExpression, bindingContext, allowNamespaces); + + return combineInfo(receiverId, selectorId); } if (expression instanceof JetSimpleNameExpression) { - JetSimpleNameExpression simpleNameExpression = (JetSimpleNameExpression) expression; - DeclarationDescriptor declarationDescriptor = bindingContext.get(REFERENCE_TARGET, simpleNameExpression); - if (declarationDescriptor instanceof VariableDescriptor) { - return Pair.create((Object) declarationDescriptor, isStableVariable((VariableDescriptor) declarationDescriptor)); - } - if (declarationDescriptor instanceof NamespaceDescriptor) { - return Pair.create((Object) declarationDescriptor, allowNamespaces); - } - if (declarationDescriptor instanceof ClassDescriptor) { - ClassDescriptor classDescriptor = (ClassDescriptor) declarationDescriptor; - return Pair.create((Object) classDescriptor, classDescriptor.isClassObjectAValue()); - } + return getIdForSimpleNameExpression((JetSimpleNameExpression) expression, bindingContext, allowNamespaces); } else if (expression instanceof JetThisExpression) { JetThisExpression thisExpression = (JetThisExpression) expression; DeclarationDescriptor declarationDescriptor = bindingContext.get(REFERENCE_TARGET, thisExpression.getInstanceReference()); - if (declarationDescriptor instanceof CallableDescriptor) { - return Pair.create((Object) ((CallableDescriptor) declarationDescriptor).getReceiverParameter().getValue(), true); - } - if (declarationDescriptor instanceof ClassDescriptor) { - return Pair.create((Object) ((ClassDescriptor) declarationDescriptor).getThisAsReceiverParameter().getValue(), true); - } - return Pair.create(null, true); + + return getIdForThisReceiver(declarationDescriptor); } else if (expression instanceof JetRootNamespaceExpression) { - return Pair.create((Object) JetModuleUtil.getRootNamespaceType(expression), allowNamespaces); + return createNamespaceInfo(JetModuleUtil.getRootNamespaceType(expression), allowNamespaces); } - return Pair.create(null, false); + return ERROR_IDENTIFIER_INFO; + } + + @NotNull + private static IdentifierInfo getIdForSimpleNameExpression( + @NotNull JetSimpleNameExpression simpleNameExpression, + @NotNull BindingContext bindingContext, + boolean allowNamespaces + ) { + DeclarationDescriptor declarationDescriptor = bindingContext.get(REFERENCE_TARGET, simpleNameExpression); + if (declarationDescriptor instanceof VariableDescriptor) { + ResolvedCall resolvedCall = bindingContext.get(RESOLVED_CALL, simpleNameExpression); + // todo return assert + // for now it fails for resolving 'invoke' convention, return it after 'invoke' algorithm changes + // assert resolvedCall != null : "Cannot create right identifier info if the resolved call is not known yet for " + declarationDescriptor; + + IdentifierInfo receiverInfo = resolvedCall != null ? getIdForImplicitReceiver(resolvedCall.getThisObject(), simpleNameExpression) : null; + + VariableDescriptor variableDescriptor = (VariableDescriptor) declarationDescriptor; + return combineInfo(receiverInfo, createInfo(variableDescriptor, isStableVariable(variableDescriptor))); + } + if (declarationDescriptor instanceof NamespaceDescriptor) { + return createNamespaceInfo(declarationDescriptor, allowNamespaces); + } + if (declarationDescriptor instanceof ClassDescriptor) { + ClassDescriptor classDescriptor = (ClassDescriptor) declarationDescriptor; + return createInfo(classDescriptor, classDescriptor.isClassObjectAValue()); + } + return ERROR_IDENTIFIER_INFO; + } + + @Nullable + private static IdentifierInfo getIdForImplicitReceiver(@NotNull ReceiverValue receiverValue, @Nullable final JetExpression expression) { + return receiverValue.accept(new ReceiverValueVisitor() { + + @Override + public IdentifierInfo visitNoReceiver(ReceiverValue noReceiver, Void data) { + return null; + } + + @Override + public IdentifierInfo visitTransientReceiver(TransientReceiver receiver, Void data) { + assert false: "Transient receiver is implicit for an explicit expression: " + expression + ". Receiver: " + receiver; + return null; + } + + @Override + public IdentifierInfo visitExtensionReceiver(ExtensionReceiver receiver, Void data) { + return getIdForThisReceiver(receiver); + } + + @Override + public IdentifierInfo visitExpressionReceiver(ExpressionReceiver receiver, Void data) { + // there is an explicit "this" expression and it was analyzed earlier + return null; + } + + @Override + public IdentifierInfo visitClassReceiver(ClassReceiver receiver, Void data) { + return getIdForThisReceiver(receiver); + } + + @Override + public IdentifierInfo visitScriptReceiver(ScriptReceiver receiver, Void data) { + return getIdForThisReceiver(receiver); + } + }, null); + } + + @NotNull + private static IdentifierInfo getIdForThisReceiver(@NotNull ThisReceiver thisReceiver) { + return getIdForThisReceiver(thisReceiver.getDeclarationDescriptor()); + } + + @NotNull + private static IdentifierInfo getIdForThisReceiver(@Nullable DeclarationDescriptor descriptorOfThisReceiver) { + if (descriptorOfThisReceiver instanceof CallableDescriptor) { + ReceiverParameterDescriptor receiverParameter = ((CallableDescriptor) descriptorOfThisReceiver).getReceiverParameter(); + assert receiverParameter != null : "'This' refers to the callable member without a receiver parameter: " + descriptorOfThisReceiver; + return createInfo(receiverParameter.getValue(), true); + } + if (descriptorOfThisReceiver instanceof ClassDescriptor) { + return createInfo(((ClassDescriptor) descriptorOfThisReceiver).getThisAsReceiverParameter().getValue(), true); + } + return ERROR_IDENTIFIER_INFO; } public static boolean isStableVariable(@NotNull VariableDescriptor variableDescriptor) { diff --git a/compiler/testData/diagnostics/tests/smartCasts/kt2422.kt b/compiler/testData/diagnostics/tests/smartCasts/kt2422.kt new file mode 100644 index 00000000000..ea3ac5e68fd --- /dev/null +++ b/compiler/testData/diagnostics/tests/smartCasts/kt2422.kt @@ -0,0 +1,23 @@ +package bar + +class Test { + val foo: Int? = null + fun foo(o: Test) = foo == null && o.foo == null // ERROR warning: o.test == null is always true + + fun bar(a: Test, b: Test) { + if (a.foo != null) { + useInt(b.foo) + } + if (a.foo != null) { + useInt(foo) + } + if (this.foo != null) { + useInt(foo) + } + if (foo != null) { + useInt(this.foo) + } + } + + fun useInt(i: Int) = i +} \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/smartCasts/noErrorCheckForPackageLevelVal.kt b/compiler/testData/diagnostics/tests/smartCasts/noErrorCheckForPackageLevelVal.kt new file mode 100644 index 00000000000..c993a144277 --- /dev/null +++ b/compiler/testData/diagnostics/tests/smartCasts/noErrorCheckForPackageLevelVal.kt @@ -0,0 +1,25 @@ +//FILE: bar.kt +package bar + +val i: Int? = 2 + +//FILE: foo.kt +package foo + +val i: Int? = 1 + +class A(val i: Int?) { + fun testUseFromClass() { + if (foo.i != null) { + useInt(i) + } + } +} + +fun testUseFromOtherPackage() { + if (bar.i != null) { + useInt(i) + } +} + +fun useInt(i: Int) = i \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/smartCasts/thisWithLabel.kt b/compiler/testData/diagnostics/tests/smartCasts/thisWithLabel.kt new file mode 100644 index 00000000000..618f5b66a69 --- /dev/null +++ b/compiler/testData/diagnostics/tests/smartCasts/thisWithLabel.kt @@ -0,0 +1,36 @@ +package foo + +class A(val i: Int?) { + fun test1() { + if (this@A.i != null) { + useInt(this.i) + useInt(i) + } + } + + inner class B { + fun test2() { + if (i != null) { + useInt(this@A.i) + } + } + } +} + +fun A.foo() { + if (this@foo.i != null) { + useInt(this.i) + useInt(i) + } +} + +fun test3() { + useFunction { + if(i != null) { + useInt(this.i) + } + } +} + +fun useInt(i: Int) = i +fun useFunction(f: A.() -> Unit) = f \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/smartCasts/thisWithLabelAsReceiverPart.kt b/compiler/testData/diagnostics/tests/smartCasts/thisWithLabelAsReceiverPart.kt new file mode 100644 index 00000000000..bdbc0aa44f7 --- /dev/null +++ b/compiler/testData/diagnostics/tests/smartCasts/thisWithLabelAsReceiverPart.kt @@ -0,0 +1,39 @@ +package foo + +class C(val i: Int?) {} + +class A(val c: C) { + fun test1() { + if (this@A.c.i != null) { + useInt(this.c.i) + useInt(c.i) + } + } + + inner class B { + fun test2() { + if (c.i != null) { + useInt(this@A.c.i) + } + } + } +} + +fun A.foo() { + if (this@foo.c.i != null) { + useInt(this.c.i) + useInt(c.i) + } +} + +fun test3() { + useFunction { + if(c.i != null) { + useInt(this.c.i) + } + } +} + +fun useInt(i: Int) = i +fun useFunction(f: A.() -> Unit) = f + diff --git a/compiler/tests/org/jetbrains/jet/checkers/JetDiagnosticsTestGenerated.java b/compiler/tests/org/jetbrains/jet/checkers/JetDiagnosticsTestGenerated.java index 115e37c96fa..3ccf049c0d8 100644 --- a/compiler/tests/org/jetbrains/jet/checkers/JetDiagnosticsTestGenerated.java +++ b/compiler/tests/org/jetbrains/jet/checkers/JetDiagnosticsTestGenerated.java @@ -4722,6 +4722,26 @@ public class JetDiagnosticsTestGenerated extends AbstractDiagnosticsTestWithEage doTest("compiler/testData/diagnostics/tests/smartCasts/kt1461.kt"); } + @TestMetadata("kt2422.kt") + public void testKt2422() throws Exception { + doTest("compiler/testData/diagnostics/tests/smartCasts/kt2422.kt"); + } + + @TestMetadata("noErrorCheckForPackageLevelVal.kt") + public void testNoErrorCheckForPackageLevelVal() throws Exception { + doTest("compiler/testData/diagnostics/tests/smartCasts/noErrorCheckForPackageLevelVal.kt"); + } + + @TestMetadata("thisWithLabel.kt") + public void testThisWithLabel() throws Exception { + doTest("compiler/testData/diagnostics/tests/smartCasts/thisWithLabel.kt"); + } + + @TestMetadata("thisWithLabelAsReceiverPart.kt") + public void testThisWithLabelAsReceiverPart() throws Exception { + doTest("compiler/testData/diagnostics/tests/smartCasts/thisWithLabelAsReceiverPart.kt"); + } + } @TestMetadata("compiler/testData/diagnostics/tests/substitutions") From 42b34586bd47a2b0e81f061d585b4619ca3ef791 Mon Sep 17 00:00:00 2001 From: Svetlana Isakova Date: Fri, 31 May 2013 14:10:58 +0400 Subject: [PATCH 183/249] made ReceiverValueVisitor an interface --- .../receivers/ReceiverValueVisitor.java | 26 +++++-------------- 1 file changed, 7 insertions(+), 19 deletions(-) diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/scopes/receivers/ReceiverValueVisitor.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/scopes/receivers/ReceiverValueVisitor.java index 44281585f7c..110189c2330 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/scopes/receivers/ReceiverValueVisitor.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/scopes/receivers/ReceiverValueVisitor.java @@ -16,28 +16,16 @@ package org.jetbrains.jet.lang.resolve.scopes.receivers; -public class ReceiverValueVisitor { - public R visitNoReceiver(ReceiverValue noReceiver, D data) { - return null; - } +public interface ReceiverValueVisitor { + R visitNoReceiver(ReceiverValue noReceiver, D data); - public R visitTransientReceiver(TransientReceiver receiver, D data) { - return null; - } + R visitTransientReceiver(TransientReceiver receiver, D data); - public R visitExtensionReceiver(ExtensionReceiver receiver, D data) { - return null; - } + R visitExtensionReceiver(ExtensionReceiver receiver, D data); - public R visitExpressionReceiver(ExpressionReceiver receiver, D data) { - return null; - } + R visitExpressionReceiver(ExpressionReceiver receiver, D data); - public R visitClassReceiver(ClassReceiver receiver, D data) { - return null; - } + R visitClassReceiver(ClassReceiver receiver, D data); - public R visitScriptReceiver(ScriptReceiver receiver, D data) { - return null; - } + R visitScriptReceiver(ScriptReceiver receiver, D data); } From 61f50fc83247882574c5e3340fc8627c8ba340d3 Mon Sep 17 00:00:00 2001 From: Svetlana Isakova Date: Fri, 31 May 2013 16:04:32 +0400 Subject: [PATCH 184/249] removed 'allowNamespaces' flag from creating IdentifierInfo --- .../calls/autocasts/DataFlowValueFactory.java | 24 +++++++++---------- 1 file changed, 11 insertions(+), 13 deletions(-) diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/autocasts/DataFlowValueFactory.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/autocasts/DataFlowValueFactory.java index d8793b33b33..5399c1a0af1 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/autocasts/DataFlowValueFactory.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/autocasts/DataFlowValueFactory.java @@ -45,7 +45,7 @@ public class DataFlowValueFactory { if (constantExpression.getNode().getElementType() == JetNodeTypes.NULL) return DataFlowValue.NULL; } if (TypeUtils.equalTypes(type, KotlinBuiltIns.getInstance().getNullableNothingType())) return DataFlowValue.NULL; // 'null' is the only inhabitant of 'Nothing?' - IdentifierInfo result = getIdForStableIdentifier(expression, bindingContext, false); + IdentifierInfo result = getIdForStableIdentifier(expression, bindingContext); return new DataFlowValue(result.id == null ? expression : result.id, type, result.isStable, getImmanentNullability(type)); } @@ -127,8 +127,8 @@ public class DataFlowValueFactory { } @NotNull - private static IdentifierInfo createNamespaceInfo(Object id, boolean isStable) { - return new IdentifierInfo(id, isStable, true); + private static IdentifierInfo createNamespaceInfo(Object id) { + return new IdentifierInfo(id, true, true); } @NotNull @@ -142,26 +142,25 @@ public class DataFlowValueFactory { @NotNull private static IdentifierInfo getIdForStableIdentifier( @Nullable JetExpression expression, - @NotNull BindingContext bindingContext, - boolean allowNamespaces + @NotNull BindingContext bindingContext ) { if (expression instanceof JetParenthesizedExpression) { JetParenthesizedExpression parenthesizedExpression = (JetParenthesizedExpression) expression; JetExpression innerExpression = parenthesizedExpression.getExpression(); - return getIdForStableIdentifier(innerExpression, bindingContext, allowNamespaces); + return getIdForStableIdentifier(innerExpression, bindingContext); } else if (expression instanceof JetQualifiedExpression) { JetQualifiedExpression qualifiedExpression = (JetQualifiedExpression) expression; JetExpression receiverExpression = qualifiedExpression.getReceiverExpression(); JetExpression selectorExpression = qualifiedExpression.getSelectorExpression(); - IdentifierInfo receiverId = getIdForStableIdentifier(receiverExpression, bindingContext, true); - IdentifierInfo selectorId = getIdForStableIdentifier(selectorExpression, bindingContext, allowNamespaces); + IdentifierInfo receiverId = getIdForStableIdentifier(receiverExpression, bindingContext); + IdentifierInfo selectorId = getIdForStableIdentifier(selectorExpression, bindingContext); return combineInfo(receiverId, selectorId); } if (expression instanceof JetSimpleNameExpression) { - return getIdForSimpleNameExpression((JetSimpleNameExpression) expression, bindingContext, allowNamespaces); + return getIdForSimpleNameExpression((JetSimpleNameExpression) expression, bindingContext); } else if (expression instanceof JetThisExpression) { JetThisExpression thisExpression = (JetThisExpression) expression; @@ -170,7 +169,7 @@ public class DataFlowValueFactory { return getIdForThisReceiver(declarationDescriptor); } else if (expression instanceof JetRootNamespaceExpression) { - return createNamespaceInfo(JetModuleUtil.getRootNamespaceType(expression), allowNamespaces); + return createNamespaceInfo(JetModuleUtil.getRootNamespaceType(expression)); } return ERROR_IDENTIFIER_INFO; } @@ -178,8 +177,7 @@ public class DataFlowValueFactory { @NotNull private static IdentifierInfo getIdForSimpleNameExpression( @NotNull JetSimpleNameExpression simpleNameExpression, - @NotNull BindingContext bindingContext, - boolean allowNamespaces + @NotNull BindingContext bindingContext ) { DeclarationDescriptor declarationDescriptor = bindingContext.get(REFERENCE_TARGET, simpleNameExpression); if (declarationDescriptor instanceof VariableDescriptor) { @@ -194,7 +192,7 @@ public class DataFlowValueFactory { return combineInfo(receiverInfo, createInfo(variableDescriptor, isStableVariable(variableDescriptor))); } if (declarationDescriptor instanceof NamespaceDescriptor) { - return createNamespaceInfo(declarationDescriptor, allowNamespaces); + return createNamespaceInfo(declarationDescriptor); } if (declarationDescriptor instanceof ClassDescriptor) { ClassDescriptor classDescriptor = (ClassDescriptor) declarationDescriptor; From 6d6e627641a9cc292c2023653ce58f29bf016c3d Mon Sep 17 00:00:00 2001 From: Andrey Breslav Date: Fri, 31 May 2013 20:26:18 +0400 Subject: [PATCH 185/249] Support custom JDK annotations path for TeamCity --- .../jps/build/KotlinBuilderModuleScriptGenerator.java | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/jps-plugin/src/org/jetbrains/jet/jps/build/KotlinBuilderModuleScriptGenerator.java b/jps-plugin/src/org/jetbrains/jet/jps/build/KotlinBuilderModuleScriptGenerator.java index ce53354d6ad..593cf2407c6 100644 --- a/jps-plugin/src/org/jetbrains/jet/jps/build/KotlinBuilderModuleScriptGenerator.java +++ b/jps-plugin/src/org/jetbrains/jet/jps/build/KotlinBuilderModuleScriptGenerator.java @@ -130,6 +130,16 @@ public class KotlinBuilderModuleScriptGenerator { } } + // JDK is stored locally on user's machine, so its configuration, including external annotation paths + // is not available on TeamCity. When running on TeamCity, one has to provide extra path to JDK annotations + String extraAnnotationsPaths = System.getProperty("jps.kotlin.extra.annotation.paths"); + if (extraAnnotationsPaths != null) { + String[] paths = extraAnnotationsPaths.split(File.pathSeparator); + for (String path : paths) { + annotationRootFiles.add(new File(path)); + } + } + return annotationRootFiles; } From 555e182d6dbf011c02b2966501e9036bee17c7d6 Mon Sep 17 00:00:00 2001 From: Nikolay Krasko Date: Fri, 31 May 2013 20:42:39 +0400 Subject: [PATCH 186/249] Fix returned indices from TextBlockTransferableData Thanks to Alexander (https://github.com/Alefas) for idea #KT-3662 Fixed --- .../jetbrains/jet/plugin/conversion/copy/ConvertedCode.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/idea/src/org/jetbrains/jet/plugin/conversion/copy/ConvertedCode.java b/idea/src/org/jetbrains/jet/plugin/conversion/copy/ConvertedCode.java index 89827815faa..e9af4d9cebc 100644 --- a/idea/src/org/jetbrains/jet/plugin/conversion/copy/ConvertedCode.java +++ b/idea/src/org/jetbrains/jet/plugin/conversion/copy/ConvertedCode.java @@ -43,12 +43,12 @@ class ConvertedCode implements TextBlockTransferableData { @Override public int getOffsets(int[] offsets, int index) { - return 0; + return index; } @Override public int setOffsets(int[] offsets, int index) { - return 0; + return index; } public String getData() { From 6d0b8f953d847e9e0ab0ea905dd3aecb5c4b3d88 Mon Sep 17 00:00:00 2001 From: Evgeny Gerashchenko Date: Fri, 31 May 2013 15:36:15 +0400 Subject: [PATCH 187/249] Typo. --- compiler/preloader/instrumentation/ReadMe.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/preloader/instrumentation/ReadMe.md b/compiler/preloader/instrumentation/ReadMe.md index dfdb9eac23c..22506fd0086 100644 --- a/compiler/preloader/instrumentation/ReadMe.md +++ b/compiler/preloader/instrumentation/ReadMe.md @@ -27,7 +27,7 @@ This is determined by the ```src/META-INF/services/org.jetbrains.jet.preloading. Preloader loads the **first** instrumenter service found on the class path. Services are provided through the [standard JDK mechanism](http://docs.oracle.com/javase/6/docs/api/java/util/ServiceLoader.html). -Every preloaded class is run through the instrumenter. Before exiting the program instrumenter's dupm() method is called. +Every preloaded class is run through the instrumenter. Before exiting the program instrumenter's dump() method is called. **Note** JDK classes and everything in the Preloader's own class path are not preloaded, thus not instrumented. The ```instrumentation``` module provides a convenient way to define useful instrumenters: From 89b3f953d15716224728acf6cc8d1295129b42a9 Mon Sep 17 00:00:00 2001 From: Evgeny Gerashchenko Date: Fri, 31 May 2013 17:39:45 +0400 Subject: [PATCH 188/249] Fixed broken reference to jar. --- .idea/artifacts/instrumentation_jar.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.idea/artifacts/instrumentation_jar.xml b/.idea/artifacts/instrumentation_jar.xml index 5e0f98bc70e..be868324bfb 100644 --- a/.idea/artifacts/instrumentation_jar.xml +++ b/.idea/artifacts/instrumentation_jar.xml @@ -4,7 +4,7 @@ - + \ No newline at end of file From 3e5feeb4361400b82c03923081a645c5276bcaaf Mon Sep 17 00:00:00 2001 From: Evgeny Gerashchenko Date: Fri, 31 May 2013 17:39:57 +0400 Subject: [PATCH 189/249] Minor. Added comments. --- build.xml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/build.xml b/build.xml index 182b6655096..90421ff0b54 100644 --- a/build.xml +++ b/build.xml @@ -539,12 +539,15 @@ + + + From 343a28ac2d5b38e71bbd8666547b02b68d774573 Mon Sep 17 00:00:00 2001 From: Evgeny Gerashchenko Date: Mon, 3 Jun 2013 17:47:36 +0400 Subject: [PATCH 190/249] Ignored local Gradle repository. --- libraries/tools/kotlin-gradle-plugin/.gitignore | 1 + 1 file changed, 1 insertion(+) create mode 100644 libraries/tools/kotlin-gradle-plugin/.gitignore diff --git a/libraries/tools/kotlin-gradle-plugin/.gitignore b/libraries/tools/kotlin-gradle-plugin/.gitignore new file mode 100644 index 00000000000..b97b22398a9 --- /dev/null +++ b/libraries/tools/kotlin-gradle-plugin/.gitignore @@ -0,0 +1 @@ +local-repo From c51a70b3b8af90ed863a61b32131bdd68943e9d5 Mon Sep 17 00:00:00 2001 From: Evgeny Gerashchenko Date: Mon, 3 Jun 2013 18:20:36 +0400 Subject: [PATCH 191/249] Optimized obtaining super methods. --- .../PropagationHeuristics.java | 119 +++++++++++++++++- 1 file changed, 115 insertions(+), 4 deletions(-) diff --git a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/kotlinSignature/PropagationHeuristics.java b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/kotlinSignature/PropagationHeuristics.java index abe2a333b0d..941175e951c 100644 --- a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/kotlinSignature/PropagationHeuristics.java +++ b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/kotlinSignature/PropagationHeuristics.java @@ -17,9 +17,11 @@ package org.jetbrains.jet.lang.resolve.java.kotlinSignature; import com.google.common.collect.Lists; +import com.google.common.collect.Maps; +import com.intellij.openapi.util.Comparing; import com.intellij.openapi.util.Condition; -import com.intellij.psi.HierarchicalMethodSignature; -import com.intellij.psi.PsiMethod; +import com.intellij.psi.*; +import com.intellij.psi.impl.PsiSubstitutorImpl; import com.intellij.util.containers.ContainerUtil; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -38,7 +40,11 @@ import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns; import org.jetbrains.jet.renderer.DescriptorRenderer; import java.util.Arrays; +import java.util.Collections; import java.util.List; +import java.util.Map; + +import static com.intellij.psi.util.TypeConversionUtil.erasure; // This class contains heuristics for processing corner cases in propagation class PropagationHeuristics { @@ -122,8 +128,7 @@ class PropagationHeuristics { @NotNull static List getSuperMethods(@NotNull PsiMethod method) { List superMethods = Lists.newArrayList(); - for (HierarchicalMethodSignature superSignature : method.getHierarchicalMethodSignature().getSuperSignatures()) { - PsiMethod superMethod = superSignature.getMethod(); + for (PsiMethod superMethod : new SuperMethodCollector(method).collect()) { CallableMemberDescriptor.Kind kindFromFlags = DescriptorKindUtils.flagsToKind(new PsiMethodWrapper(superMethod).getJetMethodAnnotation().kind()); if (kindFromFlags == CallableMemberDescriptor.Kind.FAKE_OVERRIDE) { @@ -141,4 +146,110 @@ class PropagationHeuristics { private PropagationHeuristics() { } + + private static class SuperMethodCollector { + private final PsiMethod initialMethod; + private final String initialMethodName; + private final List initialParametersErasure; + + private final List visitedSuperclasses = Lists.newArrayList(); + private final List collectedMethods = Lists.newArrayList(); + + private SuperMethodCollector(@NotNull PsiMethod initialMethod) { + this.initialMethod = initialMethod; + initialMethodName = initialMethod.getName(); + + PsiParameterList parameterList = initialMethod.getParameterList(); + initialParametersErasure = Lists.newArrayListWithExpectedSize(parameterList.getParametersCount()); + for (PsiParameter parameter : parameterList.getParameters()) { + initialParametersErasure.add(erasureNoEllipsis(parameter.getType())); + } + } + + public List collect() { + if (!canHaveSuperMethod(initialMethod)) { + return Collections.emptyList(); + } + + PsiClass containingClass = initialMethod.getContainingClass(); + assert containingClass != null : " containing class is null for " + initialMethod; + + for (PsiClassType superType : containingClass.getSuperTypes()) { + collectFromSupertype(superType); + } + + return collectedMethods; + } + + private void collectFromSupertype(PsiClassType type) { + PsiClass klass = type.resolve(); + if (klass == null) { + return; + } + if (!visitedSuperclasses.add(klass)) { + return; + } + + PsiSubstitutor supertypeSubstitutor = getErasedSubstitutor(type); + for (PsiMethod methodFromSuper : klass.getMethods()) { + if (isSubMethodOf(methodFromSuper, supertypeSubstitutor)) { + collectedMethods.add(methodFromSuper); + return; + } + } + + for (PsiType superType : type.getSuperTypes()) { + assert superType instanceof PsiClassType : "supertype is not a PsiClassType for " + type + ": " + superType; + collectFromSupertype((PsiClassType) superType); + } + } + + private boolean isSubMethodOf(@NotNull PsiMethod methodFromSuper, @NotNull PsiSubstitutor supertypeSubstitutor) { + if (!methodFromSuper.getName().equals(initialMethodName)) { + return false; + } + + PsiParameterList fromSuperParameterList = methodFromSuper.getParameterList(); + + if (fromSuperParameterList.getParametersCount() != initialParametersErasure.size()) { + return false; + } + + for (int i = 0; i < initialParametersErasure.size(); i++) { + PsiType originalType = initialParametersErasure.get(i); + PsiType typeFromSuper = fromSuperParameterList.getParameters()[i].getType(); + PsiType typeFromSuperErased = erasureNoEllipsis(supertypeSubstitutor.substitute(typeFromSuper)); + + if (!Comparing.equal(originalType, typeFromSuperErased)) { + return false; + } + } + + return true; + } + + private static PsiType erasureNoEllipsis(PsiType type) { + if (type instanceof PsiEllipsisType) { + return erasureNoEllipsis(((PsiEllipsisType) type).toArrayType()); + } + return erasure(type); + } + + private static PsiSubstitutor getErasedSubstitutor(PsiClassType type) { + Map unerasedMap = type.resolveGenerics().getSubstitutor().getSubstitutionMap(); + Map erasedMap = Maps.newHashMapWithExpectedSize(unerasedMap.size()); + for (Map.Entry entry : unerasedMap.entrySet()) { + erasedMap.put(entry.getKey(), erasure(entry.getValue())); + } + return PsiSubstitutorImpl.createSubstitutor(erasedMap); + } + + private static boolean canHaveSuperMethod(PsiMethod method) { + if (method.isConstructor()) return false; + if (method.hasModifierProperty(PsiModifier.STATIC)) return false; + if (method.hasModifierProperty(PsiModifier.PRIVATE)) return false; + PsiClass containingClass = method.getContainingClass(); + return containingClass != null && !CommonClassNames.JAVA_LANG_OBJECT.equals(containingClass.getQualifiedName()); + } + } } From 9270eec30ff6f7001f1b88f66fbabbde8c8441f0 Mon Sep 17 00:00:00 2001 From: Andrey Breslav Date: Wed, 22 May 2013 15:30:02 +0400 Subject: [PATCH 192/249] Using properties for dependency build id's (cherry picked from commit 68b0aa0) --- update_dependencies.xml | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/update_dependencies.xml b/update_dependencies.xml index b3fe11a630b..1d2c8f09340 100644 --- a/update_dependencies.xml +++ b/update_dependencies.xml @@ -1,16 +1,19 @@ + + + From ce402068c9228c84ce9cd6dead42172f8369256a Mon Sep 17 00:00:00 2001 From: Andrey Breslav Date: Wed, 22 May 2013 15:47:59 +0400 Subject: [PATCH 193/249] Using a property for IDEA zip name (cherry picked from commit 42683dc) --- update_dependencies.xml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/update_dependencies.xml b/update_dependencies.xml index 1d2c8f09340..993c64ab546 100644 --- a/update_dependencies.xml +++ b/update_dependencies.xml @@ -1,20 +1,21 @@ + From acbccb9411194c6fd3fa8c20831084ec1dbaf716 Mon Sep 17 00:00:00 2001 From: "Natalia.Ukhorskaya" Date: Mon, 3 Jun 2013 13:58:53 +0400 Subject: [PATCH 194/249] Get asm from fixed idea build (jar with debug info and patched for java 8) --- update_dependencies.xml | 14 +++----------- 1 file changed, 3 insertions(+), 11 deletions(-) diff --git a/update_dependencies.xml b/update_dependencies.xml index 993c64ab546..8af22a17daf 100644 --- a/update_dependencies.xml +++ b/update_dependencies.xml @@ -126,17 +126,9 @@ - - - - - - - - - - - + + + From ecec6acde89a8a1c6abf301d0e661c677ecfd343 Mon Sep 17 00:00:00 2001 From: Svetlana Isakova Date: Tue, 4 Jun 2013 16:25:31 +0400 Subject: [PATCH 195/249] use explicit type of delegated property as expected while resolving constraint system for delegated expression --- .../jetbrains/jet/lang/psi/JetPsiUtil.java | 21 ++++ .../jet/lang/resolve/BindingContext.java | 2 + .../jet/lang/resolve/BodyResolver.java | 95 ++++++++++++++++++- .../lang/resolve/calls/CandidateResolver.java | 15 +++ .../calls/inference/ConstraintPosition.java | 1 + .../inference/ConstraintSystemCompleter.java | 27 ++++++ .../expressions/DelegatedPropertyUtils.java | 72 ++++++++------ .../differentDelegatedExpressions.kt | 50 ++++++++++ .../noErrorsForImplicitConstraints.kt | 42 ++++++++ .../inference/useExpectedType.kt | 84 ++++++++++++++++ .../checkers/JetDiagnosticsTestGenerated.java | 37 +++++++- .../BlackBoxCodegenTestGenerated.java | 4 +- 12 files changed, 416 insertions(+), 34 deletions(-) create mode 100644 compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/inference/ConstraintSystemCompleter.java create mode 100644 compiler/testData/diagnostics/tests/delegatedProperty/inference/differentDelegatedExpressions.kt create mode 100644 compiler/testData/diagnostics/tests/delegatedProperty/inference/noErrorsForImplicitConstraints.kt create mode 100644 compiler/testData/diagnostics/tests/delegatedProperty/inference/useExpectedType.kt diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetPsiUtil.java b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetPsiUtil.java index bb3a578a368..379a1e36630 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetPsiUtil.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetPsiUtil.java @@ -755,4 +755,25 @@ public class JetPsiUtil { public static boolean isInComment(PsiElement element) { return CommentUtilCore.isComment(element) || element instanceof KDocElement; } + + @Nullable + public static JetExpression getCalleeExpressionIfAny(@NotNull JetExpression expression) { + if (expression instanceof JetCallElement) { + JetCallElement callExpression = (JetCallElement) expression; + return callExpression.getCalleeExpression(); + } + if (expression instanceof JetQualifiedExpression) { + JetExpression selectorExpression = ((JetQualifiedExpression) expression).getSelectorExpression(); + if (selectorExpression != null) { + return getCalleeExpressionIfAny(selectorExpression); + } + } + if (expression instanceof JetUnaryExpression) { + return ((JetUnaryExpression) expression).getOperationReference(); + } + if (expression instanceof JetBinaryExpression) { + return ((JetBinaryExpression) expression).getOperationReference(); + } + return null; + } } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/BindingContext.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/BindingContext.java index fe4b97949a4..9e51ebd58c2 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/BindingContext.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/BindingContext.java @@ -26,6 +26,7 @@ import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor; import org.jetbrains.jet.lang.diagnostics.Diagnostic; import org.jetbrains.jet.lang.psi.*; import org.jetbrains.jet.lang.resolve.calls.autocasts.DataFlowInfo; +import org.jetbrains.jet.lang.resolve.calls.inference.ConstraintSystemCompleter; import org.jetbrains.jet.lang.resolve.calls.model.ResolvedCall; import org.jetbrains.jet.lang.resolve.constants.CompileTimeConstant; import org.jetbrains.jet.lang.resolve.name.FqName; @@ -82,6 +83,7 @@ public interface BindingContext { new BasicWritableSlice(DO_NOTHING); WritableSlice> RESOLVED_CALL = new BasicWritableSlice>(DO_NOTHING); + WritableSlice CONSTRAINT_SYSTEM_COMPLETER = new BasicWritableSlice(DO_NOTHING); WritableSlice CALL = new BasicWritableSlice(DO_NOTHING); WritableSlice> AMBIGUOUS_REFERENCE_TARGET = diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/BodyResolver.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/BodyResolver.java index 19c1188212f..f3f5946f9cb 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/BodyResolver.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/BodyResolver.java @@ -26,6 +26,10 @@ import org.jetbrains.jet.lang.descriptors.*; import org.jetbrains.jet.lang.descriptors.impl.FunctionDescriptorUtil; import org.jetbrains.jet.lang.descriptors.impl.MutableClassDescriptor; import org.jetbrains.jet.lang.psi.*; +import org.jetbrains.jet.lang.resolve.calls.inference.ConstraintPosition; +import org.jetbrains.jet.lang.resolve.calls.inference.ConstraintSystem; +import org.jetbrains.jet.lang.resolve.calls.inference.ConstraintSystemCompleter; +import org.jetbrains.jet.lang.resolve.calls.model.ResolvedCall; import org.jetbrains.jet.lang.resolve.calls.util.CallMaker; import org.jetbrains.jet.lang.resolve.calls.CallResolver; import org.jetbrains.jet.lang.resolve.calls.results.OverloadResolutionResults; @@ -46,7 +50,8 @@ import java.util.*; import static org.jetbrains.jet.lang.descriptors.ReceiverParameterDescriptor.NO_RECEIVER_PARAMETER; import static org.jetbrains.jet.lang.diagnostics.Errors.*; -import static org.jetbrains.jet.lang.resolve.BindingContext.DEFERRED_TYPE; +import static org.jetbrains.jet.lang.resolve.BindingContext.*; +import static org.jetbrains.jet.lang.resolve.calls.results.OverloadResolutionResults.Code; import static org.jetbrains.jet.lang.types.TypeUtils.NO_EXPECTED_TYPE; public class BodyResolver { @@ -487,10 +492,25 @@ public class BodyResolver { JetScope propertyDeclarationInnerScope = descriptorResolver.getPropertyDeclarationInnerScopeForInitializer( propertyScope, propertyDescriptor.getTypeParameters(), NO_RECEIVER_PARAMETER, trace); - JetType delegateType = expressionTypingServices.safeGetType(propertyDeclarationInnerScope, delegateExpression, NO_EXPECTED_TYPE, - DataFlowInfo.EMPTY, trace); + TemporaryBindingTrace traceToResolveDelegatedProperty = TemporaryBindingTrace.create(trace, "Trace to resolve delegated property"); + JetScope accessorScope = JetScopeUtils.makeScopeForPropertyAccessor( + propertyDescriptor, parentScopeForAccessor, descriptorResolver, trace); + + JetExpression calleeExpression = JetPsiUtil.getCalleeExpressionIfAny(delegateExpression); + ConstraintSystemCompleter completer = + createConstraintSystemCompleter(jetProperty, propertyDescriptor, delegateExpression, accessorScope); + if (calleeExpression != null) { + traceToResolveDelegatedProperty.record(CONSTRAINT_SYSTEM_COMPLETER, calleeExpression, completer); + } + JetType delegateType = expressionTypingServices.safeGetType(propertyDeclarationInnerScope, delegateExpression, NO_EXPECTED_TYPE, + DataFlowInfo.EMPTY, traceToResolveDelegatedProperty); + traceToResolveDelegatedProperty.commit(new TraceEntryFilter() { + @Override + public boolean accept(@NotNull WritableSlice slice, Object key) { + return slice != CONSTRAINT_SYSTEM_COMPLETER; + } + }, true); - JetScope accessorScope = JetScopeUtils.makeScopeForPropertyAccessor(propertyDescriptor, parentScopeForAccessor, descriptorResolver, trace); DelegatedPropertyUtils.resolveDelegatedPropertyGetMethod(propertyDescriptor, delegateExpression, delegateType, expressionTypingServices, trace, accessorScope); @@ -500,6 +520,73 @@ public class BodyResolver { } } + private ConstraintSystemCompleter createConstraintSystemCompleter( + JetProperty property, + final PropertyDescriptor propertyDescriptor, + final JetExpression delegateExpression, + final JetScope accessorScope + ) { + final JetType expectedType = property.getTypeRef() != null ? propertyDescriptor.getType() : NO_EXPECTED_TYPE; + return new ConstraintSystemCompleter() { + @Override + public void completeConstraintSystem( + @NotNull ConstraintSystem constraintSystem, @NotNull ResolvedCall resolvedCall + ) { + JetType returnType = resolvedCall.getCandidateDescriptor().getReturnType(); + if (returnType == null) return; + + TemporaryBindingTrace traceToResolveConventionMethods = + TemporaryBindingTrace.create(trace, "Trace to resolve delegated property convention methods"); + OverloadResolutionResults + getMethodResults = DelegatedPropertyUtils.getDelegatedPropertyConventionMethod( + propertyDescriptor, delegateExpression, returnType, expressionTypingServices, + traceToResolveConventionMethods, accessorScope, true); + + if (conventionMethodFound(getMethodResults)) { + FunctionDescriptor descriptor = getMethodResults.getResultingDescriptor(); + JetType returnTypeOfGetMethod = descriptor.getReturnType(); + if (returnTypeOfGetMethod != null) { + constraintSystem.addSupertypeConstraint(expectedType, returnTypeOfGetMethod, ConstraintPosition.FROM_COMPLETER); + } + addConstraintForThisValue(constraintSystem, descriptor); + } + if (propertyDescriptor.isVar()) { + OverloadResolutionResults setMethodResults = + DelegatedPropertyUtils.getDelegatedPropertyConventionMethod( + propertyDescriptor, delegateExpression, returnType, expressionTypingServices, + traceToResolveConventionMethods, accessorScope, false); + + if (conventionMethodFound(setMethodResults)) { + FunctionDescriptor descriptor = setMethodResults.getResultingDescriptor(); + List valueParameters = descriptor.getValueParameters(); + if (valueParameters.size() == 3) { + ValueParameterDescriptor valueParameterForThis = valueParameters.get(2); + constraintSystem.addSubtypeConstraint(expectedType, valueParameterForThis.getType(), ConstraintPosition.FROM_COMPLETER); + addConstraintForThisValue(constraintSystem, descriptor); + } + } + } + } + + private boolean conventionMethodFound(@NotNull OverloadResolutionResults results) { + return results.isSuccess() || + (results.isSingleResult() && results.getResultCode() == Code.SINGLE_CANDIDATE_ARGUMENT_MISMATCH); + } + + private void addConstraintForThisValue(ConstraintSystem constraintSystem, FunctionDescriptor resultingDescriptor) { + ReceiverParameterDescriptor receiverParameter = propertyDescriptor.getReceiverParameter(); + ReceiverParameterDescriptor thisObject = propertyDescriptor.getExpectedThisObject(); + if (receiverParameter == null && thisObject == null) return; + + List valueParameters = resultingDescriptor.getValueParameters(); + if (valueParameters.isEmpty()) return; + ValueParameterDescriptor valueParameterForThis = valueParameters.get(0); + JetType typeOfThis = receiverParameter != null ? receiverParameter.getType() : thisObject.getType(); + constraintSystem.addSubtypeConstraint(typeOfThis, valueParameterForThis.getType(), ConstraintPosition.FROM_COMPLETER); + } + }; + } + public void resolvePropertyInitializer( @NotNull JetProperty property, @NotNull PropertyDescriptor propertyDescriptor, diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/CandidateResolver.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/CandidateResolver.java index d79ca3fbbf1..8d15321b81d 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/CandidateResolver.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/CandidateResolver.java @@ -235,6 +235,21 @@ public class CandidateResolver { constraintSystem.addSupertypeConstraint(context.expectedType, descriptor.getReturnType(), ConstraintPosition.EXPECTED_TYPE_POSITION); + ConstraintSystemCompleter constraintSystemCompleter = context.trace.get( + BindingContext.CONSTRAINT_SYSTEM_COMPLETER, context.call.getCalleeExpression()); + if (constraintSystemCompleter != null) { + ConstraintSystemImpl backup = (ConstraintSystemImpl) constraintSystem.copy(); + + //todo improve error reporting with errors in constraints from completer + constraintSystemCompleter.completeConstraintSystem(constraintSystem, resolvedCall); + if (constraintSystem.hasTypeConstructorMismatchAt(ConstraintPosition.FROM_COMPLETER) || + (constraintSystem.hasContradiction() && !backup.hasContradiction())) { + + constraintSystem = backup; + resolvedCall.setConstraintSystem(backup); + } + } + if (constraintSystem.hasContradiction()) { return reportInferenceError(context); } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/inference/ConstraintPosition.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/inference/ConstraintPosition.java index c8c77099e8d..d2343cb0e7b 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/inference/ConstraintPosition.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/inference/ConstraintPosition.java @@ -24,6 +24,7 @@ public class ConstraintPosition { public static final ConstraintPosition RECEIVER_POSITION = new ConstraintPosition("RECEIVER_POSITION"); public static final ConstraintPosition EXPECTED_TYPE_POSITION = new ConstraintPosition("EXPECTED_TYPE_POSITION"); public static final ConstraintPosition BOUND_CONSTRAINT_POSITION = new ConstraintPosition("BOUND_CONSTRAINT_POSITION"); + public static final ConstraintPosition FROM_COMPLETER = new ConstraintPosition("FROM_COMPLETER"); private static final Map valueParameterPositions = Maps.newHashMap(); diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/inference/ConstraintSystemCompleter.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/inference/ConstraintSystemCompleter.java new file mode 100644 index 00000000000..20df3897113 --- /dev/null +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/inference/ConstraintSystemCompleter.java @@ -0,0 +1,27 @@ +/* + * Copyright 2010-2013 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.jetbrains.jet.lang.resolve.calls.inference; + +import org.jetbrains.annotations.NotNull; +import org.jetbrains.jet.lang.resolve.calls.model.ResolvedCall; + +public interface ConstraintSystemCompleter { + void completeConstraintSystem( + @NotNull ConstraintSystem constraintSystem, + @NotNull ResolvedCall resolvedCall + ); +} diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/DelegatedPropertyUtils.java b/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/DelegatedPropertyUtils.java index c852ed51ad2..2165091bd94 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/DelegatedPropertyUtils.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/DelegatedPropertyUtils.java @@ -123,8 +123,48 @@ public class DelegatedPropertyUtils { PropertyAccessorDescriptor accessor = isGet ? propertyDescriptor.getGetter() : propertyDescriptor.getSetter(); assert accessor != null : "Delegated property should have getter/setter " + propertyDescriptor + " " + delegateExpression.getText(); + if (trace.getBindingContext().get(DELEGATED_PROPERTY_CALL, accessor) != null) return; + + OverloadResolutionResults functionResults = getDelegatedPropertyConventionMethod( + propertyDescriptor, delegateExpression, delegateType, expressionTypingServices, trace, scope, isGet); Call call = trace.getBindingContext().get(DELEGATED_PROPERTY_CALL, accessor); - if (call != null) return; + assert call != null : "'getDelegatedPropertyConventionMethod' didn't record a call"; + + if (!functionResults.isSuccess()) { + String expectedFunction = renderCall(call, trace.getBindingContext()); + if (functionResults.isIncomplete()) { + trace.report(DELEGATE_SPECIAL_FUNCTION_MISSING.on(delegateExpression, expectedFunction, delegateType)); + } + else if (functionResults.isSingleResult() || + functionResults.getResultCode() == OverloadResolutionResults.Code.MANY_FAILED_CANDIDATES) { + trace.report(DELEGATE_SPECIAL_FUNCTION_NONE_APPLICABLE + .on(delegateExpression, expectedFunction, functionResults.getResultingCalls())); + } + else if (functionResults.isAmbiguity()) { + trace.report(DELEGATE_SPECIAL_FUNCTION_AMBIGUITY + .on(delegateExpression, expectedFunction, functionResults.getResultingCalls())); + } + else { + trace.report(DELEGATE_SPECIAL_FUNCTION_MISSING.on(delegateExpression, expectedFunction, delegateType)); + } + return; + } + + trace.record(DELEGATED_PROPERTY_RESOLVED_CALL, accessor, functionResults.getResultingCall()); + } + + /* Resolve get() or set() methods from delegate */ + public static OverloadResolutionResults getDelegatedPropertyConventionMethod( + @NotNull PropertyDescriptor propertyDescriptor, + @NotNull JetExpression delegateExpression, + @NotNull JetType delegateType, + @NotNull ExpressionTypingServices expressionTypingServices, + @NotNull BindingTrace trace, + @NotNull JetScope scope, + boolean isGet + ) { + PropertyAccessorDescriptor accessor = isGet ? propertyDescriptor.getGetter() : propertyDescriptor.getSetter(); + assert accessor != null : "Delegated property should have getter/setter " + propertyDescriptor + " " + delegateExpression.getText(); ExpressionTypingContext context = ExpressionTypingContext.newContext( expressionTypingServices, trace, scope, @@ -144,39 +184,17 @@ public class DelegatedPropertyUtils { propertyDescriptor.getType()); arguments.add(fakeArgument); List valueParameters = accessor.getValueParameters(); - context.trace.record(REFERENCE_TARGET, fakeArgument, valueParameters.get(0)); + trace.record(REFERENCE_TARGET, fakeArgument, valueParameters.get(0)); } Name functionName = Name.identifier(isGet ? "get" : "set"); JetReferenceExpression fakeCalleeExpression = createSimpleName(project, functionName.asString()); ExpressionReceiver receiver = new ExpressionReceiver(delegateExpression, delegateType); - call = CallMaker.makeCallWithExpressions(fakeCalleeExpression, receiver, null, fakeCalleeExpression, arguments, Call.CallType.DEFAULT); - context.trace.record(BindingContext.DELEGATED_PROPERTY_CALL, accessor, call); + Call call = CallMaker.makeCallWithExpressions(fakeCalleeExpression, receiver, null, fakeCalleeExpression, arguments, Call.CallType.DEFAULT); + trace.record(BindingContext.DELEGATED_PROPERTY_CALL, accessor, call); - OverloadResolutionResults functionResults = context.resolveCallWithGivenName(call, fakeCalleeExpression, functionName); - - if (!functionResults.isSuccess()) { - String expectedFunction = renderCall(call, trace.getBindingContext()); - if (functionResults.isIncomplete()) { - context.trace.report(DELEGATE_SPECIAL_FUNCTION_MISSING.on(delegateExpression, expectedFunction, delegateType)); - } - else if (functionResults.isSingleResult() || - functionResults.getResultCode() == OverloadResolutionResults.Code.MANY_FAILED_CANDIDATES) { - context.trace.report(DELEGATE_SPECIAL_FUNCTION_NONE_APPLICABLE - .on(delegateExpression, expectedFunction, functionResults.getResultingCalls())); - } - else if (functionResults.isAmbiguity()) { - context.trace.report(DELEGATE_SPECIAL_FUNCTION_AMBIGUITY - .on(delegateExpression, expectedFunction, functionResults.getResultingCalls())); - } - else { - context.trace.report(DELEGATE_SPECIAL_FUNCTION_MISSING.on(delegateExpression, expectedFunction, delegateType)); - } - return; - } - - context.trace.record(DELEGATED_PROPERTY_RESOLVED_CALL, accessor, functionResults.getResultingCall()); + return context.resolveCallWithGivenName(call, fakeCalleeExpression, functionName); } private static String renderCall(@NotNull Call call, @NotNull BindingContext context) { diff --git a/compiler/testData/diagnostics/tests/delegatedProperty/inference/differentDelegatedExpressions.kt b/compiler/testData/diagnostics/tests/delegatedProperty/inference/differentDelegatedExpressions.kt new file mode 100644 index 00000000000..fe071d20932 --- /dev/null +++ b/compiler/testData/diagnostics/tests/delegatedProperty/inference/differentDelegatedExpressions.kt @@ -0,0 +1,50 @@ +package baz + +class A(outer: Outer) { + var i: String by + getMyConcreteProperty() + var d: String by getMyConcreteProperty() - 1 + var c: String by O.getMyProperty() + var g: String by outer.getContainer().getMyProperty() + + + var b: String by foo(getMyProperty()) + var r: String by foo(outer.getContainer().getMyProperty()) + var e: String by + foo(getMyProperty()) + var f: String by foo(getMyProperty()) - 1 +} + +fun foo(a: Any?) = MyProperty() + +fun getMyProperty() = MyProperty() + +fun getMyConcreteProperty() = MyProperty() + +class MyProperty { + + public fun get(thisRef: R, desc: PropertyMetadata): T { + println("get $thisRef ${desc.name}") + return null as T + } + + public fun set(thisRef: R, desc: PropertyMetadata, value: T) { + println("set $thisRef ${desc.name} $value") + } +} + +fun MyProperty.plus() = MyProperty() +fun MyProperty.minus(i: Int) = MyProperty() + +object O { + fun getMyProperty() = MyProperty() +} + +trait MyPropertyContainer { + fun getMyProperty(): MyProperty +} + +trait Outer { + fun getContainer(): MyPropertyContainer +} + +// ----------------- +fun println(a: Any?) = a \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/delegatedProperty/inference/noErrorsForImplicitConstraints.kt b/compiler/testData/diagnostics/tests/delegatedProperty/inference/noErrorsForImplicitConstraints.kt new file mode 100644 index 00000000000..8a4bdbe9836 --- /dev/null +++ b/compiler/testData/diagnostics/tests/delegatedProperty/inference/noErrorsForImplicitConstraints.kt @@ -0,0 +1,42 @@ +package foo + +class A { + var a5: String by MyProperty1() + var b5: String by getMyProperty1() +} + +fun getMyProperty1() = MyProperty1() + +class MyProperty1 { + + public fun get(thisRef: R, desc: PropertyMetadata): T { + throw Exception() + } + + public fun set(i: Int, j: Int, k: Int) { + println("set") + } +} + +// ----------------- + +class B { + var a5: String by MyProperty2() + var b5: String by getMyProperty2() +} + +fun getMyProperty2() = MyProperty2() + +class MyProperty2 { + + public fun get(thisRef: R, desc: PropertyMetadata): T { + throw Exception() + } + + public fun set(i: Int) { + println("set") + } +} + +// ----------------- +fun println(a: Any?) = a \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/delegatedProperty/inference/useExpectedType.kt b/compiler/testData/diagnostics/tests/delegatedProperty/inference/useExpectedType.kt new file mode 100644 index 00000000000..ac018117d76 --- /dev/null +++ b/compiler/testData/diagnostics/tests/delegatedProperty/inference/useExpectedType.kt @@ -0,0 +1,84 @@ +package foo + +class A1 { + var a1: String by MyProperty1() + var b1: String by getMyProperty1() +} + +var c1: String by getMyProperty1() + +fun getMyProperty1() = MyProperty1() + +class MyProperty1 { + + public fun get(thisRef: R, desc: PropertyMetadata): T { + println("get $thisRef ${desc.name}") + throw Exception() + } + + public fun set(thisRef: R, desc: PropertyMetadata, value: T) { + println("set $thisRef ${desc.name} $value") + } +} + +//-------------------------- + +class A2 { + var a2: String by MyProperty2() + var b2: String by getMyProperty2() +} + +fun getMyProperty2() = MyProperty2() + +class MyProperty2 { + + public fun get(thisRef: Any?, desc: PropertyMetadata): T { + println("get $thisRef ${desc.name}") + throw Exception() + } + + public fun set(thisRef: Any?, desc: PropertyMetadata, value: T) { + println("set $thisRef ${desc.name} $value") + } +} + +//-------------------------- + +class A3 { + var a3: String by MyProperty3() + var b3: String by getMyProperty3() +} + +fun getMyProperty3() = MyProperty3() + +class MyProperty3 { + + public fun get(thisRef: T, desc: PropertyMetadata): String { + println("get $thisRef ${desc.name}") + return "" + } + + public fun set(thisRef: Any?, desc: PropertyMetadata, value: T) { + println("set $thisRef ${desc.name} $value") + } +} + +//-------------------------- + +class A4 { + val a4: String by MyProperty4() + val b4: String by getMyProperty4() +} + +fun getMyProperty4() = MyProperty4() + +class MyProperty4 { + + public fun get(thisRef: R, desc: PropertyMetadata): T { + println("get $thisRef ${desc.name}") + throw Exception() + } +} + +//-------------------------- +fun println(a: Any?) = a \ No newline at end of file diff --git a/compiler/tests/org/jetbrains/jet/checkers/JetDiagnosticsTestGenerated.java b/compiler/tests/org/jetbrains/jet/checkers/JetDiagnosticsTestGenerated.java index 3ccf049c0d8..6c6e4d1a01c 100644 --- a/compiler/tests/org/jetbrains/jet/checkers/JetDiagnosticsTestGenerated.java +++ b/compiler/tests/org/jetbrains/jet/checkers/JetDiagnosticsTestGenerated.java @@ -1888,6 +1888,7 @@ public class JetDiagnosticsTestGenerated extends AbstractDiagnosticsTestWithEage } @TestMetadata("compiler/testData/diagnostics/tests/delegatedProperty") + @InnerTestClasses({DelegatedProperty.Inference.class}) public static class DelegatedProperty extends AbstractDiagnosticsTestWithEagerResolve { @TestMetadata("absentErrorAboutInitializer.kt") public void testAbsentErrorAboutInitializer() throws Exception { @@ -2053,6 +2054,35 @@ public class JetDiagnosticsTestGenerated extends AbstractDiagnosticsTestWithEage doTest("compiler/testData/diagnostics/tests/delegatedProperty/wrongSetterReturnType.kt"); } + @TestMetadata("compiler/testData/diagnostics/tests/delegatedProperty/inference") + public static class Inference extends AbstractDiagnosticsTestWithEagerResolve { + public void testAllFilesPresentInInference() throws Exception { + JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.GenerateTests", new File("compiler/testData/diagnostics/tests/delegatedProperty/inference"), Pattern.compile("^(.+)\\.kt$"), true); + } + + @TestMetadata("differentDelegatedExpressions.kt") + public void testDifferentDelegatedExpressions() throws Exception { + doTest("compiler/testData/diagnostics/tests/delegatedProperty/inference/differentDelegatedExpressions.kt"); + } + + @TestMetadata("noErrorsForImplicitConstraints.kt") + public void testNoErrorsForImplicitConstraints() throws Exception { + doTest("compiler/testData/diagnostics/tests/delegatedProperty/inference/noErrorsForImplicitConstraints.kt"); + } + + @TestMetadata("useExpectedType.kt") + public void testUseExpectedType() throws Exception { + doTest("compiler/testData/diagnostics/tests/delegatedProperty/inference/useExpectedType.kt"); + } + + } + + public static Test innerSuite() { + TestSuite suite = new TestSuite("DelegatedProperty"); + suite.addTestSuite(DelegatedProperty.class); + suite.addTestSuite(Inference.class); + return suite; + } } @TestMetadata("compiler/testData/diagnostics/tests/deparenthesize") @@ -4717,6 +4747,11 @@ public class JetDiagnosticsTestGenerated extends AbstractDiagnosticsTestWithEage JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.GenerateTests", new File("compiler/testData/diagnostics/tests/smartCasts"), Pattern.compile("^(.+)\\.kt$"), true); } + @TestMetadata("combineWithNoSelectorInfo.kt") + public void testCombineWithNoSelectorInfo() throws Exception { + doTest("compiler/testData/diagnostics/tests/smartCasts/combineWithNoSelectorInfo.kt"); + } + @TestMetadata("kt1461.kt") public void testKt1461() throws Exception { doTest("compiler/testData/diagnostics/tests/smartCasts/kt1461.kt"); @@ -4945,7 +4980,7 @@ public class JetDiagnosticsTestGenerated extends AbstractDiagnosticsTestWithEage suite.addTestSuite(DataFlow.class); suite.addTestSuite(DataFlowInfoTraversal.class); suite.addTest(DeclarationChecks.innerSuite()); - suite.addTestSuite(DelegatedProperty.class); + suite.addTest(DelegatedProperty.innerSuite()); suite.addTestSuite(Deparenthesize.class); suite.addTest(Enum.innerSuite()); suite.addTestSuite(Extensions.class); diff --git a/compiler/tests/org/jetbrains/jet/codegen/generated/BlackBoxCodegenTestGenerated.java b/compiler/tests/org/jetbrains/jet/codegen/generated/BlackBoxCodegenTestGenerated.java index aa30ff43a69..bd7388a1c49 100644 --- a/compiler/tests/org/jetbrains/jet/codegen/generated/BlackBoxCodegenTestGenerated.java +++ b/compiler/tests/org/jetbrains/jet/codegen/generated/BlackBoxCodegenTestGenerated.java @@ -1546,8 +1546,8 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest { doTest("compiler/testData/codegen/box/defaultArguments/constructor/kt2852.kt"); } - } - + } + @TestMetadata("compiler/testData/codegen/box/defaultArguments/function") public static class Function extends AbstractBlackBoxCodegenTest { public void testAllFilesPresentInFunction() throws Exception { From 2337f4b9481e3df14fc38c7c9aa4a41058c69bc0 Mon Sep 17 00:00:00 2001 From: Svetlana Isakova Date: Tue, 4 Jun 2013 18:08:13 +0400 Subject: [PATCH 196/249] bug fix do not combine receiverInfo with error selectorInfo --- .../calls/autocasts/DataFlowValueFactory.java | 5 ++++- .../tests/smartCasts/combineWithNoSelectorInfo.kt | 13 +++++++++++++ 2 files changed, 17 insertions(+), 1 deletion(-) create mode 100644 compiler/testData/diagnostics/tests/smartCasts/combineWithNoSelectorInfo.kt diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/autocasts/DataFlowValueFactory.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/autocasts/DataFlowValueFactory.java index 5399c1a0af1..4b26bddd5bb 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/autocasts/DataFlowValueFactory.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/autocasts/DataFlowValueFactory.java @@ -133,6 +133,9 @@ public class DataFlowValueFactory { @NotNull private static IdentifierInfo combineInfo(@Nullable IdentifierInfo receiverInfo, @NotNull IdentifierInfo selectorInfo) { + if (selectorInfo.id == null) { + return ERROR_IDENTIFIER_INFO; + } if (receiverInfo == null || receiverInfo == ERROR_IDENTIFIER_INFO || receiverInfo.isNamespace) { return selectorInfo; } @@ -182,7 +185,7 @@ public class DataFlowValueFactory { DeclarationDescriptor declarationDescriptor = bindingContext.get(REFERENCE_TARGET, simpleNameExpression); if (declarationDescriptor instanceof VariableDescriptor) { ResolvedCall resolvedCall = bindingContext.get(RESOLVED_CALL, simpleNameExpression); - // todo return assert + // todo uncomment assert // for now it fails for resolving 'invoke' convention, return it after 'invoke' algorithm changes // assert resolvedCall != null : "Cannot create right identifier info if the resolved call is not known yet for " + declarationDescriptor; diff --git a/compiler/testData/diagnostics/tests/smartCasts/combineWithNoSelectorInfo.kt b/compiler/testData/diagnostics/tests/smartCasts/combineWithNoSelectorInfo.kt new file mode 100644 index 00000000000..705b772b9d2 --- /dev/null +++ b/compiler/testData/diagnostics/tests/smartCasts/combineWithNoSelectorInfo.kt @@ -0,0 +1,13 @@ +package foo + +fun dispatch(request: Request) { + val url = request.getRequestURI() as String + + if (request.getMethod()?.length != 0) { + } +} + +trait Request { + fun getRequestURI(): String? + fun getMethod(): String? +} From 2b0616b1c4633aaecc3a1d749f747574f484bd58 Mon Sep 17 00:00:00 2001 From: Svetlana Isakova Date: Tue, 4 Jun 2013 19:28:57 +0400 Subject: [PATCH 197/249] rename ERROR_IDENTIFIER_INFO -> NO_IDENTIFIER_INFO --- .../calls/autocasts/DataFlowValueFactory.java | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/autocasts/DataFlowValueFactory.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/autocasts/DataFlowValueFactory.java index 4b26bddd5bb..d0069211aef 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/autocasts/DataFlowValueFactory.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/autocasts/DataFlowValueFactory.java @@ -119,7 +119,7 @@ public class DataFlowValueFactory { } } - private static final IdentifierInfo ERROR_IDENTIFIER_INFO = new IdentifierInfo(null, false, false); + private static final IdentifierInfo NO_IDENTIFIER_INFO = new IdentifierInfo(null, false, false); @NotNull private static IdentifierInfo createInfo(Object id, boolean isStable) { @@ -134,9 +134,9 @@ public class DataFlowValueFactory { @NotNull private static IdentifierInfo combineInfo(@Nullable IdentifierInfo receiverInfo, @NotNull IdentifierInfo selectorInfo) { if (selectorInfo.id == null) { - return ERROR_IDENTIFIER_INFO; + return NO_IDENTIFIER_INFO; } - if (receiverInfo == null || receiverInfo == ERROR_IDENTIFIER_INFO || receiverInfo.isNamespace) { + if (receiverInfo == null || receiverInfo == NO_IDENTIFIER_INFO || receiverInfo.isNamespace) { return selectorInfo; } return createInfo(Pair.create(receiverInfo.id, selectorInfo.id), receiverInfo.isStable && selectorInfo.isStable); @@ -174,7 +174,7 @@ public class DataFlowValueFactory { else if (expression instanceof JetRootNamespaceExpression) { return createNamespaceInfo(JetModuleUtil.getRootNamespaceType(expression)); } - return ERROR_IDENTIFIER_INFO; + return NO_IDENTIFIER_INFO; } @NotNull @@ -201,7 +201,7 @@ public class DataFlowValueFactory { ClassDescriptor classDescriptor = (ClassDescriptor) declarationDescriptor; return createInfo(classDescriptor, classDescriptor.isClassObjectAValue()); } - return ERROR_IDENTIFIER_INFO; + return NO_IDENTIFIER_INFO; } @Nullable @@ -257,7 +257,7 @@ public class DataFlowValueFactory { if (descriptorOfThisReceiver instanceof ClassDescriptor) { return createInfo(((ClassDescriptor) descriptorOfThisReceiver).getThisAsReceiverParameter().getValue(), true); } - return ERROR_IDENTIFIER_INFO; + return NO_IDENTIFIER_INFO; } public static boolean isStableVariable(@NotNull VariableDescriptor variableDescriptor) { From 7e564de71a2b0e23954df6a1fcdff01b9fc525e5 Mon Sep 17 00:00:00 2001 From: Svetlana Isakova Date: Tue, 4 Jun 2013 19:58:56 +0400 Subject: [PATCH 198/249] added constraint for package level delegated property --- .../jet/lang/resolve/BodyResolver.java | 7 ++- .../inference/useExpectedType.kt | 26 +++----- .../inference/useExpectedTypeForVal.kt | 62 +++++++++++++++++++ .../checkers/JetDiagnosticsTestGenerated.java | 5 ++ 4 files changed, 80 insertions(+), 20 deletions(-) create mode 100644 compiler/testData/diagnostics/tests/delegatedProperty/inference/useExpectedTypeForVal.kt diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/BodyResolver.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/BodyResolver.java index f3f5946f9cb..2a050a21880 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/BodyResolver.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/BodyResolver.java @@ -40,6 +40,7 @@ import org.jetbrains.jet.lang.types.*; import org.jetbrains.jet.lang.types.checker.JetTypeChecker; import org.jetbrains.jet.lang.types.expressions.DelegatedPropertyUtils; import org.jetbrains.jet.lang.types.expressions.ExpressionTypingServices; +import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns; import org.jetbrains.jet.lexer.JetTokens; import org.jetbrains.jet.util.Box; import org.jetbrains.jet.util.lazy.ReenteringLazyValueComputationException; @@ -576,12 +577,14 @@ public class BodyResolver { private void addConstraintForThisValue(ConstraintSystem constraintSystem, FunctionDescriptor resultingDescriptor) { ReceiverParameterDescriptor receiverParameter = propertyDescriptor.getReceiverParameter(); ReceiverParameterDescriptor thisObject = propertyDescriptor.getExpectedThisObject(); - if (receiverParameter == null && thisObject == null) return; + JetType typeOfThis = + receiverParameter != null ? receiverParameter.getType() : + thisObject != null ? thisObject.getType() : + KotlinBuiltIns.getInstance().getNullableNothingType(); List valueParameters = resultingDescriptor.getValueParameters(); if (valueParameters.isEmpty()) return; ValueParameterDescriptor valueParameterForThis = valueParameters.get(0); - JetType typeOfThis = receiverParameter != null ? receiverParameter.getType() : thisObject.getType(); constraintSystem.addSubtypeConstraint(typeOfThis, valueParameterForThis.getType(), ConstraintPosition.FROM_COMPLETER); } }; diff --git a/compiler/testData/diagnostics/tests/delegatedProperty/inference/useExpectedType.kt b/compiler/testData/diagnostics/tests/delegatedProperty/inference/useExpectedType.kt index ac018117d76..1d937178eb1 100644 --- a/compiler/testData/diagnostics/tests/delegatedProperty/inference/useExpectedType.kt +++ b/compiler/testData/diagnostics/tests/delegatedProperty/inference/useExpectedType.kt @@ -5,7 +5,8 @@ class A1 { var b1: String by getMyProperty1() } -var c1: String by getMyProperty1() +var c1: String by getMyProperty1() +var d1: String by MyProperty1() fun getMyProperty1() = MyProperty1() @@ -28,6 +29,9 @@ class A2 { var b2: String by getMyProperty2() } +var c2: String by getMyProperty2() +var d2: String by MyProperty2() + fun getMyProperty2() = MyProperty2() class MyProperty2 { @@ -49,6 +53,9 @@ class A3 { var b3: String by getMyProperty3() } +var c3: String by getMyProperty3() +var d3: String by MyProperty3() + fun getMyProperty3() = MyProperty3() class MyProperty3 { @@ -63,22 +70,5 @@ class MyProperty3 { } } -//-------------------------- - -class A4 { - val a4: String by MyProperty4() - val b4: String by getMyProperty4() -} - -fun getMyProperty4() = MyProperty4() - -class MyProperty4 { - - public fun get(thisRef: R, desc: PropertyMetadata): T { - println("get $thisRef ${desc.name}") - throw Exception() - } -} - //-------------------------- fun println(a: Any?) = a \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/delegatedProperty/inference/useExpectedTypeForVal.kt b/compiler/testData/diagnostics/tests/delegatedProperty/inference/useExpectedTypeForVal.kt new file mode 100644 index 00000000000..5de3690d5d7 --- /dev/null +++ b/compiler/testData/diagnostics/tests/delegatedProperty/inference/useExpectedTypeForVal.kt @@ -0,0 +1,62 @@ +package foo + +class A1 { + val a1: String by MyProperty1() + val b1: String by getMyProperty1() +} + +val c1: String by getMyProperty1() +val d1: String by MyProperty1() + +fun getMyProperty1() = MyProperty1() + +class MyProperty1 { + + public fun get(thisRef: R, desc: PropertyMetadata): T { + println("get $thisRef ${desc.name}") + throw Exception() + } +} + +//-------------------------- + +class A2 { + val a2: String by MyProperty2() + val b2: String by getMyProperty2() +} + +val c2: String by getMyProperty2() +val d2: String by MyProperty2() + +fun getMyProperty2() = MyProperty2() + +class MyProperty2 { + + public fun get(thisRef: Any?, desc: PropertyMetadata): T { + println("get $thisRef ${desc.name}") + throw Exception() + } +} + +//-------------------------- + +class A3 { + val a3: String by MyProperty3() + val b3: String by getMyProperty3() +} + +val c3: String by getMyProperty3() +val d3: String by MyProperty3() + +fun getMyProperty3() = MyProperty3() + +class MyProperty3 { + + public fun get(thisRef: T, desc: PropertyMetadata): String { + println("get $thisRef ${desc.name}") + return "" + } +} + +//-------------------------- +fun println(a: Any?) = a \ No newline at end of file diff --git a/compiler/tests/org/jetbrains/jet/checkers/JetDiagnosticsTestGenerated.java b/compiler/tests/org/jetbrains/jet/checkers/JetDiagnosticsTestGenerated.java index 6c6e4d1a01c..c95d768f16c 100644 --- a/compiler/tests/org/jetbrains/jet/checkers/JetDiagnosticsTestGenerated.java +++ b/compiler/tests/org/jetbrains/jet/checkers/JetDiagnosticsTestGenerated.java @@ -2075,6 +2075,11 @@ public class JetDiagnosticsTestGenerated extends AbstractDiagnosticsTestWithEage doTest("compiler/testData/diagnostics/tests/delegatedProperty/inference/useExpectedType.kt"); } + @TestMetadata("useExpectedTypeForVal.kt") + public void testUseExpectedTypeForVal() throws Exception { + doTest("compiler/testData/diagnostics/tests/delegatedProperty/inference/useExpectedTypeForVal.kt"); + } + } public static Test innerSuite() { From 3a635c537e70b48a5b68d6352ec2ae0972bbb702 Mon Sep 17 00:00:00 2001 From: Alexey Sedunov Date: Fri, 17 May 2013 13:27:54 +0400 Subject: [PATCH 199/249] Move JetPsiMatcher with tests to plugin module --- .../jet/generators/tests/GenerateTests.java | 6 +- .../branchedTransformations/WhenUtils.java | 1 + .../jet/plugin/util}/JetPsiMatcher.java | 3 +- .../expressions/arrayAccess/_arrayAccess1.kt | 0 .../arrayAccess/_arrayAccess1.kt.2 | 0 .../expressions/arrayAccess/_arrayAccess2.kt | 0 .../arrayAccess/_arrayAccess2.kt.2 | 0 .../expressions/arrayAccess/_arrayAccess3.kt | 0 .../arrayAccess/_arrayAccess3.kt.2 | 0 .../expressions/arrayAccess/arrayAccess1.kt | 0 .../expressions/arrayAccess/arrayAccess1.kt.2 | 0 .../expressions/arrayAccess/arrayAccess2.kt | 0 .../expressions/arrayAccess/arrayAccess2.kt.2 | 0 .../expressions/binaryExpr/_binaryExpr1.kt | 0 .../expressions/binaryExpr/_binaryExpr1.kt.2 | 0 .../expressions/binaryExpr/_binaryExpr2.kt | 0 .../expressions/binaryExpr/_binaryExpr2.kt.2 | 0 .../expressions/binaryExpr/_binaryExpr3.kt | 0 .../expressions/binaryExpr/_binaryExpr3.kt.2 | 0 .../expressions/binaryExpr/_binaryExpr4.kt | 0 .../expressions/binaryExpr/_binaryExpr4.kt.2 | 0 .../expressions/binaryExpr/_binaryExpr5.kt | 0 .../expressions/binaryExpr/_binaryExpr5.kt.2 | 0 .../expressions/binaryExpr/_binaryExpr6.kt | 0 .../expressions/binaryExpr/_binaryExpr6.kt.2 | 0 .../expressions/binaryExpr/binaryExpr1.kt | 0 .../expressions/binaryExpr/binaryExpr1.kt.2 | 0 .../expressions/binaryExpr/binaryExpr2.kt | 0 .../expressions/binaryExpr/binaryExpr2.kt.2 | 0 .../expressions/binaryExpr/binaryExpr3.kt | 0 .../expressions/binaryExpr/binaryExpr3.kt.2 | 0 .../expressions/binaryExpr/binaryExpr4.kt | 0 .../expressions/binaryExpr/binaryExpr4.kt.2 | 0 .../expressions/binaryExpr/binaryExpr5.kt | 0 .../expressions/binaryExpr/binaryExpr5.kt.2 | 0 .../jetPsiMatcher/expressions/call/_call1.kt | 0 .../expressions/call/_call1.kt.2 | 0 .../jetPsiMatcher/expressions/call/_call2.kt | 0 .../expressions/call/_call2.kt.2 | 0 .../jetPsiMatcher/expressions/call/_call3.kt | 0 .../expressions/call/_call3.kt.2 | 0 .../jetPsiMatcher/expressions/call/_call4.kt | 0 .../expressions/call/_call4.kt.2 | 0 .../jetPsiMatcher/expressions/call/call1.kt | 0 .../jetPsiMatcher/expressions/call/call1.kt.2 | 0 .../jetPsiMatcher/expressions/call/call2.kt | 0 .../jetPsiMatcher/expressions/call/call2.kt.2 | 0 .../jetPsiMatcher/expressions/call/call3.kt | 0 .../jetPsiMatcher/expressions/call/call3.kt.2 | 0 .../jetPsiMatcher/expressions/call/call4.kt | 0 .../jetPsiMatcher/expressions/call/call4.kt.2 | 0 .../jetPsiMatcher/expressions/const/_const.kt | 0 .../expressions/const/_const.kt.2 | 0 .../jetPsiMatcher/expressions/const/const.kt | 0 .../expressions/const/const.kt.2 | 0 .../jetPsiMatcher/expressions/misc/_misc1.kt | 0 .../expressions/misc/_misc1.kt.2 | 0 .../jetPsiMatcher/expressions/misc/_misc2.kt | 0 .../expressions/misc/_misc2.kt.2 | 0 .../jetPsiMatcher/expressions/misc/_misc3.kt | 0 .../expressions/misc/_misc3.kt.2 | 0 .../jetPsiMatcher/expressions/misc/misc1.kt | 0 .../jetPsiMatcher/expressions/misc/misc1.kt.2 | 0 .../jetPsiMatcher/expressions/misc/misc2.kt | 0 .../jetPsiMatcher/expressions/misc/misc2.kt.2 | 0 .../jetPsiMatcher/expressions/misc/misc3.kt | 0 .../jetPsiMatcher/expressions/misc/misc3.kt.2 | 0 .../expressions/simpleName/_simpleName.kt | 0 .../expressions/simpleName/_simpleName.kt.2 | 0 .../expressions/simpleName/simpleName.kt | 0 .../expressions/simpleName/simpleName.kt.2 | 0 .../expressions/super/_super1.kt | 0 .../expressions/super/_super1.kt.2 | 0 .../expressions/super/_super2.kt | 0 .../expressions/super/_super2.kt.2 | 0 .../expressions/super/_super3.kt | 0 .../expressions/super/_super3.kt.2 | 0 .../expressions/super/_super4.kt | 0 .../expressions/super/_super4.kt.2 | 0 .../jetPsiMatcher/expressions/super/super1.kt | 0 .../expressions/super/super1.kt.2 | 0 .../jetPsiMatcher/expressions/super/super2.kt | 0 .../expressions/super/super2.kt.2 | 0 .../jetPsiMatcher/expressions/super/super3.kt | 0 .../expressions/super/super3.kt.2 | 0 .../jetPsiMatcher/expressions/super/super4.kt | 0 .../expressions/super/super4.kt.2 | 0 .../jetPsiMatcher/expressions/throw/_throw.kt | 0 .../expressions/throw/_throw.kt.2 | 0 .../jetPsiMatcher/expressions/throw/throw.kt | 0 .../expressions/throw/throw.kt.2 | 0 .../expressions/unaryExpr/_unaryExpr1.kt | 0 .../expressions/unaryExpr/_unaryExpr1.kt.2 | 0 .../expressions/unaryExpr/_unaryExpr2.kt | 0 .../expressions/unaryExpr/_unaryExpr2.kt.2 | 0 .../expressions/unaryExpr/_unaryExpr3.kt | 0 .../expressions/unaryExpr/_unaryExpr3.kt.2 | 0 .../expressions/unaryExpr/unaryExpr1.kt | 0 .../expressions/unaryExpr/unaryExpr1.kt.2 | 0 .../expressions/unaryExpr/unaryExpr2.kt | 0 .../expressions/unaryExpr/unaryExpr2.kt.2 | 0 .../jet}/psi/AbstractJetPsiMatcherTest.java | 5 +- .../jetbrains/jet}/psi/JetPsiMatcherTest.java | 146 +++++++++--------- 103 files changed, 83 insertions(+), 78 deletions(-) rename {compiler/frontend/src/org/jetbrains/jet/lang/psi => idea/src/org/jetbrains/jet/plugin/util}/JetPsiMatcher.java (99%) rename {compiler/testData/psi => idea/testData}/jetPsiMatcher/expressions/arrayAccess/_arrayAccess1.kt (100%) rename {compiler/testData/psi => idea/testData}/jetPsiMatcher/expressions/arrayAccess/_arrayAccess1.kt.2 (100%) rename {compiler/testData/psi => idea/testData}/jetPsiMatcher/expressions/arrayAccess/_arrayAccess2.kt (100%) rename {compiler/testData/psi => idea/testData}/jetPsiMatcher/expressions/arrayAccess/_arrayAccess2.kt.2 (100%) rename {compiler/testData/psi => idea/testData}/jetPsiMatcher/expressions/arrayAccess/_arrayAccess3.kt (100%) rename {compiler/testData/psi => idea/testData}/jetPsiMatcher/expressions/arrayAccess/_arrayAccess3.kt.2 (100%) rename {compiler/testData/psi => idea/testData}/jetPsiMatcher/expressions/arrayAccess/arrayAccess1.kt (100%) rename {compiler/testData/psi => idea/testData}/jetPsiMatcher/expressions/arrayAccess/arrayAccess1.kt.2 (100%) rename {compiler/testData/psi => idea/testData}/jetPsiMatcher/expressions/arrayAccess/arrayAccess2.kt (100%) rename {compiler/testData/psi => idea/testData}/jetPsiMatcher/expressions/arrayAccess/arrayAccess2.kt.2 (100%) rename {compiler/testData/psi => idea/testData}/jetPsiMatcher/expressions/binaryExpr/_binaryExpr1.kt (100%) rename {compiler/testData/psi => idea/testData}/jetPsiMatcher/expressions/binaryExpr/_binaryExpr1.kt.2 (100%) rename {compiler/testData/psi => idea/testData}/jetPsiMatcher/expressions/binaryExpr/_binaryExpr2.kt (100%) rename {compiler/testData/psi => idea/testData}/jetPsiMatcher/expressions/binaryExpr/_binaryExpr2.kt.2 (100%) rename {compiler/testData/psi => idea/testData}/jetPsiMatcher/expressions/binaryExpr/_binaryExpr3.kt (100%) rename {compiler/testData/psi => idea/testData}/jetPsiMatcher/expressions/binaryExpr/_binaryExpr3.kt.2 (100%) rename {compiler/testData/psi => idea/testData}/jetPsiMatcher/expressions/binaryExpr/_binaryExpr4.kt (100%) rename {compiler/testData/psi => idea/testData}/jetPsiMatcher/expressions/binaryExpr/_binaryExpr4.kt.2 (100%) rename {compiler/testData/psi => idea/testData}/jetPsiMatcher/expressions/binaryExpr/_binaryExpr5.kt (100%) rename {compiler/testData/psi => idea/testData}/jetPsiMatcher/expressions/binaryExpr/_binaryExpr5.kt.2 (100%) rename {compiler/testData/psi => idea/testData}/jetPsiMatcher/expressions/binaryExpr/_binaryExpr6.kt (100%) rename {compiler/testData/psi => idea/testData}/jetPsiMatcher/expressions/binaryExpr/_binaryExpr6.kt.2 (100%) rename {compiler/testData/psi => idea/testData}/jetPsiMatcher/expressions/binaryExpr/binaryExpr1.kt (100%) rename {compiler/testData/psi => idea/testData}/jetPsiMatcher/expressions/binaryExpr/binaryExpr1.kt.2 (100%) rename {compiler/testData/psi => idea/testData}/jetPsiMatcher/expressions/binaryExpr/binaryExpr2.kt (100%) rename {compiler/testData/psi => idea/testData}/jetPsiMatcher/expressions/binaryExpr/binaryExpr2.kt.2 (100%) rename {compiler/testData/psi => idea/testData}/jetPsiMatcher/expressions/binaryExpr/binaryExpr3.kt (100%) rename {compiler/testData/psi => idea/testData}/jetPsiMatcher/expressions/binaryExpr/binaryExpr3.kt.2 (100%) rename {compiler/testData/psi => idea/testData}/jetPsiMatcher/expressions/binaryExpr/binaryExpr4.kt (100%) rename {compiler/testData/psi => idea/testData}/jetPsiMatcher/expressions/binaryExpr/binaryExpr4.kt.2 (100%) rename {compiler/testData/psi => idea/testData}/jetPsiMatcher/expressions/binaryExpr/binaryExpr5.kt (100%) rename {compiler/testData/psi => idea/testData}/jetPsiMatcher/expressions/binaryExpr/binaryExpr5.kt.2 (100%) rename {compiler/testData/psi => idea/testData}/jetPsiMatcher/expressions/call/_call1.kt (100%) rename {compiler/testData/psi => idea/testData}/jetPsiMatcher/expressions/call/_call1.kt.2 (100%) rename {compiler/testData/psi => idea/testData}/jetPsiMatcher/expressions/call/_call2.kt (100%) rename {compiler/testData/psi => idea/testData}/jetPsiMatcher/expressions/call/_call2.kt.2 (100%) rename {compiler/testData/psi => idea/testData}/jetPsiMatcher/expressions/call/_call3.kt (100%) rename {compiler/testData/psi => idea/testData}/jetPsiMatcher/expressions/call/_call3.kt.2 (100%) rename {compiler/testData/psi => idea/testData}/jetPsiMatcher/expressions/call/_call4.kt (100%) rename {compiler/testData/psi => idea/testData}/jetPsiMatcher/expressions/call/_call4.kt.2 (100%) rename {compiler/testData/psi => idea/testData}/jetPsiMatcher/expressions/call/call1.kt (100%) rename {compiler/testData/psi => idea/testData}/jetPsiMatcher/expressions/call/call1.kt.2 (100%) rename {compiler/testData/psi => idea/testData}/jetPsiMatcher/expressions/call/call2.kt (100%) rename {compiler/testData/psi => idea/testData}/jetPsiMatcher/expressions/call/call2.kt.2 (100%) rename {compiler/testData/psi => idea/testData}/jetPsiMatcher/expressions/call/call3.kt (100%) rename {compiler/testData/psi => idea/testData}/jetPsiMatcher/expressions/call/call3.kt.2 (100%) rename {compiler/testData/psi => idea/testData}/jetPsiMatcher/expressions/call/call4.kt (100%) rename {compiler/testData/psi => idea/testData}/jetPsiMatcher/expressions/call/call4.kt.2 (100%) rename {compiler/testData/psi => idea/testData}/jetPsiMatcher/expressions/const/_const.kt (100%) rename {compiler/testData/psi => idea/testData}/jetPsiMatcher/expressions/const/_const.kt.2 (100%) rename {compiler/testData/psi => idea/testData}/jetPsiMatcher/expressions/const/const.kt (100%) rename {compiler/testData/psi => idea/testData}/jetPsiMatcher/expressions/const/const.kt.2 (100%) rename {compiler/testData/psi => idea/testData}/jetPsiMatcher/expressions/misc/_misc1.kt (100%) rename {compiler/testData/psi => idea/testData}/jetPsiMatcher/expressions/misc/_misc1.kt.2 (100%) rename {compiler/testData/psi => idea/testData}/jetPsiMatcher/expressions/misc/_misc2.kt (100%) rename {compiler/testData/psi => idea/testData}/jetPsiMatcher/expressions/misc/_misc2.kt.2 (100%) rename {compiler/testData/psi => idea/testData}/jetPsiMatcher/expressions/misc/_misc3.kt (100%) rename {compiler/testData/psi => idea/testData}/jetPsiMatcher/expressions/misc/_misc3.kt.2 (100%) rename {compiler/testData/psi => idea/testData}/jetPsiMatcher/expressions/misc/misc1.kt (100%) rename {compiler/testData/psi => idea/testData}/jetPsiMatcher/expressions/misc/misc1.kt.2 (100%) rename {compiler/testData/psi => idea/testData}/jetPsiMatcher/expressions/misc/misc2.kt (100%) rename {compiler/testData/psi => idea/testData}/jetPsiMatcher/expressions/misc/misc2.kt.2 (100%) rename {compiler/testData/psi => idea/testData}/jetPsiMatcher/expressions/misc/misc3.kt (100%) rename {compiler/testData/psi => idea/testData}/jetPsiMatcher/expressions/misc/misc3.kt.2 (100%) rename {compiler/testData/psi => idea/testData}/jetPsiMatcher/expressions/simpleName/_simpleName.kt (100%) rename {compiler/testData/psi => idea/testData}/jetPsiMatcher/expressions/simpleName/_simpleName.kt.2 (100%) rename {compiler/testData/psi => idea/testData}/jetPsiMatcher/expressions/simpleName/simpleName.kt (100%) rename {compiler/testData/psi => idea/testData}/jetPsiMatcher/expressions/simpleName/simpleName.kt.2 (100%) rename {compiler/testData/psi => idea/testData}/jetPsiMatcher/expressions/super/_super1.kt (100%) rename {compiler/testData/psi => idea/testData}/jetPsiMatcher/expressions/super/_super1.kt.2 (100%) rename {compiler/testData/psi => idea/testData}/jetPsiMatcher/expressions/super/_super2.kt (100%) rename {compiler/testData/psi => idea/testData}/jetPsiMatcher/expressions/super/_super2.kt.2 (100%) rename {compiler/testData/psi => idea/testData}/jetPsiMatcher/expressions/super/_super3.kt (100%) rename {compiler/testData/psi => idea/testData}/jetPsiMatcher/expressions/super/_super3.kt.2 (100%) rename {compiler/testData/psi => idea/testData}/jetPsiMatcher/expressions/super/_super4.kt (100%) rename {compiler/testData/psi => idea/testData}/jetPsiMatcher/expressions/super/_super4.kt.2 (100%) rename {compiler/testData/psi => idea/testData}/jetPsiMatcher/expressions/super/super1.kt (100%) rename {compiler/testData/psi => idea/testData}/jetPsiMatcher/expressions/super/super1.kt.2 (100%) rename {compiler/testData/psi => idea/testData}/jetPsiMatcher/expressions/super/super2.kt (100%) rename {compiler/testData/psi => idea/testData}/jetPsiMatcher/expressions/super/super2.kt.2 (100%) rename {compiler/testData/psi => idea/testData}/jetPsiMatcher/expressions/super/super3.kt (100%) rename {compiler/testData/psi => idea/testData}/jetPsiMatcher/expressions/super/super3.kt.2 (100%) rename {compiler/testData/psi => idea/testData}/jetPsiMatcher/expressions/super/super4.kt (100%) rename {compiler/testData/psi => idea/testData}/jetPsiMatcher/expressions/super/super4.kt.2 (100%) rename {compiler/testData/psi => idea/testData}/jetPsiMatcher/expressions/throw/_throw.kt (100%) rename {compiler/testData/psi => idea/testData}/jetPsiMatcher/expressions/throw/_throw.kt.2 (100%) rename {compiler/testData/psi => idea/testData}/jetPsiMatcher/expressions/throw/throw.kt (100%) rename {compiler/testData/psi => idea/testData}/jetPsiMatcher/expressions/throw/throw.kt.2 (100%) rename {compiler/testData/psi => idea/testData}/jetPsiMatcher/expressions/unaryExpr/_unaryExpr1.kt (100%) rename {compiler/testData/psi => idea/testData}/jetPsiMatcher/expressions/unaryExpr/_unaryExpr1.kt.2 (100%) rename {compiler/testData/psi => idea/testData}/jetPsiMatcher/expressions/unaryExpr/_unaryExpr2.kt (100%) rename {compiler/testData/psi => idea/testData}/jetPsiMatcher/expressions/unaryExpr/_unaryExpr2.kt.2 (100%) rename {compiler/testData/psi => idea/testData}/jetPsiMatcher/expressions/unaryExpr/_unaryExpr3.kt (100%) rename {compiler/testData/psi => idea/testData}/jetPsiMatcher/expressions/unaryExpr/_unaryExpr3.kt.2 (100%) rename {compiler/testData/psi => idea/testData}/jetPsiMatcher/expressions/unaryExpr/unaryExpr1.kt (100%) rename {compiler/testData/psi => idea/testData}/jetPsiMatcher/expressions/unaryExpr/unaryExpr1.kt.2 (100%) rename {compiler/testData/psi => idea/testData}/jetPsiMatcher/expressions/unaryExpr/unaryExpr2.kt (100%) rename {compiler/testData/psi => idea/testData}/jetPsiMatcher/expressions/unaryExpr/unaryExpr2.kt.2 (100%) rename {compiler/tests/org/jetbrains/jet/lang => idea/tests/org/jetbrains/jet}/psi/AbstractJetPsiMatcherTest.java (91%) rename {compiler/tests/org/jetbrains/jet/lang => idea/tests/org/jetbrains/jet}/psi/JetPsiMatcherTest.java (61%) diff --git a/generators/org/jetbrains/jet/generators/tests/GenerateTests.java b/generators/org/jetbrains/jet/generators/tests/GenerateTests.java index cdcda21f2e6..0b4e2b3d1f0 100644 --- a/generators/org/jetbrains/jet/generators/tests/GenerateTests.java +++ b/generators/org/jetbrains/jet/generators/tests/GenerateTests.java @@ -32,7 +32,7 @@ import org.jetbrains.jet.completion.AbstractJavaWithLibCompletionTest; import org.jetbrains.jet.completion.AbstractJetJSCompletionTest; import org.jetbrains.jet.completion.AbstractKeywordCompletionTest; import org.jetbrains.jet.jvm.compiler.*; -import org.jetbrains.jet.lang.psi.AbstractJetPsiMatcherTest; +import org.jetbrains.jet.psi.AbstractJetPsiMatcherTest; import org.jetbrains.jet.lang.resolve.lazy.AbstractLazyResolveDescriptorRendererTest; import org.jetbrains.jet.lang.resolve.lazy.AbstractLazyResolveNamespaceComparingTest; import org.jetbrains.jet.lang.resolve.lazy.AbstractLazyResolveTest; @@ -213,10 +213,10 @@ public class GenerateTests { ); generateTest( - "compiler/tests/", + "idea/tests/", "JetPsiMatcherTest", AbstractJetPsiMatcherTest.class, - testModel("compiler/testData/psi/jetPsiMatcher", "doTestExpressions") + testModel("idea/testData/jetPsiMatcher", "doTestExpressions") ); generateTest( diff --git a/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/WhenUtils.java b/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/WhenUtils.java index 8f97f83b2cf..cc79bb83b4a 100644 --- a/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/WhenUtils.java +++ b/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/WhenUtils.java @@ -4,6 +4,7 @@ import com.intellij.psi.tree.IElementType; import org.jetbrains.annotations.NotNull; import org.jetbrains.jet.lang.psi.*; import org.jetbrains.jet.lexer.JetTokens; +import org.jetbrains.jet.plugin.util.JetPsiMatcher; import static org.jetbrains.jet.lang.psi.JetPsiUnparsingUtils.*; diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetPsiMatcher.java b/idea/src/org/jetbrains/jet/plugin/util/JetPsiMatcher.java similarity index 99% rename from compiler/frontend/src/org/jetbrains/jet/lang/psi/JetPsiMatcher.java rename to idea/src/org/jetbrains/jet/plugin/util/JetPsiMatcher.java index 4c10080a68b..1f5a669a5ff 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetPsiMatcher.java +++ b/idea/src/org/jetbrains/jet/plugin/util/JetPsiMatcher.java @@ -14,10 +14,11 @@ * limitations under the License. */ -package org.jetbrains.jet.lang.psi; +package org.jetbrains.jet.plugin.util; import com.google.common.collect.Lists; import org.jetbrains.annotations.Nullable; +import org.jetbrains.jet.lang.psi.*; import java.util.Arrays; import java.util.List; diff --git a/compiler/testData/psi/jetPsiMatcher/expressions/arrayAccess/_arrayAccess1.kt b/idea/testData/jetPsiMatcher/expressions/arrayAccess/_arrayAccess1.kt similarity index 100% rename from compiler/testData/psi/jetPsiMatcher/expressions/arrayAccess/_arrayAccess1.kt rename to idea/testData/jetPsiMatcher/expressions/arrayAccess/_arrayAccess1.kt diff --git a/compiler/testData/psi/jetPsiMatcher/expressions/arrayAccess/_arrayAccess1.kt.2 b/idea/testData/jetPsiMatcher/expressions/arrayAccess/_arrayAccess1.kt.2 similarity index 100% rename from compiler/testData/psi/jetPsiMatcher/expressions/arrayAccess/_arrayAccess1.kt.2 rename to idea/testData/jetPsiMatcher/expressions/arrayAccess/_arrayAccess1.kt.2 diff --git a/compiler/testData/psi/jetPsiMatcher/expressions/arrayAccess/_arrayAccess2.kt b/idea/testData/jetPsiMatcher/expressions/arrayAccess/_arrayAccess2.kt similarity index 100% rename from compiler/testData/psi/jetPsiMatcher/expressions/arrayAccess/_arrayAccess2.kt rename to idea/testData/jetPsiMatcher/expressions/arrayAccess/_arrayAccess2.kt diff --git a/compiler/testData/psi/jetPsiMatcher/expressions/arrayAccess/_arrayAccess2.kt.2 b/idea/testData/jetPsiMatcher/expressions/arrayAccess/_arrayAccess2.kt.2 similarity index 100% rename from compiler/testData/psi/jetPsiMatcher/expressions/arrayAccess/_arrayAccess2.kt.2 rename to idea/testData/jetPsiMatcher/expressions/arrayAccess/_arrayAccess2.kt.2 diff --git a/compiler/testData/psi/jetPsiMatcher/expressions/arrayAccess/_arrayAccess3.kt b/idea/testData/jetPsiMatcher/expressions/arrayAccess/_arrayAccess3.kt similarity index 100% rename from compiler/testData/psi/jetPsiMatcher/expressions/arrayAccess/_arrayAccess3.kt rename to idea/testData/jetPsiMatcher/expressions/arrayAccess/_arrayAccess3.kt diff --git a/compiler/testData/psi/jetPsiMatcher/expressions/arrayAccess/_arrayAccess3.kt.2 b/idea/testData/jetPsiMatcher/expressions/arrayAccess/_arrayAccess3.kt.2 similarity index 100% rename from compiler/testData/psi/jetPsiMatcher/expressions/arrayAccess/_arrayAccess3.kt.2 rename to idea/testData/jetPsiMatcher/expressions/arrayAccess/_arrayAccess3.kt.2 diff --git a/compiler/testData/psi/jetPsiMatcher/expressions/arrayAccess/arrayAccess1.kt b/idea/testData/jetPsiMatcher/expressions/arrayAccess/arrayAccess1.kt similarity index 100% rename from compiler/testData/psi/jetPsiMatcher/expressions/arrayAccess/arrayAccess1.kt rename to idea/testData/jetPsiMatcher/expressions/arrayAccess/arrayAccess1.kt diff --git a/compiler/testData/psi/jetPsiMatcher/expressions/arrayAccess/arrayAccess1.kt.2 b/idea/testData/jetPsiMatcher/expressions/arrayAccess/arrayAccess1.kt.2 similarity index 100% rename from compiler/testData/psi/jetPsiMatcher/expressions/arrayAccess/arrayAccess1.kt.2 rename to idea/testData/jetPsiMatcher/expressions/arrayAccess/arrayAccess1.kt.2 diff --git a/compiler/testData/psi/jetPsiMatcher/expressions/arrayAccess/arrayAccess2.kt b/idea/testData/jetPsiMatcher/expressions/arrayAccess/arrayAccess2.kt similarity index 100% rename from compiler/testData/psi/jetPsiMatcher/expressions/arrayAccess/arrayAccess2.kt rename to idea/testData/jetPsiMatcher/expressions/arrayAccess/arrayAccess2.kt diff --git a/compiler/testData/psi/jetPsiMatcher/expressions/arrayAccess/arrayAccess2.kt.2 b/idea/testData/jetPsiMatcher/expressions/arrayAccess/arrayAccess2.kt.2 similarity index 100% rename from compiler/testData/psi/jetPsiMatcher/expressions/arrayAccess/arrayAccess2.kt.2 rename to idea/testData/jetPsiMatcher/expressions/arrayAccess/arrayAccess2.kt.2 diff --git a/compiler/testData/psi/jetPsiMatcher/expressions/binaryExpr/_binaryExpr1.kt b/idea/testData/jetPsiMatcher/expressions/binaryExpr/_binaryExpr1.kt similarity index 100% rename from compiler/testData/psi/jetPsiMatcher/expressions/binaryExpr/_binaryExpr1.kt rename to idea/testData/jetPsiMatcher/expressions/binaryExpr/_binaryExpr1.kt diff --git a/compiler/testData/psi/jetPsiMatcher/expressions/binaryExpr/_binaryExpr1.kt.2 b/idea/testData/jetPsiMatcher/expressions/binaryExpr/_binaryExpr1.kt.2 similarity index 100% rename from compiler/testData/psi/jetPsiMatcher/expressions/binaryExpr/_binaryExpr1.kt.2 rename to idea/testData/jetPsiMatcher/expressions/binaryExpr/_binaryExpr1.kt.2 diff --git a/compiler/testData/psi/jetPsiMatcher/expressions/binaryExpr/_binaryExpr2.kt b/idea/testData/jetPsiMatcher/expressions/binaryExpr/_binaryExpr2.kt similarity index 100% rename from compiler/testData/psi/jetPsiMatcher/expressions/binaryExpr/_binaryExpr2.kt rename to idea/testData/jetPsiMatcher/expressions/binaryExpr/_binaryExpr2.kt diff --git a/compiler/testData/psi/jetPsiMatcher/expressions/binaryExpr/_binaryExpr2.kt.2 b/idea/testData/jetPsiMatcher/expressions/binaryExpr/_binaryExpr2.kt.2 similarity index 100% rename from compiler/testData/psi/jetPsiMatcher/expressions/binaryExpr/_binaryExpr2.kt.2 rename to idea/testData/jetPsiMatcher/expressions/binaryExpr/_binaryExpr2.kt.2 diff --git a/compiler/testData/psi/jetPsiMatcher/expressions/binaryExpr/_binaryExpr3.kt b/idea/testData/jetPsiMatcher/expressions/binaryExpr/_binaryExpr3.kt similarity index 100% rename from compiler/testData/psi/jetPsiMatcher/expressions/binaryExpr/_binaryExpr3.kt rename to idea/testData/jetPsiMatcher/expressions/binaryExpr/_binaryExpr3.kt diff --git a/compiler/testData/psi/jetPsiMatcher/expressions/binaryExpr/_binaryExpr3.kt.2 b/idea/testData/jetPsiMatcher/expressions/binaryExpr/_binaryExpr3.kt.2 similarity index 100% rename from compiler/testData/psi/jetPsiMatcher/expressions/binaryExpr/_binaryExpr3.kt.2 rename to idea/testData/jetPsiMatcher/expressions/binaryExpr/_binaryExpr3.kt.2 diff --git a/compiler/testData/psi/jetPsiMatcher/expressions/binaryExpr/_binaryExpr4.kt b/idea/testData/jetPsiMatcher/expressions/binaryExpr/_binaryExpr4.kt similarity index 100% rename from compiler/testData/psi/jetPsiMatcher/expressions/binaryExpr/_binaryExpr4.kt rename to idea/testData/jetPsiMatcher/expressions/binaryExpr/_binaryExpr4.kt diff --git a/compiler/testData/psi/jetPsiMatcher/expressions/binaryExpr/_binaryExpr4.kt.2 b/idea/testData/jetPsiMatcher/expressions/binaryExpr/_binaryExpr4.kt.2 similarity index 100% rename from compiler/testData/psi/jetPsiMatcher/expressions/binaryExpr/_binaryExpr4.kt.2 rename to idea/testData/jetPsiMatcher/expressions/binaryExpr/_binaryExpr4.kt.2 diff --git a/compiler/testData/psi/jetPsiMatcher/expressions/binaryExpr/_binaryExpr5.kt b/idea/testData/jetPsiMatcher/expressions/binaryExpr/_binaryExpr5.kt similarity index 100% rename from compiler/testData/psi/jetPsiMatcher/expressions/binaryExpr/_binaryExpr5.kt rename to idea/testData/jetPsiMatcher/expressions/binaryExpr/_binaryExpr5.kt diff --git a/compiler/testData/psi/jetPsiMatcher/expressions/binaryExpr/_binaryExpr5.kt.2 b/idea/testData/jetPsiMatcher/expressions/binaryExpr/_binaryExpr5.kt.2 similarity index 100% rename from compiler/testData/psi/jetPsiMatcher/expressions/binaryExpr/_binaryExpr5.kt.2 rename to idea/testData/jetPsiMatcher/expressions/binaryExpr/_binaryExpr5.kt.2 diff --git a/compiler/testData/psi/jetPsiMatcher/expressions/binaryExpr/_binaryExpr6.kt b/idea/testData/jetPsiMatcher/expressions/binaryExpr/_binaryExpr6.kt similarity index 100% rename from compiler/testData/psi/jetPsiMatcher/expressions/binaryExpr/_binaryExpr6.kt rename to idea/testData/jetPsiMatcher/expressions/binaryExpr/_binaryExpr6.kt diff --git a/compiler/testData/psi/jetPsiMatcher/expressions/binaryExpr/_binaryExpr6.kt.2 b/idea/testData/jetPsiMatcher/expressions/binaryExpr/_binaryExpr6.kt.2 similarity index 100% rename from compiler/testData/psi/jetPsiMatcher/expressions/binaryExpr/_binaryExpr6.kt.2 rename to idea/testData/jetPsiMatcher/expressions/binaryExpr/_binaryExpr6.kt.2 diff --git a/compiler/testData/psi/jetPsiMatcher/expressions/binaryExpr/binaryExpr1.kt b/idea/testData/jetPsiMatcher/expressions/binaryExpr/binaryExpr1.kt similarity index 100% rename from compiler/testData/psi/jetPsiMatcher/expressions/binaryExpr/binaryExpr1.kt rename to idea/testData/jetPsiMatcher/expressions/binaryExpr/binaryExpr1.kt diff --git a/compiler/testData/psi/jetPsiMatcher/expressions/binaryExpr/binaryExpr1.kt.2 b/idea/testData/jetPsiMatcher/expressions/binaryExpr/binaryExpr1.kt.2 similarity index 100% rename from compiler/testData/psi/jetPsiMatcher/expressions/binaryExpr/binaryExpr1.kt.2 rename to idea/testData/jetPsiMatcher/expressions/binaryExpr/binaryExpr1.kt.2 diff --git a/compiler/testData/psi/jetPsiMatcher/expressions/binaryExpr/binaryExpr2.kt b/idea/testData/jetPsiMatcher/expressions/binaryExpr/binaryExpr2.kt similarity index 100% rename from compiler/testData/psi/jetPsiMatcher/expressions/binaryExpr/binaryExpr2.kt rename to idea/testData/jetPsiMatcher/expressions/binaryExpr/binaryExpr2.kt diff --git a/compiler/testData/psi/jetPsiMatcher/expressions/binaryExpr/binaryExpr2.kt.2 b/idea/testData/jetPsiMatcher/expressions/binaryExpr/binaryExpr2.kt.2 similarity index 100% rename from compiler/testData/psi/jetPsiMatcher/expressions/binaryExpr/binaryExpr2.kt.2 rename to idea/testData/jetPsiMatcher/expressions/binaryExpr/binaryExpr2.kt.2 diff --git a/compiler/testData/psi/jetPsiMatcher/expressions/binaryExpr/binaryExpr3.kt b/idea/testData/jetPsiMatcher/expressions/binaryExpr/binaryExpr3.kt similarity index 100% rename from compiler/testData/psi/jetPsiMatcher/expressions/binaryExpr/binaryExpr3.kt rename to idea/testData/jetPsiMatcher/expressions/binaryExpr/binaryExpr3.kt diff --git a/compiler/testData/psi/jetPsiMatcher/expressions/binaryExpr/binaryExpr3.kt.2 b/idea/testData/jetPsiMatcher/expressions/binaryExpr/binaryExpr3.kt.2 similarity index 100% rename from compiler/testData/psi/jetPsiMatcher/expressions/binaryExpr/binaryExpr3.kt.2 rename to idea/testData/jetPsiMatcher/expressions/binaryExpr/binaryExpr3.kt.2 diff --git a/compiler/testData/psi/jetPsiMatcher/expressions/binaryExpr/binaryExpr4.kt b/idea/testData/jetPsiMatcher/expressions/binaryExpr/binaryExpr4.kt similarity index 100% rename from compiler/testData/psi/jetPsiMatcher/expressions/binaryExpr/binaryExpr4.kt rename to idea/testData/jetPsiMatcher/expressions/binaryExpr/binaryExpr4.kt diff --git a/compiler/testData/psi/jetPsiMatcher/expressions/binaryExpr/binaryExpr4.kt.2 b/idea/testData/jetPsiMatcher/expressions/binaryExpr/binaryExpr4.kt.2 similarity index 100% rename from compiler/testData/psi/jetPsiMatcher/expressions/binaryExpr/binaryExpr4.kt.2 rename to idea/testData/jetPsiMatcher/expressions/binaryExpr/binaryExpr4.kt.2 diff --git a/compiler/testData/psi/jetPsiMatcher/expressions/binaryExpr/binaryExpr5.kt b/idea/testData/jetPsiMatcher/expressions/binaryExpr/binaryExpr5.kt similarity index 100% rename from compiler/testData/psi/jetPsiMatcher/expressions/binaryExpr/binaryExpr5.kt rename to idea/testData/jetPsiMatcher/expressions/binaryExpr/binaryExpr5.kt diff --git a/compiler/testData/psi/jetPsiMatcher/expressions/binaryExpr/binaryExpr5.kt.2 b/idea/testData/jetPsiMatcher/expressions/binaryExpr/binaryExpr5.kt.2 similarity index 100% rename from compiler/testData/psi/jetPsiMatcher/expressions/binaryExpr/binaryExpr5.kt.2 rename to idea/testData/jetPsiMatcher/expressions/binaryExpr/binaryExpr5.kt.2 diff --git a/compiler/testData/psi/jetPsiMatcher/expressions/call/_call1.kt b/idea/testData/jetPsiMatcher/expressions/call/_call1.kt similarity index 100% rename from compiler/testData/psi/jetPsiMatcher/expressions/call/_call1.kt rename to idea/testData/jetPsiMatcher/expressions/call/_call1.kt diff --git a/compiler/testData/psi/jetPsiMatcher/expressions/call/_call1.kt.2 b/idea/testData/jetPsiMatcher/expressions/call/_call1.kt.2 similarity index 100% rename from compiler/testData/psi/jetPsiMatcher/expressions/call/_call1.kt.2 rename to idea/testData/jetPsiMatcher/expressions/call/_call1.kt.2 diff --git a/compiler/testData/psi/jetPsiMatcher/expressions/call/_call2.kt b/idea/testData/jetPsiMatcher/expressions/call/_call2.kt similarity index 100% rename from compiler/testData/psi/jetPsiMatcher/expressions/call/_call2.kt rename to idea/testData/jetPsiMatcher/expressions/call/_call2.kt diff --git a/compiler/testData/psi/jetPsiMatcher/expressions/call/_call2.kt.2 b/idea/testData/jetPsiMatcher/expressions/call/_call2.kt.2 similarity index 100% rename from compiler/testData/psi/jetPsiMatcher/expressions/call/_call2.kt.2 rename to idea/testData/jetPsiMatcher/expressions/call/_call2.kt.2 diff --git a/compiler/testData/psi/jetPsiMatcher/expressions/call/_call3.kt b/idea/testData/jetPsiMatcher/expressions/call/_call3.kt similarity index 100% rename from compiler/testData/psi/jetPsiMatcher/expressions/call/_call3.kt rename to idea/testData/jetPsiMatcher/expressions/call/_call3.kt diff --git a/compiler/testData/psi/jetPsiMatcher/expressions/call/_call3.kt.2 b/idea/testData/jetPsiMatcher/expressions/call/_call3.kt.2 similarity index 100% rename from compiler/testData/psi/jetPsiMatcher/expressions/call/_call3.kt.2 rename to idea/testData/jetPsiMatcher/expressions/call/_call3.kt.2 diff --git a/compiler/testData/psi/jetPsiMatcher/expressions/call/_call4.kt b/idea/testData/jetPsiMatcher/expressions/call/_call4.kt similarity index 100% rename from compiler/testData/psi/jetPsiMatcher/expressions/call/_call4.kt rename to idea/testData/jetPsiMatcher/expressions/call/_call4.kt diff --git a/compiler/testData/psi/jetPsiMatcher/expressions/call/_call4.kt.2 b/idea/testData/jetPsiMatcher/expressions/call/_call4.kt.2 similarity index 100% rename from compiler/testData/psi/jetPsiMatcher/expressions/call/_call4.kt.2 rename to idea/testData/jetPsiMatcher/expressions/call/_call4.kt.2 diff --git a/compiler/testData/psi/jetPsiMatcher/expressions/call/call1.kt b/idea/testData/jetPsiMatcher/expressions/call/call1.kt similarity index 100% rename from compiler/testData/psi/jetPsiMatcher/expressions/call/call1.kt rename to idea/testData/jetPsiMatcher/expressions/call/call1.kt diff --git a/compiler/testData/psi/jetPsiMatcher/expressions/call/call1.kt.2 b/idea/testData/jetPsiMatcher/expressions/call/call1.kt.2 similarity index 100% rename from compiler/testData/psi/jetPsiMatcher/expressions/call/call1.kt.2 rename to idea/testData/jetPsiMatcher/expressions/call/call1.kt.2 diff --git a/compiler/testData/psi/jetPsiMatcher/expressions/call/call2.kt b/idea/testData/jetPsiMatcher/expressions/call/call2.kt similarity index 100% rename from compiler/testData/psi/jetPsiMatcher/expressions/call/call2.kt rename to idea/testData/jetPsiMatcher/expressions/call/call2.kt diff --git a/compiler/testData/psi/jetPsiMatcher/expressions/call/call2.kt.2 b/idea/testData/jetPsiMatcher/expressions/call/call2.kt.2 similarity index 100% rename from compiler/testData/psi/jetPsiMatcher/expressions/call/call2.kt.2 rename to idea/testData/jetPsiMatcher/expressions/call/call2.kt.2 diff --git a/compiler/testData/psi/jetPsiMatcher/expressions/call/call3.kt b/idea/testData/jetPsiMatcher/expressions/call/call3.kt similarity index 100% rename from compiler/testData/psi/jetPsiMatcher/expressions/call/call3.kt rename to idea/testData/jetPsiMatcher/expressions/call/call3.kt diff --git a/compiler/testData/psi/jetPsiMatcher/expressions/call/call3.kt.2 b/idea/testData/jetPsiMatcher/expressions/call/call3.kt.2 similarity index 100% rename from compiler/testData/psi/jetPsiMatcher/expressions/call/call3.kt.2 rename to idea/testData/jetPsiMatcher/expressions/call/call3.kt.2 diff --git a/compiler/testData/psi/jetPsiMatcher/expressions/call/call4.kt b/idea/testData/jetPsiMatcher/expressions/call/call4.kt similarity index 100% rename from compiler/testData/psi/jetPsiMatcher/expressions/call/call4.kt rename to idea/testData/jetPsiMatcher/expressions/call/call4.kt diff --git a/compiler/testData/psi/jetPsiMatcher/expressions/call/call4.kt.2 b/idea/testData/jetPsiMatcher/expressions/call/call4.kt.2 similarity index 100% rename from compiler/testData/psi/jetPsiMatcher/expressions/call/call4.kt.2 rename to idea/testData/jetPsiMatcher/expressions/call/call4.kt.2 diff --git a/compiler/testData/psi/jetPsiMatcher/expressions/const/_const.kt b/idea/testData/jetPsiMatcher/expressions/const/_const.kt similarity index 100% rename from compiler/testData/psi/jetPsiMatcher/expressions/const/_const.kt rename to idea/testData/jetPsiMatcher/expressions/const/_const.kt diff --git a/compiler/testData/psi/jetPsiMatcher/expressions/const/_const.kt.2 b/idea/testData/jetPsiMatcher/expressions/const/_const.kt.2 similarity index 100% rename from compiler/testData/psi/jetPsiMatcher/expressions/const/_const.kt.2 rename to idea/testData/jetPsiMatcher/expressions/const/_const.kt.2 diff --git a/compiler/testData/psi/jetPsiMatcher/expressions/const/const.kt b/idea/testData/jetPsiMatcher/expressions/const/const.kt similarity index 100% rename from compiler/testData/psi/jetPsiMatcher/expressions/const/const.kt rename to idea/testData/jetPsiMatcher/expressions/const/const.kt diff --git a/compiler/testData/psi/jetPsiMatcher/expressions/const/const.kt.2 b/idea/testData/jetPsiMatcher/expressions/const/const.kt.2 similarity index 100% rename from compiler/testData/psi/jetPsiMatcher/expressions/const/const.kt.2 rename to idea/testData/jetPsiMatcher/expressions/const/const.kt.2 diff --git a/compiler/testData/psi/jetPsiMatcher/expressions/misc/_misc1.kt b/idea/testData/jetPsiMatcher/expressions/misc/_misc1.kt similarity index 100% rename from compiler/testData/psi/jetPsiMatcher/expressions/misc/_misc1.kt rename to idea/testData/jetPsiMatcher/expressions/misc/_misc1.kt diff --git a/compiler/testData/psi/jetPsiMatcher/expressions/misc/_misc1.kt.2 b/idea/testData/jetPsiMatcher/expressions/misc/_misc1.kt.2 similarity index 100% rename from compiler/testData/psi/jetPsiMatcher/expressions/misc/_misc1.kt.2 rename to idea/testData/jetPsiMatcher/expressions/misc/_misc1.kt.2 diff --git a/compiler/testData/psi/jetPsiMatcher/expressions/misc/_misc2.kt b/idea/testData/jetPsiMatcher/expressions/misc/_misc2.kt similarity index 100% rename from compiler/testData/psi/jetPsiMatcher/expressions/misc/_misc2.kt rename to idea/testData/jetPsiMatcher/expressions/misc/_misc2.kt diff --git a/compiler/testData/psi/jetPsiMatcher/expressions/misc/_misc2.kt.2 b/idea/testData/jetPsiMatcher/expressions/misc/_misc2.kt.2 similarity index 100% rename from compiler/testData/psi/jetPsiMatcher/expressions/misc/_misc2.kt.2 rename to idea/testData/jetPsiMatcher/expressions/misc/_misc2.kt.2 diff --git a/compiler/testData/psi/jetPsiMatcher/expressions/misc/_misc3.kt b/idea/testData/jetPsiMatcher/expressions/misc/_misc3.kt similarity index 100% rename from compiler/testData/psi/jetPsiMatcher/expressions/misc/_misc3.kt rename to idea/testData/jetPsiMatcher/expressions/misc/_misc3.kt diff --git a/compiler/testData/psi/jetPsiMatcher/expressions/misc/_misc3.kt.2 b/idea/testData/jetPsiMatcher/expressions/misc/_misc3.kt.2 similarity index 100% rename from compiler/testData/psi/jetPsiMatcher/expressions/misc/_misc3.kt.2 rename to idea/testData/jetPsiMatcher/expressions/misc/_misc3.kt.2 diff --git a/compiler/testData/psi/jetPsiMatcher/expressions/misc/misc1.kt b/idea/testData/jetPsiMatcher/expressions/misc/misc1.kt similarity index 100% rename from compiler/testData/psi/jetPsiMatcher/expressions/misc/misc1.kt rename to idea/testData/jetPsiMatcher/expressions/misc/misc1.kt diff --git a/compiler/testData/psi/jetPsiMatcher/expressions/misc/misc1.kt.2 b/idea/testData/jetPsiMatcher/expressions/misc/misc1.kt.2 similarity index 100% rename from compiler/testData/psi/jetPsiMatcher/expressions/misc/misc1.kt.2 rename to idea/testData/jetPsiMatcher/expressions/misc/misc1.kt.2 diff --git a/compiler/testData/psi/jetPsiMatcher/expressions/misc/misc2.kt b/idea/testData/jetPsiMatcher/expressions/misc/misc2.kt similarity index 100% rename from compiler/testData/psi/jetPsiMatcher/expressions/misc/misc2.kt rename to idea/testData/jetPsiMatcher/expressions/misc/misc2.kt diff --git a/compiler/testData/psi/jetPsiMatcher/expressions/misc/misc2.kt.2 b/idea/testData/jetPsiMatcher/expressions/misc/misc2.kt.2 similarity index 100% rename from compiler/testData/psi/jetPsiMatcher/expressions/misc/misc2.kt.2 rename to idea/testData/jetPsiMatcher/expressions/misc/misc2.kt.2 diff --git a/compiler/testData/psi/jetPsiMatcher/expressions/misc/misc3.kt b/idea/testData/jetPsiMatcher/expressions/misc/misc3.kt similarity index 100% rename from compiler/testData/psi/jetPsiMatcher/expressions/misc/misc3.kt rename to idea/testData/jetPsiMatcher/expressions/misc/misc3.kt diff --git a/compiler/testData/psi/jetPsiMatcher/expressions/misc/misc3.kt.2 b/idea/testData/jetPsiMatcher/expressions/misc/misc3.kt.2 similarity index 100% rename from compiler/testData/psi/jetPsiMatcher/expressions/misc/misc3.kt.2 rename to idea/testData/jetPsiMatcher/expressions/misc/misc3.kt.2 diff --git a/compiler/testData/psi/jetPsiMatcher/expressions/simpleName/_simpleName.kt b/idea/testData/jetPsiMatcher/expressions/simpleName/_simpleName.kt similarity index 100% rename from compiler/testData/psi/jetPsiMatcher/expressions/simpleName/_simpleName.kt rename to idea/testData/jetPsiMatcher/expressions/simpleName/_simpleName.kt diff --git a/compiler/testData/psi/jetPsiMatcher/expressions/simpleName/_simpleName.kt.2 b/idea/testData/jetPsiMatcher/expressions/simpleName/_simpleName.kt.2 similarity index 100% rename from compiler/testData/psi/jetPsiMatcher/expressions/simpleName/_simpleName.kt.2 rename to idea/testData/jetPsiMatcher/expressions/simpleName/_simpleName.kt.2 diff --git a/compiler/testData/psi/jetPsiMatcher/expressions/simpleName/simpleName.kt b/idea/testData/jetPsiMatcher/expressions/simpleName/simpleName.kt similarity index 100% rename from compiler/testData/psi/jetPsiMatcher/expressions/simpleName/simpleName.kt rename to idea/testData/jetPsiMatcher/expressions/simpleName/simpleName.kt diff --git a/compiler/testData/psi/jetPsiMatcher/expressions/simpleName/simpleName.kt.2 b/idea/testData/jetPsiMatcher/expressions/simpleName/simpleName.kt.2 similarity index 100% rename from compiler/testData/psi/jetPsiMatcher/expressions/simpleName/simpleName.kt.2 rename to idea/testData/jetPsiMatcher/expressions/simpleName/simpleName.kt.2 diff --git a/compiler/testData/psi/jetPsiMatcher/expressions/super/_super1.kt b/idea/testData/jetPsiMatcher/expressions/super/_super1.kt similarity index 100% rename from compiler/testData/psi/jetPsiMatcher/expressions/super/_super1.kt rename to idea/testData/jetPsiMatcher/expressions/super/_super1.kt diff --git a/compiler/testData/psi/jetPsiMatcher/expressions/super/_super1.kt.2 b/idea/testData/jetPsiMatcher/expressions/super/_super1.kt.2 similarity index 100% rename from compiler/testData/psi/jetPsiMatcher/expressions/super/_super1.kt.2 rename to idea/testData/jetPsiMatcher/expressions/super/_super1.kt.2 diff --git a/compiler/testData/psi/jetPsiMatcher/expressions/super/_super2.kt b/idea/testData/jetPsiMatcher/expressions/super/_super2.kt similarity index 100% rename from compiler/testData/psi/jetPsiMatcher/expressions/super/_super2.kt rename to idea/testData/jetPsiMatcher/expressions/super/_super2.kt diff --git a/compiler/testData/psi/jetPsiMatcher/expressions/super/_super2.kt.2 b/idea/testData/jetPsiMatcher/expressions/super/_super2.kt.2 similarity index 100% rename from compiler/testData/psi/jetPsiMatcher/expressions/super/_super2.kt.2 rename to idea/testData/jetPsiMatcher/expressions/super/_super2.kt.2 diff --git a/compiler/testData/psi/jetPsiMatcher/expressions/super/_super3.kt b/idea/testData/jetPsiMatcher/expressions/super/_super3.kt similarity index 100% rename from compiler/testData/psi/jetPsiMatcher/expressions/super/_super3.kt rename to idea/testData/jetPsiMatcher/expressions/super/_super3.kt diff --git a/compiler/testData/psi/jetPsiMatcher/expressions/super/_super3.kt.2 b/idea/testData/jetPsiMatcher/expressions/super/_super3.kt.2 similarity index 100% rename from compiler/testData/psi/jetPsiMatcher/expressions/super/_super3.kt.2 rename to idea/testData/jetPsiMatcher/expressions/super/_super3.kt.2 diff --git a/compiler/testData/psi/jetPsiMatcher/expressions/super/_super4.kt b/idea/testData/jetPsiMatcher/expressions/super/_super4.kt similarity index 100% rename from compiler/testData/psi/jetPsiMatcher/expressions/super/_super4.kt rename to idea/testData/jetPsiMatcher/expressions/super/_super4.kt diff --git a/compiler/testData/psi/jetPsiMatcher/expressions/super/_super4.kt.2 b/idea/testData/jetPsiMatcher/expressions/super/_super4.kt.2 similarity index 100% rename from compiler/testData/psi/jetPsiMatcher/expressions/super/_super4.kt.2 rename to idea/testData/jetPsiMatcher/expressions/super/_super4.kt.2 diff --git a/compiler/testData/psi/jetPsiMatcher/expressions/super/super1.kt b/idea/testData/jetPsiMatcher/expressions/super/super1.kt similarity index 100% rename from compiler/testData/psi/jetPsiMatcher/expressions/super/super1.kt rename to idea/testData/jetPsiMatcher/expressions/super/super1.kt diff --git a/compiler/testData/psi/jetPsiMatcher/expressions/super/super1.kt.2 b/idea/testData/jetPsiMatcher/expressions/super/super1.kt.2 similarity index 100% rename from compiler/testData/psi/jetPsiMatcher/expressions/super/super1.kt.2 rename to idea/testData/jetPsiMatcher/expressions/super/super1.kt.2 diff --git a/compiler/testData/psi/jetPsiMatcher/expressions/super/super2.kt b/idea/testData/jetPsiMatcher/expressions/super/super2.kt similarity index 100% rename from compiler/testData/psi/jetPsiMatcher/expressions/super/super2.kt rename to idea/testData/jetPsiMatcher/expressions/super/super2.kt diff --git a/compiler/testData/psi/jetPsiMatcher/expressions/super/super2.kt.2 b/idea/testData/jetPsiMatcher/expressions/super/super2.kt.2 similarity index 100% rename from compiler/testData/psi/jetPsiMatcher/expressions/super/super2.kt.2 rename to idea/testData/jetPsiMatcher/expressions/super/super2.kt.2 diff --git a/compiler/testData/psi/jetPsiMatcher/expressions/super/super3.kt b/idea/testData/jetPsiMatcher/expressions/super/super3.kt similarity index 100% rename from compiler/testData/psi/jetPsiMatcher/expressions/super/super3.kt rename to idea/testData/jetPsiMatcher/expressions/super/super3.kt diff --git a/compiler/testData/psi/jetPsiMatcher/expressions/super/super3.kt.2 b/idea/testData/jetPsiMatcher/expressions/super/super3.kt.2 similarity index 100% rename from compiler/testData/psi/jetPsiMatcher/expressions/super/super3.kt.2 rename to idea/testData/jetPsiMatcher/expressions/super/super3.kt.2 diff --git a/compiler/testData/psi/jetPsiMatcher/expressions/super/super4.kt b/idea/testData/jetPsiMatcher/expressions/super/super4.kt similarity index 100% rename from compiler/testData/psi/jetPsiMatcher/expressions/super/super4.kt rename to idea/testData/jetPsiMatcher/expressions/super/super4.kt diff --git a/compiler/testData/psi/jetPsiMatcher/expressions/super/super4.kt.2 b/idea/testData/jetPsiMatcher/expressions/super/super4.kt.2 similarity index 100% rename from compiler/testData/psi/jetPsiMatcher/expressions/super/super4.kt.2 rename to idea/testData/jetPsiMatcher/expressions/super/super4.kt.2 diff --git a/compiler/testData/psi/jetPsiMatcher/expressions/throw/_throw.kt b/idea/testData/jetPsiMatcher/expressions/throw/_throw.kt similarity index 100% rename from compiler/testData/psi/jetPsiMatcher/expressions/throw/_throw.kt rename to idea/testData/jetPsiMatcher/expressions/throw/_throw.kt diff --git a/compiler/testData/psi/jetPsiMatcher/expressions/throw/_throw.kt.2 b/idea/testData/jetPsiMatcher/expressions/throw/_throw.kt.2 similarity index 100% rename from compiler/testData/psi/jetPsiMatcher/expressions/throw/_throw.kt.2 rename to idea/testData/jetPsiMatcher/expressions/throw/_throw.kt.2 diff --git a/compiler/testData/psi/jetPsiMatcher/expressions/throw/throw.kt b/idea/testData/jetPsiMatcher/expressions/throw/throw.kt similarity index 100% rename from compiler/testData/psi/jetPsiMatcher/expressions/throw/throw.kt rename to idea/testData/jetPsiMatcher/expressions/throw/throw.kt diff --git a/compiler/testData/psi/jetPsiMatcher/expressions/throw/throw.kt.2 b/idea/testData/jetPsiMatcher/expressions/throw/throw.kt.2 similarity index 100% rename from compiler/testData/psi/jetPsiMatcher/expressions/throw/throw.kt.2 rename to idea/testData/jetPsiMatcher/expressions/throw/throw.kt.2 diff --git a/compiler/testData/psi/jetPsiMatcher/expressions/unaryExpr/_unaryExpr1.kt b/idea/testData/jetPsiMatcher/expressions/unaryExpr/_unaryExpr1.kt similarity index 100% rename from compiler/testData/psi/jetPsiMatcher/expressions/unaryExpr/_unaryExpr1.kt rename to idea/testData/jetPsiMatcher/expressions/unaryExpr/_unaryExpr1.kt diff --git a/compiler/testData/psi/jetPsiMatcher/expressions/unaryExpr/_unaryExpr1.kt.2 b/idea/testData/jetPsiMatcher/expressions/unaryExpr/_unaryExpr1.kt.2 similarity index 100% rename from compiler/testData/psi/jetPsiMatcher/expressions/unaryExpr/_unaryExpr1.kt.2 rename to idea/testData/jetPsiMatcher/expressions/unaryExpr/_unaryExpr1.kt.2 diff --git a/compiler/testData/psi/jetPsiMatcher/expressions/unaryExpr/_unaryExpr2.kt b/idea/testData/jetPsiMatcher/expressions/unaryExpr/_unaryExpr2.kt similarity index 100% rename from compiler/testData/psi/jetPsiMatcher/expressions/unaryExpr/_unaryExpr2.kt rename to idea/testData/jetPsiMatcher/expressions/unaryExpr/_unaryExpr2.kt diff --git a/compiler/testData/psi/jetPsiMatcher/expressions/unaryExpr/_unaryExpr2.kt.2 b/idea/testData/jetPsiMatcher/expressions/unaryExpr/_unaryExpr2.kt.2 similarity index 100% rename from compiler/testData/psi/jetPsiMatcher/expressions/unaryExpr/_unaryExpr2.kt.2 rename to idea/testData/jetPsiMatcher/expressions/unaryExpr/_unaryExpr2.kt.2 diff --git a/compiler/testData/psi/jetPsiMatcher/expressions/unaryExpr/_unaryExpr3.kt b/idea/testData/jetPsiMatcher/expressions/unaryExpr/_unaryExpr3.kt similarity index 100% rename from compiler/testData/psi/jetPsiMatcher/expressions/unaryExpr/_unaryExpr3.kt rename to idea/testData/jetPsiMatcher/expressions/unaryExpr/_unaryExpr3.kt diff --git a/compiler/testData/psi/jetPsiMatcher/expressions/unaryExpr/_unaryExpr3.kt.2 b/idea/testData/jetPsiMatcher/expressions/unaryExpr/_unaryExpr3.kt.2 similarity index 100% rename from compiler/testData/psi/jetPsiMatcher/expressions/unaryExpr/_unaryExpr3.kt.2 rename to idea/testData/jetPsiMatcher/expressions/unaryExpr/_unaryExpr3.kt.2 diff --git a/compiler/testData/psi/jetPsiMatcher/expressions/unaryExpr/unaryExpr1.kt b/idea/testData/jetPsiMatcher/expressions/unaryExpr/unaryExpr1.kt similarity index 100% rename from compiler/testData/psi/jetPsiMatcher/expressions/unaryExpr/unaryExpr1.kt rename to idea/testData/jetPsiMatcher/expressions/unaryExpr/unaryExpr1.kt diff --git a/compiler/testData/psi/jetPsiMatcher/expressions/unaryExpr/unaryExpr1.kt.2 b/idea/testData/jetPsiMatcher/expressions/unaryExpr/unaryExpr1.kt.2 similarity index 100% rename from compiler/testData/psi/jetPsiMatcher/expressions/unaryExpr/unaryExpr1.kt.2 rename to idea/testData/jetPsiMatcher/expressions/unaryExpr/unaryExpr1.kt.2 diff --git a/compiler/testData/psi/jetPsiMatcher/expressions/unaryExpr/unaryExpr2.kt b/idea/testData/jetPsiMatcher/expressions/unaryExpr/unaryExpr2.kt similarity index 100% rename from compiler/testData/psi/jetPsiMatcher/expressions/unaryExpr/unaryExpr2.kt rename to idea/testData/jetPsiMatcher/expressions/unaryExpr/unaryExpr2.kt diff --git a/compiler/testData/psi/jetPsiMatcher/expressions/unaryExpr/unaryExpr2.kt.2 b/idea/testData/jetPsiMatcher/expressions/unaryExpr/unaryExpr2.kt.2 similarity index 100% rename from compiler/testData/psi/jetPsiMatcher/expressions/unaryExpr/unaryExpr2.kt.2 rename to idea/testData/jetPsiMatcher/expressions/unaryExpr/unaryExpr2.kt.2 diff --git a/compiler/tests/org/jetbrains/jet/lang/psi/AbstractJetPsiMatcherTest.java b/idea/tests/org/jetbrains/jet/psi/AbstractJetPsiMatcherTest.java similarity index 91% rename from compiler/tests/org/jetbrains/jet/lang/psi/AbstractJetPsiMatcherTest.java rename to idea/tests/org/jetbrains/jet/psi/AbstractJetPsiMatcherTest.java index 68f543b7342..912904ce789 100644 --- a/compiler/tests/org/jetbrains/jet/lang/psi/AbstractJetPsiMatcherTest.java +++ b/idea/tests/org/jetbrains/jet/psi/AbstractJetPsiMatcherTest.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.jetbrains.jet.lang.psi; +package org.jetbrains.jet.psi; import com.intellij.openapi.util.io.FileUtil; import org.jetbrains.annotations.NotNull; @@ -22,6 +22,9 @@ import org.jetbrains.jet.InTextDirectivesUtils; import org.jetbrains.jet.JetLiteFixture; import org.jetbrains.jet.cli.jvm.compiler.JetCoreEnvironment; import org.jetbrains.jet.config.CompilerConfiguration; +import org.jetbrains.jet.lang.psi.JetExpression; +import org.jetbrains.jet.lang.psi.JetPsiFactory; +import org.jetbrains.jet.plugin.util.JetPsiMatcher; import java.io.File; diff --git a/compiler/tests/org/jetbrains/jet/lang/psi/JetPsiMatcherTest.java b/idea/tests/org/jetbrains/jet/psi/JetPsiMatcherTest.java similarity index 61% rename from compiler/tests/org/jetbrains/jet/lang/psi/JetPsiMatcherTest.java rename to idea/tests/org/jetbrains/jet/psi/JetPsiMatcherTest.java index 726cc5153ed..08c57f91d9b 100644 --- a/compiler/tests/org/jetbrains/jet/lang/psi/JetPsiMatcherTest.java +++ b/idea/tests/org/jetbrains/jet/psi/JetPsiMatcherTest.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.jetbrains.jet.lang.psi; +package org.jetbrains.jet.psi; import junit.framework.Assert; import junit.framework.Test; @@ -26,337 +26,337 @@ import org.jetbrains.jet.JetTestUtils; import org.jetbrains.jet.test.InnerTestClasses; import org.jetbrains.jet.test.TestMetadata; -import org.jetbrains.jet.lang.psi.AbstractJetPsiMatcherTest; +import org.jetbrains.jet.psi.AbstractJetPsiMatcherTest; /** This class is generated by {@link org.jetbrains.jet.generators.tests.GenerateTests}. DO NOT MODIFY MANUALLY */ @SuppressWarnings("all") -@TestMetadata("compiler/testData/psi/jetPsiMatcher") +@TestMetadata("idea/testData/jetPsiMatcher") @InnerTestClasses({JetPsiMatcherTest.Expressions.class}) public class JetPsiMatcherTest extends AbstractJetPsiMatcherTest { public void testAllFilesPresentInJetPsiMatcher() throws Exception { - JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.GenerateTests", new File("compiler/testData/psi/jetPsiMatcher"), Pattern.compile("^(.+)\\.kt$"), true); + JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.GenerateTests", new File("idea/testData/jetPsiMatcher"), Pattern.compile("^(.+)\\.kt$"), true); } - @TestMetadata("compiler/testData/psi/jetPsiMatcher/expressions") + @TestMetadata("idea/testData/jetPsiMatcher/expressions") @InnerTestClasses({Expressions.ArrayAccess.class, Expressions.BinaryExpr.class, Expressions.Call.class, Expressions.Const.class, Expressions.Misc.class, Expressions.SimpleName.class, Expressions.Super.class, Expressions.Throw.class, Expressions.UnaryExpr.class}) public static class Expressions extends AbstractJetPsiMatcherTest { public void testAllFilesPresentInExpressions() throws Exception { - JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.GenerateTests", new File("compiler/testData/psi/jetPsiMatcher/expressions"), Pattern.compile("^(.+)\\.kt$"), true); + JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.GenerateTests", new File("idea/testData/jetPsiMatcher/expressions"), Pattern.compile("^(.+)\\.kt$"), true); } - @TestMetadata("compiler/testData/psi/jetPsiMatcher/expressions/arrayAccess") + @TestMetadata("idea/testData/jetPsiMatcher/expressions/arrayAccess") public static class ArrayAccess extends AbstractJetPsiMatcherTest { public void testAllFilesPresentInArrayAccess() throws Exception { - JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.GenerateTests", new File("compiler/testData/psi/jetPsiMatcher/expressions/arrayAccess"), Pattern.compile("^(.+)\\.kt$"), true); + JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.GenerateTests", new File("idea/testData/jetPsiMatcher/expressions/arrayAccess"), Pattern.compile("^(.+)\\.kt$"), true); } @TestMetadata("arrayAccess1.kt") public void testArrayAccess1() throws Exception { - doTestExpressions("compiler/testData/psi/jetPsiMatcher/expressions/arrayAccess/arrayAccess1.kt"); + doTestExpressions("idea/testData/jetPsiMatcher/expressions/arrayAccess/arrayAccess1.kt"); } @TestMetadata("arrayAccess2.kt") public void testArrayAccess2() throws Exception { - doTestExpressions("compiler/testData/psi/jetPsiMatcher/expressions/arrayAccess/arrayAccess2.kt"); + doTestExpressions("idea/testData/jetPsiMatcher/expressions/arrayAccess/arrayAccess2.kt"); } @TestMetadata("_arrayAccess1.kt") public void test_arrayAccess1() throws Exception { - doTestExpressions("compiler/testData/psi/jetPsiMatcher/expressions/arrayAccess/_arrayAccess1.kt"); + doTestExpressions("idea/testData/jetPsiMatcher/expressions/arrayAccess/_arrayAccess1.kt"); } @TestMetadata("_arrayAccess2.kt") public void test_arrayAccess2() throws Exception { - doTestExpressions("compiler/testData/psi/jetPsiMatcher/expressions/arrayAccess/_arrayAccess2.kt"); + doTestExpressions("idea/testData/jetPsiMatcher/expressions/arrayAccess/_arrayAccess2.kt"); } @TestMetadata("_arrayAccess3.kt") public void test_arrayAccess3() throws Exception { - doTestExpressions("compiler/testData/psi/jetPsiMatcher/expressions/arrayAccess/_arrayAccess3.kt"); + doTestExpressions("idea/testData/jetPsiMatcher/expressions/arrayAccess/_arrayAccess3.kt"); } } - @TestMetadata("compiler/testData/psi/jetPsiMatcher/expressions/binaryExpr") + @TestMetadata("idea/testData/jetPsiMatcher/expressions/binaryExpr") public static class BinaryExpr extends AbstractJetPsiMatcherTest { public void testAllFilesPresentInBinaryExpr() throws Exception { - JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.GenerateTests", new File("compiler/testData/psi/jetPsiMatcher/expressions/binaryExpr"), Pattern.compile("^(.+)\\.kt$"), true); + JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.GenerateTests", new File("idea/testData/jetPsiMatcher/expressions/binaryExpr"), Pattern.compile("^(.+)\\.kt$"), true); } @TestMetadata("binaryExpr1.kt") public void testBinaryExpr1() throws Exception { - doTestExpressions("compiler/testData/psi/jetPsiMatcher/expressions/binaryExpr/binaryExpr1.kt"); + doTestExpressions("idea/testData/jetPsiMatcher/expressions/binaryExpr/binaryExpr1.kt"); } @TestMetadata("binaryExpr2.kt") public void testBinaryExpr2() throws Exception { - doTestExpressions("compiler/testData/psi/jetPsiMatcher/expressions/binaryExpr/binaryExpr2.kt"); + doTestExpressions("idea/testData/jetPsiMatcher/expressions/binaryExpr/binaryExpr2.kt"); } @TestMetadata("binaryExpr3.kt") public void testBinaryExpr3() throws Exception { - doTestExpressions("compiler/testData/psi/jetPsiMatcher/expressions/binaryExpr/binaryExpr3.kt"); + doTestExpressions("idea/testData/jetPsiMatcher/expressions/binaryExpr/binaryExpr3.kt"); } @TestMetadata("binaryExpr4.kt") public void testBinaryExpr4() throws Exception { - doTestExpressions("compiler/testData/psi/jetPsiMatcher/expressions/binaryExpr/binaryExpr4.kt"); + doTestExpressions("idea/testData/jetPsiMatcher/expressions/binaryExpr/binaryExpr4.kt"); } @TestMetadata("binaryExpr5.kt") public void testBinaryExpr5() throws Exception { - doTestExpressions("compiler/testData/psi/jetPsiMatcher/expressions/binaryExpr/binaryExpr5.kt"); + doTestExpressions("idea/testData/jetPsiMatcher/expressions/binaryExpr/binaryExpr5.kt"); } @TestMetadata("_binaryExpr1.kt") public void test_binaryExpr1() throws Exception { - doTestExpressions("compiler/testData/psi/jetPsiMatcher/expressions/binaryExpr/_binaryExpr1.kt"); + doTestExpressions("idea/testData/jetPsiMatcher/expressions/binaryExpr/_binaryExpr1.kt"); } @TestMetadata("_binaryExpr2.kt") public void test_binaryExpr2() throws Exception { - doTestExpressions("compiler/testData/psi/jetPsiMatcher/expressions/binaryExpr/_binaryExpr2.kt"); + doTestExpressions("idea/testData/jetPsiMatcher/expressions/binaryExpr/_binaryExpr2.kt"); } @TestMetadata("_binaryExpr3.kt") public void test_binaryExpr3() throws Exception { - doTestExpressions("compiler/testData/psi/jetPsiMatcher/expressions/binaryExpr/_binaryExpr3.kt"); + doTestExpressions("idea/testData/jetPsiMatcher/expressions/binaryExpr/_binaryExpr3.kt"); } @TestMetadata("_binaryExpr4.kt") public void test_binaryExpr4() throws Exception { - doTestExpressions("compiler/testData/psi/jetPsiMatcher/expressions/binaryExpr/_binaryExpr4.kt"); + doTestExpressions("idea/testData/jetPsiMatcher/expressions/binaryExpr/_binaryExpr4.kt"); } @TestMetadata("_binaryExpr5.kt") public void test_binaryExpr5() throws Exception { - doTestExpressions("compiler/testData/psi/jetPsiMatcher/expressions/binaryExpr/_binaryExpr5.kt"); + doTestExpressions("idea/testData/jetPsiMatcher/expressions/binaryExpr/_binaryExpr5.kt"); } @TestMetadata("_binaryExpr6.kt") public void test_binaryExpr6() throws Exception { - doTestExpressions("compiler/testData/psi/jetPsiMatcher/expressions/binaryExpr/_binaryExpr6.kt"); + doTestExpressions("idea/testData/jetPsiMatcher/expressions/binaryExpr/_binaryExpr6.kt"); } } - @TestMetadata("compiler/testData/psi/jetPsiMatcher/expressions/call") + @TestMetadata("idea/testData/jetPsiMatcher/expressions/call") public static class Call extends AbstractJetPsiMatcherTest { public void testAllFilesPresentInCall() throws Exception { - JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.GenerateTests", new File("compiler/testData/psi/jetPsiMatcher/expressions/call"), Pattern.compile("^(.+)\\.kt$"), true); + JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.GenerateTests", new File("idea/testData/jetPsiMatcher/expressions/call"), Pattern.compile("^(.+)\\.kt$"), true); } @TestMetadata("call1.kt") public void testCall1() throws Exception { - doTestExpressions("compiler/testData/psi/jetPsiMatcher/expressions/call/call1.kt"); + doTestExpressions("idea/testData/jetPsiMatcher/expressions/call/call1.kt"); } @TestMetadata("call2.kt") public void testCall2() throws Exception { - doTestExpressions("compiler/testData/psi/jetPsiMatcher/expressions/call/call2.kt"); + doTestExpressions("idea/testData/jetPsiMatcher/expressions/call/call2.kt"); } @TestMetadata("call3.kt") public void testCall3() throws Exception { - doTestExpressions("compiler/testData/psi/jetPsiMatcher/expressions/call/call3.kt"); + doTestExpressions("idea/testData/jetPsiMatcher/expressions/call/call3.kt"); } @TestMetadata("call4.kt") public void testCall4() throws Exception { - doTestExpressions("compiler/testData/psi/jetPsiMatcher/expressions/call/call4.kt"); + doTestExpressions("idea/testData/jetPsiMatcher/expressions/call/call4.kt"); } @TestMetadata("_call1.kt") public void test_call1() throws Exception { - doTestExpressions("compiler/testData/psi/jetPsiMatcher/expressions/call/_call1.kt"); + doTestExpressions("idea/testData/jetPsiMatcher/expressions/call/_call1.kt"); } @TestMetadata("_call2.kt") public void test_call2() throws Exception { - doTestExpressions("compiler/testData/psi/jetPsiMatcher/expressions/call/_call2.kt"); + doTestExpressions("idea/testData/jetPsiMatcher/expressions/call/_call2.kt"); } @TestMetadata("_call3.kt") public void test_call3() throws Exception { - doTestExpressions("compiler/testData/psi/jetPsiMatcher/expressions/call/_call3.kt"); + doTestExpressions("idea/testData/jetPsiMatcher/expressions/call/_call3.kt"); } @TestMetadata("_call4.kt") public void test_call4() throws Exception { - doTestExpressions("compiler/testData/psi/jetPsiMatcher/expressions/call/_call4.kt"); + doTestExpressions("idea/testData/jetPsiMatcher/expressions/call/_call4.kt"); } } - @TestMetadata("compiler/testData/psi/jetPsiMatcher/expressions/const") + @TestMetadata("idea/testData/jetPsiMatcher/expressions/const") public static class Const extends AbstractJetPsiMatcherTest { public void testAllFilesPresentInConst() throws Exception { - JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.GenerateTests", new File("compiler/testData/psi/jetPsiMatcher/expressions/const"), Pattern.compile("^(.+)\\.kt$"), true); + JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.GenerateTests", new File("idea/testData/jetPsiMatcher/expressions/const"), Pattern.compile("^(.+)\\.kt$"), true); } @TestMetadata("const.kt") public void testConst() throws Exception { - doTestExpressions("compiler/testData/psi/jetPsiMatcher/expressions/const/const.kt"); + doTestExpressions("idea/testData/jetPsiMatcher/expressions/const/const.kt"); } @TestMetadata("_const.kt") public void test_const() throws Exception { - doTestExpressions("compiler/testData/psi/jetPsiMatcher/expressions/const/_const.kt"); + doTestExpressions("idea/testData/jetPsiMatcher/expressions/const/_const.kt"); } } - @TestMetadata("compiler/testData/psi/jetPsiMatcher/expressions/misc") + @TestMetadata("idea/testData/jetPsiMatcher/expressions/misc") public static class Misc extends AbstractJetPsiMatcherTest { public void testAllFilesPresentInMisc() throws Exception { - JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.GenerateTests", new File("compiler/testData/psi/jetPsiMatcher/expressions/misc"), Pattern.compile("^(.+)\\.kt$"), true); + JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.GenerateTests", new File("idea/testData/jetPsiMatcher/expressions/misc"), Pattern.compile("^(.+)\\.kt$"), true); } @TestMetadata("misc1.kt") public void testMisc1() throws Exception { - doTestExpressions("compiler/testData/psi/jetPsiMatcher/expressions/misc/misc1.kt"); + doTestExpressions("idea/testData/jetPsiMatcher/expressions/misc/misc1.kt"); } @TestMetadata("misc2.kt") public void testMisc2() throws Exception { - doTestExpressions("compiler/testData/psi/jetPsiMatcher/expressions/misc/misc2.kt"); + doTestExpressions("idea/testData/jetPsiMatcher/expressions/misc/misc2.kt"); } @TestMetadata("misc3.kt") public void testMisc3() throws Exception { - doTestExpressions("compiler/testData/psi/jetPsiMatcher/expressions/misc/misc3.kt"); + doTestExpressions("idea/testData/jetPsiMatcher/expressions/misc/misc3.kt"); } @TestMetadata("_misc1.kt") public void test_misc1() throws Exception { - doTestExpressions("compiler/testData/psi/jetPsiMatcher/expressions/misc/_misc1.kt"); + doTestExpressions("idea/testData/jetPsiMatcher/expressions/misc/_misc1.kt"); } @TestMetadata("_misc2.kt") public void test_misc2() throws Exception { - doTestExpressions("compiler/testData/psi/jetPsiMatcher/expressions/misc/_misc2.kt"); + doTestExpressions("idea/testData/jetPsiMatcher/expressions/misc/_misc2.kt"); } @TestMetadata("_misc3.kt") public void test_misc3() throws Exception { - doTestExpressions("compiler/testData/psi/jetPsiMatcher/expressions/misc/_misc3.kt"); + doTestExpressions("idea/testData/jetPsiMatcher/expressions/misc/_misc3.kt"); } } - @TestMetadata("compiler/testData/psi/jetPsiMatcher/expressions/simpleName") + @TestMetadata("idea/testData/jetPsiMatcher/expressions/simpleName") public static class SimpleName extends AbstractJetPsiMatcherTest { public void testAllFilesPresentInSimpleName() throws Exception { - JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.GenerateTests", new File("compiler/testData/psi/jetPsiMatcher/expressions/simpleName"), Pattern.compile("^(.+)\\.kt$"), true); + JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.GenerateTests", new File("idea/testData/jetPsiMatcher/expressions/simpleName"), Pattern.compile("^(.+)\\.kt$"), true); } @TestMetadata("simpleName.kt") public void testSimpleName() throws Exception { - doTestExpressions("compiler/testData/psi/jetPsiMatcher/expressions/simpleName/simpleName.kt"); + doTestExpressions("idea/testData/jetPsiMatcher/expressions/simpleName/simpleName.kt"); } @TestMetadata("_simpleName.kt") public void test_simpleName() throws Exception { - doTestExpressions("compiler/testData/psi/jetPsiMatcher/expressions/simpleName/_simpleName.kt"); + doTestExpressions("idea/testData/jetPsiMatcher/expressions/simpleName/_simpleName.kt"); } } - @TestMetadata("compiler/testData/psi/jetPsiMatcher/expressions/super") + @TestMetadata("idea/testData/jetPsiMatcher/expressions/super") public static class Super extends AbstractJetPsiMatcherTest { public void testAllFilesPresentInSuper() throws Exception { - JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.GenerateTests", new File("compiler/testData/psi/jetPsiMatcher/expressions/super"), Pattern.compile("^(.+)\\.kt$"), true); + JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.GenerateTests", new File("idea/testData/jetPsiMatcher/expressions/super"), Pattern.compile("^(.+)\\.kt$"), true); } @TestMetadata("super1.kt") public void testSuper1() throws Exception { - doTestExpressions("compiler/testData/psi/jetPsiMatcher/expressions/super/super1.kt"); + doTestExpressions("idea/testData/jetPsiMatcher/expressions/super/super1.kt"); } @TestMetadata("super2.kt") public void testSuper2() throws Exception { - doTestExpressions("compiler/testData/psi/jetPsiMatcher/expressions/super/super2.kt"); + doTestExpressions("idea/testData/jetPsiMatcher/expressions/super/super2.kt"); } @TestMetadata("super3.kt") public void testSuper3() throws Exception { - doTestExpressions("compiler/testData/psi/jetPsiMatcher/expressions/super/super3.kt"); + doTestExpressions("idea/testData/jetPsiMatcher/expressions/super/super3.kt"); } @TestMetadata("super4.kt") public void testSuper4() throws Exception { - doTestExpressions("compiler/testData/psi/jetPsiMatcher/expressions/super/super4.kt"); + doTestExpressions("idea/testData/jetPsiMatcher/expressions/super/super4.kt"); } @TestMetadata("_super1.kt") public void test_super1() throws Exception { - doTestExpressions("compiler/testData/psi/jetPsiMatcher/expressions/super/_super1.kt"); + doTestExpressions("idea/testData/jetPsiMatcher/expressions/super/_super1.kt"); } @TestMetadata("_super2.kt") public void test_super2() throws Exception { - doTestExpressions("compiler/testData/psi/jetPsiMatcher/expressions/super/_super2.kt"); + doTestExpressions("idea/testData/jetPsiMatcher/expressions/super/_super2.kt"); } @TestMetadata("_super3.kt") public void test_super3() throws Exception { - doTestExpressions("compiler/testData/psi/jetPsiMatcher/expressions/super/_super3.kt"); + doTestExpressions("idea/testData/jetPsiMatcher/expressions/super/_super3.kt"); } @TestMetadata("_super4.kt") public void test_super4() throws Exception { - doTestExpressions("compiler/testData/psi/jetPsiMatcher/expressions/super/_super4.kt"); + doTestExpressions("idea/testData/jetPsiMatcher/expressions/super/_super4.kt"); } } - @TestMetadata("compiler/testData/psi/jetPsiMatcher/expressions/throw") + @TestMetadata("idea/testData/jetPsiMatcher/expressions/throw") public static class Throw extends AbstractJetPsiMatcherTest { public void testAllFilesPresentInThrow() throws Exception { - JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.GenerateTests", new File("compiler/testData/psi/jetPsiMatcher/expressions/throw"), Pattern.compile("^(.+)\\.kt$"), true); + JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.GenerateTests", new File("idea/testData/jetPsiMatcher/expressions/throw"), Pattern.compile("^(.+)\\.kt$"), true); } @TestMetadata("throw.kt") public void testThrow() throws Exception { - doTestExpressions("compiler/testData/psi/jetPsiMatcher/expressions/throw/throw.kt"); + doTestExpressions("idea/testData/jetPsiMatcher/expressions/throw/throw.kt"); } @TestMetadata("_throw.kt") public void test_throw() throws Exception { - doTestExpressions("compiler/testData/psi/jetPsiMatcher/expressions/throw/_throw.kt"); + doTestExpressions("idea/testData/jetPsiMatcher/expressions/throw/_throw.kt"); } } - @TestMetadata("compiler/testData/psi/jetPsiMatcher/expressions/unaryExpr") + @TestMetadata("idea/testData/jetPsiMatcher/expressions/unaryExpr") public static class UnaryExpr extends AbstractJetPsiMatcherTest { public void testAllFilesPresentInUnaryExpr() throws Exception { - JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.GenerateTests", new File("compiler/testData/psi/jetPsiMatcher/expressions/unaryExpr"), Pattern.compile("^(.+)\\.kt$"), true); + JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.GenerateTests", new File("idea/testData/jetPsiMatcher/expressions/unaryExpr"), Pattern.compile("^(.+)\\.kt$"), true); } @TestMetadata("unaryExpr1.kt") public void testUnaryExpr1() throws Exception { - doTestExpressions("compiler/testData/psi/jetPsiMatcher/expressions/unaryExpr/unaryExpr1.kt"); + doTestExpressions("idea/testData/jetPsiMatcher/expressions/unaryExpr/unaryExpr1.kt"); } @TestMetadata("unaryExpr2.kt") public void testUnaryExpr2() throws Exception { - doTestExpressions("compiler/testData/psi/jetPsiMatcher/expressions/unaryExpr/unaryExpr2.kt"); + doTestExpressions("idea/testData/jetPsiMatcher/expressions/unaryExpr/unaryExpr2.kt"); } @TestMetadata("_unaryExpr1.kt") public void test_unaryExpr1() throws Exception { - doTestExpressions("compiler/testData/psi/jetPsiMatcher/expressions/unaryExpr/_unaryExpr1.kt"); + doTestExpressions("idea/testData/jetPsiMatcher/expressions/unaryExpr/_unaryExpr1.kt"); } @TestMetadata("_unaryExpr2.kt") public void test_unaryExpr2() throws Exception { - doTestExpressions("compiler/testData/psi/jetPsiMatcher/expressions/unaryExpr/_unaryExpr2.kt"); + doTestExpressions("idea/testData/jetPsiMatcher/expressions/unaryExpr/_unaryExpr2.kt"); } @TestMetadata("_unaryExpr3.kt") public void test_unaryExpr3() throws Exception { - doTestExpressions("compiler/testData/psi/jetPsiMatcher/expressions/unaryExpr/_unaryExpr3.kt"); + doTestExpressions("idea/testData/jetPsiMatcher/expressions/unaryExpr/_unaryExpr3.kt"); } } From 3a2be3be01723b7a716f7744db5a6352e4b62b9a Mon Sep 17 00:00:00 2001 From: Alexey Sedunov Date: Wed, 29 May 2013 15:33:32 +0400 Subject: [PATCH 200/249] Fix functional type matching --- .../org/jetbrains/jet/plugin/util/JetPsiMatcher.java | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/idea/src/org/jetbrains/jet/plugin/util/JetPsiMatcher.java b/idea/src/org/jetbrains/jet/plugin/util/JetPsiMatcher.java index 1f5a669a5ff..da964464410 100644 --- a/idea/src/org/jetbrains/jet/plugin/util/JetPsiMatcher.java +++ b/idea/src/org/jetbrains/jet/plugin/util/JetPsiMatcher.java @@ -16,7 +16,6 @@ package org.jetbrains.jet.plugin.util; -import com.google.common.collect.Lists; import org.jetbrains.annotations.Nullable; import org.jetbrains.jet.lang.psi.*; @@ -62,6 +61,13 @@ public class JetPsiMatcher { } }; + private static final Predicate2 PARAMETER_TYPE_CHECKER = new Predicate2() { + @Override + public boolean apply(JetParameter param1, JetParameter param2) { + return checkElementMatch(param1.getTypeReference(), param2.getTypeReference()); + } + }; + private static boolean checkListMatch(List list1, List list2, Predicate2 checker) { int n = list1.size(); if (list2.size() != n) return false; @@ -205,7 +211,9 @@ public class JetPsiMatcher { public Boolean visitFunctionType(JetFunctionType type1, JetElement data) { JetFunctionType type2 = (JetFunctionType) data; - return checkListMatch(type1.getTypeArgumentsAsTypes(), type2.getTypeArgumentsAsTypes()); + return checkElementMatch(type1.getReceiverTypeRef(), type2.getReceiverTypeRef()) && + checkElementMatch(type1.getReturnTypeRef(), type2.getReturnTypeRef()) && + checkListMatch(type1.getParameters(), type2.getParameters(), PARAMETER_TYPE_CHECKER); } @Override From a2ee65e64ca87e0b4f2abfe1d1d356f9bbcf4500 Mon Sep 17 00:00:00 2001 From: Alexey Sedunov Date: Wed, 29 May 2013 15:33:53 +0400 Subject: [PATCH 201/249] Add type tests for JetPsiMatcher --- .../jet/generators/tests/GenerateTests.java | 3 +- .../jetPsiMatcher/types/_functional1.kt | 2 + .../jetPsiMatcher/types/_functional1.kt.2 | 1 + .../jetPsiMatcher/types/_functional2.kt | 2 + .../jetPsiMatcher/types/_functional2.kt.2 | 1 + .../jetPsiMatcher/types/_nullable1.kt | 2 + .../jetPsiMatcher/types/_nullable1.kt.2 | 1 + idea/testData/jetPsiMatcher/types/_user1.kt | 2 + idea/testData/jetPsiMatcher/types/_user1.kt.2 | 1 + idea/testData/jetPsiMatcher/types/_user2.kt | 2 + idea/testData/jetPsiMatcher/types/_user2.kt.2 | 1 + .../jetPsiMatcher/types/functional1.kt | 1 + .../jetPsiMatcher/types/functional1.kt.2 | 1 + .../jetPsiMatcher/types/functional2.kt | 1 + .../jetPsiMatcher/types/functional2.kt.2 | 1 + .../jetPsiMatcher/types/functional3.kt | 1 + .../jetPsiMatcher/types/functional3.kt.2 | 1 + .../testData/jetPsiMatcher/types/nullable1.kt | 1 + .../jetPsiMatcher/types/nullable1.kt.2 | 1 + idea/testData/jetPsiMatcher/types/user1.kt | 1 + idea/testData/jetPsiMatcher/types/user1.kt.2 | 1 + idea/testData/jetPsiMatcher/types/user2.kt | 1 + idea/testData/jetPsiMatcher/types/user2.kt.2 | 1 + .../jet/psi/AbstractJetPsiMatcherTest.java | 19 +++++ .../jetbrains/jet/psi/JetPsiMatcherTest.java | 72 +++++++++++++++++-- 25 files changed, 113 insertions(+), 8 deletions(-) create mode 100644 idea/testData/jetPsiMatcher/types/_functional1.kt create mode 100644 idea/testData/jetPsiMatcher/types/_functional1.kt.2 create mode 100644 idea/testData/jetPsiMatcher/types/_functional2.kt create mode 100644 idea/testData/jetPsiMatcher/types/_functional2.kt.2 create mode 100644 idea/testData/jetPsiMatcher/types/_nullable1.kt create mode 100644 idea/testData/jetPsiMatcher/types/_nullable1.kt.2 create mode 100644 idea/testData/jetPsiMatcher/types/_user1.kt create mode 100644 idea/testData/jetPsiMatcher/types/_user1.kt.2 create mode 100644 idea/testData/jetPsiMatcher/types/_user2.kt create mode 100644 idea/testData/jetPsiMatcher/types/_user2.kt.2 create mode 100644 idea/testData/jetPsiMatcher/types/functional1.kt create mode 100644 idea/testData/jetPsiMatcher/types/functional1.kt.2 create mode 100644 idea/testData/jetPsiMatcher/types/functional2.kt create mode 100644 idea/testData/jetPsiMatcher/types/functional2.kt.2 create mode 100644 idea/testData/jetPsiMatcher/types/functional3.kt create mode 100644 idea/testData/jetPsiMatcher/types/functional3.kt.2 create mode 100644 idea/testData/jetPsiMatcher/types/nullable1.kt create mode 100644 idea/testData/jetPsiMatcher/types/nullable1.kt.2 create mode 100644 idea/testData/jetPsiMatcher/types/user1.kt create mode 100644 idea/testData/jetPsiMatcher/types/user1.kt.2 create mode 100644 idea/testData/jetPsiMatcher/types/user2.kt create mode 100644 idea/testData/jetPsiMatcher/types/user2.kt.2 diff --git a/generators/org/jetbrains/jet/generators/tests/GenerateTests.java b/generators/org/jetbrains/jet/generators/tests/GenerateTests.java index 0b4e2b3d1f0..4971a06f9cf 100644 --- a/generators/org/jetbrains/jet/generators/tests/GenerateTests.java +++ b/generators/org/jetbrains/jet/generators/tests/GenerateTests.java @@ -216,7 +216,8 @@ public class GenerateTests { "idea/tests/", "JetPsiMatcherTest", AbstractJetPsiMatcherTest.class, - testModel("idea/testData/jetPsiMatcher", "doTestExpressions") + testModel("idea/testData/jetPsiMatcher/expressions", "doTestExpressions"), + testModel("idea/testData/jetPsiMatcher/types", "doTestTypes") ); generateTest( diff --git a/idea/testData/jetPsiMatcher/types/_functional1.kt b/idea/testData/jetPsiMatcher/types/_functional1.kt new file mode 100644 index 00000000000..f33284d37f3 --- /dev/null +++ b/idea/testData/jetPsiMatcher/types/_functional1.kt @@ -0,0 +1,2 @@ +// NOT_EQUAL +val x: (s: String, b: Boolean) -> Int \ No newline at end of file diff --git a/idea/testData/jetPsiMatcher/types/_functional1.kt.2 b/idea/testData/jetPsiMatcher/types/_functional1.kt.2 new file mode 100644 index 00000000000..38402488d77 --- /dev/null +++ b/idea/testData/jetPsiMatcher/types/_functional1.kt.2 @@ -0,0 +1 @@ +val x: (s: Boolean, b: String) -> Int \ No newline at end of file diff --git a/idea/testData/jetPsiMatcher/types/_functional2.kt b/idea/testData/jetPsiMatcher/types/_functional2.kt new file mode 100644 index 00000000000..10576c8c432 --- /dev/null +++ b/idea/testData/jetPsiMatcher/types/_functional2.kt @@ -0,0 +1,2 @@ +// NOT_EQUAL +val x: String.(b: Boolean) -> Int \ No newline at end of file diff --git a/idea/testData/jetPsiMatcher/types/_functional2.kt.2 b/idea/testData/jetPsiMatcher/types/_functional2.kt.2 new file mode 100644 index 00000000000..310f441f850 --- /dev/null +++ b/idea/testData/jetPsiMatcher/types/_functional2.kt.2 @@ -0,0 +1 @@ +val x: (s: String, b: Boolean) -> Int \ No newline at end of file diff --git a/idea/testData/jetPsiMatcher/types/_nullable1.kt b/idea/testData/jetPsiMatcher/types/_nullable1.kt new file mode 100644 index 00000000000..acb4730cc08 --- /dev/null +++ b/idea/testData/jetPsiMatcher/types/_nullable1.kt @@ -0,0 +1,2 @@ +// NOT_EQUAL +val x: String \ No newline at end of file diff --git a/idea/testData/jetPsiMatcher/types/_nullable1.kt.2 b/idea/testData/jetPsiMatcher/types/_nullable1.kt.2 new file mode 100644 index 00000000000..b43528c36f1 --- /dev/null +++ b/idea/testData/jetPsiMatcher/types/_nullable1.kt.2 @@ -0,0 +1 @@ +val x: String? \ No newline at end of file diff --git a/idea/testData/jetPsiMatcher/types/_user1.kt b/idea/testData/jetPsiMatcher/types/_user1.kt new file mode 100644 index 00000000000..d85c1b188ac --- /dev/null +++ b/idea/testData/jetPsiMatcher/types/_user1.kt @@ -0,0 +1,2 @@ +// NOT_EQUAL +val x: Map> \ No newline at end of file diff --git a/idea/testData/jetPsiMatcher/types/_user1.kt.2 b/idea/testData/jetPsiMatcher/types/_user1.kt.2 new file mode 100644 index 00000000000..eea5c86cdd2 --- /dev/null +++ b/idea/testData/jetPsiMatcher/types/_user1.kt.2 @@ -0,0 +1 @@ +val y: Map> \ No newline at end of file diff --git a/idea/testData/jetPsiMatcher/types/_user2.kt b/idea/testData/jetPsiMatcher/types/_user2.kt new file mode 100644 index 00000000000..797debd3543 --- /dev/null +++ b/idea/testData/jetPsiMatcher/types/_user2.kt @@ -0,0 +1,2 @@ +// NOT_EQUAL +val x: Collection \ No newline at end of file diff --git a/idea/testData/jetPsiMatcher/types/_user2.kt.2 b/idea/testData/jetPsiMatcher/types/_user2.kt.2 new file mode 100644 index 00000000000..6c8662b0250 --- /dev/null +++ b/idea/testData/jetPsiMatcher/types/_user2.kt.2 @@ -0,0 +1 @@ +val x: MutableCollection \ No newline at end of file diff --git a/idea/testData/jetPsiMatcher/types/functional1.kt b/idea/testData/jetPsiMatcher/types/functional1.kt new file mode 100644 index 00000000000..40071fe2b1c --- /dev/null +++ b/idea/testData/jetPsiMatcher/types/functional1.kt @@ -0,0 +1 @@ +val x: String -> Int \ No newline at end of file diff --git a/idea/testData/jetPsiMatcher/types/functional1.kt.2 b/idea/testData/jetPsiMatcher/types/functional1.kt.2 new file mode 100644 index 00000000000..799a25379cf --- /dev/null +++ b/idea/testData/jetPsiMatcher/types/functional1.kt.2 @@ -0,0 +1 @@ +val y: String -> Int \ No newline at end of file diff --git a/idea/testData/jetPsiMatcher/types/functional2.kt b/idea/testData/jetPsiMatcher/types/functional2.kt new file mode 100644 index 00000000000..310f441f850 --- /dev/null +++ b/idea/testData/jetPsiMatcher/types/functional2.kt @@ -0,0 +1 @@ +val x: (s: String, b: Boolean) -> Int \ No newline at end of file diff --git a/idea/testData/jetPsiMatcher/types/functional2.kt.2 b/idea/testData/jetPsiMatcher/types/functional2.kt.2 new file mode 100644 index 00000000000..004a1d24a98 --- /dev/null +++ b/idea/testData/jetPsiMatcher/types/functional2.kt.2 @@ -0,0 +1 @@ +val x: (x: String, y: Boolean) -> Int \ No newline at end of file diff --git a/idea/testData/jetPsiMatcher/types/functional3.kt b/idea/testData/jetPsiMatcher/types/functional3.kt new file mode 100644 index 00000000000..aac457e03f0 --- /dev/null +++ b/idea/testData/jetPsiMatcher/types/functional3.kt @@ -0,0 +1 @@ +val x: String.(b: Boolean) -> Int \ No newline at end of file diff --git a/idea/testData/jetPsiMatcher/types/functional3.kt.2 b/idea/testData/jetPsiMatcher/types/functional3.kt.2 new file mode 100644 index 00000000000..202b79b1e59 --- /dev/null +++ b/idea/testData/jetPsiMatcher/types/functional3.kt.2 @@ -0,0 +1 @@ +val x: String.(n: Boolean) -> Int \ No newline at end of file diff --git a/idea/testData/jetPsiMatcher/types/nullable1.kt b/idea/testData/jetPsiMatcher/types/nullable1.kt new file mode 100644 index 00000000000..b43528c36f1 --- /dev/null +++ b/idea/testData/jetPsiMatcher/types/nullable1.kt @@ -0,0 +1 @@ +val x: String? \ No newline at end of file diff --git a/idea/testData/jetPsiMatcher/types/nullable1.kt.2 b/idea/testData/jetPsiMatcher/types/nullable1.kt.2 new file mode 100644 index 00000000000..bb095c9d12d --- /dev/null +++ b/idea/testData/jetPsiMatcher/types/nullable1.kt.2 @@ -0,0 +1 @@ +val y: String? \ No newline at end of file diff --git a/idea/testData/jetPsiMatcher/types/user1.kt b/idea/testData/jetPsiMatcher/types/user1.kt new file mode 100644 index 00000000000..b15fdf0cf95 --- /dev/null +++ b/idea/testData/jetPsiMatcher/types/user1.kt @@ -0,0 +1 @@ +val x: Collection \ No newline at end of file diff --git a/idea/testData/jetPsiMatcher/types/user1.kt.2 b/idea/testData/jetPsiMatcher/types/user1.kt.2 new file mode 100644 index 00000000000..809fba40a0e --- /dev/null +++ b/idea/testData/jetPsiMatcher/types/user1.kt.2 @@ -0,0 +1 @@ +val y: Collection \ No newline at end of file diff --git a/idea/testData/jetPsiMatcher/types/user2.kt b/idea/testData/jetPsiMatcher/types/user2.kt new file mode 100644 index 00000000000..3715d26a30f --- /dev/null +++ b/idea/testData/jetPsiMatcher/types/user2.kt @@ -0,0 +1 @@ +val x: Map> \ No newline at end of file diff --git a/idea/testData/jetPsiMatcher/types/user2.kt.2 b/idea/testData/jetPsiMatcher/types/user2.kt.2 new file mode 100644 index 00000000000..95a905d3a30 --- /dev/null +++ b/idea/testData/jetPsiMatcher/types/user2.kt.2 @@ -0,0 +1 @@ +val y: Map> \ No newline at end of file diff --git a/idea/tests/org/jetbrains/jet/psi/AbstractJetPsiMatcherTest.java b/idea/tests/org/jetbrains/jet/psi/AbstractJetPsiMatcherTest.java index 912904ce789..cf35da9fa89 100644 --- a/idea/tests/org/jetbrains/jet/psi/AbstractJetPsiMatcherTest.java +++ b/idea/tests/org/jetbrains/jet/psi/AbstractJetPsiMatcherTest.java @@ -24,6 +24,7 @@ import org.jetbrains.jet.cli.jvm.compiler.JetCoreEnvironment; import org.jetbrains.jet.config.CompilerConfiguration; import org.jetbrains.jet.lang.psi.JetExpression; import org.jetbrains.jet.lang.psi.JetPsiFactory; +import org.jetbrains.jet.lang.psi.JetTypeReference; import org.jetbrains.jet.plugin.util.JetPsiMatcher; import java.io.File; @@ -44,6 +45,24 @@ public abstract class AbstractJetPsiMatcherTest extends JetLiteFixture { ); } + public void doTestTypes(@NotNull String path) throws Exception { + String fileText = FileUtil.loadFile(new File(path)); + String fileText2 = FileUtil.loadFile(new File(path + ".2")); + + boolean equalityExpected = InTextDirectivesUtils.findStringWithPrefixes(fileText, "// NOT_EQUAL") == null; + + JetTypeReference typeRef = JetPsiFactory.createProperty(getProject(), fileText).getTypeRef(); + JetTypeReference typeRef2 = JetPsiFactory.createProperty(getProject(), fileText2).getTypeRef(); + + assertNotNull(typeRef); + assertNotNull(typeRef2); + + assertTrue( + "JetPsiMatcher.checkElementMatch() should return " + equalityExpected, + equalityExpected == JetPsiMatcher.checkElementMatch(typeRef, typeRef2) + ); + } + @Override protected JetCoreEnvironment createEnvironment() { return new JetCoreEnvironment(getTestRootDisposable(), new CompilerConfiguration()); diff --git a/idea/tests/org/jetbrains/jet/psi/JetPsiMatcherTest.java b/idea/tests/org/jetbrains/jet/psi/JetPsiMatcherTest.java index 08c57f91d9b..c365371af18 100644 --- a/idea/tests/org/jetbrains/jet/psi/JetPsiMatcherTest.java +++ b/idea/tests/org/jetbrains/jet/psi/JetPsiMatcherTest.java @@ -30,13 +30,8 @@ import org.jetbrains.jet.psi.AbstractJetPsiMatcherTest; /** This class is generated by {@link org.jetbrains.jet.generators.tests.GenerateTests}. DO NOT MODIFY MANUALLY */ @SuppressWarnings("all") -@TestMetadata("idea/testData/jetPsiMatcher") -@InnerTestClasses({JetPsiMatcherTest.Expressions.class}) +@InnerTestClasses({JetPsiMatcherTest.Expressions.class, JetPsiMatcherTest.Types.class}) public class JetPsiMatcherTest extends AbstractJetPsiMatcherTest { - public void testAllFilesPresentInJetPsiMatcher() throws Exception { - JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.GenerateTests", new File("idea/testData/jetPsiMatcher"), Pattern.compile("^(.+)\\.kt$"), true); - } - @TestMetadata("idea/testData/jetPsiMatcher/expressions") @InnerTestClasses({Expressions.ArrayAccess.class, Expressions.BinaryExpr.class, Expressions.Call.class, Expressions.Const.class, Expressions.Misc.class, Expressions.SimpleName.class, Expressions.Super.class, Expressions.Throw.class, Expressions.UnaryExpr.class}) public static class Expressions extends AbstractJetPsiMatcherTest { @@ -377,10 +372,73 @@ public class JetPsiMatcherTest extends AbstractJetPsiMatcherTest { } } + @TestMetadata("idea/testData/jetPsiMatcher/types") + public static class Types extends AbstractJetPsiMatcherTest { + public void testAllFilesPresentInTypes() throws Exception { + JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.GenerateTests", new File("idea/testData/jetPsiMatcher/types"), Pattern.compile("^(.+)\\.kt$"), true); + } + + @TestMetadata("functional1.kt") + public void testFunctional1() throws Exception { + doTestTypes("idea/testData/jetPsiMatcher/types/functional1.kt"); + } + + @TestMetadata("functional2.kt") + public void testFunctional2() throws Exception { + doTestTypes("idea/testData/jetPsiMatcher/types/functional2.kt"); + } + + @TestMetadata("functional3.kt") + public void testFunctional3() throws Exception { + doTestTypes("idea/testData/jetPsiMatcher/types/functional3.kt"); + } + + @TestMetadata("nullable1.kt") + public void testNullable1() throws Exception { + doTestTypes("idea/testData/jetPsiMatcher/types/nullable1.kt"); + } + + @TestMetadata("user1.kt") + public void testUser1() throws Exception { + doTestTypes("idea/testData/jetPsiMatcher/types/user1.kt"); + } + + @TestMetadata("user2.kt") + public void testUser2() throws Exception { + doTestTypes("idea/testData/jetPsiMatcher/types/user2.kt"); + } + + @TestMetadata("_functional1.kt") + public void test_functional1() throws Exception { + doTestTypes("idea/testData/jetPsiMatcher/types/_functional1.kt"); + } + + @TestMetadata("_functional2.kt") + public void test_functional2() throws Exception { + doTestTypes("idea/testData/jetPsiMatcher/types/_functional2.kt"); + } + + @TestMetadata("_nullable1.kt") + public void test_nullable1() throws Exception { + doTestTypes("idea/testData/jetPsiMatcher/types/_nullable1.kt"); + } + + @TestMetadata("_user1.kt") + public void test_user1() throws Exception { + doTestTypes("idea/testData/jetPsiMatcher/types/_user1.kt"); + } + + @TestMetadata("_user2.kt") + public void test_user2() throws Exception { + doTestTypes("idea/testData/jetPsiMatcher/types/_user2.kt"); + } + + } + public static Test suite() { TestSuite suite = new TestSuite("JetPsiMatcherTest"); - suite.addTestSuite(JetPsiMatcherTest.class); suite.addTest(Expressions.innerSuite()); + suite.addTestSuite(Types.class); return suite; } } From 3a2e30152a97ac03e1d4019f112189c978dc2cd6 Mon Sep 17 00:00:00 2001 From: Alexey Sedunov Date: Fri, 31 May 2013 19:32:21 +0400 Subject: [PATCH 202/249] Improve parser recovery for list of value parameters/arguments --- .../lang/parsing/JetExpressionParsing.java | 126 +++++++++--------- .../jet/lang/parsing/JetParsing.java | 7 +- .../org/jetbrains/jet/lexer/JetTokens.java | 40 +++--- .../MissingCommaInValueArgumentList.kt | 5 + .../MissingCommaInValueArgumentList.txt | 32 +++++ .../MissingCommaInValueParameterList.kt | 7 + .../MissingCommaInValueParameterList.txt | 44 ++++++ 7 files changed, 176 insertions(+), 85 deletions(-) create mode 100644 compiler/testData/psi/recovery/MissingCommaInValueArgumentList.kt create mode 100644 compiler/testData/psi/recovery/MissingCommaInValueArgumentList.txt create mode 100644 compiler/testData/psi/recovery/MissingCommaInValueParameterList.kt create mode 100644 compiler/testData/psi/recovery/MissingCommaInValueParameterList.txt diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/parsing/JetExpressionParsing.java b/compiler/frontend/src/org/jetbrains/jet/lang/parsing/JetExpressionParsing.java index 1d2166f6e60..7fb709deed9 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/parsing/JetExpressionParsing.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/parsing/JetExpressionParsing.java @@ -53,7 +53,7 @@ public class JetExpressionParsing extends AbstractJetParsing { TRUE_KEYWORD, FALSE_KEYWORD, IS_KEYWORD, THROW_KEYWORD, RETURN_KEYWORD, BREAK_KEYWORD, CONTINUE_KEYWORD, OBJECT_KEYWORD, IF_KEYWORD, TRY_KEYWORD, ELSE_KEYWORD, WHILE_KEYWORD, DO_KEYWORD, WHEN_KEYWORD, RBRACKET, RBRACE, RPAR, PLUSPLUS, MINUSMINUS, EXCLEXCL, -// MUL, + // MUL, PLUS, MINUS, EXCL, DIV, PERC, LTEQ, // TODO GTEQ, foo=x EQEQEQ, EXCLEQEQEQ, EQEQ, EXCLEQ, ANDAND, OROR, SAFE_ACCESS, ELVIS, @@ -111,17 +111,17 @@ public class JetExpressionParsing extends AbstractJetParsing { ); private static final TokenSet STATEMENT_FIRST = TokenSet.orSet( - EXPRESSION_FIRST, - TokenSet.create( - // declaration - LBRACKET, // attribute - FUN_KEYWORD, - VAL_KEYWORD, VAR_KEYWORD, - TRAIT_KEYWORD, - CLASS_KEYWORD, - TYPE_KEYWORD - ), - MODIFIER_KEYWORDS + EXPRESSION_FIRST, + TokenSet.create( + // declaration + LBRACKET, // attribute + FUN_KEYWORD, + VAL_KEYWORD, VAR_KEYWORD, + TRAIT_KEYWORD, + CLASS_KEYWORD, + TYPE_KEYWORD + ), + MODIFIER_KEYWORDS ); /*package*/ static final TokenSet EXPRESSION_FOLLOW = TokenSet.create( @@ -174,7 +174,7 @@ public class JetExpressionParsing extends AbstractJetParsing { EQUALITY(EQEQ, EXCLEQ, EQEQEQ, EXCLEQEQEQ), CONJUNCTION(ANDAND), DISJUNCTION(OROR), -// ARROW(JetTokens.ARROW), + // ARROW(JetTokens.ARROW), ASSIGNMENT(EQ, PLUSEQ, MINUSEQ, MULTEQ, DIVEQ, PERCEQ), ; @@ -287,7 +287,7 @@ public class JetExpressionParsing extends AbstractJetParsing { * see the precedence table */ private void parseBinaryExpression(Precedence precedence) { -// System.out.println(precedence.name() + " at " + myBuilder.getTokenText()); + // System.out.println(precedence.name() + " at " + myBuilder.getTokenText()); PsiBuilder.Marker expression = mark(); @@ -300,7 +300,7 @@ public class JetExpressionParsing extends AbstractJetParsing { JetNodeType resultType = precedence.parseRightHandSide(operation, this); expression.done(resultType); - expression = expression.precede(); + expression = expression.precede(); } expression.drop(); @@ -310,7 +310,7 @@ public class JetExpressionParsing extends AbstractJetParsing { * operation? prefixExpression */ private void parsePrefixExpression() { -// System.out.println("pre at " + myBuilder.getTokenText()); + // System.out.println("pre at " + myBuilder.getTokenText()); if (at(LBRACKET)) { if (!parseLocalDeclaration()) { @@ -485,10 +485,10 @@ public class JetExpressionParsing extends AbstractJetParsing { */ protected boolean parseCallWithClosure() { boolean success = false; -// while (!myBuilder.newlineBeforeCurrentToken() -// && (at(LBRACE) + // while (!myBuilder.newlineBeforeCurrentToken() + // && (at(LBRACE) while ((at(LBRACE) - || atSet(LABELS) && lookahead(1) == LBRACE)) { + || atSet(LABELS) && lookahead(1) == LBRACE)) { if (!at(LBRACE)) { assert _atSet(LABELS); parsePrefixExpression(); @@ -520,7 +520,7 @@ public class JetExpressionParsing extends AbstractJetParsing { * ; */ private void parseAtomicExpression() { -// System.out.println("atom at " + myBuilder.getTokenText()); + // System.out.println("atom at " + myBuilder.getTokenText()); if (at(LPAR)) { parseParenthesizedExpression(); @@ -574,7 +574,7 @@ public class JetExpressionParsing extends AbstractJetParsing { parseDoWhile(); } else if (atSet(CLASS_KEYWORD, FUN_KEYWORD, VAL_KEYWORD, - VAR_KEYWORD, TYPE_KEYWORD)) { + VAR_KEYWORD, TYPE_KEYWORD)) { parseLocalDeclaration(); } else if (at(FIELD_IDENTIFIER)) { @@ -784,7 +784,7 @@ public class JetExpressionParsing extends AbstractJetParsing { if (!at(ARROW)) { errorUntil("Expecting '->'", TokenSet.create(ARROW, - RBRACE, EOL_OR_SEMICOLON)); + RBRACE, EOL_OR_SEMICOLON)); } if (at(ARROW)) { @@ -798,7 +798,7 @@ public class JetExpressionParsing extends AbstractJetParsing { } } else if (!atSet(WHEN_CONDITION_RECOVERY_SET)) { - errorAndAdvance("Expecting '->'"); + errorAndAdvance("Expecting '->'"); } } else { @@ -982,8 +982,8 @@ public class JetExpressionParsing extends AbstractJetParsing { parseFunctionLiteralParametersAndType(); paramsFound = preferParamsToExpressions ? - rollbackOrDrop(rollbackMarker, ARROW, "An -> is expected", RBRACE) : - rollbackOrDropAt(rollbackMarker, ARROW); + rollbackOrDrop(rollbackMarker, ARROW, "An -> is expected", RBRACE) : + rollbackOrDropAt(rollbackMarker, ARROW); } if (!paramsFound) { @@ -1047,8 +1047,8 @@ public class JetExpressionParsing extends AbstractJetParsing { } private boolean rollbackOrDrop(PsiBuilder.Marker rollbackMarker, - JetToken expected, String expectMessage, - IElementType validForDrop) { + JetToken expected, String expectMessage, + IElementType validForDrop) { if (at(expected)) { advance(); // dropAt rollbackMarker.drop(); @@ -1074,8 +1074,8 @@ public class JetExpressionParsing extends AbstractJetParsing { while (!eof()) { PsiBuilder.Marker parameter = mark(); -// int parameterNamePos = matchTokenStreamPredicate(new LastBefore(new At(IDENTIFIER), new AtOffset(doubleArrowPos))); -// createTruncatedBuilder(parameterNamePos).parseModifierList(MODIFIER_LIST, false); + // int parameterNamePos = matchTokenStreamPredicate(new LastBefore(new At(IDENTIFIER), new AtOffset(doubleArrowPos))); + // createTruncatedBuilder(parameterNamePos).parseModifierList(MODIFIER_LIST, false); expect(IDENTIFIER, "Expecting parameter name", TokenSet.create(ARROW)); @@ -1135,8 +1135,8 @@ public class JetExpressionParsing extends AbstractJetParsing { } return preferParamsToExpressions ? - rollbackOrDrop(rollbackMarker, ARROW, "An -> is expected", RBRACE) : - rollbackOrDropAt(rollbackMarker, ARROW); + rollbackOrDrop(rollbackMarker, ARROW, "An -> is expected", RBRACE) : + rollbackOrDropAt(rollbackMarker, ARROW); } private void parseFunctionLiteralParametersAndType() { @@ -1252,38 +1252,38 @@ public class JetExpressionParsing extends AbstractJetParsing { * ; */ private IElementType parseLocalDeclarationRest(boolean isEnum) { - IElementType keywordToken = tt(); - IElementType declType = null; - if (keywordToken == CLASS_KEYWORD || keywordToken == TRAIT_KEYWORD) { - declType = myJetParsing.parseClass(isEnum); - } - else if (keywordToken == FUN_KEYWORD) { - declType = myJetParsing.parseFunction(); - } - else if (keywordToken == VAL_KEYWORD || keywordToken == VAR_KEYWORD) { - declType = myJetParsing.parseProperty(true); - } - else if (keywordToken == TYPE_KEYWORD) { - declType = myJetParsing.parseTypeDef(); - } - else if (keywordToken == OBJECT_KEYWORD) { - // Object expression may appear at the statement position: should parse it - // as expression instead of object declaration - // sample: - // { - // object : Thread() { - // } - // } - IElementType lookahead = lookahead(1); - if (lookahead == COLON || lookahead == LBRACE) { - return null; - } - - myJetParsing.parseObject(true, true); - declType = OBJECT_DECLARATION; - } - return declType; - } + IElementType keywordToken = tt(); + IElementType declType = null; + if (keywordToken == CLASS_KEYWORD || keywordToken == TRAIT_KEYWORD) { + declType = myJetParsing.parseClass(isEnum); + } + else if (keywordToken == FUN_KEYWORD) { + declType = myJetParsing.parseFunction(); + } + else if (keywordToken == VAL_KEYWORD || keywordToken == VAR_KEYWORD) { + declType = myJetParsing.parseProperty(true); + } + else if (keywordToken == TYPE_KEYWORD) { + declType = myJetParsing.parseTypeDef(); + } + else if (keywordToken == OBJECT_KEYWORD) { + // Object expression may appear at the statement position: should parse it + // as expression instead of object declaration + // sample: + // { + // object : Thread() { + // } + // } + IElementType lookahead = lookahead(1); + if (lookahead == COLON || lookahead == LBRACE) { + return null; + } + + myJetParsing.parseObject(true, true); + declType = OBJECT_DECLARATION; + } + return declType; + } /* * doWhile 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 dd519065f11..a56cd115ef9 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/parsing/JetParsing.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/parsing/JetParsing.java @@ -50,6 +50,7 @@ public class JetParsing extends AbstractJetParsing { private static final TokenSet IMPORT_RECOVERY_SET = TokenSet.create(AS_KEYWORD, DOT, EOL_OR_SEMICOLON); /*package*/ static final TokenSet TYPE_REF_FIRST = TokenSet.create(LBRACKET, IDENTIFIER, FUN_KEYWORD, LPAR, CAPITALIZED_THIS_KEYWORD, HASH); private static final TokenSet RECEIVER_TYPE_TERMINATORS = TokenSet.create(DOT, SAFE_ACCESS); + private static final TokenSet VALUE_PARAMETER_FIRST = TokenSet.orSet(TokenSet.create(IDENTIFIER, LBRACKET), MODIFIER_KEYWORDS); static JetParsing createForTopLevel(SemanticWhitespaceAwarePsiBuilder builder) { JetParsing jetParsing = new JetParsing(builder); @@ -1722,8 +1723,10 @@ public class JetParsing extends AbstractJetParsing { else { parseValueParameter(); } - if (!at(COMMA)) break; - advance(); // COMMA + if (at(COMMA)) { + advance(); // COMMA + } + else if (!atSet(VALUE_PARAMETER_FIRST)) break; } } } diff --git a/compiler/frontend/src/org/jetbrains/jet/lexer/JetTokens.java b/compiler/frontend/src/org/jetbrains/jet/lexer/JetTokens.java index 6407280a4a1..0477cd27a1d 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lexer/JetTokens.java +++ b/compiler/frontend/src/org/jetbrains/jet/lexer/JetTokens.java @@ -114,7 +114,7 @@ public interface JetTokens { JetToken SAFE_ACCESS = new JetToken("SAFE_ACCESS"); JetToken ELVIS = new JetToken("ELVIS"); // JetToken MAP = new JetToken("MAP"); -// JetToken FILTER = new JetToken("FILTER"); + // JetToken FILTER = new JetToken("FILTER"); JetToken QUEST = new JetToken("QUEST"); JetToken COLONCOLON = new JetToken("COLONCOLON"); JetToken COLON = new JetToken("COLON"); @@ -131,7 +131,7 @@ public interface JetTokens { JetToken HASH = new JetToken("HASH"); JetToken AT = new JetToken("AT"); JetToken ATAT = new JetToken("ATAT"); - + JetToken IDE_TEMPLATE_START = new JetToken("IDE_TEMPLATE_START"); JetToken IDE_TEMPLATE_END = new JetToken("IDE_TEMPLATE_END"); @@ -165,23 +165,23 @@ public interface JetTokens { JetKeywordToken FINAL_KEYWORD = JetKeywordToken.softKeyword("final"); TokenSet KEYWORDS = TokenSet.create(PACKAGE_KEYWORD, AS_KEYWORD, TYPE_KEYWORD, CLASS_KEYWORD, TRAIT_KEYWORD, - THIS_KEYWORD, SUPER_KEYWORD, VAL_KEYWORD, VAR_KEYWORD, FUN_KEYWORD, FOR_KEYWORD, - NULL_KEYWORD, - TRUE_KEYWORD, FALSE_KEYWORD, IS_KEYWORD, - IN_KEYWORD, THROW_KEYWORD, RETURN_KEYWORD, BREAK_KEYWORD, CONTINUE_KEYWORD, OBJECT_KEYWORD, IF_KEYWORD, - ELSE_KEYWORD, WHILE_KEYWORD, DO_KEYWORD, TRY_KEYWORD, WHEN_KEYWORD, - NOT_IN, NOT_IS, CAPITALIZED_THIS_KEYWORD, AS_SAFE + THIS_KEYWORD, SUPER_KEYWORD, VAL_KEYWORD, VAR_KEYWORD, FUN_KEYWORD, FOR_KEYWORD, + NULL_KEYWORD, + TRUE_KEYWORD, FALSE_KEYWORD, IS_KEYWORD, + IN_KEYWORD, THROW_KEYWORD, RETURN_KEYWORD, BREAK_KEYWORD, CONTINUE_KEYWORD, OBJECT_KEYWORD, IF_KEYWORD, + ELSE_KEYWORD, WHILE_KEYWORD, DO_KEYWORD, TRY_KEYWORD, WHEN_KEYWORD, + NOT_IN, NOT_IS, CAPITALIZED_THIS_KEYWORD, AS_SAFE ); TokenSet SOFT_KEYWORDS = TokenSet.create(IMPORT_KEYWORD, WHERE_KEYWORD, BY_KEYWORD, GET_KEYWORD, - SET_KEYWORD, ABSTRACT_KEYWORD, ENUM_KEYWORD, OPEN_KEYWORD, INNER_KEYWORD, ANNOTATION_KEYWORD, - OVERRIDE_KEYWORD, PRIVATE_KEYWORD, PUBLIC_KEYWORD, INTERNAL_KEYWORD, PROTECTED_KEYWORD, - CATCH_KEYWORD, FINALLY_KEYWORD, OUT_KEYWORD, FINAL_KEYWORD, VARARG_KEYWORD, INLINE_KEYWORD, REIFIED_KEYWORD + SET_KEYWORD, ABSTRACT_KEYWORD, ENUM_KEYWORD, OPEN_KEYWORD, INNER_KEYWORD, ANNOTATION_KEYWORD, + OVERRIDE_KEYWORD, PRIVATE_KEYWORD, PUBLIC_KEYWORD, INTERNAL_KEYWORD, PROTECTED_KEYWORD, + CATCH_KEYWORD, FINALLY_KEYWORD, OUT_KEYWORD, FINAL_KEYWORD, VARARG_KEYWORD, INLINE_KEYWORD, REIFIED_KEYWORD ); TokenSet MODIFIER_KEYWORDS = TokenSet.create(ABSTRACT_KEYWORD, ENUM_KEYWORD, - OPEN_KEYWORD, INNER_KEYWORD, ANNOTATION_KEYWORD, OVERRIDE_KEYWORD, PRIVATE_KEYWORD, PUBLIC_KEYWORD, INTERNAL_KEYWORD, - PROTECTED_KEYWORD, OUT_KEYWORD, IN_KEYWORD, FINAL_KEYWORD, VARARG_KEYWORD, INLINE_KEYWORD, REIFIED_KEYWORD + OPEN_KEYWORD, INNER_KEYWORD, ANNOTATION_KEYWORD, OVERRIDE_KEYWORD, PRIVATE_KEYWORD, PUBLIC_KEYWORD, INTERNAL_KEYWORD, + PROTECTED_KEYWORD, OUT_KEYWORD, IN_KEYWORD, FINAL_KEYWORD, VARARG_KEYWORD, INLINE_KEYWORD, REIFIED_KEYWORD ); TokenSet WHITESPACES = TokenSet.create(TokenType.WHITE_SPACE); @@ -196,13 +196,13 @@ public interface JetTokens { TokenSet STRINGS = TokenSet.create(CHARACTER_LITERAL, REGULAR_STRING_PART); TokenSet OPERATIONS = TokenSet.create(AS_KEYWORD, AS_SAFE, IS_KEYWORD, IN_KEYWORD, DOT, PLUSPLUS, MINUSMINUS, EXCLEXCL, MUL, PLUS, - MINUS, EXCL, DIV, PERC, LT, GT, LTEQ, GTEQ, EQEQEQ, EXCLEQEQEQ, EQEQ, EXCLEQ, ANDAND, OROR, - SAFE_ACCESS, ELVIS, -// MAP, FILTER, - COLON, - RANGE, EQ, MULTEQ, DIVEQ, PERCEQ, PLUSEQ, MINUSEQ, - NOT_IN, NOT_IS, - IDENTIFIER, LABEL_IDENTIFIER, ATAT, AT); + MINUS, EXCL, DIV, PERC, LT, GT, LTEQ, GTEQ, EQEQEQ, EXCLEQEQEQ, EQEQ, EXCLEQ, ANDAND, OROR, + SAFE_ACCESS, ELVIS, + // MAP, FILTER, + COLON, + RANGE, EQ, MULTEQ, DIVEQ, PERCEQ, PLUSEQ, MINUSEQ, + NOT_IN, NOT_IS, + IDENTIFIER, LABEL_IDENTIFIER, ATAT, AT); TokenSet AUGMENTED_ASSIGNMENTS = TokenSet.create(PLUSEQ, MINUSEQ, MULTEQ, PERCEQ, DIVEQ); TokenSet ALL_ASSIGNMENTS = TokenSet.create(EQ, PLUSEQ, MINUSEQ, MULTEQ, PERCEQ, DIVEQ); diff --git a/compiler/testData/psi/recovery/MissingCommaInValueArgumentList.kt b/compiler/testData/psi/recovery/MissingCommaInValueArgumentList.kt new file mode 100644 index 00000000000..38256a1b0e6 --- /dev/null +++ b/compiler/testData/psi/recovery/MissingCommaInValueArgumentList.kt @@ -0,0 +1,5 @@ +val x = foo( + a, + b + c +) \ No newline at end of file diff --git a/compiler/testData/psi/recovery/MissingCommaInValueArgumentList.txt b/compiler/testData/psi/recovery/MissingCommaInValueArgumentList.txt new file mode 100644 index 00000000000..76cd7f04939 --- /dev/null +++ b/compiler/testData/psi/recovery/MissingCommaInValueArgumentList.txt @@ -0,0 +1,32 @@ +JetFile: MissingCommaInValueArgumentList.kt + NAMESPACE_HEADER + + PROPERTY + PsiElement(val)('val') + PsiWhiteSpace(' ') + PsiElement(IDENTIFIER)('x') + PsiWhiteSpace(' ') + PsiElement(EQ)('=') + PsiWhiteSpace(' ') + CALL_EXPRESSION + REFERENCE_EXPRESSION + PsiElement(IDENTIFIER)('foo') + VALUE_ARGUMENT_LIST + PsiElement(LPAR)('(') + PsiWhiteSpace('\n ') + VALUE_ARGUMENT + REFERENCE_EXPRESSION + PsiElement(IDENTIFIER)('a') + PsiElement(COMMA)(',') + PsiWhiteSpace('\n ') + VALUE_ARGUMENT + BINARY_EXPRESSION + REFERENCE_EXPRESSION + PsiElement(IDENTIFIER)('b') + PsiWhiteSpace('\n ') + OPERATION_REFERENCE + PsiElement(IDENTIFIER)('c') + PsiErrorElement:Expecting an element + + PsiWhiteSpace('\n') + PsiElement(RPAR)(')') \ No newline at end of file diff --git a/compiler/testData/psi/recovery/MissingCommaInValueParameterList.kt b/compiler/testData/psi/recovery/MissingCommaInValueParameterList.kt new file mode 100644 index 00000000000..88e4a6d115a --- /dev/null +++ b/compiler/testData/psi/recovery/MissingCommaInValueParameterList.kt @@ -0,0 +1,7 @@ +fun foo( + a: Any, + b: Int + c: String +) { + +} \ No newline at end of file diff --git a/compiler/testData/psi/recovery/MissingCommaInValueParameterList.txt b/compiler/testData/psi/recovery/MissingCommaInValueParameterList.txt new file mode 100644 index 00000000000..6d69387549b --- /dev/null +++ b/compiler/testData/psi/recovery/MissingCommaInValueParameterList.txt @@ -0,0 +1,44 @@ +JetFile: MissingCommaInValueParameterList.kt + NAMESPACE_HEADER + + FUN + PsiElement(fun)('fun') + PsiWhiteSpace(' ') + PsiElement(IDENTIFIER)('foo') + VALUE_PARAMETER_LIST + PsiElement(LPAR)('(') + PsiWhiteSpace('\n ') + VALUE_PARAMETER + PsiElement(IDENTIFIER)('a') + PsiElement(COLON)(':') + PsiWhiteSpace(' ') + TYPE_REFERENCE + USER_TYPE + REFERENCE_EXPRESSION + PsiElement(IDENTIFIER)('Any') + PsiElement(COMMA)(',') + PsiWhiteSpace('\n ') + VALUE_PARAMETER + PsiElement(IDENTIFIER)('b') + PsiElement(COLON)(':') + PsiWhiteSpace(' ') + TYPE_REFERENCE + USER_TYPE + REFERENCE_EXPRESSION + PsiElement(IDENTIFIER)('Int') + PsiWhiteSpace('\n ') + VALUE_PARAMETER + PsiElement(IDENTIFIER)('c') + PsiElement(COLON)(':') + PsiWhiteSpace(' ') + TYPE_REFERENCE + USER_TYPE + REFERENCE_EXPRESSION + PsiElement(IDENTIFIER)('String') + PsiWhiteSpace('\n') + PsiElement(RPAR)(')') + PsiWhiteSpace(' ') + BLOCK + PsiElement(LBRACE)('{') + PsiWhiteSpace('\n\n') + PsiElement(RBRACE)('}') \ No newline at end of file From fe8891299b6b2c09c2e7169e281136077b00ee0f Mon Sep 17 00:00:00 2001 From: Alexey Sedunov Date: Wed, 29 May 2013 13:11:46 +0400 Subject: [PATCH 203/249] Implement "move class-level declaration up/down" action handler --- .../jet/lang/psi/JetClassInitializer.java | 10 + .../jet/lang/psi/JetClassObject.java | 7 + .../jet/generators/tests/GenerateTests.java | 8 + idea/src/META-INF/plugin.xml | 4 + .../upDownMover/AbstractJetUpDownMover.java | 63 +++ .../upDownMover/JetDeclarationMover.java | 263 ++++++++++ .../accessors/accessor1.kt | 6 + .../accessors/accessor2.kt | 6 + .../accessors/accessor3.kt | 8 + .../accessors/accessor3.kt.after | 8 + .../accessors/accessor4.kt | 8 + .../accessors/accessor4.kt.after | 8 + .../class/classAtBrace1.kt | 8 + .../class/classAtBrace1.kt.after | 8 + .../class/classAtBrace2.kt | 8 + .../class/classAtBrace2.kt.after | 8 + .../class/classAtBrace3.kt | 8 + .../class/classAtBrace3.kt.after | 8 + .../class/classAtBrace4.kt | 8 + .../class/classAtBrace4.kt.after | 8 + .../class/classAtBrace5.kt | 9 + .../class/classAtBrace6.kt | 9 + .../class/classAtClass1.kt | 9 + .../class/classAtClass1.kt.after | 9 + .../class/classAtClass2.kt | 9 + .../class/classAtClass2.kt.after | 9 + .../class/classAtClassInitializer1.kt | 9 + .../class/classAtClassInitializer1.kt.after | 9 + .../class/classAtClassInitializer2.kt | 9 + .../class/classAtClassInitializer2.kt.after | 9 + .../class/classAtEmptyLine1.kt | 8 + .../class/classAtEmptyLine1.kt.after | 8 + .../class/classAtEmptyLine2.kt | 8 + .../class/classAtEmptyLine2.kt.after | 8 + .../class/classAtFunction1.kt | 9 + .../class/classAtFunction1.kt.after | 9 + .../class/classAtFunction2.kt | 9 + .../class/classAtFunction2.kt.after | 9 + .../class/classAtProperty1.kt | 7 + .../class/classAtProperty1.kt.after | 7 + .../class/classAtProperty2.kt | 7 + .../class/classAtProperty2.kt.after | 7 + .../classInitializerAtBrace1.kt | 7 + .../classInitializerAtBrace2.kt | 7 + .../classInitializerAtClass1.kt | 9 + .../classInitializerAtClass1.kt.after | 9 + .../classInitializerAtClass2.kt | 9 + .../classInitializerAtClass2.kt.after | 9 + .../classInitializerAtClassInitializer1.kt | 9 + ...assInitializerAtClassInitializer1.kt.after | 9 + .../classInitializerAtClassInitializer2.kt | 9 + ...assInitializerAtClassInitializer2.kt.after | 9 + .../classInitializerAtEmptyLine1.kt | 8 + .../classInitializerAtEmptyLine1.kt.after | 8 + .../classInitializerAtEmptyLine2.kt | 8 + .../classInitializerAtEmptyLine2.kt.after | 8 + .../classInitializerAtFunction1.kt | 9 + .../classInitializerAtFunction1.kt.after | 9 + .../classInitializerAtFunction2.kt | 9 + .../classInitializerAtFunction2.kt.after | 9 + .../classInitializerAtProperty1.kt | 7 + .../classInitializerAtProperty1.kt.after | 7 + .../classInitializerAtProperty2.kt | 7 + .../classInitializerAtProperty2.kt.after | 7 + .../classBodyDeclarations/enums/enum1.kt | 7 + .../enums/enum1.kt.after | 7 + .../classBodyDeclarations/enums/enum2.kt | 8 + .../classBodyDeclarations/enums/enum3.kt | 8 + .../classBodyDeclarations/enums/enum4.kt | 7 + .../enums/enum4.kt.after | 7 + .../classBodyDeclarations/enums/enum5.kt | 10 + .../enums/enum5.kt.after | 10 + .../classBodyDeclarations/enums/enum6.kt | 10 + .../enums/enum6.kt.after | 10 + .../function/functionAtBrace1.kt | 8 + .../function/functionAtBrace1.kt.after | 8 + .../function/functionAtBrace2.kt | 8 + .../function/functionAtBrace2.kt.after | 8 + .../function/functionAtBrace3.kt | 8 + .../function/functionAtBrace3.kt.after | 8 + .../function/functionAtBrace4.kt | 8 + .../function/functionAtBrace4.kt.after | 8 + .../function/functionAtBrace5.kt | 9 + .../function/functionAtBrace6.kt | 9 + .../function/functionAtClass1.kt | 9 + .../function/functionAtClass1.kt.after | 9 + .../function/functionAtClass2.kt | 9 + .../function/functionAtClass2.kt.after | 9 + .../function/functionAtClassInitializer1.kt | 9 + .../functionAtClassInitializer1.kt.after | 9 + .../function/functionAtClassInitializer2.kt | 9 + .../functionAtClassInitializer2.kt.after | 9 + .../function/functionAtEmptyLine1.kt | 8 + .../function/functionAtEmptyLine1.kt.after | 8 + .../function/functionAtEmptyLine2.kt | 8 + .../function/functionAtEmptyLine2.kt.after | 8 + .../function/functionAtFunction1.kt | 9 + .../function/functionAtFunction1.kt.after | 9 + .../function/functionAtFunction2.kt | 9 + .../function/functionAtFunction2.kt.after | 9 + .../function/functionAtProperty1.kt | 7 + .../function/functionAtProperty1.kt.after | 7 + .../function/functionAtProperty2.kt | 7 + .../function/functionAtProperty2.kt.after | 7 + .../property/propertyAtBrace1.kt | 6 + .../property/propertyAtBrace1.kt.after | 6 + .../property/propertyAtBrace2.kt | 6 + .../property/propertyAtBrace2.kt.after | 6 + .../property/propertyAtBrace3.kt | 6 + .../property/propertyAtBrace3.kt.after | 6 + .../property/propertyAtBrace4.kt | 6 + .../property/propertyAtBrace4.kt.after | 6 + .../property/propertyAtBrace5.kt | 7 + .../property/propertyAtBrace6.kt | 7 + .../property/propertyAtClass1.kt | 7 + .../property/propertyAtClass1.kt.after | 7 + .../property/propertyAtClass2.kt | 7 + .../property/propertyAtClass2.kt.after | 7 + .../property/propertyAtClassInitializer1.kt | 7 + .../propertyAtClassInitializer1.kt.after | 7 + .../property/propertyAtClassInitializer2.kt | 7 + .../propertyAtClassInitializer2.kt.after | 7 + .../property/propertyAtEmptyLine1.kt | 6 + .../property/propertyAtEmptyLine1.kt.after | 6 + .../property/propertyAtEmptyLine2.kt | 6 + .../property/propertyAtEmptyLine2.kt.after | 6 + .../property/propertyAtFunction1.kt | 7 + .../property/propertyAtFunction1.kt.after | 7 + .../property/propertyAtFunction2.kt | 7 + .../property/propertyAtFunction2.kt.after | 7 + .../property/propertyAtProperty1.kt | 5 + .../property/propertyAtProperty1.kt.after | 5 + .../property/propertyAtProperty2.kt | 5 + .../property/propertyAtProperty2.kt.after | 5 + .../moveUpDown/AbstractCodeMoverTest.java | 87 ++++ .../moveUpDown/CodeMoverTestGenerated.java | 458 ++++++++++++++++++ 136 files changed, 1900 insertions(+) create mode 100644 idea/src/org/jetbrains/jet/plugin/codeInsight/upDownMover/AbstractJetUpDownMover.java create mode 100644 idea/src/org/jetbrains/jet/plugin/codeInsight/upDownMover/JetDeclarationMover.java create mode 100644 idea/testData/codeInsight/moveUpDown/classBodyDeclarations/accessors/accessor1.kt create mode 100644 idea/testData/codeInsight/moveUpDown/classBodyDeclarations/accessors/accessor2.kt create mode 100644 idea/testData/codeInsight/moveUpDown/classBodyDeclarations/accessors/accessor3.kt create mode 100644 idea/testData/codeInsight/moveUpDown/classBodyDeclarations/accessors/accessor3.kt.after create mode 100644 idea/testData/codeInsight/moveUpDown/classBodyDeclarations/accessors/accessor4.kt create mode 100644 idea/testData/codeInsight/moveUpDown/classBodyDeclarations/accessors/accessor4.kt.after create mode 100644 idea/testData/codeInsight/moveUpDown/classBodyDeclarations/class/classAtBrace1.kt create mode 100644 idea/testData/codeInsight/moveUpDown/classBodyDeclarations/class/classAtBrace1.kt.after create mode 100644 idea/testData/codeInsight/moveUpDown/classBodyDeclarations/class/classAtBrace2.kt create mode 100644 idea/testData/codeInsight/moveUpDown/classBodyDeclarations/class/classAtBrace2.kt.after create mode 100644 idea/testData/codeInsight/moveUpDown/classBodyDeclarations/class/classAtBrace3.kt create mode 100644 idea/testData/codeInsight/moveUpDown/classBodyDeclarations/class/classAtBrace3.kt.after create mode 100644 idea/testData/codeInsight/moveUpDown/classBodyDeclarations/class/classAtBrace4.kt create mode 100644 idea/testData/codeInsight/moveUpDown/classBodyDeclarations/class/classAtBrace4.kt.after create mode 100644 idea/testData/codeInsight/moveUpDown/classBodyDeclarations/class/classAtBrace5.kt create mode 100644 idea/testData/codeInsight/moveUpDown/classBodyDeclarations/class/classAtBrace6.kt create mode 100644 idea/testData/codeInsight/moveUpDown/classBodyDeclarations/class/classAtClass1.kt create mode 100644 idea/testData/codeInsight/moveUpDown/classBodyDeclarations/class/classAtClass1.kt.after create mode 100644 idea/testData/codeInsight/moveUpDown/classBodyDeclarations/class/classAtClass2.kt create mode 100644 idea/testData/codeInsight/moveUpDown/classBodyDeclarations/class/classAtClass2.kt.after create mode 100644 idea/testData/codeInsight/moveUpDown/classBodyDeclarations/class/classAtClassInitializer1.kt create mode 100644 idea/testData/codeInsight/moveUpDown/classBodyDeclarations/class/classAtClassInitializer1.kt.after create mode 100644 idea/testData/codeInsight/moveUpDown/classBodyDeclarations/class/classAtClassInitializer2.kt create mode 100644 idea/testData/codeInsight/moveUpDown/classBodyDeclarations/class/classAtClassInitializer2.kt.after create mode 100644 idea/testData/codeInsight/moveUpDown/classBodyDeclarations/class/classAtEmptyLine1.kt create mode 100644 idea/testData/codeInsight/moveUpDown/classBodyDeclarations/class/classAtEmptyLine1.kt.after create mode 100644 idea/testData/codeInsight/moveUpDown/classBodyDeclarations/class/classAtEmptyLine2.kt create mode 100644 idea/testData/codeInsight/moveUpDown/classBodyDeclarations/class/classAtEmptyLine2.kt.after create mode 100644 idea/testData/codeInsight/moveUpDown/classBodyDeclarations/class/classAtFunction1.kt create mode 100644 idea/testData/codeInsight/moveUpDown/classBodyDeclarations/class/classAtFunction1.kt.after create mode 100644 idea/testData/codeInsight/moveUpDown/classBodyDeclarations/class/classAtFunction2.kt create mode 100644 idea/testData/codeInsight/moveUpDown/classBodyDeclarations/class/classAtFunction2.kt.after create mode 100644 idea/testData/codeInsight/moveUpDown/classBodyDeclarations/class/classAtProperty1.kt create mode 100644 idea/testData/codeInsight/moveUpDown/classBodyDeclarations/class/classAtProperty1.kt.after create mode 100644 idea/testData/codeInsight/moveUpDown/classBodyDeclarations/class/classAtProperty2.kt create mode 100644 idea/testData/codeInsight/moveUpDown/classBodyDeclarations/class/classAtProperty2.kt.after create mode 100644 idea/testData/codeInsight/moveUpDown/classBodyDeclarations/classInitializer/classInitializerAtBrace1.kt create mode 100644 idea/testData/codeInsight/moveUpDown/classBodyDeclarations/classInitializer/classInitializerAtBrace2.kt create mode 100644 idea/testData/codeInsight/moveUpDown/classBodyDeclarations/classInitializer/classInitializerAtClass1.kt create mode 100644 idea/testData/codeInsight/moveUpDown/classBodyDeclarations/classInitializer/classInitializerAtClass1.kt.after create mode 100644 idea/testData/codeInsight/moveUpDown/classBodyDeclarations/classInitializer/classInitializerAtClass2.kt create mode 100644 idea/testData/codeInsight/moveUpDown/classBodyDeclarations/classInitializer/classInitializerAtClass2.kt.after create mode 100644 idea/testData/codeInsight/moveUpDown/classBodyDeclarations/classInitializer/classInitializerAtClassInitializer1.kt create mode 100644 idea/testData/codeInsight/moveUpDown/classBodyDeclarations/classInitializer/classInitializerAtClassInitializer1.kt.after create mode 100644 idea/testData/codeInsight/moveUpDown/classBodyDeclarations/classInitializer/classInitializerAtClassInitializer2.kt create mode 100644 idea/testData/codeInsight/moveUpDown/classBodyDeclarations/classInitializer/classInitializerAtClassInitializer2.kt.after create mode 100644 idea/testData/codeInsight/moveUpDown/classBodyDeclarations/classInitializer/classInitializerAtEmptyLine1.kt create mode 100644 idea/testData/codeInsight/moveUpDown/classBodyDeclarations/classInitializer/classInitializerAtEmptyLine1.kt.after create mode 100644 idea/testData/codeInsight/moveUpDown/classBodyDeclarations/classInitializer/classInitializerAtEmptyLine2.kt create mode 100644 idea/testData/codeInsight/moveUpDown/classBodyDeclarations/classInitializer/classInitializerAtEmptyLine2.kt.after create mode 100644 idea/testData/codeInsight/moveUpDown/classBodyDeclarations/classInitializer/classInitializerAtFunction1.kt create mode 100644 idea/testData/codeInsight/moveUpDown/classBodyDeclarations/classInitializer/classInitializerAtFunction1.kt.after create mode 100644 idea/testData/codeInsight/moveUpDown/classBodyDeclarations/classInitializer/classInitializerAtFunction2.kt create mode 100644 idea/testData/codeInsight/moveUpDown/classBodyDeclarations/classInitializer/classInitializerAtFunction2.kt.after create mode 100644 idea/testData/codeInsight/moveUpDown/classBodyDeclarations/classInitializer/classInitializerAtProperty1.kt create mode 100644 idea/testData/codeInsight/moveUpDown/classBodyDeclarations/classInitializer/classInitializerAtProperty1.kt.after create mode 100644 idea/testData/codeInsight/moveUpDown/classBodyDeclarations/classInitializer/classInitializerAtProperty2.kt create mode 100644 idea/testData/codeInsight/moveUpDown/classBodyDeclarations/classInitializer/classInitializerAtProperty2.kt.after create mode 100644 idea/testData/codeInsight/moveUpDown/classBodyDeclarations/enums/enum1.kt create mode 100644 idea/testData/codeInsight/moveUpDown/classBodyDeclarations/enums/enum1.kt.after create mode 100644 idea/testData/codeInsight/moveUpDown/classBodyDeclarations/enums/enum2.kt create mode 100644 idea/testData/codeInsight/moveUpDown/classBodyDeclarations/enums/enum3.kt create mode 100644 idea/testData/codeInsight/moveUpDown/classBodyDeclarations/enums/enum4.kt create mode 100644 idea/testData/codeInsight/moveUpDown/classBodyDeclarations/enums/enum4.kt.after create mode 100644 idea/testData/codeInsight/moveUpDown/classBodyDeclarations/enums/enum5.kt create mode 100644 idea/testData/codeInsight/moveUpDown/classBodyDeclarations/enums/enum5.kt.after create mode 100644 idea/testData/codeInsight/moveUpDown/classBodyDeclarations/enums/enum6.kt create mode 100644 idea/testData/codeInsight/moveUpDown/classBodyDeclarations/enums/enum6.kt.after create mode 100644 idea/testData/codeInsight/moveUpDown/classBodyDeclarations/function/functionAtBrace1.kt create mode 100644 idea/testData/codeInsight/moveUpDown/classBodyDeclarations/function/functionAtBrace1.kt.after create mode 100644 idea/testData/codeInsight/moveUpDown/classBodyDeclarations/function/functionAtBrace2.kt create mode 100644 idea/testData/codeInsight/moveUpDown/classBodyDeclarations/function/functionAtBrace2.kt.after create mode 100644 idea/testData/codeInsight/moveUpDown/classBodyDeclarations/function/functionAtBrace3.kt create mode 100644 idea/testData/codeInsight/moveUpDown/classBodyDeclarations/function/functionAtBrace3.kt.after create mode 100644 idea/testData/codeInsight/moveUpDown/classBodyDeclarations/function/functionAtBrace4.kt create mode 100644 idea/testData/codeInsight/moveUpDown/classBodyDeclarations/function/functionAtBrace4.kt.after create mode 100644 idea/testData/codeInsight/moveUpDown/classBodyDeclarations/function/functionAtBrace5.kt create mode 100644 idea/testData/codeInsight/moveUpDown/classBodyDeclarations/function/functionAtBrace6.kt create mode 100644 idea/testData/codeInsight/moveUpDown/classBodyDeclarations/function/functionAtClass1.kt create mode 100644 idea/testData/codeInsight/moveUpDown/classBodyDeclarations/function/functionAtClass1.kt.after create mode 100644 idea/testData/codeInsight/moveUpDown/classBodyDeclarations/function/functionAtClass2.kt create mode 100644 idea/testData/codeInsight/moveUpDown/classBodyDeclarations/function/functionAtClass2.kt.after create mode 100644 idea/testData/codeInsight/moveUpDown/classBodyDeclarations/function/functionAtClassInitializer1.kt create mode 100644 idea/testData/codeInsight/moveUpDown/classBodyDeclarations/function/functionAtClassInitializer1.kt.after create mode 100644 idea/testData/codeInsight/moveUpDown/classBodyDeclarations/function/functionAtClassInitializer2.kt create mode 100644 idea/testData/codeInsight/moveUpDown/classBodyDeclarations/function/functionAtClassInitializer2.kt.after create mode 100644 idea/testData/codeInsight/moveUpDown/classBodyDeclarations/function/functionAtEmptyLine1.kt create mode 100644 idea/testData/codeInsight/moveUpDown/classBodyDeclarations/function/functionAtEmptyLine1.kt.after create mode 100644 idea/testData/codeInsight/moveUpDown/classBodyDeclarations/function/functionAtEmptyLine2.kt create mode 100644 idea/testData/codeInsight/moveUpDown/classBodyDeclarations/function/functionAtEmptyLine2.kt.after create mode 100644 idea/testData/codeInsight/moveUpDown/classBodyDeclarations/function/functionAtFunction1.kt create mode 100644 idea/testData/codeInsight/moveUpDown/classBodyDeclarations/function/functionAtFunction1.kt.after create mode 100644 idea/testData/codeInsight/moveUpDown/classBodyDeclarations/function/functionAtFunction2.kt create mode 100644 idea/testData/codeInsight/moveUpDown/classBodyDeclarations/function/functionAtFunction2.kt.after create mode 100644 idea/testData/codeInsight/moveUpDown/classBodyDeclarations/function/functionAtProperty1.kt create mode 100644 idea/testData/codeInsight/moveUpDown/classBodyDeclarations/function/functionAtProperty1.kt.after create mode 100644 idea/testData/codeInsight/moveUpDown/classBodyDeclarations/function/functionAtProperty2.kt create mode 100644 idea/testData/codeInsight/moveUpDown/classBodyDeclarations/function/functionAtProperty2.kt.after create mode 100644 idea/testData/codeInsight/moveUpDown/classBodyDeclarations/property/propertyAtBrace1.kt create mode 100644 idea/testData/codeInsight/moveUpDown/classBodyDeclarations/property/propertyAtBrace1.kt.after create mode 100644 idea/testData/codeInsight/moveUpDown/classBodyDeclarations/property/propertyAtBrace2.kt create mode 100644 idea/testData/codeInsight/moveUpDown/classBodyDeclarations/property/propertyAtBrace2.kt.after create mode 100644 idea/testData/codeInsight/moveUpDown/classBodyDeclarations/property/propertyAtBrace3.kt create mode 100644 idea/testData/codeInsight/moveUpDown/classBodyDeclarations/property/propertyAtBrace3.kt.after create mode 100644 idea/testData/codeInsight/moveUpDown/classBodyDeclarations/property/propertyAtBrace4.kt create mode 100644 idea/testData/codeInsight/moveUpDown/classBodyDeclarations/property/propertyAtBrace4.kt.after create mode 100644 idea/testData/codeInsight/moveUpDown/classBodyDeclarations/property/propertyAtBrace5.kt create mode 100644 idea/testData/codeInsight/moveUpDown/classBodyDeclarations/property/propertyAtBrace6.kt create mode 100644 idea/testData/codeInsight/moveUpDown/classBodyDeclarations/property/propertyAtClass1.kt create mode 100644 idea/testData/codeInsight/moveUpDown/classBodyDeclarations/property/propertyAtClass1.kt.after create mode 100644 idea/testData/codeInsight/moveUpDown/classBodyDeclarations/property/propertyAtClass2.kt create mode 100644 idea/testData/codeInsight/moveUpDown/classBodyDeclarations/property/propertyAtClass2.kt.after create mode 100644 idea/testData/codeInsight/moveUpDown/classBodyDeclarations/property/propertyAtClassInitializer1.kt create mode 100644 idea/testData/codeInsight/moveUpDown/classBodyDeclarations/property/propertyAtClassInitializer1.kt.after create mode 100644 idea/testData/codeInsight/moveUpDown/classBodyDeclarations/property/propertyAtClassInitializer2.kt create mode 100644 idea/testData/codeInsight/moveUpDown/classBodyDeclarations/property/propertyAtClassInitializer2.kt.after create mode 100644 idea/testData/codeInsight/moveUpDown/classBodyDeclarations/property/propertyAtEmptyLine1.kt create mode 100644 idea/testData/codeInsight/moveUpDown/classBodyDeclarations/property/propertyAtEmptyLine1.kt.after create mode 100644 idea/testData/codeInsight/moveUpDown/classBodyDeclarations/property/propertyAtEmptyLine2.kt create mode 100644 idea/testData/codeInsight/moveUpDown/classBodyDeclarations/property/propertyAtEmptyLine2.kt.after create mode 100644 idea/testData/codeInsight/moveUpDown/classBodyDeclarations/property/propertyAtFunction1.kt create mode 100644 idea/testData/codeInsight/moveUpDown/classBodyDeclarations/property/propertyAtFunction1.kt.after create mode 100644 idea/testData/codeInsight/moveUpDown/classBodyDeclarations/property/propertyAtFunction2.kt create mode 100644 idea/testData/codeInsight/moveUpDown/classBodyDeclarations/property/propertyAtFunction2.kt.after create mode 100644 idea/testData/codeInsight/moveUpDown/classBodyDeclarations/property/propertyAtProperty1.kt create mode 100644 idea/testData/codeInsight/moveUpDown/classBodyDeclarations/property/propertyAtProperty1.kt.after create mode 100644 idea/testData/codeInsight/moveUpDown/classBodyDeclarations/property/propertyAtProperty2.kt create mode 100644 idea/testData/codeInsight/moveUpDown/classBodyDeclarations/property/propertyAtProperty2.kt.after create mode 100644 idea/tests/org/jetbrains/jet/plugin/codeInsight/moveUpDown/AbstractCodeMoverTest.java create mode 100644 idea/tests/org/jetbrains/jet/plugin/codeInsight/moveUpDown/CodeMoverTestGenerated.java diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetClassInitializer.java b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetClassInitializer.java index 1dce4c753ad..3d40cdd11c1 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetClassInitializer.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetClassInitializer.java @@ -17,7 +17,10 @@ package org.jetbrains.jet.lang.psi; import com.intellij.lang.ASTNode; +import com.intellij.psi.PsiElement; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import org.jetbrains.jet.lexer.JetTokens; public class JetClassInitializer extends JetDeclarationImpl implements JetStatementExpression { public JetClassInitializer(@NotNull ASTNode node) { @@ -40,4 +43,11 @@ public class JetClassInitializer extends JetDeclarationImpl implements JetStatem assert body != null; return body; } + + @NotNull + public PsiElement getOpenBraceNode() { + ASTNode openBraceNode = getNode().findChildByType(JetTokens.LBRACE); + assert openBraceNode != null; + return openBraceNode.getPsi(); + } } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetClassObject.java b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetClassObject.java index 4d12d816e2a..e2169addfa0 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetClassObject.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetClassObject.java @@ -17,9 +17,11 @@ package org.jetbrains.jet.lang.psi; import com.intellij.lang.ASTNode; +import com.intellij.psi.PsiElement; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.jet.JetNodeTypes; +import org.jetbrains.jet.lexer.JetTokens; public class JetClassObject extends JetDeclarationImpl implements JetStatementExpression { public JetClassObject(@NotNull ASTNode node) { @@ -41,4 +43,9 @@ public class JetClassObject extends JetDeclarationImpl implements JetStatementEx return (JetObjectDeclaration) findChildByType(JetNodeTypes.OBJECT_DECLARATION); } + @Nullable @IfNotParsed + public PsiElement getClassKeywordNode() { + ASTNode keywordNode = getNode().findChildByType(JetTokens.CLASS_KEYWORD); + return keywordNode != null ? keywordNode.getPsi() : null; + } } diff --git a/generators/org/jetbrains/jet/generators/tests/GenerateTests.java b/generators/org/jetbrains/jet/generators/tests/GenerateTests.java index 4971a06f9cf..46224ddf2f9 100644 --- a/generators/org/jetbrains/jet/generators/tests/GenerateTests.java +++ b/generators/org/jetbrains/jet/generators/tests/GenerateTests.java @@ -32,6 +32,7 @@ import org.jetbrains.jet.completion.AbstractJavaWithLibCompletionTest; import org.jetbrains.jet.completion.AbstractJetJSCompletionTest; import org.jetbrains.jet.completion.AbstractKeywordCompletionTest; import org.jetbrains.jet.jvm.compiler.*; +import org.jetbrains.jet.plugin.codeInsight.moveUpDown.AbstractCodeMoverTest; import org.jetbrains.jet.psi.AbstractJetPsiMatcherTest; import org.jetbrains.jet.lang.resolve.lazy.AbstractLazyResolveDescriptorRendererTest; import org.jetbrains.jet.lang.resolve.lazy.AbstractLazyResolveNamespaceComparingTest; @@ -338,6 +339,13 @@ public class GenerateTests { testModelWithDirectories("idea/testData/hierarchy/class/super", "doSuperClassHierarchyTest"), testModelWithDirectories("idea/testData/hierarchy/class/sub", "doSubClassHierarchyTest") ); + + generateTest( + "idea/tests/", + "CodeMoverTestGenerated", + AbstractCodeMoverTest.class, + testModel("idea/testData/codeInsight/moveUpDown/classBodyDeclarations", "doTestClassBodyDeclaration") + ); } private static SimpleTestClassModel testModel(@NotNull String rootPath) { diff --git a/idea/src/META-INF/plugin.xml b/idea/src/META-INF/plugin.xml index f1e7fd11e46..18f3e23205a 100644 --- a/idea/src/META-INF/plugin.xml +++ b/idea/src/META-INF/plugin.xml @@ -283,6 +283,10 @@ serviceImplementation="org.jetbrains.jet.plugin.editor.JetEditorOptions"/> + + org.jetbrains.jet.plugin.intentions.SpecifyTypeExplicitlyAction Kotlin diff --git a/idea/src/org/jetbrains/jet/plugin/codeInsight/upDownMover/AbstractJetUpDownMover.java b/idea/src/org/jetbrains/jet/plugin/codeInsight/upDownMover/AbstractJetUpDownMover.java new file mode 100644 index 00000000000..5c1b3851294 --- /dev/null +++ b/idea/src/org/jetbrains/jet/plugin/codeInsight/upDownMover/AbstractJetUpDownMover.java @@ -0,0 +1,63 @@ +package org.jetbrains.jet.plugin.codeInsight.upDownMover; + +import com.intellij.codeInsight.editorActions.moveUpDown.LineMover; +import com.intellij.codeInsight.editorActions.moveUpDown.LineRange; +import com.intellij.openapi.editor.Document; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.util.TextRange; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiFile; +import com.intellij.psi.PsiWhiteSpace; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import org.jetbrains.jet.lang.psi.JetFile; + +public abstract class AbstractJetUpDownMover extends LineMover { + protected AbstractJetUpDownMover() { + } + + protected static PsiElement adjustWhiteSpaceSibling( + @NotNull Editor editor, + @NotNull LineRange sourceRange, + @NotNull MoveInfo info, + boolean down + ) { + PsiElement sibling = down ? sourceRange.lastElement.getNextSibling() : sourceRange.firstElement.getPrevSibling(); + + if (sibling instanceof PsiWhiteSpace) { + Document doc = editor.getDocument(); + TextRange spaceRange = sibling.getTextRange(); + + int startLine = doc.getLineNumber(spaceRange.getStartOffset()); + int endLine = doc.getLineNumber(spaceRange.getEndOffset()); + + if (endLine - startLine > 1) { + int nearLine = down ? sourceRange.endLine : sourceRange.startLine - 1; + + info.toMove = sourceRange; + info.toMove2 = new LineRange(nearLine, nearLine + 1); + + return null; + } + + sibling = firstNonWhiteElement(sibling, down); + } + + if (sibling == null) { + info.toMove2 = null; + return null; + } + + return sibling; + } + + @Nullable + protected static PsiElement firstNonWhiteSibling(@NotNull LineRange lineRange, boolean down) { + return firstNonWhiteElement(down ? lineRange.lastElement.getNextSibling() : lineRange.firstElement.getPrevSibling(), down); + } + + @Override + public boolean checkAvailable(@NotNull Editor editor, @NotNull PsiFile file, @NotNull MoveInfo info, boolean down) { + return (file instanceof JetFile) && super.checkAvailable(editor, file, info, down); + } +} diff --git a/idea/src/org/jetbrains/jet/plugin/codeInsight/upDownMover/JetDeclarationMover.java b/idea/src/org/jetbrains/jet/plugin/codeInsight/upDownMover/JetDeclarationMover.java new file mode 100644 index 00000000000..f720fd312b2 --- /dev/null +++ b/idea/src/org/jetbrains/jet/plugin/codeInsight/upDownMover/JetDeclarationMover.java @@ -0,0 +1,263 @@ +package org.jetbrains.jet.plugin.codeInsight.upDownMover; + +import com.intellij.codeInsight.editorActions.moveUpDown.LineRange; +import com.intellij.openapi.editor.Document; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.util.Pair; +import com.intellij.openapi.util.TextRange; +import com.intellij.psi.*; +import com.intellij.psi.util.PsiTreeUtil; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import org.jetbrains.jet.lang.psi.*; +import org.jetbrains.jet.lexer.JetTokens; + +import java.util.ArrayList; +import java.util.List; + +public class JetDeclarationMover extends AbstractJetUpDownMover { + public JetDeclarationMover() { + } + + @NotNull + private static List getDeclarationAnchors(@NotNull JetDeclaration declaration) { + final List memberSuspects = new ArrayList(); + + JetModifierList modifierList = declaration.getModifierList(); + if (modifierList != null) memberSuspects.add(modifierList); + + if (declaration instanceof JetNamedDeclaration) { + PsiElement nameIdentifier = ((JetNamedDeclaration) declaration).getNameIdentifier(); + if (nameIdentifier != null) memberSuspects.add(nameIdentifier); + } + + declaration.accept( + new JetVisitorVoid() { + @Override + public void visitAnonymousInitializer(JetClassInitializer initializer) { + memberSuspects.add(initializer.getOpenBraceNode()); + } + + @Override + public void visitClassObject(JetClassObject classObject) { + PsiElement classKeyword = classObject.getClassKeywordNode(); + if (classKeyword != null) memberSuspects.add(classKeyword); + } + + @Override + public void visitNamedFunction(JetNamedFunction function) { + PsiElement equalsToken = function.getEqualsToken(); + if (equalsToken != null) memberSuspects.add(equalsToken); + + JetParameterList parameterList = function.getValueParameterList(); + if (parameterList != null) memberSuspects.add(parameterList); + + JetTypeParameterList typeParameterList = function.getTypeParameterList(); + if (typeParameterList != null) memberSuspects.add(typeParameterList); + + JetTypeReference receiverTypeRef = function.getReceiverTypeRef(); + if (receiverTypeRef != null) memberSuspects.add(receiverTypeRef); + + JetTypeReference returnTypeRef = function.getReturnTypeRef(); + if (returnTypeRef != null) memberSuspects.add(returnTypeRef); + } + + @Override + public void visitProperty(JetProperty property) { + PsiElement valOrVarNode = property.getValOrVarNode().getPsi(); + if (valOrVarNode != null) memberSuspects.add(valOrVarNode); + + JetTypeParameterList typeParameterList = property.getTypeParameterList(); + if (typeParameterList != null) memberSuspects.add(typeParameterList); + + JetTypeReference receiverTypeRef = property.getReceiverTypeRef(); + if (receiverTypeRef != null) memberSuspects.add(receiverTypeRef); + + JetTypeReference returnTypeRef = property.getTypeRef(); + if (returnTypeRef != null) memberSuspects.add(returnTypeRef); + } + } + ); + + return memberSuspects; + } + + @Nullable + private static LineRange adjustDeclarationRange( + @NotNull JetDeclaration declaration, + @NotNull Editor editor, + @NotNull LineRange lineRange + ) { + Document doc = editor.getDocument(); + TextRange textRange = declaration.getTextRange(); + if (doc.getTextLength() < textRange.getEndOffset()) return null; + + int startLine = editor.offsetToLogicalPosition(textRange.getStartOffset()).line; + int endLine = editor.offsetToLogicalPosition(textRange.getEndOffset()).line + 1; + + if (startLine == lineRange.startLine || startLine == lineRange.endLine + || endLine == lineRange.startLine || endLine == lineRange.endLine) { + return new LineRange(startLine, endLine); + } + + TextRange lineTextRange = new TextRange(doc.getLineStartOffset(lineRange.startLine), + doc.getLineEndOffset(lineRange.endLine)); + for (PsiElement anchor : getDeclarationAnchors(declaration)) { + TextRange suspectTextRange = anchor.getTextRange(); + if (suspectTextRange != null && lineTextRange.intersects(suspectTextRange)) return new LineRange(startLine, endLine); + } + + return null; + } + + private static final Class[] DECLARATION_CONTAINER_CLASSES = + {JetClassBody.class, JetClassInitializer.class, JetFunction.class, JetPropertyAccessor.class, JetFile.class}; + + private static final Class[] CLASSBODYLIKE_DECLARATION_CONTAINER_CLASSES = {JetClassBody.class, JetFile.class}; + + @Nullable + private static JetDeclaration getMovableDeclaration(@Nullable PsiElement element) { + if (element == null) return null; + + JetDeclaration declaration = PsiTreeUtil.getParentOfType(element, JetDeclaration.class, false); + + return PsiTreeUtil.instanceOf(PsiTreeUtil.getParentOfType(declaration, + DECLARATION_CONTAINER_CLASSES), + CLASSBODYLIKE_DECLARATION_CONTAINER_CLASSES) ? declaration : null; + } + + @Nullable + private static LineRange getSourceRange( + @NotNull JetDeclaration firstDecl, + @NotNull JetDeclaration lastDecl, + @NotNull Editor editor, + @NotNull LineRange oldRange + ) { + if (firstDecl == lastDecl) { + LineRange range = adjustDeclarationRange(firstDecl, editor, oldRange); + + if (range != null) { + range.firstElement = range.lastElement = firstDecl; + } + + return range; + } + + PsiElement parent = PsiTreeUtil.findCommonParent(firstDecl, lastDecl); + if (parent == null) return null; + + Pair combinedRange = getElementRange(parent, firstDecl, lastDecl); + + if (combinedRange == null + || !(combinedRange.first instanceof JetDeclaration) + || !(combinedRange.second instanceof JetDeclaration)) { + return null; + } + + LineRange lineRange1 = adjustDeclarationRange((JetDeclaration) combinedRange.getFirst(), editor, oldRange); + if (lineRange1 == null) return null; + + LineRange lineRange2 = adjustDeclarationRange((JetDeclaration) combinedRange.getSecond(), editor, oldRange); + if (lineRange2 == null) return null; + + LineRange range = new LineRange(lineRange1.startLine, lineRange2.endLine); + range.firstElement = combinedRange.getFirst(); + range.lastElement = combinedRange.getSecond(); + + return range; + } + + @Nullable + private static LineRange getTargetRange( + @NotNull Editor editor, + @NotNull PsiElement sibling, + boolean down, + @NotNull PsiElement target + ) { + PsiElement start = sibling; + PsiElement end = sibling; + + PsiElement nextParent = null; + + // moving out of code block + if (sibling.getNode().getElementType() == (down ? JetTokens.RBRACE : JetTokens.LBRACE)) { + // elements which aren't immediately placed in class body can't leave the block + PsiElement parent = sibling.getParent(); + if (!(parent instanceof JetClassBody)) return null; + + JetClassOrObject jetClassOrObject = (JetClassOrObject) parent.getParent(); + assert jetClassOrObject != null; + + nextParent = jetClassOrObject.getParent(); + + // elements may be placed only to class body or file + if (!(nextParent instanceof JetFile || nextParent instanceof JetClassBody)) return null; + + if (!down) { + start = jetClassOrObject; + } + } + // moving into code block + // element may move only into class body + else if (sibling instanceof JetClassOrObject) { + JetClassOrObject jetClassOrObject = (JetClassOrObject) sibling; + JetClassBody classBody = jetClassOrObject.getBody(); + + // confined elements can't leave their block + if (classBody != null) { + nextParent = classBody; + start = down ? jetClassOrObject : classBody.getRBrace(); + end = down ? classBody.getLBrace() : classBody.getRBrace(); + } + } + + if (nextParent != null) { + if (target instanceof JetClassInitializer && !(nextParent instanceof JetClassBody)) return null; + + if (target instanceof JetEnumEntry) { + if (!(nextParent instanceof JetClassBody)) return null; + + JetClassOrObject nextClassOrObject = (JetClassOrObject) nextParent.getParent(); + assert nextClassOrObject != null; + + if (!nextClassOrObject.hasModifier(JetTokens.ENUM_KEYWORD)) return null; + } + } + + if (target instanceof JetPropertyAccessor && !(sibling instanceof JetPropertyAccessor)) return null; + + return start != null && end != null ? new LineRange(start, end, editor.getDocument()) : null; + } + + @Override + public boolean checkAvailable(@NotNull Editor editor, @NotNull PsiFile file, @NotNull MoveInfo info, boolean down) { + if (!super.checkAvailable(editor, file, info, down)) return false; + + LineRange oldRange = info.toMove; + + Pair psiRange = getElementRange(editor, file, oldRange); + if (psiRange == null) return false; + + JetDeclaration firstDecl = getMovableDeclaration(psiRange.getFirst()); + if (firstDecl == null) return false; + + JetDeclaration lastDecl = getMovableDeclaration(psiRange.getSecond()); + if (lastDecl == null) return false; + + //noinspection ConstantConditions + LineRange sourceRange = getSourceRange(firstDecl, lastDecl, editor, oldRange); + if (sourceRange == null) return false; + + PsiElement sibling = firstNonWhiteSibling(sourceRange, down); + + // Either reached last sibling, or jumped over multi-line whitespace + if (sibling == null) { + info.toMove2 = null; + return true; + } + + info.toMove = sourceRange; + info.toMove2 = getTargetRange(editor, sibling, down, sourceRange.firstElement); + return true; + } +} diff --git a/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/accessors/accessor1.kt b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/accessors/accessor1.kt new file mode 100644 index 00000000000..fe7f1e832c5 --- /dev/null +++ b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/accessors/accessor1.kt @@ -0,0 +1,6 @@ +// MOVE: down +// IS_APPLICABLE: false +val x: String + get() { + return "" + } \ No newline at end of file diff --git a/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/accessors/accessor2.kt b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/accessors/accessor2.kt new file mode 100644 index 00000000000..38bfcb856a4 --- /dev/null +++ b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/accessors/accessor2.kt @@ -0,0 +1,6 @@ +// MOVE: up +// IS_APPLICABLE: false +val x: String + get() { + return "" + } \ No newline at end of file diff --git a/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/accessors/accessor3.kt b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/accessors/accessor3.kt new file mode 100644 index 00000000000..a49ddbd3b7b --- /dev/null +++ b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/accessors/accessor3.kt @@ -0,0 +1,8 @@ +// MOVE: down +var x: String + get() { + return "" + } + set(v: String) { + // test + } \ No newline at end of file diff --git a/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/accessors/accessor3.kt.after b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/accessors/accessor3.kt.after new file mode 100644 index 00000000000..215dca40fdf --- /dev/null +++ b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/accessors/accessor3.kt.after @@ -0,0 +1,8 @@ +// MOVE: down +var x: String + set(v: String) { + // test + } + get() { + return "" + } diff --git a/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/accessors/accessor4.kt b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/accessors/accessor4.kt new file mode 100644 index 00000000000..bc8c11238fc --- /dev/null +++ b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/accessors/accessor4.kt @@ -0,0 +1,8 @@ +// MOVE: up +var x: String + get() { + return "" + } + set(v: String) { + // test + } \ No newline at end of file diff --git a/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/accessors/accessor4.kt.after b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/accessors/accessor4.kt.after new file mode 100644 index 00000000000..2282767b110 --- /dev/null +++ b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/accessors/accessor4.kt.after @@ -0,0 +1,8 @@ +// MOVE: up +var x: String + set(v: String) { + // test + } + get() { + return "" + } diff --git a/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/class/classAtBrace1.kt b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/class/classAtBrace1.kt new file mode 100644 index 00000000000..f238eae366c --- /dev/null +++ b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/class/classAtBrace1.kt @@ -0,0 +1,8 @@ +// MOVE: down +class A { + val x = "" + + class B { + + } +} \ No newline at end of file diff --git a/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/class/classAtBrace1.kt.after b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/class/classAtBrace1.kt.after new file mode 100644 index 00000000000..9c3c6850e8a --- /dev/null +++ b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/class/classAtBrace1.kt.after @@ -0,0 +1,8 @@ +// MOVE: down +class A { + val x = "" + +} +class B { + +} diff --git a/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/class/classAtBrace2.kt b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/class/classAtBrace2.kt new file mode 100644 index 00000000000..4013210f036 --- /dev/null +++ b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/class/classAtBrace2.kt @@ -0,0 +1,8 @@ +// MOVE: up +class A { + class B { + + } + + val y = "" +} \ No newline at end of file diff --git a/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/class/classAtBrace2.kt.after b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/class/classAtBrace2.kt.after new file mode 100644 index 00000000000..016f4e20de3 --- /dev/null +++ b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/class/classAtBrace2.kt.after @@ -0,0 +1,8 @@ +// MOVE: up +class B { + +} +class A { + + val y = "" +} \ No newline at end of file diff --git a/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/class/classAtBrace3.kt b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/class/classAtBrace3.kt new file mode 100644 index 00000000000..4df12cc2365 --- /dev/null +++ b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/class/classAtBrace3.kt @@ -0,0 +1,8 @@ +// MOVE: down +class A { + class B { + class B { + + } + } +} \ No newline at end of file diff --git a/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/class/classAtBrace3.kt.after b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/class/classAtBrace3.kt.after new file mode 100644 index 00000000000..eff2f26ab80 --- /dev/null +++ b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/class/classAtBrace3.kt.after @@ -0,0 +1,8 @@ +// MOVE: down +class A { + class B { + } + class B { + + } +} \ No newline at end of file diff --git a/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/class/classAtBrace4.kt b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/class/classAtBrace4.kt new file mode 100644 index 00000000000..9b3c200f843 --- /dev/null +++ b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/class/classAtBrace4.kt @@ -0,0 +1,8 @@ +// MOVE: up +class A { + class B { + class B { + + } + } +} \ No newline at end of file diff --git a/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/class/classAtBrace4.kt.after b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/class/classAtBrace4.kt.after new file mode 100644 index 00000000000..af47bd31201 --- /dev/null +++ b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/class/classAtBrace4.kt.after @@ -0,0 +1,8 @@ +// MOVE: up +class A { + class B { + + } + class B { + } +} \ No newline at end of file diff --git a/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/class/classAtBrace5.kt b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/class/classAtBrace5.kt new file mode 100644 index 00000000000..5511821cbc4 --- /dev/null +++ b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/class/classAtBrace5.kt @@ -0,0 +1,9 @@ +// MOVE: down +// IS_APPLICABLE: false +fun foo() { + class B { + class B { + + } + } +} \ No newline at end of file diff --git a/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/class/classAtBrace6.kt b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/class/classAtBrace6.kt new file mode 100644 index 00000000000..711e905df5e --- /dev/null +++ b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/class/classAtBrace6.kt @@ -0,0 +1,9 @@ +// MOVE: up +// IS_APPLICABLE: false +fun foo() { + class B { + class B { + + } + } +} \ No newline at end of file diff --git a/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/class/classAtClass1.kt b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/class/classAtClass1.kt new file mode 100644 index 00000000000..df30122b176 --- /dev/null +++ b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/class/classAtClass1.kt @@ -0,0 +1,9 @@ +// MOVE: down +class A { + class B { + + } + class B { + + } +} \ No newline at end of file diff --git a/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/class/classAtClass1.kt.after b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/class/classAtClass1.kt.after new file mode 100644 index 00000000000..7c7fc272bdd --- /dev/null +++ b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/class/classAtClass1.kt.after @@ -0,0 +1,9 @@ +// MOVE: down +class A { + class B { + class B { + + } + + } +} \ No newline at end of file diff --git a/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/class/classAtClass2.kt b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/class/classAtClass2.kt new file mode 100644 index 00000000000..27843d81cb1 --- /dev/null +++ b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/class/classAtClass2.kt @@ -0,0 +1,9 @@ +// MOVE: up +class A { + class B { + + } + class B { + + } +} \ No newline at end of file diff --git a/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/class/classAtClass2.kt.after b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/class/classAtClass2.kt.after new file mode 100644 index 00000000000..1cb0fe81495 --- /dev/null +++ b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/class/classAtClass2.kt.after @@ -0,0 +1,9 @@ +// MOVE: up +class A { + class B { + + class B { + + } + } +} \ No newline at end of file diff --git a/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/class/classAtClassInitializer1.kt b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/class/classAtClassInitializer1.kt new file mode 100644 index 00000000000..9db424e8c1e --- /dev/null +++ b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/class/classAtClassInitializer1.kt @@ -0,0 +1,9 @@ +// MOVE: down +class A { + class B { + + } + { + + } +} \ No newline at end of file diff --git a/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/class/classAtClassInitializer1.kt.after b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/class/classAtClassInitializer1.kt.after new file mode 100644 index 00000000000..c5b81847fbf --- /dev/null +++ b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/class/classAtClassInitializer1.kt.after @@ -0,0 +1,9 @@ +// MOVE: down +class A { + { + + } + class B { + + } +} \ No newline at end of file diff --git a/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/class/classAtClassInitializer2.kt b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/class/classAtClassInitializer2.kt new file mode 100644 index 00000000000..ff56bfabc8d --- /dev/null +++ b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/class/classAtClassInitializer2.kt @@ -0,0 +1,9 @@ +// MOVE: up +class A { + { + + } + class B { + + } +} \ No newline at end of file diff --git a/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/class/classAtClassInitializer2.kt.after b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/class/classAtClassInitializer2.kt.after new file mode 100644 index 00000000000..5dbb4935da5 --- /dev/null +++ b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/class/classAtClassInitializer2.kt.after @@ -0,0 +1,9 @@ +// MOVE: up +class A { + class B { + + } + { + + } +} \ No newline at end of file diff --git a/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/class/classAtEmptyLine1.kt b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/class/classAtEmptyLine1.kt new file mode 100644 index 00000000000..5115c6bc9aa --- /dev/null +++ b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/class/classAtEmptyLine1.kt @@ -0,0 +1,8 @@ +// MOVE: down +class A { + class B { + + } + + val y = "" +} \ No newline at end of file diff --git a/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/class/classAtEmptyLine1.kt.after b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/class/classAtEmptyLine1.kt.after new file mode 100644 index 00000000000..af1e0f40e69 --- /dev/null +++ b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/class/classAtEmptyLine1.kt.after @@ -0,0 +1,8 @@ +// MOVE: down +class A { + val y = "" + + class B { + + } +} \ No newline at end of file diff --git a/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/class/classAtEmptyLine2.kt b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/class/classAtEmptyLine2.kt new file mode 100644 index 00000000000..3e3b8ba0d1e --- /dev/null +++ b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/class/classAtEmptyLine2.kt @@ -0,0 +1,8 @@ +// MOVE: up +class A { + val x = "" + + class B { + + } +} \ No newline at end of file diff --git a/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/class/classAtEmptyLine2.kt.after b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/class/classAtEmptyLine2.kt.after new file mode 100644 index 00000000000..bdc0749a1cd --- /dev/null +++ b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/class/classAtEmptyLine2.kt.after @@ -0,0 +1,8 @@ +// MOVE: up +class A { + class B { + + } + + val x = "" +} \ No newline at end of file diff --git a/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/class/classAtFunction1.kt b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/class/classAtFunction1.kt new file mode 100644 index 00000000000..505b9673e72 --- /dev/null +++ b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/class/classAtFunction1.kt @@ -0,0 +1,9 @@ +// MOVE: down +class A { + class B { + + } + fun foo() { + + } +} \ No newline at end of file diff --git a/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/class/classAtFunction1.kt.after b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/class/classAtFunction1.kt.after new file mode 100644 index 00000000000..5b76fe3bb9d --- /dev/null +++ b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/class/classAtFunction1.kt.after @@ -0,0 +1,9 @@ +// MOVE: down +class A { + fun foo() { + + } + class B { + + } +} \ No newline at end of file diff --git a/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/class/classAtFunction2.kt b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/class/classAtFunction2.kt new file mode 100644 index 00000000000..e864fe1af4c --- /dev/null +++ b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/class/classAtFunction2.kt @@ -0,0 +1,9 @@ +// MOVE: up +class A { + fun foo() { + + } + class B { + + } +} \ No newline at end of file diff --git a/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/class/classAtFunction2.kt.after b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/class/classAtFunction2.kt.after new file mode 100644 index 00000000000..793416b57de --- /dev/null +++ b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/class/classAtFunction2.kt.after @@ -0,0 +1,9 @@ +// MOVE: up +class A { + class B { + + } + fun foo() { + + } +} \ No newline at end of file diff --git a/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/class/classAtProperty1.kt b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/class/classAtProperty1.kt new file mode 100644 index 00000000000..bb5a18b8488 --- /dev/null +++ b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/class/classAtProperty1.kt @@ -0,0 +1,7 @@ +// MOVE: down +class A { + class B { + + } + val y = "" +} \ No newline at end of file diff --git a/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/class/classAtProperty1.kt.after b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/class/classAtProperty1.kt.after new file mode 100644 index 00000000000..c65358748f6 --- /dev/null +++ b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/class/classAtProperty1.kt.after @@ -0,0 +1,7 @@ +// MOVE: down +class A { + val y = "" + class B { + + } +} \ No newline at end of file diff --git a/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/class/classAtProperty2.kt b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/class/classAtProperty2.kt new file mode 100644 index 00000000000..fa7dd65a83e --- /dev/null +++ b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/class/classAtProperty2.kt @@ -0,0 +1,7 @@ +// MOVE: up +class A { + val y = "" + class B { + + } +} \ No newline at end of file diff --git a/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/class/classAtProperty2.kt.after b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/class/classAtProperty2.kt.after new file mode 100644 index 00000000000..805ab2a7edd --- /dev/null +++ b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/class/classAtProperty2.kt.after @@ -0,0 +1,7 @@ +// MOVE: up +class A { + class B { + + } + val y = "" +} \ No newline at end of file diff --git a/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/classInitializer/classInitializerAtBrace1.kt b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/classInitializer/classInitializerAtBrace1.kt new file mode 100644 index 00000000000..2c6164d0151 --- /dev/null +++ b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/classInitializer/classInitializerAtBrace1.kt @@ -0,0 +1,7 @@ +// MOVE: down +// IS_APPLICABLE: false +class B { + { + + } +} \ No newline at end of file diff --git a/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/classInitializer/classInitializerAtBrace2.kt b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/classInitializer/classInitializerAtBrace2.kt new file mode 100644 index 00000000000..d7618556f6d --- /dev/null +++ b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/classInitializer/classInitializerAtBrace2.kt @@ -0,0 +1,7 @@ +// MOVE: up +// IS_APPLICABLE: false +class B { + { + + } +} \ No newline at end of file diff --git a/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/classInitializer/classInitializerAtClass1.kt b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/classInitializer/classInitializerAtClass1.kt new file mode 100644 index 00000000000..9018b8dec8b --- /dev/null +++ b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/classInitializer/classInitializerAtClass1.kt @@ -0,0 +1,9 @@ +// MOVE: down +class A { + { + + } + class B { + + } +} \ No newline at end of file diff --git a/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/classInitializer/classInitializerAtClass1.kt.after b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/classInitializer/classInitializerAtClass1.kt.after new file mode 100644 index 00000000000..d73569a6ee8 --- /dev/null +++ b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/classInitializer/classInitializerAtClass1.kt.after @@ -0,0 +1,9 @@ +// MOVE: down +class A { + class B { + { + + } + + } +} \ No newline at end of file diff --git a/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/classInitializer/classInitializerAtClass2.kt b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/classInitializer/classInitializerAtClass2.kt new file mode 100644 index 00000000000..8b4afc7fcee --- /dev/null +++ b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/classInitializer/classInitializerAtClass2.kt @@ -0,0 +1,9 @@ +// MOVE: up +class A { + class B { + + } + { + + } +} \ No newline at end of file diff --git a/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/classInitializer/classInitializerAtClass2.kt.after b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/classInitializer/classInitializerAtClass2.kt.after new file mode 100644 index 00000000000..2adf3bd6994 --- /dev/null +++ b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/classInitializer/classInitializerAtClass2.kt.after @@ -0,0 +1,9 @@ +// MOVE: up +class A { + class B { + + { + + } + } +} \ No newline at end of file diff --git a/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/classInitializer/classInitializerAtClassInitializer1.kt b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/classInitializer/classInitializerAtClassInitializer1.kt new file mode 100644 index 00000000000..4aa8284a1e5 --- /dev/null +++ b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/classInitializer/classInitializerAtClassInitializer1.kt @@ -0,0 +1,9 @@ +// MOVE: down +class A { + { + + } + { + + } +} \ No newline at end of file diff --git a/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/classInitializer/classInitializerAtClassInitializer1.kt.after b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/classInitializer/classInitializerAtClassInitializer1.kt.after new file mode 100644 index 00000000000..19f70a7a811 --- /dev/null +++ b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/classInitializer/classInitializerAtClassInitializer1.kt.after @@ -0,0 +1,9 @@ +// MOVE: down +class A { + { + + } + { + + } +} \ No newline at end of file diff --git a/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/classInitializer/classInitializerAtClassInitializer2.kt b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/classInitializer/classInitializerAtClassInitializer2.kt new file mode 100644 index 00000000000..1f4c19053ca --- /dev/null +++ b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/classInitializer/classInitializerAtClassInitializer2.kt @@ -0,0 +1,9 @@ +// MOVE: up +class A { + { + + } + { + + } +} \ No newline at end of file diff --git a/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/classInitializer/classInitializerAtClassInitializer2.kt.after b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/classInitializer/classInitializerAtClassInitializer2.kt.after new file mode 100644 index 00000000000..e4331ac665d --- /dev/null +++ b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/classInitializer/classInitializerAtClassInitializer2.kt.after @@ -0,0 +1,9 @@ +// MOVE: up +class A { + { + + } + { + + } +} \ No newline at end of file diff --git a/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/classInitializer/classInitializerAtEmptyLine1.kt b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/classInitializer/classInitializerAtEmptyLine1.kt new file mode 100644 index 00000000000..24c23194614 --- /dev/null +++ b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/classInitializer/classInitializerAtEmptyLine1.kt @@ -0,0 +1,8 @@ +// MOVE: down +class A { + { + + } + + val y = "" +} \ No newline at end of file diff --git a/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/classInitializer/classInitializerAtEmptyLine1.kt.after b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/classInitializer/classInitializerAtEmptyLine1.kt.after new file mode 100644 index 00000000000..7bf43a8bc70 --- /dev/null +++ b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/classInitializer/classInitializerAtEmptyLine1.kt.after @@ -0,0 +1,8 @@ +// MOVE: down +class A { + val y = "" + + { + + } +} \ No newline at end of file diff --git a/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/classInitializer/classInitializerAtEmptyLine2.kt b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/classInitializer/classInitializerAtEmptyLine2.kt new file mode 100644 index 00000000000..0db82eeed0a --- /dev/null +++ b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/classInitializer/classInitializerAtEmptyLine2.kt @@ -0,0 +1,8 @@ +// MOVE: up +class A { + val x = "" + + { + + } +} \ No newline at end of file diff --git a/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/classInitializer/classInitializerAtEmptyLine2.kt.after b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/classInitializer/classInitializerAtEmptyLine2.kt.after new file mode 100644 index 00000000000..26c68820d05 --- /dev/null +++ b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/classInitializer/classInitializerAtEmptyLine2.kt.after @@ -0,0 +1,8 @@ +// MOVE: up +class A { + { + + } + + val x = "" +} \ No newline at end of file diff --git a/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/classInitializer/classInitializerAtFunction1.kt b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/classInitializer/classInitializerAtFunction1.kt new file mode 100644 index 00000000000..320823670f7 --- /dev/null +++ b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/classInitializer/classInitializerAtFunction1.kt @@ -0,0 +1,9 @@ +// MOVE: down +class A { + { + + } + fun foo() { + + } +} \ No newline at end of file diff --git a/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/classInitializer/classInitializerAtFunction1.kt.after b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/classInitializer/classInitializerAtFunction1.kt.after new file mode 100644 index 00000000000..8f1498c5712 --- /dev/null +++ b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/classInitializer/classInitializerAtFunction1.kt.after @@ -0,0 +1,9 @@ +// MOVE: down +class A { + fun foo() { + + } + { + + } +} \ No newline at end of file diff --git a/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/classInitializer/classInitializerAtFunction2.kt b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/classInitializer/classInitializerAtFunction2.kt new file mode 100644 index 00000000000..b760f2b323f --- /dev/null +++ b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/classInitializer/classInitializerAtFunction2.kt @@ -0,0 +1,9 @@ +// MOVE: up +class A { + fun foo() { + + } + { + + } +} \ No newline at end of file diff --git a/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/classInitializer/classInitializerAtFunction2.kt.after b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/classInitializer/classInitializerAtFunction2.kt.after new file mode 100644 index 00000000000..14466daa282 --- /dev/null +++ b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/classInitializer/classInitializerAtFunction2.kt.after @@ -0,0 +1,9 @@ +// MOVE: up +class A { + { + + } + fun foo() { + + } +} \ No newline at end of file diff --git a/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/classInitializer/classInitializerAtProperty1.kt b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/classInitializer/classInitializerAtProperty1.kt new file mode 100644 index 00000000000..311bfea21c7 --- /dev/null +++ b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/classInitializer/classInitializerAtProperty1.kt @@ -0,0 +1,7 @@ +// MOVE: down +class A { + { + + } + val y = "" +} \ No newline at end of file diff --git a/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/classInitializer/classInitializerAtProperty1.kt.after b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/classInitializer/classInitializerAtProperty1.kt.after new file mode 100644 index 00000000000..33e1b63aea3 --- /dev/null +++ b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/classInitializer/classInitializerAtProperty1.kt.after @@ -0,0 +1,7 @@ +// MOVE: down +class A { + val y = "" + { + + } +} \ No newline at end of file diff --git a/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/classInitializer/classInitializerAtProperty2.kt b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/classInitializer/classInitializerAtProperty2.kt new file mode 100644 index 00000000000..edc47ba9a63 --- /dev/null +++ b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/classInitializer/classInitializerAtProperty2.kt @@ -0,0 +1,7 @@ +// MOVE: up +class A { + val y = "" + { + + } +} \ No newline at end of file diff --git a/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/classInitializer/classInitializerAtProperty2.kt.after b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/classInitializer/classInitializerAtProperty2.kt.after new file mode 100644 index 00000000000..639531d527e --- /dev/null +++ b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/classInitializer/classInitializerAtProperty2.kt.after @@ -0,0 +1,7 @@ +// MOVE: up +class A { + { + + } + val y = "" +} \ No newline at end of file diff --git a/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/enums/enum1.kt b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/enums/enum1.kt new file mode 100644 index 00000000000..4ae012544bb --- /dev/null +++ b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/enums/enum1.kt @@ -0,0 +1,7 @@ +// MOVE: down +class A { + enum class B { + X + Y + } +} \ No newline at end of file diff --git a/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/enums/enum1.kt.after b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/enums/enum1.kt.after new file mode 100644 index 00000000000..c5204c15f7b --- /dev/null +++ b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/enums/enum1.kt.after @@ -0,0 +1,7 @@ +// MOVE: down +class A { + enum class B { + Y + X + } +} \ No newline at end of file diff --git a/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/enums/enum2.kt b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/enums/enum2.kt new file mode 100644 index 00000000000..bee76ae3993 --- /dev/null +++ b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/enums/enum2.kt @@ -0,0 +1,8 @@ +// MOVE: up +// IS_APPLICABLE: false +class A { + enum class B { + X + Y + } +} \ No newline at end of file diff --git a/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/enums/enum3.kt b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/enums/enum3.kt new file mode 100644 index 00000000000..174f5429afa --- /dev/null +++ b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/enums/enum3.kt @@ -0,0 +1,8 @@ +// MOVE: down +// IS_APPLICABLE: false +class A { + enum class B { + X + Y + } +} \ No newline at end of file diff --git a/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/enums/enum4.kt b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/enums/enum4.kt new file mode 100644 index 00000000000..d4728baaea8 --- /dev/null +++ b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/enums/enum4.kt @@ -0,0 +1,7 @@ +// MOVE: up +class A { + enum class B { + X + Y + } +} \ No newline at end of file diff --git a/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/enums/enum4.kt.after b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/enums/enum4.kt.after new file mode 100644 index 00000000000..cbd8a807887 --- /dev/null +++ b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/enums/enum4.kt.after @@ -0,0 +1,7 @@ +// MOVE: up +class A { + enum class B { + Y + X + } +} \ No newline at end of file diff --git a/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/enums/enum5.kt b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/enums/enum5.kt new file mode 100644 index 00000000000..83702b078af --- /dev/null +++ b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/enums/enum5.kt @@ -0,0 +1,10 @@ +// MOVE: up +enum class A { + U + V + + enum class B { + X + Y + } +} \ No newline at end of file diff --git a/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/enums/enum5.kt.after b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/enums/enum5.kt.after new file mode 100644 index 00000000000..cc4b4b404ae --- /dev/null +++ b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/enums/enum5.kt.after @@ -0,0 +1,10 @@ +// MOVE: up +enum class A { + U + V + + X + enum class B { + Y + } +} \ No newline at end of file diff --git a/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/enums/enum6.kt b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/enums/enum6.kt new file mode 100644 index 00000000000..97a1cd07409 --- /dev/null +++ b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/enums/enum6.kt @@ -0,0 +1,10 @@ +// MOVE: down +enum class A { + U + V + + enum class B { + X + Y + } +} \ No newline at end of file diff --git a/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/enums/enum6.kt.after b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/enums/enum6.kt.after new file mode 100644 index 00000000000..1b3cf977b69 --- /dev/null +++ b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/enums/enum6.kt.after @@ -0,0 +1,10 @@ +// MOVE: down +enum class A { + U + V + + enum class B { + X + } + Y +} \ No newline at end of file diff --git a/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/function/functionAtBrace1.kt b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/function/functionAtBrace1.kt new file mode 100644 index 00000000000..da0d16d59c6 --- /dev/null +++ b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/function/functionAtBrace1.kt @@ -0,0 +1,8 @@ +// MOVE: down +class A { + val x = "" + + fun foo() { + + } +} \ No newline at end of file diff --git a/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/function/functionAtBrace1.kt.after b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/function/functionAtBrace1.kt.after new file mode 100644 index 00000000000..3e4844d3aca --- /dev/null +++ b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/function/functionAtBrace1.kt.after @@ -0,0 +1,8 @@ +// MOVE: down +class A { + val x = "" + +} +fun foo() { + +} diff --git a/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/function/functionAtBrace2.kt b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/function/functionAtBrace2.kt new file mode 100644 index 00000000000..890a295d7c5 --- /dev/null +++ b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/function/functionAtBrace2.kt @@ -0,0 +1,8 @@ +// MOVE: up +class A { + fun foo() { + + } + + val y = "" +} \ No newline at end of file diff --git a/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/function/functionAtBrace2.kt.after b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/function/functionAtBrace2.kt.after new file mode 100644 index 00000000000..047bcb5dbe5 --- /dev/null +++ b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/function/functionAtBrace2.kt.after @@ -0,0 +1,8 @@ +// MOVE: up +fun foo() { + +} +class A { + + val y = "" +} \ No newline at end of file diff --git a/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/function/functionAtBrace3.kt b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/function/functionAtBrace3.kt new file mode 100644 index 00000000000..f6c03ac3d36 --- /dev/null +++ b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/function/functionAtBrace3.kt @@ -0,0 +1,8 @@ +// MOVE: down +class A { + class B { + fun foo() { + + } + } +} \ No newline at end of file diff --git a/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/function/functionAtBrace3.kt.after b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/function/functionAtBrace3.kt.after new file mode 100644 index 00000000000..6c850a5f3f0 --- /dev/null +++ b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/function/functionAtBrace3.kt.after @@ -0,0 +1,8 @@ +// MOVE: down +class A { + class B { + } + fun foo() { + + } +} \ No newline at end of file diff --git a/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/function/functionAtBrace4.kt b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/function/functionAtBrace4.kt new file mode 100644 index 00000000000..d5e17c63f8a --- /dev/null +++ b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/function/functionAtBrace4.kt @@ -0,0 +1,8 @@ +// MOVE: up +class A { + class B { + fun foo() { + + } + } +} \ No newline at end of file diff --git a/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/function/functionAtBrace4.kt.after b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/function/functionAtBrace4.kt.after new file mode 100644 index 00000000000..862f49f1559 --- /dev/null +++ b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/function/functionAtBrace4.kt.after @@ -0,0 +1,8 @@ +// MOVE: up +class A { + fun foo() { + + } + class B { + } +} \ No newline at end of file diff --git a/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/function/functionAtBrace5.kt b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/function/functionAtBrace5.kt new file mode 100644 index 00000000000..977102561eb --- /dev/null +++ b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/function/functionAtBrace5.kt @@ -0,0 +1,9 @@ +// MOVE: down +// IS_APPLICABLE: false +fun foo() { + class B { + fun foo() { + + } + } +} \ No newline at end of file diff --git a/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/function/functionAtBrace6.kt b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/function/functionAtBrace6.kt new file mode 100644 index 00000000000..d3a54cf6fc1 --- /dev/null +++ b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/function/functionAtBrace6.kt @@ -0,0 +1,9 @@ +// MOVE: up +// IS_APPLICABLE: false +fun foo() { + class B { + fun foo() { + + } + } +} \ No newline at end of file diff --git a/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/function/functionAtClass1.kt b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/function/functionAtClass1.kt new file mode 100644 index 00000000000..2cd599697ee --- /dev/null +++ b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/function/functionAtClass1.kt @@ -0,0 +1,9 @@ +// MOVE: down +class A { + fun foo() { + + } + class B { + + } +} \ No newline at end of file diff --git a/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/function/functionAtClass1.kt.after b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/function/functionAtClass1.kt.after new file mode 100644 index 00000000000..451987e96c0 --- /dev/null +++ b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/function/functionAtClass1.kt.after @@ -0,0 +1,9 @@ +// MOVE: down +class A { + class B { + fun foo() { + + } + + } +} \ No newline at end of file diff --git a/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/function/functionAtClass2.kt b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/function/functionAtClass2.kt new file mode 100644 index 00000000000..64a149bd3e6 --- /dev/null +++ b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/function/functionAtClass2.kt @@ -0,0 +1,9 @@ +// MOVE: up +class A { + class B { + + } + fun foo() { + + } +} \ No newline at end of file diff --git a/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/function/functionAtClass2.kt.after b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/function/functionAtClass2.kt.after new file mode 100644 index 00000000000..bfe43bde50b --- /dev/null +++ b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/function/functionAtClass2.kt.after @@ -0,0 +1,9 @@ +// MOVE: up +class A { + class B { + + fun foo() { + + } + } +} \ No newline at end of file diff --git a/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/function/functionAtClassInitializer1.kt b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/function/functionAtClassInitializer1.kt new file mode 100644 index 00000000000..49862cd92fa --- /dev/null +++ b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/function/functionAtClassInitializer1.kt @@ -0,0 +1,9 @@ +// MOVE: down +class A { + fun foo() { + + } + { + + } +} \ No newline at end of file diff --git a/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/function/functionAtClassInitializer1.kt.after b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/function/functionAtClassInitializer1.kt.after new file mode 100644 index 00000000000..256788cf66a --- /dev/null +++ b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/function/functionAtClassInitializer1.kt.after @@ -0,0 +1,9 @@ +// MOVE: down +class A { + { + + } + fun foo() { + + } +} \ No newline at end of file diff --git a/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/function/functionAtClassInitializer2.kt b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/function/functionAtClassInitializer2.kt new file mode 100644 index 00000000000..69731c0828e --- /dev/null +++ b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/function/functionAtClassInitializer2.kt @@ -0,0 +1,9 @@ +// MOVE: up +class A { + { + + } + fun foo() { + + } +} \ No newline at end of file diff --git a/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/function/functionAtClassInitializer2.kt.after b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/function/functionAtClassInitializer2.kt.after new file mode 100644 index 00000000000..6277aed9f85 --- /dev/null +++ b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/function/functionAtClassInitializer2.kt.after @@ -0,0 +1,9 @@ +// MOVE: up +class A { + fun foo() { + + } + { + + } +} \ No newline at end of file diff --git a/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/function/functionAtEmptyLine1.kt b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/function/functionAtEmptyLine1.kt new file mode 100644 index 00000000000..4094dac0928 --- /dev/null +++ b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/function/functionAtEmptyLine1.kt @@ -0,0 +1,8 @@ +// MOVE: down +class A { + fun foo() { + + } + + val y = "" +} \ No newline at end of file diff --git a/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/function/functionAtEmptyLine1.kt.after b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/function/functionAtEmptyLine1.kt.after new file mode 100644 index 00000000000..4e4d801f3b8 --- /dev/null +++ b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/function/functionAtEmptyLine1.kt.after @@ -0,0 +1,8 @@ +// MOVE: down +class A { + val y = "" + + fun foo() { + + } +} \ No newline at end of file diff --git a/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/function/functionAtEmptyLine2.kt b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/function/functionAtEmptyLine2.kt new file mode 100644 index 00000000000..7b24eec0b88 --- /dev/null +++ b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/function/functionAtEmptyLine2.kt @@ -0,0 +1,8 @@ +// MOVE: up +class A { + val x = "" + + fun foo() { + + } +} \ No newline at end of file diff --git a/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/function/functionAtEmptyLine2.kt.after b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/function/functionAtEmptyLine2.kt.after new file mode 100644 index 00000000000..b7a881772e1 --- /dev/null +++ b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/function/functionAtEmptyLine2.kt.after @@ -0,0 +1,8 @@ +// MOVE: up +class A { + fun foo() { + + } + + val x = "" +} \ No newline at end of file diff --git a/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/function/functionAtFunction1.kt b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/function/functionAtFunction1.kt new file mode 100644 index 00000000000..4c7bdd78a3c --- /dev/null +++ b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/function/functionAtFunction1.kt @@ -0,0 +1,9 @@ +// MOVE: down +class A { + fun foo() { + + } + fun foo() { + + } +} \ No newline at end of file diff --git a/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/function/functionAtFunction1.kt.after b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/function/functionAtFunction1.kt.after new file mode 100644 index 00000000000..fec94704f1f --- /dev/null +++ b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/function/functionAtFunction1.kt.after @@ -0,0 +1,9 @@ +// MOVE: down +class A { + fun foo() { + + } + fun foo() { + + } +} \ No newline at end of file diff --git a/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/function/functionAtFunction2.kt b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/function/functionAtFunction2.kt new file mode 100644 index 00000000000..d019e81a5bb --- /dev/null +++ b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/function/functionAtFunction2.kt @@ -0,0 +1,9 @@ +// MOVE: up +class A { + fun foo() { + + } + fun foo() { + + } +} \ No newline at end of file diff --git a/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/function/functionAtFunction2.kt.after b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/function/functionAtFunction2.kt.after new file mode 100644 index 00000000000..93202aaf691 --- /dev/null +++ b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/function/functionAtFunction2.kt.after @@ -0,0 +1,9 @@ +// MOVE: up +class A { + fun foo() { + + } + fun foo() { + + } +} \ No newline at end of file diff --git a/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/function/functionAtProperty1.kt b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/function/functionAtProperty1.kt new file mode 100644 index 00000000000..d8a3887b204 --- /dev/null +++ b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/function/functionAtProperty1.kt @@ -0,0 +1,7 @@ +// MOVE: down +class A { + fun foo() { + + } + val y = "" +} \ No newline at end of file diff --git a/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/function/functionAtProperty1.kt.after b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/function/functionAtProperty1.kt.after new file mode 100644 index 00000000000..8ea5a5d2fd8 --- /dev/null +++ b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/function/functionAtProperty1.kt.after @@ -0,0 +1,7 @@ +// MOVE: down +class A { + val y = "" + fun foo() { + + } +} \ No newline at end of file diff --git a/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/function/functionAtProperty2.kt b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/function/functionAtProperty2.kt new file mode 100644 index 00000000000..e013617ebc6 --- /dev/null +++ b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/function/functionAtProperty2.kt @@ -0,0 +1,7 @@ +// MOVE: up +class A { + val y = "" + fun foo() { + + } +} \ No newline at end of file diff --git a/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/function/functionAtProperty2.kt.after b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/function/functionAtProperty2.kt.after new file mode 100644 index 00000000000..80a5ce4d34e --- /dev/null +++ b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/function/functionAtProperty2.kt.after @@ -0,0 +1,7 @@ +// MOVE: up +class A { + fun foo() { + + } + val y = "" +} \ No newline at end of file diff --git a/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/property/propertyAtBrace1.kt b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/property/propertyAtBrace1.kt new file mode 100644 index 00000000000..2ba360e9efe --- /dev/null +++ b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/property/propertyAtBrace1.kt @@ -0,0 +1,6 @@ +// MOVE: down +class A { + val x = "" + + val y = "" +} \ No newline at end of file diff --git a/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/property/propertyAtBrace1.kt.after b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/property/propertyAtBrace1.kt.after new file mode 100644 index 00000000000..660bf8af9e1 --- /dev/null +++ b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/property/propertyAtBrace1.kt.after @@ -0,0 +1,6 @@ +// MOVE: down +class A { + val x = "" + +} +val y = "" diff --git a/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/property/propertyAtBrace2.kt b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/property/propertyAtBrace2.kt new file mode 100644 index 00000000000..7f94c0ac8d8 --- /dev/null +++ b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/property/propertyAtBrace2.kt @@ -0,0 +1,6 @@ +// MOVE: up +class A { + val x = "" + + val y = "" +} \ No newline at end of file diff --git a/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/property/propertyAtBrace2.kt.after b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/property/propertyAtBrace2.kt.after new file mode 100644 index 00000000000..c47556639ea --- /dev/null +++ b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/property/propertyAtBrace2.kt.after @@ -0,0 +1,6 @@ +// MOVE: up +val x = "" +class A { + + val y = "" +} \ No newline at end of file diff --git a/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/property/propertyAtBrace3.kt b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/property/propertyAtBrace3.kt new file mode 100644 index 00000000000..3e5dbf4d82b --- /dev/null +++ b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/property/propertyAtBrace3.kt @@ -0,0 +1,6 @@ +// MOVE: down +class A { + class B { + val y = "" + } +} \ No newline at end of file diff --git a/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/property/propertyAtBrace3.kt.after b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/property/propertyAtBrace3.kt.after new file mode 100644 index 00000000000..28def27d9bb --- /dev/null +++ b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/property/propertyAtBrace3.kt.after @@ -0,0 +1,6 @@ +// MOVE: down +class A { + class B { + } + val y = "" +} \ No newline at end of file diff --git a/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/property/propertyAtBrace4.kt b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/property/propertyAtBrace4.kt new file mode 100644 index 00000000000..5e3c869f9b1 --- /dev/null +++ b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/property/propertyAtBrace4.kt @@ -0,0 +1,6 @@ +// MOVE: up +class A { + class B { + val y = "" + } +} \ No newline at end of file diff --git a/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/property/propertyAtBrace4.kt.after b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/property/propertyAtBrace4.kt.after new file mode 100644 index 00000000000..89d0876a81a --- /dev/null +++ b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/property/propertyAtBrace4.kt.after @@ -0,0 +1,6 @@ +// MOVE: up +class A { + val y = "" + class B { + } +} \ No newline at end of file diff --git a/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/property/propertyAtBrace5.kt b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/property/propertyAtBrace5.kt new file mode 100644 index 00000000000..97ca96de10c --- /dev/null +++ b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/property/propertyAtBrace5.kt @@ -0,0 +1,7 @@ +// MOVE: down +// IS_APPLICABLE: false +fun foo() { + class B { + val y = "" + } +} \ No newline at end of file diff --git a/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/property/propertyAtBrace6.kt b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/property/propertyAtBrace6.kt new file mode 100644 index 00000000000..bfe83368b6b --- /dev/null +++ b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/property/propertyAtBrace6.kt @@ -0,0 +1,7 @@ +// MOVE: up +// IS_APPLICABLE: false +fun foo() { + class B { + val y = "" + } +} \ No newline at end of file diff --git a/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/property/propertyAtClass1.kt b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/property/propertyAtClass1.kt new file mode 100644 index 00000000000..a4afb87fdf6 --- /dev/null +++ b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/property/propertyAtClass1.kt @@ -0,0 +1,7 @@ +// MOVE: down +class A { + val x = "" + class B { + + } +} \ No newline at end of file diff --git a/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/property/propertyAtClass1.kt.after b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/property/propertyAtClass1.kt.after new file mode 100644 index 00000000000..7d20f71189c --- /dev/null +++ b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/property/propertyAtClass1.kt.after @@ -0,0 +1,7 @@ +// MOVE: down +class A { + class B { + val x = "" + + } +} \ No newline at end of file diff --git a/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/property/propertyAtClass2.kt b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/property/propertyAtClass2.kt new file mode 100644 index 00000000000..4b483cc8c42 --- /dev/null +++ b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/property/propertyAtClass2.kt @@ -0,0 +1,7 @@ +// MOVE: up +class A { + class B { + + } + val x = "" +} \ No newline at end of file diff --git a/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/property/propertyAtClass2.kt.after b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/property/propertyAtClass2.kt.after new file mode 100644 index 00000000000..fd5185d4e3e --- /dev/null +++ b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/property/propertyAtClass2.kt.after @@ -0,0 +1,7 @@ +// MOVE: up +class A { + class B { + + val x = "" + } +} \ No newline at end of file diff --git a/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/property/propertyAtClassInitializer1.kt b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/property/propertyAtClassInitializer1.kt new file mode 100644 index 00000000000..d34dca815da --- /dev/null +++ b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/property/propertyAtClassInitializer1.kt @@ -0,0 +1,7 @@ +// MOVE: down +class A { + val x = "" + { + + } +} \ No newline at end of file diff --git a/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/property/propertyAtClassInitializer1.kt.after b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/property/propertyAtClassInitializer1.kt.after new file mode 100644 index 00000000000..ea29706876a --- /dev/null +++ b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/property/propertyAtClassInitializer1.kt.after @@ -0,0 +1,7 @@ +// MOVE: down +class A { + { + + } + val x = "" +} \ No newline at end of file diff --git a/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/property/propertyAtClassInitializer2.kt b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/property/propertyAtClassInitializer2.kt new file mode 100644 index 00000000000..86d1b0124f6 --- /dev/null +++ b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/property/propertyAtClassInitializer2.kt @@ -0,0 +1,7 @@ +// MOVE: up +class A { + { + + } + val x = "" +} \ No newline at end of file diff --git a/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/property/propertyAtClassInitializer2.kt.after b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/property/propertyAtClassInitializer2.kt.after new file mode 100644 index 00000000000..56abf6d5b73 --- /dev/null +++ b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/property/propertyAtClassInitializer2.kt.after @@ -0,0 +1,7 @@ +// MOVE: up +class A { + val x = "" + { + + } +} \ No newline at end of file diff --git a/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/property/propertyAtEmptyLine1.kt b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/property/propertyAtEmptyLine1.kt new file mode 100644 index 00000000000..3143a3065e0 --- /dev/null +++ b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/property/propertyAtEmptyLine1.kt @@ -0,0 +1,6 @@ +// MOVE: down +class A { + val x = "" + + val y = "" +} \ No newline at end of file diff --git a/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/property/propertyAtEmptyLine1.kt.after b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/property/propertyAtEmptyLine1.kt.after new file mode 100644 index 00000000000..ea331d0437f --- /dev/null +++ b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/property/propertyAtEmptyLine1.kt.after @@ -0,0 +1,6 @@ +// MOVE: down +class A { + val y = "" + + val x = "" +} \ No newline at end of file diff --git a/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/property/propertyAtEmptyLine2.kt b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/property/propertyAtEmptyLine2.kt new file mode 100644 index 00000000000..365cbec7f8c --- /dev/null +++ b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/property/propertyAtEmptyLine2.kt @@ -0,0 +1,6 @@ +// MOVE: up +class A { + val x = "" + + val y = "" +} \ No newline at end of file diff --git a/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/property/propertyAtEmptyLine2.kt.after b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/property/propertyAtEmptyLine2.kt.after new file mode 100644 index 00000000000..66a6c8aafb2 --- /dev/null +++ b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/property/propertyAtEmptyLine2.kt.after @@ -0,0 +1,6 @@ +// MOVE: up +class A { + val y = "" + + val x = "" +} \ No newline at end of file diff --git a/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/property/propertyAtFunction1.kt b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/property/propertyAtFunction1.kt new file mode 100644 index 00000000000..86d43aa16b2 --- /dev/null +++ b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/property/propertyAtFunction1.kt @@ -0,0 +1,7 @@ +// MOVE: down +class A { + val x = "" + fun foo() { + + } +} \ No newline at end of file diff --git a/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/property/propertyAtFunction1.kt.after b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/property/propertyAtFunction1.kt.after new file mode 100644 index 00000000000..0398f74620d --- /dev/null +++ b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/property/propertyAtFunction1.kt.after @@ -0,0 +1,7 @@ +// MOVE: down +class A { + fun foo() { + + } + val x = "" +} \ No newline at end of file diff --git a/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/property/propertyAtFunction2.kt b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/property/propertyAtFunction2.kt new file mode 100644 index 00000000000..28fbf893349 --- /dev/null +++ b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/property/propertyAtFunction2.kt @@ -0,0 +1,7 @@ +// MOVE: up +class A { + fun foo() { + + } + val x = "" +} \ No newline at end of file diff --git a/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/property/propertyAtFunction2.kt.after b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/property/propertyAtFunction2.kt.after new file mode 100644 index 00000000000..96a307f37dd --- /dev/null +++ b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/property/propertyAtFunction2.kt.after @@ -0,0 +1,7 @@ +// MOVE: up +class A { + val x = "" + fun foo() { + + } +} \ No newline at end of file diff --git a/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/property/propertyAtProperty1.kt b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/property/propertyAtProperty1.kt new file mode 100644 index 00000000000..d88a50f3ee2 --- /dev/null +++ b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/property/propertyAtProperty1.kt @@ -0,0 +1,5 @@ +// MOVE: down +class A { + val x = "" + val y = "" +} \ No newline at end of file diff --git a/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/property/propertyAtProperty1.kt.after b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/property/propertyAtProperty1.kt.after new file mode 100644 index 00000000000..e46e2f58701 --- /dev/null +++ b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/property/propertyAtProperty1.kt.after @@ -0,0 +1,5 @@ +// MOVE: down +class A { + val y = "" + val x = "" +} \ No newline at end of file diff --git a/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/property/propertyAtProperty2.kt b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/property/propertyAtProperty2.kt new file mode 100644 index 00000000000..df38ee26773 --- /dev/null +++ b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/property/propertyAtProperty2.kt @@ -0,0 +1,5 @@ +// MOVE: up +class A { + val y = "" + val x = "" +} \ No newline at end of file diff --git a/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/property/propertyAtProperty2.kt.after b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/property/propertyAtProperty2.kt.after new file mode 100644 index 00000000000..f139e2efebd --- /dev/null +++ b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/property/propertyAtProperty2.kt.after @@ -0,0 +1,5 @@ +// MOVE: up +class A { + val x = "" + val y = "" +} \ No newline at end of file diff --git a/idea/tests/org/jetbrains/jet/plugin/codeInsight/moveUpDown/AbstractCodeMoverTest.java b/idea/tests/org/jetbrains/jet/plugin/codeInsight/moveUpDown/AbstractCodeMoverTest.java new file mode 100644 index 00000000000..b1271d50891 --- /dev/null +++ b/idea/tests/org/jetbrains/jet/plugin/codeInsight/moveUpDown/AbstractCodeMoverTest.java @@ -0,0 +1,87 @@ +/* + * Copyright 2010-2013 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.jetbrains.jet.plugin.codeInsight.moveUpDown; + +import com.intellij.codeInsight.editorActions.moveUpDown.MoveStatementDownAction; +import com.intellij.codeInsight.editorActions.moveUpDown.MoveStatementUpAction; +import com.intellij.codeInsight.editorActions.moveUpDown.StatementUpDownMover; +import com.intellij.openapi.editor.actionSystem.EditorAction; +import com.intellij.openapi.extensions.Extensions; +import com.intellij.openapi.util.io.FileUtil; +import com.intellij.testFramework.LightCodeInsightTestCase; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.jet.InTextDirectivesUtils; +import org.jetbrains.jet.plugin.codeInsight.upDownMover.JetDeclarationMover; + +import java.io.File; + +public abstract class AbstractCodeMoverTest extends LightCodeInsightTestCase { + public void doTestClassBodyDeclaration(@NotNull String path) throws Exception { + doTest(path, JetDeclarationMover.class); + } + + private void doTest(@NotNull String path, @NotNull Class moverClass) throws Exception { + configureByFile(path); + + String fileText = FileUtil.loadFile(new File(path)); + String direction = InTextDirectivesUtils.findStringWithPrefixes(fileText, "// MOVE: "); + + boolean down = true; + if ("up".equals(direction)) { + down = false; + } + else if ("down".equals(direction)) { + down = true; + } + else { + fail("Direction is not specified"); + } + + String isApplicableString = InTextDirectivesUtils.findStringWithPrefixes(fileText, "// IS_APPLICABLE: "); + boolean isApplicableExpected = isApplicableString == null || isApplicableString.equals("true"); + + StatementUpDownMover[] movers = Extensions.getExtensions(StatementUpDownMover.STATEMENT_UP_DOWN_MOVER_EP); + StatementUpDownMover.MoveInfo info = new StatementUpDownMover.MoveInfo(); + StatementUpDownMover actualMover = null; + for (StatementUpDownMover mover : movers) { + if (mover.checkAvailable(getEditor(), getFile(), info, down)) { + actualMover = mover; + break; + } + } + + assertTrue("No mover found", actualMover != null); + assertEquals("Unmatched movers", moverClass, actualMover.getClass()); + assertEquals("Invalid applicability", isApplicableExpected, info.toMove2 != null); + + if (isApplicableExpected) { + invokeAndCheck(path, down); + } + } + + private void invokeAndCheck(@NotNull String path, boolean down) { + EditorAction action = down ? new MoveStatementDownAction() : new MoveStatementUpAction(); + action.actionPerformed(getEditor(), getCurrentEditorDataContext()); + checkResultByFile(path + ".after"); + } + + @NotNull + @Override + protected String getTestDataPath() { + return ""; + } +} diff --git a/idea/tests/org/jetbrains/jet/plugin/codeInsight/moveUpDown/CodeMoverTestGenerated.java b/idea/tests/org/jetbrains/jet/plugin/codeInsight/moveUpDown/CodeMoverTestGenerated.java new file mode 100644 index 00000000000..44c810ed49d --- /dev/null +++ b/idea/tests/org/jetbrains/jet/plugin/codeInsight/moveUpDown/CodeMoverTestGenerated.java @@ -0,0 +1,458 @@ +/* + * Copyright 2010-2013 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.jetbrains.jet.plugin.codeInsight.moveUpDown; + +import junit.framework.Assert; +import junit.framework.Test; +import junit.framework.TestSuite; + +import java.io.File; +import java.util.regex.Pattern; +import org.jetbrains.jet.JetTestUtils; +import org.jetbrains.jet.test.InnerTestClasses; +import org.jetbrains.jet.test.TestMetadata; + +import org.jetbrains.jet.plugin.codeInsight.moveUpDown.AbstractCodeMoverTest; + +/** This class is generated by {@link org.jetbrains.jet.generators.tests.GenerateTests}. DO NOT MODIFY MANUALLY */ +@SuppressWarnings("all") +@InnerTestClasses({CodeMoverTestGenerated.ClassBodyDeclarations.class}) +public class CodeMoverTestGenerated extends AbstractCodeMoverTest { + @TestMetadata("idea/testData/codeInsight/moveUpDown/classBodyDeclarations") + @InnerTestClasses({ClassBodyDeclarations.Accessors.class, ClassBodyDeclarations.Class.class, ClassBodyDeclarations.ClassInitializer.class, ClassBodyDeclarations.Enums.class, ClassBodyDeclarations.Function.class, ClassBodyDeclarations.Property.class}) + public static class ClassBodyDeclarations extends AbstractCodeMoverTest { + public void testAllFilesPresentInClassBodyDeclarations() throws Exception { + JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.GenerateTests", new File("idea/testData/codeInsight/moveUpDown/classBodyDeclarations"), Pattern.compile("^(.+)\\.kt$"), true); + } + + @TestMetadata("idea/testData/codeInsight/moveUpDown/classBodyDeclarations/accessors") + public static class Accessors extends AbstractCodeMoverTest { + @TestMetadata("accessor1.kt") + public void testAccessor1() throws Exception { + doTestClassBodyDeclaration("idea/testData/codeInsight/moveUpDown/classBodyDeclarations/accessors/accessor1.kt"); + } + + @TestMetadata("accessor2.kt") + public void testAccessor2() throws Exception { + doTestClassBodyDeclaration("idea/testData/codeInsight/moveUpDown/classBodyDeclarations/accessors/accessor2.kt"); + } + + @TestMetadata("accessor3.kt") + public void testAccessor3() throws Exception { + doTestClassBodyDeclaration("idea/testData/codeInsight/moveUpDown/classBodyDeclarations/accessors/accessor3.kt"); + } + + @TestMetadata("accessor4.kt") + public void testAccessor4() throws Exception { + doTestClassBodyDeclaration("idea/testData/codeInsight/moveUpDown/classBodyDeclarations/accessors/accessor4.kt"); + } + + public void testAllFilesPresentInAccessors() throws Exception { + JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.GenerateTests", new File("idea/testData/codeInsight/moveUpDown/classBodyDeclarations/accessors"), Pattern.compile("^(.+)\\.kt$"), true); + } + + } + + @TestMetadata("idea/testData/codeInsight/moveUpDown/classBodyDeclarations/class") + public static class Class extends AbstractCodeMoverTest { + public void testAllFilesPresentInClass() throws Exception { + JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.GenerateTests", new File("idea/testData/codeInsight/moveUpDown/classBodyDeclarations/class"), Pattern.compile("^(.+)\\.kt$"), true); + } + + @TestMetadata("classAtBrace1.kt") + public void testClassAtBrace1() throws Exception { + doTestClassBodyDeclaration("idea/testData/codeInsight/moveUpDown/classBodyDeclarations/class/classAtBrace1.kt"); + } + + @TestMetadata("classAtBrace2.kt") + public void testClassAtBrace2() throws Exception { + doTestClassBodyDeclaration("idea/testData/codeInsight/moveUpDown/classBodyDeclarations/class/classAtBrace2.kt"); + } + + @TestMetadata("classAtBrace3.kt") + public void testClassAtBrace3() throws Exception { + doTestClassBodyDeclaration("idea/testData/codeInsight/moveUpDown/classBodyDeclarations/class/classAtBrace3.kt"); + } + + @TestMetadata("classAtBrace4.kt") + public void testClassAtBrace4() throws Exception { + doTestClassBodyDeclaration("idea/testData/codeInsight/moveUpDown/classBodyDeclarations/class/classAtBrace4.kt"); + } + + @TestMetadata("classAtBrace5.kt") + public void testClassAtBrace5() throws Exception { + doTestClassBodyDeclaration("idea/testData/codeInsight/moveUpDown/classBodyDeclarations/class/classAtBrace5.kt"); + } + + @TestMetadata("classAtBrace6.kt") + public void testClassAtBrace6() throws Exception { + doTestClassBodyDeclaration("idea/testData/codeInsight/moveUpDown/classBodyDeclarations/class/classAtBrace6.kt"); + } + + @TestMetadata("classAtClass1.kt") + public void testClassAtClass1() throws Exception { + doTestClassBodyDeclaration("idea/testData/codeInsight/moveUpDown/classBodyDeclarations/class/classAtClass1.kt"); + } + + @TestMetadata("classAtClass2.kt") + public void testClassAtClass2() throws Exception { + doTestClassBodyDeclaration("idea/testData/codeInsight/moveUpDown/classBodyDeclarations/class/classAtClass2.kt"); + } + + @TestMetadata("classAtClassInitializer1.kt") + public void testClassAtClassInitializer1() throws Exception { + doTestClassBodyDeclaration("idea/testData/codeInsight/moveUpDown/classBodyDeclarations/class/classAtClassInitializer1.kt"); + } + + @TestMetadata("classAtClassInitializer2.kt") + public void testClassAtClassInitializer2() throws Exception { + doTestClassBodyDeclaration("idea/testData/codeInsight/moveUpDown/classBodyDeclarations/class/classAtClassInitializer2.kt"); + } + + @TestMetadata("classAtEmptyLine1.kt") + public void testClassAtEmptyLine1() throws Exception { + doTestClassBodyDeclaration("idea/testData/codeInsight/moveUpDown/classBodyDeclarations/class/classAtEmptyLine1.kt"); + } + + @TestMetadata("classAtEmptyLine2.kt") + public void testClassAtEmptyLine2() throws Exception { + doTestClassBodyDeclaration("idea/testData/codeInsight/moveUpDown/classBodyDeclarations/class/classAtEmptyLine2.kt"); + } + + @TestMetadata("classAtFunction1.kt") + public void testClassAtFunction1() throws Exception { + doTestClassBodyDeclaration("idea/testData/codeInsight/moveUpDown/classBodyDeclarations/class/classAtFunction1.kt"); + } + + @TestMetadata("classAtFunction2.kt") + public void testClassAtFunction2() throws Exception { + doTestClassBodyDeclaration("idea/testData/codeInsight/moveUpDown/classBodyDeclarations/class/classAtFunction2.kt"); + } + + @TestMetadata("classAtProperty1.kt") + public void testClassAtProperty1() throws Exception { + doTestClassBodyDeclaration("idea/testData/codeInsight/moveUpDown/classBodyDeclarations/class/classAtProperty1.kt"); + } + + @TestMetadata("classAtProperty2.kt") + public void testClassAtProperty2() throws Exception { + doTestClassBodyDeclaration("idea/testData/codeInsight/moveUpDown/classBodyDeclarations/class/classAtProperty2.kt"); + } + + } + + @TestMetadata("idea/testData/codeInsight/moveUpDown/classBodyDeclarations/classInitializer") + public static class ClassInitializer extends AbstractCodeMoverTest { + public void testAllFilesPresentInClassInitializer() throws Exception { + JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.GenerateTests", new File("idea/testData/codeInsight/moveUpDown/classBodyDeclarations/classInitializer"), Pattern.compile("^(.+)\\.kt$"), true); + } + + @TestMetadata("classInitializerAtBrace1.kt") + public void testClassInitializerAtBrace1() throws Exception { + doTestClassBodyDeclaration("idea/testData/codeInsight/moveUpDown/classBodyDeclarations/classInitializer/classInitializerAtBrace1.kt"); + } + + @TestMetadata("classInitializerAtBrace2.kt") + public void testClassInitializerAtBrace2() throws Exception { + doTestClassBodyDeclaration("idea/testData/codeInsight/moveUpDown/classBodyDeclarations/classInitializer/classInitializerAtBrace2.kt"); + } + + @TestMetadata("classInitializerAtClass1.kt") + public void testClassInitializerAtClass1() throws Exception { + doTestClassBodyDeclaration("idea/testData/codeInsight/moveUpDown/classBodyDeclarations/classInitializer/classInitializerAtClass1.kt"); + } + + @TestMetadata("classInitializerAtClass2.kt") + public void testClassInitializerAtClass2() throws Exception { + doTestClassBodyDeclaration("idea/testData/codeInsight/moveUpDown/classBodyDeclarations/classInitializer/classInitializerAtClass2.kt"); + } + + @TestMetadata("classInitializerAtClassInitializer1.kt") + public void testClassInitializerAtClassInitializer1() throws Exception { + doTestClassBodyDeclaration("idea/testData/codeInsight/moveUpDown/classBodyDeclarations/classInitializer/classInitializerAtClassInitializer1.kt"); + } + + @TestMetadata("classInitializerAtClassInitializer2.kt") + public void testClassInitializerAtClassInitializer2() throws Exception { + doTestClassBodyDeclaration("idea/testData/codeInsight/moveUpDown/classBodyDeclarations/classInitializer/classInitializerAtClassInitializer2.kt"); + } + + @TestMetadata("classInitializerAtEmptyLine1.kt") + public void testClassInitializerAtEmptyLine1() throws Exception { + doTestClassBodyDeclaration("idea/testData/codeInsight/moveUpDown/classBodyDeclarations/classInitializer/classInitializerAtEmptyLine1.kt"); + } + + @TestMetadata("classInitializerAtEmptyLine2.kt") + public void testClassInitializerAtEmptyLine2() throws Exception { + doTestClassBodyDeclaration("idea/testData/codeInsight/moveUpDown/classBodyDeclarations/classInitializer/classInitializerAtEmptyLine2.kt"); + } + + @TestMetadata("classInitializerAtFunction1.kt") + public void testClassInitializerAtFunction1() throws Exception { + doTestClassBodyDeclaration("idea/testData/codeInsight/moveUpDown/classBodyDeclarations/classInitializer/classInitializerAtFunction1.kt"); + } + + @TestMetadata("classInitializerAtFunction2.kt") + public void testClassInitializerAtFunction2() throws Exception { + doTestClassBodyDeclaration("idea/testData/codeInsight/moveUpDown/classBodyDeclarations/classInitializer/classInitializerAtFunction2.kt"); + } + + @TestMetadata("classInitializerAtProperty1.kt") + public void testClassInitializerAtProperty1() throws Exception { + doTestClassBodyDeclaration("idea/testData/codeInsight/moveUpDown/classBodyDeclarations/classInitializer/classInitializerAtProperty1.kt"); + } + + @TestMetadata("classInitializerAtProperty2.kt") + public void testClassInitializerAtProperty2() throws Exception { + doTestClassBodyDeclaration("idea/testData/codeInsight/moveUpDown/classBodyDeclarations/classInitializer/classInitializerAtProperty2.kt"); + } + + } + + @TestMetadata("idea/testData/codeInsight/moveUpDown/classBodyDeclarations/enums") + public static class Enums extends AbstractCodeMoverTest { + public void testAllFilesPresentInEnums() throws Exception { + JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.GenerateTests", new File("idea/testData/codeInsight/moveUpDown/classBodyDeclarations/enums"), Pattern.compile("^(.+)\\.kt$"), true); + } + + @TestMetadata("enum1.kt") + public void testEnum1() throws Exception { + doTestClassBodyDeclaration("idea/testData/codeInsight/moveUpDown/classBodyDeclarations/enums/enum1.kt"); + } + + @TestMetadata("enum2.kt") + public void testEnum2() throws Exception { + doTestClassBodyDeclaration("idea/testData/codeInsight/moveUpDown/classBodyDeclarations/enums/enum2.kt"); + } + + @TestMetadata("enum3.kt") + public void testEnum3() throws Exception { + doTestClassBodyDeclaration("idea/testData/codeInsight/moveUpDown/classBodyDeclarations/enums/enum3.kt"); + } + + @TestMetadata("enum4.kt") + public void testEnum4() throws Exception { + doTestClassBodyDeclaration("idea/testData/codeInsight/moveUpDown/classBodyDeclarations/enums/enum4.kt"); + } + + @TestMetadata("enum5.kt") + public void testEnum5() throws Exception { + doTestClassBodyDeclaration("idea/testData/codeInsight/moveUpDown/classBodyDeclarations/enums/enum5.kt"); + } + + @TestMetadata("enum6.kt") + public void testEnum6() throws Exception { + doTestClassBodyDeclaration("idea/testData/codeInsight/moveUpDown/classBodyDeclarations/enums/enum6.kt"); + } + + } + + @TestMetadata("idea/testData/codeInsight/moveUpDown/classBodyDeclarations/function") + public static class Function extends AbstractCodeMoverTest { + public void testAllFilesPresentInFunction() throws Exception { + JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.GenerateTests", new File("idea/testData/codeInsight/moveUpDown/classBodyDeclarations/function"), Pattern.compile("^(.+)\\.kt$"), true); + } + + @TestMetadata("functionAtBrace1.kt") + public void testFunctionAtBrace1() throws Exception { + doTestClassBodyDeclaration("idea/testData/codeInsight/moveUpDown/classBodyDeclarations/function/functionAtBrace1.kt"); + } + + @TestMetadata("functionAtBrace2.kt") + public void testFunctionAtBrace2() throws Exception { + doTestClassBodyDeclaration("idea/testData/codeInsight/moveUpDown/classBodyDeclarations/function/functionAtBrace2.kt"); + } + + @TestMetadata("functionAtBrace3.kt") + public void testFunctionAtBrace3() throws Exception { + doTestClassBodyDeclaration("idea/testData/codeInsight/moveUpDown/classBodyDeclarations/function/functionAtBrace3.kt"); + } + + @TestMetadata("functionAtBrace4.kt") + public void testFunctionAtBrace4() throws Exception { + doTestClassBodyDeclaration("idea/testData/codeInsight/moveUpDown/classBodyDeclarations/function/functionAtBrace4.kt"); + } + + @TestMetadata("functionAtBrace5.kt") + public void testFunctionAtBrace5() throws Exception { + doTestClassBodyDeclaration("idea/testData/codeInsight/moveUpDown/classBodyDeclarations/function/functionAtBrace5.kt"); + } + + @TestMetadata("functionAtBrace6.kt") + public void testFunctionAtBrace6() throws Exception { + doTestClassBodyDeclaration("idea/testData/codeInsight/moveUpDown/classBodyDeclarations/function/functionAtBrace6.kt"); + } + + @TestMetadata("functionAtClass1.kt") + public void testFunctionAtClass1() throws Exception { + doTestClassBodyDeclaration("idea/testData/codeInsight/moveUpDown/classBodyDeclarations/function/functionAtClass1.kt"); + } + + @TestMetadata("functionAtClass2.kt") + public void testFunctionAtClass2() throws Exception { + doTestClassBodyDeclaration("idea/testData/codeInsight/moveUpDown/classBodyDeclarations/function/functionAtClass2.kt"); + } + + @TestMetadata("functionAtClassInitializer1.kt") + public void testFunctionAtClassInitializer1() throws Exception { + doTestClassBodyDeclaration("idea/testData/codeInsight/moveUpDown/classBodyDeclarations/function/functionAtClassInitializer1.kt"); + } + + @TestMetadata("functionAtClassInitializer2.kt") + public void testFunctionAtClassInitializer2() throws Exception { + doTestClassBodyDeclaration("idea/testData/codeInsight/moveUpDown/classBodyDeclarations/function/functionAtClassInitializer2.kt"); + } + + @TestMetadata("functionAtEmptyLine1.kt") + public void testFunctionAtEmptyLine1() throws Exception { + doTestClassBodyDeclaration("idea/testData/codeInsight/moveUpDown/classBodyDeclarations/function/functionAtEmptyLine1.kt"); + } + + @TestMetadata("functionAtEmptyLine2.kt") + public void testFunctionAtEmptyLine2() throws Exception { + doTestClassBodyDeclaration("idea/testData/codeInsight/moveUpDown/classBodyDeclarations/function/functionAtEmptyLine2.kt"); + } + + @TestMetadata("functionAtFunction1.kt") + public void testFunctionAtFunction1() throws Exception { + doTestClassBodyDeclaration("idea/testData/codeInsight/moveUpDown/classBodyDeclarations/function/functionAtFunction1.kt"); + } + + @TestMetadata("functionAtFunction2.kt") + public void testFunctionAtFunction2() throws Exception { + doTestClassBodyDeclaration("idea/testData/codeInsight/moveUpDown/classBodyDeclarations/function/functionAtFunction2.kt"); + } + + @TestMetadata("functionAtProperty1.kt") + public void testFunctionAtProperty1() throws Exception { + doTestClassBodyDeclaration("idea/testData/codeInsight/moveUpDown/classBodyDeclarations/function/functionAtProperty1.kt"); + } + + @TestMetadata("functionAtProperty2.kt") + public void testFunctionAtProperty2() throws Exception { + doTestClassBodyDeclaration("idea/testData/codeInsight/moveUpDown/classBodyDeclarations/function/functionAtProperty2.kt"); + } + + } + + @TestMetadata("idea/testData/codeInsight/moveUpDown/classBodyDeclarations/property") + public static class Property extends AbstractCodeMoverTest { + public void testAllFilesPresentInProperty() throws Exception { + JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.GenerateTests", new File("idea/testData/codeInsight/moveUpDown/classBodyDeclarations/property"), Pattern.compile("^(.+)\\.kt$"), true); + } + + @TestMetadata("propertyAtBrace1.kt") + public void testPropertyAtBrace1() throws Exception { + doTestClassBodyDeclaration("idea/testData/codeInsight/moveUpDown/classBodyDeclarations/property/propertyAtBrace1.kt"); + } + + @TestMetadata("propertyAtBrace2.kt") + public void testPropertyAtBrace2() throws Exception { + doTestClassBodyDeclaration("idea/testData/codeInsight/moveUpDown/classBodyDeclarations/property/propertyAtBrace2.kt"); + } + + @TestMetadata("propertyAtBrace3.kt") + public void testPropertyAtBrace3() throws Exception { + doTestClassBodyDeclaration("idea/testData/codeInsight/moveUpDown/classBodyDeclarations/property/propertyAtBrace3.kt"); + } + + @TestMetadata("propertyAtBrace4.kt") + public void testPropertyAtBrace4() throws Exception { + doTestClassBodyDeclaration("idea/testData/codeInsight/moveUpDown/classBodyDeclarations/property/propertyAtBrace4.kt"); + } + + @TestMetadata("propertyAtBrace5.kt") + public void testPropertyAtBrace5() throws Exception { + doTestClassBodyDeclaration("idea/testData/codeInsight/moveUpDown/classBodyDeclarations/property/propertyAtBrace5.kt"); + } + + @TestMetadata("propertyAtBrace6.kt") + public void testPropertyAtBrace6() throws Exception { + doTestClassBodyDeclaration("idea/testData/codeInsight/moveUpDown/classBodyDeclarations/property/propertyAtBrace6.kt"); + } + + @TestMetadata("propertyAtClass1.kt") + public void testPropertyAtClass1() throws Exception { + doTestClassBodyDeclaration("idea/testData/codeInsight/moveUpDown/classBodyDeclarations/property/propertyAtClass1.kt"); + } + + @TestMetadata("propertyAtClass2.kt") + public void testPropertyAtClass2() throws Exception { + doTestClassBodyDeclaration("idea/testData/codeInsight/moveUpDown/classBodyDeclarations/property/propertyAtClass2.kt"); + } + + @TestMetadata("propertyAtClassInitializer1.kt") + public void testPropertyAtClassInitializer1() throws Exception { + doTestClassBodyDeclaration("idea/testData/codeInsight/moveUpDown/classBodyDeclarations/property/propertyAtClassInitializer1.kt"); + } + + @TestMetadata("propertyAtClassInitializer2.kt") + public void testPropertyAtClassInitializer2() throws Exception { + doTestClassBodyDeclaration("idea/testData/codeInsight/moveUpDown/classBodyDeclarations/property/propertyAtClassInitializer2.kt"); + } + + @TestMetadata("propertyAtEmptyLine1.kt") + public void testPropertyAtEmptyLine1() throws Exception { + doTestClassBodyDeclaration("idea/testData/codeInsight/moveUpDown/classBodyDeclarations/property/propertyAtEmptyLine1.kt"); + } + + @TestMetadata("propertyAtEmptyLine2.kt") + public void testPropertyAtEmptyLine2() throws Exception { + doTestClassBodyDeclaration("idea/testData/codeInsight/moveUpDown/classBodyDeclarations/property/propertyAtEmptyLine2.kt"); + } + + @TestMetadata("propertyAtFunction1.kt") + public void testPropertyAtFunction1() throws Exception { + doTestClassBodyDeclaration("idea/testData/codeInsight/moveUpDown/classBodyDeclarations/property/propertyAtFunction1.kt"); + } + + @TestMetadata("propertyAtFunction2.kt") + public void testPropertyAtFunction2() throws Exception { + doTestClassBodyDeclaration("idea/testData/codeInsight/moveUpDown/classBodyDeclarations/property/propertyAtFunction2.kt"); + } + + @TestMetadata("propertyAtProperty1.kt") + public void testPropertyAtProperty1() throws Exception { + doTestClassBodyDeclaration("idea/testData/codeInsight/moveUpDown/classBodyDeclarations/property/propertyAtProperty1.kt"); + } + + @TestMetadata("propertyAtProperty2.kt") + public void testPropertyAtProperty2() throws Exception { + doTestClassBodyDeclaration("idea/testData/codeInsight/moveUpDown/classBodyDeclarations/property/propertyAtProperty2.kt"); + } + + } + + public static Test innerSuite() { + TestSuite suite = new TestSuite("ClassBodyDeclarations"); + suite.addTestSuite(ClassBodyDeclarations.class); + suite.addTestSuite(Accessors.class); + suite.addTestSuite(Class.class); + suite.addTestSuite(ClassInitializer.class); + suite.addTestSuite(Enums.class); + suite.addTestSuite(Function.class); + suite.addTestSuite(Property.class); + return suite; + } + } + + public static Test suite() { + TestSuite suite = new TestSuite("CodeMoverTestGenerated"); + suite.addTest(ClassBodyDeclarations.innerSuite()); + return suite; + } +} From b00ec828847973102195a6bc9dbf7afc44a7bfd1 Mon Sep 17 00:00:00 2001 From: Alexey Sedunov Date: Thu, 23 May 2013 20:25:52 +0400 Subject: [PATCH 204/249] Implement "move expression up/down" action handler --- .../jet/lang/psi/JetBlockExpression.java | 12 +- .../jetbrains/jet/lang/psi/JetPsiUtil.java | 53 +++ .../jet/generators/tests/GenerateTests.java | 4 +- idea/src/META-INF/plugin.xml | 4 + .../upDownMover/JetExpressionMover.java | 333 ++++++++++++++++++ .../moveUpDown/closingBraces/for/for1.kt | 7 + .../closingBraces/for/for1.kt.after | 7 + .../moveUpDown/closingBraces/for/for2.kt | 8 + .../moveUpDown/closingBraces/if/if1.kt | 10 + .../moveUpDown/closingBraces/if/if1.kt.after | 10 + .../moveUpDown/closingBraces/if/if2.kt | 11 + .../moveUpDown/closingBraces/if/if3.kt | 11 + .../moveUpDown/closingBraces/if/if4.kt | 11 + .../closingBraces/nested/nested1.kt | 11 + .../closingBraces/nested/nested1.kt.after | 11 + .../closingBraces/nested/nested2.kt | 12 + .../moveUpDown/closingBraces/when/when1.kt | 17 + .../moveUpDown/closingBraces/when/when2.kt | 17 + .../closingBraces/when/whenEntry1.kt | 17 + .../closingBraces/when/whenEntry2.kt | 17 + .../closingBraces/when/whenEntry3.kt | 17 + .../closingBraces/when/whenEntry4.kt | 17 + .../moveUpDown/closingBraces/while/while1.kt | 7 + .../closingBraces/while/while1.kt.after | 7 + .../moveUpDown/closingBraces/while/while2.kt | 8 + .../moveUpDown/closingBraces/while/while3.kt | 9 + .../moveUpDown/closingBraces/while/while4.kt | 9 + .../codeInsight/moveUpDown/expressions/If1.kt | 11 + .../moveUpDown/expressions/If1.kt.after | 11 + .../moveUpDown/expressions/declaration1.kt | 5 + .../expressions/declaration1.kt.after | 5 + .../moveUpDown/expressions/declaration2.kt | 5 + .../expressions/declaration2.kt.after | 5 + .../codeInsight/moveUpDown/expressions/if2.kt | 10 + .../moveUpDown/expressions/if2.kt.after | 10 + .../codeInsight/moveUpDown/expressions/if3.kt | 9 + .../moveUpDown/expressions/if3.kt.after | 9 + .../codeInsight/moveUpDown/expressions/if4.kt | 9 + .../moveUpDown/expressions/if4.kt.after | 9 + .../moveUpDown/expressions/when1.kt | 16 + .../moveUpDown/expressions/when1.kt.after | 16 + .../moveUpDown/expressions/when2.kt | 16 + .../moveUpDown/expressions/when2.kt.after | 16 + .../moveUpDown/expressions/whenEntry1.kt | 16 + .../expressions/whenEntry1.kt.after | 16 + .../moveUpDown/expressions/whenEntry2.kt | 13 + .../expressions/whenEntry2.kt.after | 13 + .../moveUpDown/expressions/whenEntry3.kt | 15 + .../expressions/whenEntry3.kt.after | 15 + .../moveUpDown/expressions/whenEntry4.kt | 16 + .../expressions/whenEntry4.kt.after | 16 + .../moveUpDown/expressions/whenEntry5.kt | 15 + .../expressions/whenEntry5.kt.after | 15 + .../moveUpDown/expressions/whenEntry6.kt | 15 + .../expressions/whenEntry6.kt.after | 15 + .../moveUpDown/expressions/while1.kt | 8 + .../moveUpDown/expressions/while1.kt.after | 8 + .../moveUpDown/expressions/while2.kt | 7 + .../moveUpDown/expressions/while2.kt.after | 7 + .../moveUpDown/AbstractCodeMoverTest.java | 5 + .../moveUpDown/CodeMoverTestGenerated.java | 241 ++++++++++++- 61 files changed, 1272 insertions(+), 3 deletions(-) create mode 100644 idea/src/org/jetbrains/jet/plugin/codeInsight/upDownMover/JetExpressionMover.java create mode 100644 idea/testData/codeInsight/moveUpDown/closingBraces/for/for1.kt create mode 100644 idea/testData/codeInsight/moveUpDown/closingBraces/for/for1.kt.after create mode 100644 idea/testData/codeInsight/moveUpDown/closingBraces/for/for2.kt create mode 100644 idea/testData/codeInsight/moveUpDown/closingBraces/if/if1.kt create mode 100644 idea/testData/codeInsight/moveUpDown/closingBraces/if/if1.kt.after create mode 100644 idea/testData/codeInsight/moveUpDown/closingBraces/if/if2.kt create mode 100644 idea/testData/codeInsight/moveUpDown/closingBraces/if/if3.kt create mode 100644 idea/testData/codeInsight/moveUpDown/closingBraces/if/if4.kt create mode 100644 idea/testData/codeInsight/moveUpDown/closingBraces/nested/nested1.kt create mode 100644 idea/testData/codeInsight/moveUpDown/closingBraces/nested/nested1.kt.after create mode 100644 idea/testData/codeInsight/moveUpDown/closingBraces/nested/nested2.kt create mode 100644 idea/testData/codeInsight/moveUpDown/closingBraces/when/when1.kt create mode 100644 idea/testData/codeInsight/moveUpDown/closingBraces/when/when2.kt create mode 100644 idea/testData/codeInsight/moveUpDown/closingBraces/when/whenEntry1.kt create mode 100644 idea/testData/codeInsight/moveUpDown/closingBraces/when/whenEntry2.kt create mode 100644 idea/testData/codeInsight/moveUpDown/closingBraces/when/whenEntry3.kt create mode 100644 idea/testData/codeInsight/moveUpDown/closingBraces/when/whenEntry4.kt create mode 100644 idea/testData/codeInsight/moveUpDown/closingBraces/while/while1.kt create mode 100644 idea/testData/codeInsight/moveUpDown/closingBraces/while/while1.kt.after create mode 100644 idea/testData/codeInsight/moveUpDown/closingBraces/while/while2.kt create mode 100644 idea/testData/codeInsight/moveUpDown/closingBraces/while/while3.kt create mode 100644 idea/testData/codeInsight/moveUpDown/closingBraces/while/while4.kt create mode 100644 idea/testData/codeInsight/moveUpDown/expressions/If1.kt create mode 100644 idea/testData/codeInsight/moveUpDown/expressions/If1.kt.after create mode 100644 idea/testData/codeInsight/moveUpDown/expressions/declaration1.kt create mode 100644 idea/testData/codeInsight/moveUpDown/expressions/declaration1.kt.after create mode 100644 idea/testData/codeInsight/moveUpDown/expressions/declaration2.kt create mode 100644 idea/testData/codeInsight/moveUpDown/expressions/declaration2.kt.after create mode 100644 idea/testData/codeInsight/moveUpDown/expressions/if2.kt create mode 100644 idea/testData/codeInsight/moveUpDown/expressions/if2.kt.after create mode 100644 idea/testData/codeInsight/moveUpDown/expressions/if3.kt create mode 100644 idea/testData/codeInsight/moveUpDown/expressions/if3.kt.after create mode 100644 idea/testData/codeInsight/moveUpDown/expressions/if4.kt create mode 100644 idea/testData/codeInsight/moveUpDown/expressions/if4.kt.after create mode 100644 idea/testData/codeInsight/moveUpDown/expressions/when1.kt create mode 100644 idea/testData/codeInsight/moveUpDown/expressions/when1.kt.after create mode 100644 idea/testData/codeInsight/moveUpDown/expressions/when2.kt create mode 100644 idea/testData/codeInsight/moveUpDown/expressions/when2.kt.after create mode 100644 idea/testData/codeInsight/moveUpDown/expressions/whenEntry1.kt create mode 100644 idea/testData/codeInsight/moveUpDown/expressions/whenEntry1.kt.after create mode 100644 idea/testData/codeInsight/moveUpDown/expressions/whenEntry2.kt create mode 100644 idea/testData/codeInsight/moveUpDown/expressions/whenEntry2.kt.after create mode 100644 idea/testData/codeInsight/moveUpDown/expressions/whenEntry3.kt create mode 100644 idea/testData/codeInsight/moveUpDown/expressions/whenEntry3.kt.after create mode 100644 idea/testData/codeInsight/moveUpDown/expressions/whenEntry4.kt create mode 100644 idea/testData/codeInsight/moveUpDown/expressions/whenEntry4.kt.after create mode 100644 idea/testData/codeInsight/moveUpDown/expressions/whenEntry5.kt create mode 100644 idea/testData/codeInsight/moveUpDown/expressions/whenEntry5.kt.after create mode 100644 idea/testData/codeInsight/moveUpDown/expressions/whenEntry6.kt create mode 100644 idea/testData/codeInsight/moveUpDown/expressions/whenEntry6.kt.after create mode 100644 idea/testData/codeInsight/moveUpDown/expressions/while1.kt create mode 100644 idea/testData/codeInsight/moveUpDown/expressions/while1.kt.after create mode 100644 idea/testData/codeInsight/moveUpDown/expressions/while2.kt create mode 100644 idea/testData/codeInsight/moveUpDown/expressions/while2.kt.after diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetBlockExpression.java b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetBlockExpression.java index 6ab402a5e88..bbceac0a464 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetBlockExpression.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetBlockExpression.java @@ -54,7 +54,17 @@ public class JetBlockExpression extends JetExpressionImpl implements JetStatemen @Nullable public TextRange getLastBracketRange() { - PsiElement rBrace = findChildByType(JetTokens.RBRACE); + PsiElement rBrace = getRBrace(); return rBrace != null ? rBrace.getTextRange() : null; } + + @Nullable + public PsiElement getRBrace() { + return findChildByType(JetTokens.RBRACE); + } + + @Nullable + public PsiElement getLBrace() { + return findChildByType(JetTokens.LBRACE); + } } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetPsiUtil.java b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetPsiUtil.java index 379a1e36630..d95e66fcf47 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetPsiUtil.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetPsiUtil.java @@ -756,6 +756,59 @@ public class JetPsiUtil { return CommentUtilCore.isComment(element) || element instanceof KDocElement; } + @Nullable + public static PsiElement getOutermostParent(@NotNull PsiElement element, @NotNull PsiElement upperBound, boolean strict) { + PsiElement parent = strict ? element.getParent() : element; + while (parent != null && parent.getParent() != upperBound) { + parent = parent.getParent(); + } + + return parent; + } + + public static T getLastChildByType(@NotNull PsiElement root, @NotNull Class... elementTypes) { + PsiElement[] children = root.getChildren(); + + for (int i = children.length - 1; i >= 0; i--) { + if (PsiTreeUtil.instanceOf(children[i], elementTypes)) { + //noinspection unchecked + return (T) children[i]; + } + } + + return null; + } + + @Nullable + public static T getOutermostJetElement( + @Nullable PsiElement root, + boolean first, + @NotNull final Class... elementTypes + ) { + if (!(root instanceof JetElement)) return null; + + final List results = Lists.newArrayList(); + + ((JetElement) root).accept( + new JetVisitorVoid() { + @Override + public void visitJetElement(JetElement element) { + if (PsiTreeUtil.instanceOf(element, elementTypes)) { + //noinspection unchecked + results.add((T) element); + } + else { + element.acceptChildren(this); + } + } + } + ); + + if (results.isEmpty()) return null; + + return first ? results.get(0) : results.get(results.size() - 1); + } + @Nullable public static JetExpression getCalleeExpressionIfAny(@NotNull JetExpression expression) { if (expression instanceof JetCallElement) { diff --git a/generators/org/jetbrains/jet/generators/tests/GenerateTests.java b/generators/org/jetbrains/jet/generators/tests/GenerateTests.java index 46224ddf2f9..08afc8565f7 100644 --- a/generators/org/jetbrains/jet/generators/tests/GenerateTests.java +++ b/generators/org/jetbrains/jet/generators/tests/GenerateTests.java @@ -344,7 +344,9 @@ public class GenerateTests { "idea/tests/", "CodeMoverTestGenerated", AbstractCodeMoverTest.class, - testModel("idea/testData/codeInsight/moveUpDown/classBodyDeclarations", "doTestClassBodyDeclaration") + testModel("idea/testData/codeInsight/moveUpDown/classBodyDeclarations", "doTestClassBodyDeclaration"), + testModel("idea/testData/codeInsight/moveUpDown/closingBraces", "doTestExpression"), + testModel("idea/testData/codeInsight/moveUpDown/expressions", "doTestExpression") ); } diff --git a/idea/src/META-INF/plugin.xml b/idea/src/META-INF/plugin.xml index 18f3e23205a..1148214b80e 100644 --- a/idea/src/META-INF/plugin.xml +++ b/idea/src/META-INF/plugin.xml @@ -283,6 +283,10 @@ serviceImplementation="org.jetbrains.jet.plugin.editor.JetEditorOptions"/> + + diff --git a/idea/src/org/jetbrains/jet/plugin/codeInsight/upDownMover/JetExpressionMover.java b/idea/src/org/jetbrains/jet/plugin/codeInsight/upDownMover/JetExpressionMover.java new file mode 100644 index 00000000000..419cab627e4 --- /dev/null +++ b/idea/src/org/jetbrains/jet/plugin/codeInsight/upDownMover/JetExpressionMover.java @@ -0,0 +1,333 @@ +package org.jetbrains.jet.plugin.codeInsight.upDownMover; + +import com.intellij.codeInsight.editorActions.moveUpDown.LineRange; +import com.intellij.openapi.editor.Document; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.util.Pair; +import com.intellij.openapi.util.TextRange; +import com.intellij.psi.PsiComment; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiFile; +import com.intellij.psi.util.PsiTreeUtil; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import org.jetbrains.jet.lang.psi.*; +import org.jetbrains.jet.lexer.JetTokens; + +public class JetExpressionMover extends AbstractJetUpDownMover { + public JetExpressionMover() { + } + + @SuppressWarnings("FieldMayBeFinal") + private static Class[] MOVABLE_ELEMENT_CLASSES = {JetExpression.class, JetWhenEntry.class, PsiComment.class}; + + @SuppressWarnings("FieldMayBeFinal") + private static Class[] BLOCKLIKE_ELEMENT_CLASSES = + {JetBlockExpression.class, JetWhenExpression.class, JetPropertyAccessor.class, JetClassBody.class, JetFile.class}; + + @SuppressWarnings("FieldMayBeFinal") + private static Class[] FUNCTIONLIKE_ELEMENT_CLASSES = + {JetFunction.class, JetPropertyAccessor.class, JetClassInitializer.class}; + + @Nullable + private static LineRange getLineRange(@NotNull PsiElement element, @NotNull Editor editor) { + TextRange textRange = element.getTextRange(); + if (editor.getDocument().getTextLength() < textRange.getEndOffset()) return null; + + int startLine = editor.offsetToLogicalPosition(textRange.getStartOffset()).line; + int endLine = editor.offsetToLogicalPosition(textRange.getEndOffset()).line + 1; + + return new LineRange(startLine, endLine); + } + + @Nullable + private static PsiElement getStandaloneClosingBrace(@NotNull PsiFile file, @NotNull Editor editor) { + LineRange range = getLineRangeFromSelection(editor); + if (range.endLine - range.startLine != 1) return null; + int offset = editor.getCaretModel().getOffset(); + Document document = editor.getDocument(); + int line = document.getLineNumber(offset); + int lineStartOffset = document.getLineStartOffset(line); + String lineText = document.getText().substring(lineStartOffset, document.getLineEndOffset(line)); + if (!lineText.trim().equals("}")) return null; + + return file.findElementAt(lineStartOffset + lineText.indexOf('}')); + } + + private static boolean checkForMovableDownClosingBrace( + @NotNull PsiElement closingBrace, + @NotNull PsiElement block, + @NotNull Editor editor, + @NotNull MoveInfo info + ) { + PsiElement current = block; + PsiElement nextElement = null; + PsiElement nextExpression = null; + do { + PsiElement sibling = firstNonWhiteElement(current.getNextSibling(), true); + if (sibling != null && nextElement == null) { + nextElement = sibling; + } + + if (sibling instanceof JetExpression) { + nextExpression = sibling; + break; + } + + current = current.getParent(); + } + while (current != null && !(PsiTreeUtil.instanceOf(current, BLOCKLIKE_ELEMENT_CLASSES))); + + if (nextExpression == null) return false; + + Document doc = editor.getDocument(); + + info.toMove = new LineRange(closingBrace, closingBrace, doc); + info.toMove2 = new LineRange(nextElement, nextExpression); + info.indentSource = true; + + return true; + } + + private static boolean checkForMovableUpClosingBrace( + @NotNull PsiElement closingBrace, + PsiElement block, + @NotNull Editor editor, + @NotNull MoveInfo info + ) { + //noinspection unchecked + PsiElement prev = JetPsiUtil.getLastChildByType(block, JetExpression.class); + if (prev == null) return false; + + Document doc = editor.getDocument(); + + info.toMove = new LineRange(closingBrace, closingBrace, doc); + info.toMove2 = new LineRange(prev, prev, doc); + info.indentSource = true; + + return true; + } + + // Returns null if standalone closing brace is not found + private static Boolean checkForMovableClosingBrace( + @NotNull Editor editor, + @NotNull PsiFile file, + @NotNull MoveInfo info, + boolean down + ) { + PsiElement closingBrace = getStandaloneClosingBrace(file, editor); + if (closingBrace == null) return null; + + PsiElement blockLikeElement = closingBrace.getParent(); + if (!(blockLikeElement instanceof JetBlockExpression)) return false; + if (blockLikeElement.getParent() instanceof JetWhenEntry) return false; + + PsiElement enclosingExpression = PsiTreeUtil.getParentOfType(blockLikeElement, JetExpression.class); + + if (enclosingExpression instanceof JetDoWhileExpression) return false; + + if (enclosingExpression instanceof JetIfExpression) { + JetIfExpression ifExpression = (JetIfExpression) enclosingExpression; + + if (blockLikeElement == ifExpression.getThen() && ifExpression.getElse() != null) return false; + } + + return down ? checkForMovableDownClosingBrace(closingBrace, blockLikeElement, editor, info) : + checkForMovableUpClosingBrace(closingBrace, blockLikeElement, editor, info); + } + + @Nullable + private static JetBlockExpression findClosestBlock(@NotNull PsiElement anchor, boolean down) { + PsiElement current = PsiTreeUtil.getParentOfType(anchor, JetBlockExpression.class); + while (current != null) { + PsiElement parent = current.getParent(); + if (parent instanceof JetClassBody || + parent instanceof JetClassInitializer || + parent instanceof JetFunction || + parent instanceof JetProperty) { + return null; + } + + if (parent instanceof JetBlockExpression) return (JetBlockExpression) parent; + + PsiElement sibling = down ? current.getNextSibling() : current.getPrevSibling(); + if (sibling != null) { + //noinspection unchecked + JetBlockExpression block = JetPsiUtil.getOutermostJetElement(sibling, down, JetBlockExpression.class); + if (block != null) return block; + + current = sibling; + } + else { + current = parent; + } + } + + return null; + } + + @Nullable + private static LineRange getExpressionTargetRange(@NotNull Editor editor, @NotNull PsiElement sibling, boolean down) { + PsiElement start = sibling; + PsiElement end = sibling; + + // moving out of code block + if (sibling.getNode().getElementType() == (down ? JetTokens.RBRACE : JetTokens.LBRACE)) { + PsiElement parent = sibling.getParent(); + if (!(parent instanceof JetBlockExpression)) return null; + + JetBlockExpression block = (JetBlockExpression) parent; + + JetBlockExpression newBlock = findClosestBlock(sibling, down); + if (newBlock == null) return null; + + if (PsiTreeUtil.isAncestor(newBlock, block, true)) { + PsiElement outermostParent = JetPsiUtil.getOutermostParent(block, newBlock, true); + + if (down) { + end = outermostParent; + } + else { + start = outermostParent; + } + } + else { + if (down) { + end = newBlock.getLBrace(); + } + else { + start = newBlock.getRBrace(); + } + } + } + else { + // moving into code block + //noinspection unchecked + JetElement blockLikeElement = JetPsiUtil.getOutermostJetElement(sibling, down, JetBlockExpression.class, JetWhenExpression.class); + if (blockLikeElement != null && + !(PsiTreeUtil.instanceOf(blockLikeElement, FUNCTIONLIKE_ELEMENT_CLASSES))) { + if (blockLikeElement instanceof JetWhenExpression) { + //noinspection unchecked + blockLikeElement = JetPsiUtil.getOutermostJetElement(blockLikeElement, down, JetBlockExpression.class); + } + + if (blockLikeElement != null) { + JetBlockExpression block = (JetBlockExpression) blockLikeElement; + + if (down) { + end = block.getLBrace(); + } + else { + start = block.getRBrace(); + } + } + } + } + + return start != null && end != null ? new LineRange(start, end, editor.getDocument()) : null; + } + + @Nullable + private static LineRange getWhenEntryTargetRange(@NotNull Editor editor, @NotNull PsiElement sibling, boolean down) { + if (sibling.getNode().getElementType() == (down ? JetTokens.RBRACE : JetTokens.LBRACE) && + PsiTreeUtil.getParentOfType(sibling, JetWhenEntry.class) == null) { + return null; + } + + return new LineRange(sibling, sibling, editor.getDocument()); + } + + @Nullable + private static LineRange getTargetRange( + @NotNull Editor editor, + @Nullable PsiElement elementToCheck, + @NotNull PsiElement sibling, + boolean down + ) { + if (elementToCheck instanceof JetExpression || elementToCheck instanceof PsiComment) { + return getExpressionTargetRange(editor, sibling, down); + } + + if (elementToCheck instanceof JetWhenEntry) { + return getWhenEntryTargetRange(editor, sibling, down); + } + + return null; + } + + @Nullable + private static LineRange getSourceRange(@NotNull PsiElement firstElement, @NotNull PsiElement lastElement, @NotNull Editor editor) { + if (firstElement == lastElement) { + //noinspection ConstantConditions + LineRange sourceRange = getLineRange(firstElement, editor); + + if (sourceRange != null) { + sourceRange.firstElement = sourceRange.lastElement = firstElement; + } + + return sourceRange; + } + + //noinspection ConstantConditions + PsiElement parent = PsiTreeUtil.findCommonParent(firstElement, lastElement); + if (parent == null) return null; + + Pair combinedRange = getElementRange(parent, firstElement, lastElement); + + if (combinedRange == null + || !(PsiTreeUtil.instanceOf(combinedRange.first, MOVABLE_ELEMENT_CLASSES)) + || !(PsiTreeUtil.instanceOf(combinedRange.second, MOVABLE_ELEMENT_CLASSES))) { + return null; + } + + LineRange lineRange1 = getLineRange(combinedRange.first, editor); + if (lineRange1 == null) return null; + + LineRange lineRange2 = getLineRange(combinedRange.second, editor); + if (lineRange2 == null) return null; + + LineRange sourceRange = new LineRange(lineRange1.startLine, lineRange2.endLine); + sourceRange.firstElement = combinedRange.first; + sourceRange.lastElement = combinedRange.second; + + return sourceRange; + } + + @Override + public boolean checkAvailable(@NotNull Editor editor, @NotNull PsiFile file, @NotNull MoveInfo info, boolean down) { + if (!super.checkAvailable(editor, file, info, down)) return false; + + Boolean closingBraceWin = checkForMovableClosingBrace(editor, file, info, down); + if (closingBraceWin != null) { + if (!closingBraceWin) { + info.toMove2 = null; + } + return true; + } + + LineRange oldRange = info.toMove; + + Pair psiRange = getElementRange(editor, file, oldRange); + if (psiRange == null) return false; + + //noinspection unchecked + PsiElement firstElement = PsiTreeUtil.getNonStrictParentOfType(psiRange.getFirst(), MOVABLE_ELEMENT_CLASSES); + if (firstElement == null) return false; + + //noinspection unchecked + PsiElement lastElement = PsiTreeUtil.getNonStrictParentOfType(psiRange.getSecond(), MOVABLE_ELEMENT_CLASSES); + if (lastElement == null) return false; + + LineRange sourceRange = getSourceRange(firstElement, lastElement, editor); + if (sourceRange == null) return false; + + PsiElement sibling = adjustWhiteSpaceSibling(editor, sourceRange, info, down); + + // Either reached last sibling, or jumped over multi-line whitespace + if (sibling == null) return true; + + info.toMove = sourceRange; + info.toMove2 = getTargetRange(editor, sourceRange.firstElement, sibling, down); + return true; + } +} diff --git a/idea/testData/codeInsight/moveUpDown/closingBraces/for/for1.kt b/idea/testData/codeInsight/moveUpDown/closingBraces/for/for1.kt new file mode 100644 index 00000000000..eae0ea27cec --- /dev/null +++ b/idea/testData/codeInsight/moveUpDown/closingBraces/for/for1.kt @@ -0,0 +1,7 @@ +// MOVE: down +fun(n: Int) { + for (i in 0..n) { + + } + val x = "" +} \ No newline at end of file diff --git a/idea/testData/codeInsight/moveUpDown/closingBraces/for/for1.kt.after b/idea/testData/codeInsight/moveUpDown/closingBraces/for/for1.kt.after new file mode 100644 index 00000000000..756d6cee613 --- /dev/null +++ b/idea/testData/codeInsight/moveUpDown/closingBraces/for/for1.kt.after @@ -0,0 +1,7 @@ +// MOVE: down +fun(n: Int) { + for (i in 0..n) { + + val x = "" + } +} \ No newline at end of file diff --git a/idea/testData/codeInsight/moveUpDown/closingBraces/for/for2.kt b/idea/testData/codeInsight/moveUpDown/closingBraces/for/for2.kt new file mode 100644 index 00000000000..bf2aeb7c808 --- /dev/null +++ b/idea/testData/codeInsight/moveUpDown/closingBraces/for/for2.kt @@ -0,0 +1,8 @@ +// MOVE: up +// IS_APPLICABLE: false +fun(n: Int) { + for (i in 0..n) { + + } + val x = "" +} \ No newline at end of file diff --git a/idea/testData/codeInsight/moveUpDown/closingBraces/if/if1.kt b/idea/testData/codeInsight/moveUpDown/closingBraces/if/if1.kt new file mode 100644 index 00000000000..a5583bc773f --- /dev/null +++ b/idea/testData/codeInsight/moveUpDown/closingBraces/if/if1.kt @@ -0,0 +1,10 @@ +// MOVE: down +fun(n: Int) { + if (n > 0) { + + } + else { + + } + val x = "" +} \ No newline at end of file diff --git a/idea/testData/codeInsight/moveUpDown/closingBraces/if/if1.kt.after b/idea/testData/codeInsight/moveUpDown/closingBraces/if/if1.kt.after new file mode 100644 index 00000000000..5bca3816643 --- /dev/null +++ b/idea/testData/codeInsight/moveUpDown/closingBraces/if/if1.kt.after @@ -0,0 +1,10 @@ +// MOVE: down +fun(n: Int) { + if (n > 0) { + + } + else { + + val x = "" + } +} \ No newline at end of file diff --git a/idea/testData/codeInsight/moveUpDown/closingBraces/if/if2.kt b/idea/testData/codeInsight/moveUpDown/closingBraces/if/if2.kt new file mode 100644 index 00000000000..0d5fcedafc0 --- /dev/null +++ b/idea/testData/codeInsight/moveUpDown/closingBraces/if/if2.kt @@ -0,0 +1,11 @@ +// MOVE: up +// IS_APPLICABLE: false +fun(n: Int) { + if (n > 0) { + + } + else { + + } + val x = "" +} \ No newline at end of file diff --git a/idea/testData/codeInsight/moveUpDown/closingBraces/if/if3.kt b/idea/testData/codeInsight/moveUpDown/closingBraces/if/if3.kt new file mode 100644 index 00000000000..ff9a2c7d9e2 --- /dev/null +++ b/idea/testData/codeInsight/moveUpDown/closingBraces/if/if3.kt @@ -0,0 +1,11 @@ +// MOVE: down +// IS_APPLICABLE: false +fun(n: Int) { + if (n > 0) { + + } + else { + + } + val x = "" +} \ No newline at end of file diff --git a/idea/testData/codeInsight/moveUpDown/closingBraces/if/if4.kt b/idea/testData/codeInsight/moveUpDown/closingBraces/if/if4.kt new file mode 100644 index 00000000000..b738d13d3a9 --- /dev/null +++ b/idea/testData/codeInsight/moveUpDown/closingBraces/if/if4.kt @@ -0,0 +1,11 @@ +// MOVE: up +// IS_APPLICABLE: false +fun(n: Int) { + if (n > 0) { + + } + else { + + } + val x = "" +} \ No newline at end of file diff --git a/idea/testData/codeInsight/moveUpDown/closingBraces/nested/nested1.kt b/idea/testData/codeInsight/moveUpDown/closingBraces/nested/nested1.kt new file mode 100644 index 00000000000..7373ab8af34 --- /dev/null +++ b/idea/testData/codeInsight/moveUpDown/closingBraces/nested/nested1.kt @@ -0,0 +1,11 @@ +// MOVE: down +fun foo(n: Int) { + if (n > 0) { + + } else { + + } + while (n > 0) { + + } +} \ No newline at end of file diff --git a/idea/testData/codeInsight/moveUpDown/closingBraces/nested/nested1.kt.after b/idea/testData/codeInsight/moveUpDown/closingBraces/nested/nested1.kt.after new file mode 100644 index 00000000000..9c43a1014cc --- /dev/null +++ b/idea/testData/codeInsight/moveUpDown/closingBraces/nested/nested1.kt.after @@ -0,0 +1,11 @@ +// MOVE: down +fun foo(n: Int) { + if (n > 0) { + + } else { + + while (n > 0) { + + } + } +} \ No newline at end of file diff --git a/idea/testData/codeInsight/moveUpDown/closingBraces/nested/nested2.kt b/idea/testData/codeInsight/moveUpDown/closingBraces/nested/nested2.kt new file mode 100644 index 00000000000..9ae75a6dd88 --- /dev/null +++ b/idea/testData/codeInsight/moveUpDown/closingBraces/nested/nested2.kt @@ -0,0 +1,12 @@ +// MOVE: down +// IS_APPLICABLE: false +fun foo(n: Int) { + if (n > 0) { + + } else { + + } + while (n > 0) { + + } +} \ No newline at end of file diff --git a/idea/testData/codeInsight/moveUpDown/closingBraces/when/when1.kt b/idea/testData/codeInsight/moveUpDown/closingBraces/when/when1.kt new file mode 100644 index 00000000000..37e4b329134 --- /dev/null +++ b/idea/testData/codeInsight/moveUpDown/closingBraces/when/when1.kt @@ -0,0 +1,17 @@ +// IS_APPLICABLE: false +// MOVE: down + +fun foo(n: Int) { + when (n) { + 0 -> { + + } + 1 -> { + + } + else -> { + + } + } + val x = "" +} \ No newline at end of file diff --git a/idea/testData/codeInsight/moveUpDown/closingBraces/when/when2.kt b/idea/testData/codeInsight/moveUpDown/closingBraces/when/when2.kt new file mode 100644 index 00000000000..3e40febebf3 --- /dev/null +++ b/idea/testData/codeInsight/moveUpDown/closingBraces/when/when2.kt @@ -0,0 +1,17 @@ +// IS_APPLICABLE: false +// MOVE: up + +fun foo(n: Int) { + when (n) { + 0 -> { + + } + 1 -> { + + } + else -> { + + } + } + val x = "" +} \ No newline at end of file diff --git a/idea/testData/codeInsight/moveUpDown/closingBraces/when/whenEntry1.kt b/idea/testData/codeInsight/moveUpDown/closingBraces/when/whenEntry1.kt new file mode 100644 index 00000000000..3c5f5775bb8 --- /dev/null +++ b/idea/testData/codeInsight/moveUpDown/closingBraces/when/whenEntry1.kt @@ -0,0 +1,17 @@ +// IS_APPLICABLE: false +// MOVE: down + +fun foo(n: Int) { + when (n) { + 0 -> { + + } + 1 -> { + + } + else -> { + + } + } + val x = "" +} \ No newline at end of file diff --git a/idea/testData/codeInsight/moveUpDown/closingBraces/when/whenEntry2.kt b/idea/testData/codeInsight/moveUpDown/closingBraces/when/whenEntry2.kt new file mode 100644 index 00000000000..a8f199fbc69 --- /dev/null +++ b/idea/testData/codeInsight/moveUpDown/closingBraces/when/whenEntry2.kt @@ -0,0 +1,17 @@ +// IS_APPLICABLE: false +// MOVE: up + +fun foo(n: Int) { + when (n) { + 0 -> { + + } + 1 -> { + + } + else -> { + + } + } + val x = "" +} \ No newline at end of file diff --git a/idea/testData/codeInsight/moveUpDown/closingBraces/when/whenEntry3.kt b/idea/testData/codeInsight/moveUpDown/closingBraces/when/whenEntry3.kt new file mode 100644 index 00000000000..e357586805d --- /dev/null +++ b/idea/testData/codeInsight/moveUpDown/closingBraces/when/whenEntry3.kt @@ -0,0 +1,17 @@ +// IS_APPLICABLE: false +// MOVE: down + +fun foo(n: Int) { + when (n) { + 0 -> { + + } + 1 -> { + + } + else -> { + + } + } + val x = "" +} \ No newline at end of file diff --git a/idea/testData/codeInsight/moveUpDown/closingBraces/when/whenEntry4.kt b/idea/testData/codeInsight/moveUpDown/closingBraces/when/whenEntry4.kt new file mode 100644 index 00000000000..b54c1574f67 --- /dev/null +++ b/idea/testData/codeInsight/moveUpDown/closingBraces/when/whenEntry4.kt @@ -0,0 +1,17 @@ +// IS_APPLICABLE: false +// MOVE: up + +fun foo(n: Int) { + when (n) { + 0 -> { + + } + 1 -> { + + } + else -> { + + } + } + val x = "" +} \ No newline at end of file diff --git a/idea/testData/codeInsight/moveUpDown/closingBraces/while/while1.kt b/idea/testData/codeInsight/moveUpDown/closingBraces/while/while1.kt new file mode 100644 index 00000000000..f3a44d20769 --- /dev/null +++ b/idea/testData/codeInsight/moveUpDown/closingBraces/while/while1.kt @@ -0,0 +1,7 @@ +// MOVE: down +fun(n: Int) { + while (true) { + + } + val x = "" +} \ No newline at end of file diff --git a/idea/testData/codeInsight/moveUpDown/closingBraces/while/while1.kt.after b/idea/testData/codeInsight/moveUpDown/closingBraces/while/while1.kt.after new file mode 100644 index 00000000000..99dd7cfaca5 --- /dev/null +++ b/idea/testData/codeInsight/moveUpDown/closingBraces/while/while1.kt.after @@ -0,0 +1,7 @@ +// MOVE: down +fun(n: Int) { + while (true) { + + val x = "" + } +} \ No newline at end of file diff --git a/idea/testData/codeInsight/moveUpDown/closingBraces/while/while2.kt b/idea/testData/codeInsight/moveUpDown/closingBraces/while/while2.kt new file mode 100644 index 00000000000..254f34c7b1f --- /dev/null +++ b/idea/testData/codeInsight/moveUpDown/closingBraces/while/while2.kt @@ -0,0 +1,8 @@ +// MOVE: up +// IS_APPLICABLE: false +fun(n: Int) { + while (true) { + + } + val x = "" +} \ No newline at end of file diff --git a/idea/testData/codeInsight/moveUpDown/closingBraces/while/while3.kt b/idea/testData/codeInsight/moveUpDown/closingBraces/while/while3.kt new file mode 100644 index 00000000000..8adc8b57da9 --- /dev/null +++ b/idea/testData/codeInsight/moveUpDown/closingBraces/while/while3.kt @@ -0,0 +1,9 @@ +// MOVE: down +// IS_APPLICABLE: false +fun(n: Int) { + do { + + } + while (true) + val x = "" +} \ No newline at end of file diff --git a/idea/testData/codeInsight/moveUpDown/closingBraces/while/while4.kt b/idea/testData/codeInsight/moveUpDown/closingBraces/while/while4.kt new file mode 100644 index 00000000000..22af102194b --- /dev/null +++ b/idea/testData/codeInsight/moveUpDown/closingBraces/while/while4.kt @@ -0,0 +1,9 @@ +// MOVE: up +// IS_APPLICABLE: false +fun(n: Int) { + do { + + } + while (true) + val x = "" +} \ No newline at end of file diff --git a/idea/testData/codeInsight/moveUpDown/expressions/If1.kt b/idea/testData/codeInsight/moveUpDown/expressions/If1.kt new file mode 100644 index 00000000000..dc363c3a5c9 --- /dev/null +++ b/idea/testData/codeInsight/moveUpDown/expressions/If1.kt @@ -0,0 +1,11 @@ +// MOVE: down + +fun foo(x: Boolean) { + // test + if (x) { + + } + else { + + } +} diff --git a/idea/testData/codeInsight/moveUpDown/expressions/If1.kt.after b/idea/testData/codeInsight/moveUpDown/expressions/If1.kt.after new file mode 100644 index 00000000000..42673921651 --- /dev/null +++ b/idea/testData/codeInsight/moveUpDown/expressions/If1.kt.after @@ -0,0 +1,11 @@ +// MOVE: down + +fun foo(x: Boolean) { + if (x) { + // test + + } + else { + + } +} diff --git a/idea/testData/codeInsight/moveUpDown/expressions/declaration1.kt b/idea/testData/codeInsight/moveUpDown/expressions/declaration1.kt new file mode 100644 index 00000000000..ff51a8e408d --- /dev/null +++ b/idea/testData/codeInsight/moveUpDown/expressions/declaration1.kt @@ -0,0 +1,5 @@ +// MOVE: down +fun foo() { + // test + val x = "" +} diff --git a/idea/testData/codeInsight/moveUpDown/expressions/declaration1.kt.after b/idea/testData/codeInsight/moveUpDown/expressions/declaration1.kt.after new file mode 100644 index 00000000000..7540c6285d0 --- /dev/null +++ b/idea/testData/codeInsight/moveUpDown/expressions/declaration1.kt.after @@ -0,0 +1,5 @@ +// MOVE: down +fun foo() { + val x = "" + // test +} diff --git a/idea/testData/codeInsight/moveUpDown/expressions/declaration2.kt b/idea/testData/codeInsight/moveUpDown/expressions/declaration2.kt new file mode 100644 index 00000000000..4e791764e35 --- /dev/null +++ b/idea/testData/codeInsight/moveUpDown/expressions/declaration2.kt @@ -0,0 +1,5 @@ +// MOVE: up +fun foo() { + val x = "" + // test +} diff --git a/idea/testData/codeInsight/moveUpDown/expressions/declaration2.kt.after b/idea/testData/codeInsight/moveUpDown/expressions/declaration2.kt.after new file mode 100644 index 00000000000..e46650fce17 --- /dev/null +++ b/idea/testData/codeInsight/moveUpDown/expressions/declaration2.kt.after @@ -0,0 +1,5 @@ +// MOVE: up +fun foo() { + // test + val x = "" +} diff --git a/idea/testData/codeInsight/moveUpDown/expressions/if2.kt b/idea/testData/codeInsight/moveUpDown/expressions/if2.kt new file mode 100644 index 00000000000..4517ef16f9b --- /dev/null +++ b/idea/testData/codeInsight/moveUpDown/expressions/if2.kt @@ -0,0 +1,10 @@ +// MOVE: up +fun foo(x: Boolean) { + if (x) { + + } + else { + + } + // test +} diff --git a/idea/testData/codeInsight/moveUpDown/expressions/if2.kt.after b/idea/testData/codeInsight/moveUpDown/expressions/if2.kt.after new file mode 100644 index 00000000000..e88441309f2 --- /dev/null +++ b/idea/testData/codeInsight/moveUpDown/expressions/if2.kt.after @@ -0,0 +1,10 @@ +// MOVE: up +fun foo(x: Boolean) { + if (x) { + + } + else { + + // test + } +} diff --git a/idea/testData/codeInsight/moveUpDown/expressions/if3.kt b/idea/testData/codeInsight/moveUpDown/expressions/if3.kt new file mode 100644 index 00000000000..c659bd2d03d --- /dev/null +++ b/idea/testData/codeInsight/moveUpDown/expressions/if3.kt @@ -0,0 +1,9 @@ +// MOVE: down + +fun foo(x: Boolean) { + if (x) { + // test + } + else { + } +} diff --git a/idea/testData/codeInsight/moveUpDown/expressions/if3.kt.after b/idea/testData/codeInsight/moveUpDown/expressions/if3.kt.after new file mode 100644 index 00000000000..54b18882ec8 --- /dev/null +++ b/idea/testData/codeInsight/moveUpDown/expressions/if3.kt.after @@ -0,0 +1,9 @@ +// MOVE: down + +fun foo(x: Boolean) { + if (x) { + } + else { + // test + } +} diff --git a/idea/testData/codeInsight/moveUpDown/expressions/if4.kt b/idea/testData/codeInsight/moveUpDown/expressions/if4.kt new file mode 100644 index 00000000000..63ffdabe366 --- /dev/null +++ b/idea/testData/codeInsight/moveUpDown/expressions/if4.kt @@ -0,0 +1,9 @@ +// MOVE: up + +fun foo(x: Boolean) { + if (x) { + } + else { + // test + } +} diff --git a/idea/testData/codeInsight/moveUpDown/expressions/if4.kt.after b/idea/testData/codeInsight/moveUpDown/expressions/if4.kt.after new file mode 100644 index 00000000000..5483bf42414 --- /dev/null +++ b/idea/testData/codeInsight/moveUpDown/expressions/if4.kt.after @@ -0,0 +1,9 @@ +// MOVE: up + +fun foo(x: Boolean) { + if (x) { + // test + } + else { + } +} diff --git a/idea/testData/codeInsight/moveUpDown/expressions/when1.kt b/idea/testData/codeInsight/moveUpDown/expressions/when1.kt new file mode 100644 index 00000000000..f05655dbafd --- /dev/null +++ b/idea/testData/codeInsight/moveUpDown/expressions/when1.kt @@ -0,0 +1,16 @@ +// MOVE: down + +fun foo(x: Boolean) { + // test + when (x) { + false -> { + + } + true -> { + + } + else -> { + + } + } +} diff --git a/idea/testData/codeInsight/moveUpDown/expressions/when1.kt.after b/idea/testData/codeInsight/moveUpDown/expressions/when1.kt.after new file mode 100644 index 00000000000..80eaaac0b28 --- /dev/null +++ b/idea/testData/codeInsight/moveUpDown/expressions/when1.kt.after @@ -0,0 +1,16 @@ +// MOVE: down + +fun foo(x: Boolean) { + when (x) { + false -> { + // test + + } + true -> { + + } + else -> { + + } + } +} diff --git a/idea/testData/codeInsight/moveUpDown/expressions/when2.kt b/idea/testData/codeInsight/moveUpDown/expressions/when2.kt new file mode 100644 index 00000000000..f8fef0d66a4 --- /dev/null +++ b/idea/testData/codeInsight/moveUpDown/expressions/when2.kt @@ -0,0 +1,16 @@ +// MOVE: up + +fun foo(x: Boolean) { + when (x) { + false -> { + + } + true -> { + + } + else -> { + + } + } + // test +} diff --git a/idea/testData/codeInsight/moveUpDown/expressions/when2.kt.after b/idea/testData/codeInsight/moveUpDown/expressions/when2.kt.after new file mode 100644 index 00000000000..bac9bf0cc9d --- /dev/null +++ b/idea/testData/codeInsight/moveUpDown/expressions/when2.kt.after @@ -0,0 +1,16 @@ +// MOVE: up + +fun foo(x: Boolean) { + when (x) { + false -> { + + } + true -> { + + } + else -> { + + // test + } + } +} diff --git a/idea/testData/codeInsight/moveUpDown/expressions/whenEntry1.kt b/idea/testData/codeInsight/moveUpDown/expressions/whenEntry1.kt new file mode 100644 index 00000000000..7a7c2610296 --- /dev/null +++ b/idea/testData/codeInsight/moveUpDown/expressions/whenEntry1.kt @@ -0,0 +1,16 @@ +// MOVE: down + +fun foo(x: Boolean) { + when (x) { + // test + false -> { + + } + true -> { + + } + else -> { + + } + } +} diff --git a/idea/testData/codeInsight/moveUpDown/expressions/whenEntry1.kt.after b/idea/testData/codeInsight/moveUpDown/expressions/whenEntry1.kt.after new file mode 100644 index 00000000000..80eaaac0b28 --- /dev/null +++ b/idea/testData/codeInsight/moveUpDown/expressions/whenEntry1.kt.after @@ -0,0 +1,16 @@ +// MOVE: down + +fun foo(x: Boolean) { + when (x) { + false -> { + // test + + } + true -> { + + } + else -> { + + } + } +} diff --git a/idea/testData/codeInsight/moveUpDown/expressions/whenEntry2.kt b/idea/testData/codeInsight/moveUpDown/expressions/whenEntry2.kt new file mode 100644 index 00000000000..a8ae614ee51 --- /dev/null +++ b/idea/testData/codeInsight/moveUpDown/expressions/whenEntry2.kt @@ -0,0 +1,13 @@ +// MOVE: down + +fun foo(x: Boolean) { + when (x) { + false -> { + // test + } + true -> { + } + else -> { + } + } +} diff --git a/idea/testData/codeInsight/moveUpDown/expressions/whenEntry2.kt.after b/idea/testData/codeInsight/moveUpDown/expressions/whenEntry2.kt.after new file mode 100644 index 00000000000..8dbe015f785 --- /dev/null +++ b/idea/testData/codeInsight/moveUpDown/expressions/whenEntry2.kt.after @@ -0,0 +1,13 @@ +// MOVE: down + +fun foo(x: Boolean) { + when (x) { + false -> { + } + true -> { + // test + } + else -> { + } + } +} diff --git a/idea/testData/codeInsight/moveUpDown/expressions/whenEntry3.kt b/idea/testData/codeInsight/moveUpDown/expressions/whenEntry3.kt new file mode 100644 index 00000000000..083664a07df --- /dev/null +++ b/idea/testData/codeInsight/moveUpDown/expressions/whenEntry3.kt @@ -0,0 +1,15 @@ +// MOVE: down + +fun foo(x: Boolean) { + when (x) { + false -> { + + } + true -> { + + } + else -> { + // test + } + } +} diff --git a/idea/testData/codeInsight/moveUpDown/expressions/whenEntry3.kt.after b/idea/testData/codeInsight/moveUpDown/expressions/whenEntry3.kt.after new file mode 100644 index 00000000000..77de8a9f66d --- /dev/null +++ b/idea/testData/codeInsight/moveUpDown/expressions/whenEntry3.kt.after @@ -0,0 +1,15 @@ +// MOVE: down + +fun foo(x: Boolean) { + when (x) { + false -> { + + } + true -> { + + } + else -> { + } + } + // test +} diff --git a/idea/testData/codeInsight/moveUpDown/expressions/whenEntry4.kt b/idea/testData/codeInsight/moveUpDown/expressions/whenEntry4.kt new file mode 100644 index 00000000000..88fe7d65d15 --- /dev/null +++ b/idea/testData/codeInsight/moveUpDown/expressions/whenEntry4.kt @@ -0,0 +1,16 @@ +// MOVE: up + +fun foo(x: Boolean) { + when (x) { + false -> { + + } + true -> { + + } + else -> { + + } + // test + } +} diff --git a/idea/testData/codeInsight/moveUpDown/expressions/whenEntry4.kt.after b/idea/testData/codeInsight/moveUpDown/expressions/whenEntry4.kt.after new file mode 100644 index 00000000000..bac9bf0cc9d --- /dev/null +++ b/idea/testData/codeInsight/moveUpDown/expressions/whenEntry4.kt.after @@ -0,0 +1,16 @@ +// MOVE: up + +fun foo(x: Boolean) { + when (x) { + false -> { + + } + true -> { + + } + else -> { + + // test + } + } +} diff --git a/idea/testData/codeInsight/moveUpDown/expressions/whenEntry5.kt b/idea/testData/codeInsight/moveUpDown/expressions/whenEntry5.kt new file mode 100644 index 00000000000..8fbc8cdbf7d --- /dev/null +++ b/idea/testData/codeInsight/moveUpDown/expressions/whenEntry5.kt @@ -0,0 +1,15 @@ +// MOVE: up + +fun foo(x: Boolean) { + when (x) { + false -> { + + } + true -> { + + } + else -> { + // test + } + } +} diff --git a/idea/testData/codeInsight/moveUpDown/expressions/whenEntry5.kt.after b/idea/testData/codeInsight/moveUpDown/expressions/whenEntry5.kt.after new file mode 100644 index 00000000000..9418f7325a0 --- /dev/null +++ b/idea/testData/codeInsight/moveUpDown/expressions/whenEntry5.kt.after @@ -0,0 +1,15 @@ +// MOVE: up + +fun foo(x: Boolean) { + when (x) { + false -> { + + } + true -> { + + // test + } + else -> { + } + } +} diff --git a/idea/testData/codeInsight/moveUpDown/expressions/whenEntry6.kt b/idea/testData/codeInsight/moveUpDown/expressions/whenEntry6.kt new file mode 100644 index 00000000000..6c285ac6988 --- /dev/null +++ b/idea/testData/codeInsight/moveUpDown/expressions/whenEntry6.kt @@ -0,0 +1,15 @@ +// MOVE: up + +fun foo(x: Boolean) { + when (x) { + false -> { + // test + } + true -> { + + } + else -> { + + } + } +} diff --git a/idea/testData/codeInsight/moveUpDown/expressions/whenEntry6.kt.after b/idea/testData/codeInsight/moveUpDown/expressions/whenEntry6.kt.after new file mode 100644 index 00000000000..a2e1088cb2e --- /dev/null +++ b/idea/testData/codeInsight/moveUpDown/expressions/whenEntry6.kt.after @@ -0,0 +1,15 @@ +// MOVE: up + +fun foo(x: Boolean) { + // test + when (x) { + false -> { + } + true -> { + + } + else -> { + + } + } +} diff --git a/idea/testData/codeInsight/moveUpDown/expressions/while1.kt b/idea/testData/codeInsight/moveUpDown/expressions/while1.kt new file mode 100644 index 00000000000..5b5801b65b8 --- /dev/null +++ b/idea/testData/codeInsight/moveUpDown/expressions/while1.kt @@ -0,0 +1,8 @@ +// MOVE: down + +fun foo(x: Boolean) { + // test + while (x) { + + } +} diff --git a/idea/testData/codeInsight/moveUpDown/expressions/while1.kt.after b/idea/testData/codeInsight/moveUpDown/expressions/while1.kt.after new file mode 100644 index 00000000000..6a399a964ea --- /dev/null +++ b/idea/testData/codeInsight/moveUpDown/expressions/while1.kt.after @@ -0,0 +1,8 @@ +// MOVE: down + +fun foo(x: Boolean) { + while (x) { + // test + + } +} diff --git a/idea/testData/codeInsight/moveUpDown/expressions/while2.kt b/idea/testData/codeInsight/moveUpDown/expressions/while2.kt new file mode 100644 index 00000000000..1141e224018 --- /dev/null +++ b/idea/testData/codeInsight/moveUpDown/expressions/while2.kt @@ -0,0 +1,7 @@ +// MOVE: up +fun foo(x: Boolean) { + while (x) { + + } + // test +} diff --git a/idea/testData/codeInsight/moveUpDown/expressions/while2.kt.after b/idea/testData/codeInsight/moveUpDown/expressions/while2.kt.after new file mode 100644 index 00000000000..9c90bd924fe --- /dev/null +++ b/idea/testData/codeInsight/moveUpDown/expressions/while2.kt.after @@ -0,0 +1,7 @@ +// MOVE: up +fun foo(x: Boolean) { + while (x) { + + // test + } +} diff --git a/idea/tests/org/jetbrains/jet/plugin/codeInsight/moveUpDown/AbstractCodeMoverTest.java b/idea/tests/org/jetbrains/jet/plugin/codeInsight/moveUpDown/AbstractCodeMoverTest.java index b1271d50891..329bf8489e8 100644 --- a/idea/tests/org/jetbrains/jet/plugin/codeInsight/moveUpDown/AbstractCodeMoverTest.java +++ b/idea/tests/org/jetbrains/jet/plugin/codeInsight/moveUpDown/AbstractCodeMoverTest.java @@ -26,6 +26,7 @@ import com.intellij.testFramework.LightCodeInsightTestCase; import org.jetbrains.annotations.NotNull; import org.jetbrains.jet.InTextDirectivesUtils; import org.jetbrains.jet.plugin.codeInsight.upDownMover.JetDeclarationMover; +import org.jetbrains.jet.plugin.codeInsight.upDownMover.JetExpressionMover; import java.io.File; @@ -34,6 +35,10 @@ public abstract class AbstractCodeMoverTest extends LightCodeInsightTestCase { doTest(path, JetDeclarationMover.class); } + public void doTestExpression(@NotNull String path) throws Exception { + doTest(path, JetExpressionMover.class); + } + private void doTest(@NotNull String path, @NotNull Class moverClass) throws Exception { configureByFile(path); diff --git a/idea/tests/org/jetbrains/jet/plugin/codeInsight/moveUpDown/CodeMoverTestGenerated.java b/idea/tests/org/jetbrains/jet/plugin/codeInsight/moveUpDown/CodeMoverTestGenerated.java index 44c810ed49d..6b4ca6785ef 100644 --- a/idea/tests/org/jetbrains/jet/plugin/codeInsight/moveUpDown/CodeMoverTestGenerated.java +++ b/idea/tests/org/jetbrains/jet/plugin/codeInsight/moveUpDown/CodeMoverTestGenerated.java @@ -30,7 +30,7 @@ import org.jetbrains.jet.plugin.codeInsight.moveUpDown.AbstractCodeMoverTest; /** This class is generated by {@link org.jetbrains.jet.generators.tests.GenerateTests}. DO NOT MODIFY MANUALLY */ @SuppressWarnings("all") -@InnerTestClasses({CodeMoverTestGenerated.ClassBodyDeclarations.class}) +@InnerTestClasses({CodeMoverTestGenerated.ClassBodyDeclarations.class, CodeMoverTestGenerated.ClosingBraces.class, CodeMoverTestGenerated.Expressions.class}) public class CodeMoverTestGenerated extends AbstractCodeMoverTest { @TestMetadata("idea/testData/codeInsight/moveUpDown/classBodyDeclarations") @InnerTestClasses({ClassBodyDeclarations.Accessors.class, ClassBodyDeclarations.Class.class, ClassBodyDeclarations.ClassInitializer.class, ClassBodyDeclarations.Enums.class, ClassBodyDeclarations.Function.class, ClassBodyDeclarations.Property.class}) @@ -450,9 +450,248 @@ public class CodeMoverTestGenerated extends AbstractCodeMoverTest { } } + @TestMetadata("idea/testData/codeInsight/moveUpDown/closingBraces") + @InnerTestClasses({ClosingBraces.For.class, ClosingBraces.If.class, ClosingBraces.Nested.class, ClosingBraces.When.class, ClosingBraces.While.class}) + public static class ClosingBraces extends AbstractCodeMoverTest { + public void testAllFilesPresentInClosingBraces() throws Exception { + JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.GenerateTests", new File("idea/testData/codeInsight/moveUpDown/closingBraces"), Pattern.compile("^(.+)\\.kt$"), true); + } + + @TestMetadata("idea/testData/codeInsight/moveUpDown/closingBraces/for") + public static class For extends AbstractCodeMoverTest { + public void testAllFilesPresentInFor() throws Exception { + JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.GenerateTests", new File("idea/testData/codeInsight/moveUpDown/closingBraces/for"), Pattern.compile("^(.+)\\.kt$"), true); + } + + @TestMetadata("for1.kt") + public void testFor1() throws Exception { + doTestExpression("idea/testData/codeInsight/moveUpDown/closingBraces/for/for1.kt"); + } + + @TestMetadata("for2.kt") + public void testFor2() throws Exception { + doTestExpression("idea/testData/codeInsight/moveUpDown/closingBraces/for/for2.kt"); + } + + } + + @TestMetadata("idea/testData/codeInsight/moveUpDown/closingBraces/if") + public static class If extends AbstractCodeMoverTest { + public void testAllFilesPresentInIf() throws Exception { + JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.GenerateTests", new File("idea/testData/codeInsight/moveUpDown/closingBraces/if"), Pattern.compile("^(.+)\\.kt$"), true); + } + + @TestMetadata("if1.kt") + public void testIf1() throws Exception { + doTestExpression("idea/testData/codeInsight/moveUpDown/closingBraces/if/if1.kt"); + } + + @TestMetadata("if2.kt") + public void testIf2() throws Exception { + doTestExpression("idea/testData/codeInsight/moveUpDown/closingBraces/if/if2.kt"); + } + + @TestMetadata("if3.kt") + public void testIf3() throws Exception { + doTestExpression("idea/testData/codeInsight/moveUpDown/closingBraces/if/if3.kt"); + } + + @TestMetadata("if4.kt") + public void testIf4() throws Exception { + doTestExpression("idea/testData/codeInsight/moveUpDown/closingBraces/if/if4.kt"); + } + + } + + @TestMetadata("idea/testData/codeInsight/moveUpDown/closingBraces/nested") + public static class Nested extends AbstractCodeMoverTest { + public void testAllFilesPresentInNested() throws Exception { + JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.GenerateTests", new File("idea/testData/codeInsight/moveUpDown/closingBraces/nested"), Pattern.compile("^(.+)\\.kt$"), true); + } + + @TestMetadata("nested1.kt") + public void testNested1() throws Exception { + doTestExpression("idea/testData/codeInsight/moveUpDown/closingBraces/nested/nested1.kt"); + } + + @TestMetadata("nested2.kt") + public void testNested2() throws Exception { + doTestExpression("idea/testData/codeInsight/moveUpDown/closingBraces/nested/nested2.kt"); + } + + } + + @TestMetadata("idea/testData/codeInsight/moveUpDown/closingBraces/when") + public static class When extends AbstractCodeMoverTest { + public void testAllFilesPresentInWhen() throws Exception { + JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.GenerateTests", new File("idea/testData/codeInsight/moveUpDown/closingBraces/when"), Pattern.compile("^(.+)\\.kt$"), true); + } + + @TestMetadata("when1.kt") + public void testWhen1() throws Exception { + doTestExpression("idea/testData/codeInsight/moveUpDown/closingBraces/when/when1.kt"); + } + + @TestMetadata("when2.kt") + public void testWhen2() throws Exception { + doTestExpression("idea/testData/codeInsight/moveUpDown/closingBraces/when/when2.kt"); + } + + @TestMetadata("whenEntry1.kt") + public void testWhenEntry1() throws Exception { + doTestExpression("idea/testData/codeInsight/moveUpDown/closingBraces/when/whenEntry1.kt"); + } + + @TestMetadata("whenEntry2.kt") + public void testWhenEntry2() throws Exception { + doTestExpression("idea/testData/codeInsight/moveUpDown/closingBraces/when/whenEntry2.kt"); + } + + @TestMetadata("whenEntry3.kt") + public void testWhenEntry3() throws Exception { + doTestExpression("idea/testData/codeInsight/moveUpDown/closingBraces/when/whenEntry3.kt"); + } + + @TestMetadata("whenEntry4.kt") + public void testWhenEntry4() throws Exception { + doTestExpression("idea/testData/codeInsight/moveUpDown/closingBraces/when/whenEntry4.kt"); + } + + } + + @TestMetadata("idea/testData/codeInsight/moveUpDown/closingBraces/while") + public static class While extends AbstractCodeMoverTest { + public void testAllFilesPresentInWhile() throws Exception { + JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.GenerateTests", new File("idea/testData/codeInsight/moveUpDown/closingBraces/while"), Pattern.compile("^(.+)\\.kt$"), true); + } + + @TestMetadata("while1.kt") + public void testWhile1() throws Exception { + doTestExpression("idea/testData/codeInsight/moveUpDown/closingBraces/while/while1.kt"); + } + + @TestMetadata("while2.kt") + public void testWhile2() throws Exception { + doTestExpression("idea/testData/codeInsight/moveUpDown/closingBraces/while/while2.kt"); + } + + @TestMetadata("while3.kt") + public void testWhile3() throws Exception { + doTestExpression("idea/testData/codeInsight/moveUpDown/closingBraces/while/while3.kt"); + } + + @TestMetadata("while4.kt") + public void testWhile4() throws Exception { + doTestExpression("idea/testData/codeInsight/moveUpDown/closingBraces/while/while4.kt"); + } + + } + + public static Test innerSuite() { + TestSuite suite = new TestSuite("ClosingBraces"); + suite.addTestSuite(ClosingBraces.class); + suite.addTestSuite(For.class); + suite.addTestSuite(If.class); + suite.addTestSuite(Nested.class); + suite.addTestSuite(When.class); + suite.addTestSuite(While.class); + return suite; + } + } + + @TestMetadata("idea/testData/codeInsight/moveUpDown/expressions") + public static class Expressions extends AbstractCodeMoverTest { + public void testAllFilesPresentInExpressions() throws Exception { + JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.GenerateTests", new File("idea/testData/codeInsight/moveUpDown/expressions"), Pattern.compile("^(.+)\\.kt$"), true); + } + + @TestMetadata("declaration1.kt") + public void testDeclaration1() throws Exception { + doTestExpression("idea/testData/codeInsight/moveUpDown/expressions/declaration1.kt"); + } + + @TestMetadata("declaration2.kt") + public void testDeclaration2() throws Exception { + doTestExpression("idea/testData/codeInsight/moveUpDown/expressions/declaration2.kt"); + } + + @TestMetadata("If1.kt") + public void testIf1() throws Exception { + doTestExpression("idea/testData/codeInsight/moveUpDown/expressions/If1.kt"); + } + + @TestMetadata("if2.kt") + public void testIf2() throws Exception { + doTestExpression("idea/testData/codeInsight/moveUpDown/expressions/if2.kt"); + } + + @TestMetadata("if3.kt") + public void testIf3() throws Exception { + doTestExpression("idea/testData/codeInsight/moveUpDown/expressions/if3.kt"); + } + + @TestMetadata("if4.kt") + public void testIf4() throws Exception { + doTestExpression("idea/testData/codeInsight/moveUpDown/expressions/if4.kt"); + } + + @TestMetadata("when1.kt") + public void testWhen1() throws Exception { + doTestExpression("idea/testData/codeInsight/moveUpDown/expressions/when1.kt"); + } + + @TestMetadata("when2.kt") + public void testWhen2() throws Exception { + doTestExpression("idea/testData/codeInsight/moveUpDown/expressions/when2.kt"); + } + + @TestMetadata("whenEntry1.kt") + public void testWhenEntry1() throws Exception { + doTestExpression("idea/testData/codeInsight/moveUpDown/expressions/whenEntry1.kt"); + } + + @TestMetadata("whenEntry2.kt") + public void testWhenEntry2() throws Exception { + doTestExpression("idea/testData/codeInsight/moveUpDown/expressions/whenEntry2.kt"); + } + + @TestMetadata("whenEntry3.kt") + public void testWhenEntry3() throws Exception { + doTestExpression("idea/testData/codeInsight/moveUpDown/expressions/whenEntry3.kt"); + } + + @TestMetadata("whenEntry4.kt") + public void testWhenEntry4() throws Exception { + doTestExpression("idea/testData/codeInsight/moveUpDown/expressions/whenEntry4.kt"); + } + + @TestMetadata("whenEntry5.kt") + public void testWhenEntry5() throws Exception { + doTestExpression("idea/testData/codeInsight/moveUpDown/expressions/whenEntry5.kt"); + } + + @TestMetadata("whenEntry6.kt") + public void testWhenEntry6() throws Exception { + doTestExpression("idea/testData/codeInsight/moveUpDown/expressions/whenEntry6.kt"); + } + + @TestMetadata("while1.kt") + public void testWhile1() throws Exception { + doTestExpression("idea/testData/codeInsight/moveUpDown/expressions/while1.kt"); + } + + @TestMetadata("while2.kt") + public void testWhile2() throws Exception { + doTestExpression("idea/testData/codeInsight/moveUpDown/expressions/while2.kt"); + } + + } + public static Test suite() { TestSuite suite = new TestSuite("CodeMoverTestGenerated"); suite.addTest(ClassBodyDeclarations.innerSuite()); + suite.addTest(ClosingBraces.innerSuite()); + suite.addTestSuite(Expressions.class); return suite; } } From 57edbdfbc4ed661ceb5843a814d0f9e91466899f Mon Sep 17 00:00:00 2001 From: Alexey Sedunov Date: Thu, 30 May 2013 17:29:53 +0400 Subject: [PATCH 205/249] Allow moving out to arbitrary blocks and moving any declaration into class body --- .../src/org/jetbrains/jet/lang/psi/JetPsiUtil.java | 6 ++++++ .../codeInsight/upDownMover/JetDeclarationMover.java | 3 --- .../codeInsight/upDownMover/JetExpressionMover.java | 8 +++----- .../classBodyDeclarations/class/classAtBrace5.kt | 3 +-- .../classBodyDeclarations/class/classAtBrace5.kt.after | 8 ++++++++ .../classBodyDeclarations/class/classAtBrace6.kt | 3 +-- .../classBodyDeclarations/class/classAtBrace6.kt.after | 8 ++++++++ .../classBodyDeclarations/function/functionAtBrace5.kt | 1 - .../function/functionAtBrace5.kt.after | 8 ++++++++ .../classBodyDeclarations/function/functionAtBrace6.kt | 1 - .../function/functionAtBrace6.kt.after | 8 ++++++++ .../classBodyDeclarations/property/propertyAtBrace5.kt | 1 - .../property/propertyAtBrace5.kt.after | 6 ++++++ .../classBodyDeclarations/property/propertyAtBrace6.kt | 1 - .../property/propertyAtBrace6.kt.after | 6 ++++++ 15 files changed, 55 insertions(+), 16 deletions(-) create mode 100644 idea/testData/codeInsight/moveUpDown/classBodyDeclarations/class/classAtBrace5.kt.after create mode 100644 idea/testData/codeInsight/moveUpDown/classBodyDeclarations/class/classAtBrace6.kt.after create mode 100644 idea/testData/codeInsight/moveUpDown/classBodyDeclarations/function/functionAtBrace5.kt.after create mode 100644 idea/testData/codeInsight/moveUpDown/classBodyDeclarations/function/functionAtBrace6.kt.after create mode 100644 idea/testData/codeInsight/moveUpDown/classBodyDeclarations/property/propertyAtBrace5.kt.after create mode 100644 idea/testData/codeInsight/moveUpDown/classBodyDeclarations/property/propertyAtBrace6.kt.after diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetPsiUtil.java b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetPsiUtil.java index d95e66fcf47..7f1f7e3093e 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetPsiUtil.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetPsiUtil.java @@ -809,6 +809,12 @@ public class JetPsiUtil { return first ? results.get(0) : results.get(results.size() - 1); } + @Nullable + public static PsiElement findChildByType(@NotNull PsiElement element, @NotNull IElementType type) { + ASTNode node = element.getNode().findChildByType(type); + return node == null ? null : node.getPsi(); + } + @Nullable public static JetExpression getCalleeExpressionIfAny(@NotNull JetExpression expression) { if (expression instanceof JetCallElement) { diff --git a/idea/src/org/jetbrains/jet/plugin/codeInsight/upDownMover/JetDeclarationMover.java b/idea/src/org/jetbrains/jet/plugin/codeInsight/upDownMover/JetDeclarationMover.java index f720fd312b2..d1ecaedb468 100644 --- a/idea/src/org/jetbrains/jet/plugin/codeInsight/upDownMover/JetDeclarationMover.java +++ b/idea/src/org/jetbrains/jet/plugin/codeInsight/upDownMover/JetDeclarationMover.java @@ -190,9 +190,6 @@ public class JetDeclarationMover extends AbstractJetUpDownMover { nextParent = jetClassOrObject.getParent(); - // elements may be placed only to class body or file - if (!(nextParent instanceof JetFile || nextParent instanceof JetClassBody)) return null; - if (!down) { start = jetClassOrObject; } diff --git a/idea/src/org/jetbrains/jet/plugin/codeInsight/upDownMover/JetExpressionMover.java b/idea/src/org/jetbrains/jet/plugin/codeInsight/upDownMover/JetExpressionMover.java index 419cab627e4..828335213ad 100644 --- a/idea/src/org/jetbrains/jet/plugin/codeInsight/upDownMover/JetExpressionMover.java +++ b/idea/src/org/jetbrains/jet/plugin/codeInsight/upDownMover/JetExpressionMover.java @@ -203,7 +203,7 @@ public class JetExpressionMover extends AbstractJetUpDownMover { else { // moving into code block //noinspection unchecked - JetElement blockLikeElement = JetPsiUtil.getOutermostJetElement(sibling, down, JetBlockExpression.class, JetWhenExpression.class); + JetElement blockLikeElement = JetPsiUtil.getOutermostJetElement(sibling, down, JetBlockExpression.class, JetWhenExpression.class, JetClassBody.class); if (blockLikeElement != null && !(PsiTreeUtil.instanceOf(blockLikeElement, FUNCTIONLIKE_ELEMENT_CLASSES))) { if (blockLikeElement instanceof JetWhenExpression) { @@ -212,13 +212,11 @@ public class JetExpressionMover extends AbstractJetUpDownMover { } if (blockLikeElement != null) { - JetBlockExpression block = (JetBlockExpression) blockLikeElement; - if (down) { - end = block.getLBrace(); + end = JetPsiUtil.findChildByType(blockLikeElement, JetTokens.LBRACE); } else { - start = block.getRBrace(); + start = JetPsiUtil.findChildByType(blockLikeElement, JetTokens.RBRACE); } } } diff --git a/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/class/classAtBrace5.kt b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/class/classAtBrace5.kt index 5511821cbc4..b2b6b8f865a 100644 --- a/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/class/classAtBrace5.kt +++ b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/class/classAtBrace5.kt @@ -1,7 +1,6 @@ // MOVE: down -// IS_APPLICABLE: false fun foo() { - class B { + class A { class B { } diff --git a/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/class/classAtBrace5.kt.after b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/class/classAtBrace5.kt.after new file mode 100644 index 00000000000..c52276366e7 --- /dev/null +++ b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/class/classAtBrace5.kt.after @@ -0,0 +1,8 @@ +// MOVE: down +fun foo() { + class A { + } + class B { + + } +} \ No newline at end of file diff --git a/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/class/classAtBrace6.kt b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/class/classAtBrace6.kt index 711e905df5e..aa4e230f674 100644 --- a/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/class/classAtBrace6.kt +++ b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/class/classAtBrace6.kt @@ -1,7 +1,6 @@ // MOVE: up -// IS_APPLICABLE: false fun foo() { - class B { + class A { class B { } diff --git a/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/class/classAtBrace6.kt.after b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/class/classAtBrace6.kt.after new file mode 100644 index 00000000000..831f7025b08 --- /dev/null +++ b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/class/classAtBrace6.kt.after @@ -0,0 +1,8 @@ +// MOVE: up +fun foo() { + class B { + + } + class A { + } +} \ No newline at end of file diff --git a/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/function/functionAtBrace5.kt b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/function/functionAtBrace5.kt index 977102561eb..fcd181dca97 100644 --- a/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/function/functionAtBrace5.kt +++ b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/function/functionAtBrace5.kt @@ -1,5 +1,4 @@ // MOVE: down -// IS_APPLICABLE: false fun foo() { class B { fun foo() { diff --git a/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/function/functionAtBrace5.kt.after b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/function/functionAtBrace5.kt.after new file mode 100644 index 00000000000..794f2076261 --- /dev/null +++ b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/function/functionAtBrace5.kt.after @@ -0,0 +1,8 @@ +// MOVE: down +fun foo() { + class B { + } + fun foo() { + + } +} \ No newline at end of file diff --git a/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/function/functionAtBrace6.kt b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/function/functionAtBrace6.kt index d3a54cf6fc1..42314a50cc1 100644 --- a/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/function/functionAtBrace6.kt +++ b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/function/functionAtBrace6.kt @@ -1,5 +1,4 @@ // MOVE: up -// IS_APPLICABLE: false fun foo() { class B { fun foo() { diff --git a/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/function/functionAtBrace6.kt.after b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/function/functionAtBrace6.kt.after new file mode 100644 index 00000000000..1a3e7adb4c5 --- /dev/null +++ b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/function/functionAtBrace6.kt.after @@ -0,0 +1,8 @@ +// MOVE: up +fun foo() { + fun foo() { + + } + class B { + } +} \ No newline at end of file diff --git a/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/property/propertyAtBrace5.kt b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/property/propertyAtBrace5.kt index 97ca96de10c..e2dfb807f51 100644 --- a/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/property/propertyAtBrace5.kt +++ b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/property/propertyAtBrace5.kt @@ -1,5 +1,4 @@ // MOVE: down -// IS_APPLICABLE: false fun foo() { class B { val y = "" diff --git a/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/property/propertyAtBrace5.kt.after b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/property/propertyAtBrace5.kt.after new file mode 100644 index 00000000000..8df651be8f5 --- /dev/null +++ b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/property/propertyAtBrace5.kt.after @@ -0,0 +1,6 @@ +// MOVE: down +fun foo() { + class B { + } + val y = "" +} \ No newline at end of file diff --git a/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/property/propertyAtBrace6.kt b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/property/propertyAtBrace6.kt index bfe83368b6b..ab18d34ca64 100644 --- a/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/property/propertyAtBrace6.kt +++ b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/property/propertyAtBrace6.kt @@ -1,5 +1,4 @@ // MOVE: up -// IS_APPLICABLE: false fun foo() { class B { val y = "" diff --git a/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/property/propertyAtBrace6.kt.after b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/property/propertyAtBrace6.kt.after new file mode 100644 index 00000000000..12853c9e00e --- /dev/null +++ b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/property/propertyAtBrace6.kt.after @@ -0,0 +1,6 @@ +// MOVE: up +fun foo() { + val y = "" + class B { + } +} \ No newline at end of file From 5345d0a0d51b7bfc536c31a27c162027f8031fdb Mon Sep 17 00:00:00 2001 From: Alexey Sedunov Date: Thu, 30 May 2013 17:30:51 +0400 Subject: [PATCH 206/249] Fix moving of value/type parameters --- .../upDownMover/AbstractJetUpDownMover.java | 6 ++ .../upDownMover/JetDeclarationMover.java | 6 +- .../upDownMover/JetExpressionMover.java | 37 +++++++- .../functionAnchors/keyword.kt | 9 ++ .../functionAnchors/keyword.kt.after | 9 ++ .../functionAnchors/name.kt | 9 ++ .../functionAnchors/name.kt.after | 9 ++ .../functionAnchors/returnType.kt | 9 ++ .../functionAnchors/returnType.kt.after | 9 ++ .../functionAnchors/typeParams1.kt | 15 +++ .../functionAnchors/typeParams1.kt.after | 15 +++ .../functionAnchors/typeParams2.kt | 15 +++ .../functionAnchors/typeParams2.kt.after | 15 +++ .../functionAnchors/typeParams3.kt | 15 +++ .../functionAnchors/typeParams3.kt.after | 15 +++ .../functionAnchors/valueParams1.kt | 16 ++++ .../functionAnchors/valueParams1.kt.after | 16 ++++ .../functionAnchors/valueParams2.kt | 16 ++++ .../functionAnchors/valueParams2.kt.after | 16 ++++ .../functionAnchors/valueParams3.kt | 16 ++++ .../functionAnchors/valueParams3.kt.after | 16 ++++ .../functionAnchors/valueParams4.kt | 16 ++++ .../functionAnchors/valueParams4.kt.after | 16 ++++ .../functionAnchors/valueParams5.kt | 17 ++++ .../functionAnchors/valueParams6.kt | 17 ++++ .../propertyAnchors/keyword.kt | 13 +++ .../propertyAnchors/keyword.kt.after | 13 +++ .../propertyAnchors/name.kt | 13 +++ .../propertyAnchors/name.kt.after | 13 +++ .../propertyAnchors/returnType.kt | 13 +++ .../propertyAnchors/returnType.kt.after | 13 +++ .../moveUpDown/AbstractCodeMoverTest.java | 9 +- .../moveUpDown/CodeMoverTestGenerated.java | 95 ++++++++++++++++++- 33 files changed, 526 insertions(+), 11 deletions(-) create mode 100644 idea/testData/codeInsight/moveUpDown/classBodyDeclarations/functionAnchors/keyword.kt create mode 100644 idea/testData/codeInsight/moveUpDown/classBodyDeclarations/functionAnchors/keyword.kt.after create mode 100644 idea/testData/codeInsight/moveUpDown/classBodyDeclarations/functionAnchors/name.kt create mode 100644 idea/testData/codeInsight/moveUpDown/classBodyDeclarations/functionAnchors/name.kt.after create mode 100644 idea/testData/codeInsight/moveUpDown/classBodyDeclarations/functionAnchors/returnType.kt create mode 100644 idea/testData/codeInsight/moveUpDown/classBodyDeclarations/functionAnchors/returnType.kt.after create mode 100644 idea/testData/codeInsight/moveUpDown/classBodyDeclarations/functionAnchors/typeParams1.kt create mode 100644 idea/testData/codeInsight/moveUpDown/classBodyDeclarations/functionAnchors/typeParams1.kt.after create mode 100644 idea/testData/codeInsight/moveUpDown/classBodyDeclarations/functionAnchors/typeParams2.kt create mode 100644 idea/testData/codeInsight/moveUpDown/classBodyDeclarations/functionAnchors/typeParams2.kt.after create mode 100644 idea/testData/codeInsight/moveUpDown/classBodyDeclarations/functionAnchors/typeParams3.kt create mode 100644 idea/testData/codeInsight/moveUpDown/classBodyDeclarations/functionAnchors/typeParams3.kt.after create mode 100644 idea/testData/codeInsight/moveUpDown/classBodyDeclarations/functionAnchors/valueParams1.kt create mode 100644 idea/testData/codeInsight/moveUpDown/classBodyDeclarations/functionAnchors/valueParams1.kt.after create mode 100644 idea/testData/codeInsight/moveUpDown/classBodyDeclarations/functionAnchors/valueParams2.kt create mode 100644 idea/testData/codeInsight/moveUpDown/classBodyDeclarations/functionAnchors/valueParams2.kt.after create mode 100644 idea/testData/codeInsight/moveUpDown/classBodyDeclarations/functionAnchors/valueParams3.kt create mode 100644 idea/testData/codeInsight/moveUpDown/classBodyDeclarations/functionAnchors/valueParams3.kt.after create mode 100644 idea/testData/codeInsight/moveUpDown/classBodyDeclarations/functionAnchors/valueParams4.kt create mode 100644 idea/testData/codeInsight/moveUpDown/classBodyDeclarations/functionAnchors/valueParams4.kt.after create mode 100644 idea/testData/codeInsight/moveUpDown/classBodyDeclarations/functionAnchors/valueParams5.kt create mode 100644 idea/testData/codeInsight/moveUpDown/classBodyDeclarations/functionAnchors/valueParams6.kt create mode 100644 idea/testData/codeInsight/moveUpDown/classBodyDeclarations/propertyAnchors/keyword.kt create mode 100644 idea/testData/codeInsight/moveUpDown/classBodyDeclarations/propertyAnchors/keyword.kt.after create mode 100644 idea/testData/codeInsight/moveUpDown/classBodyDeclarations/propertyAnchors/name.kt create mode 100644 idea/testData/codeInsight/moveUpDown/classBodyDeclarations/propertyAnchors/name.kt.after create mode 100644 idea/testData/codeInsight/moveUpDown/classBodyDeclarations/propertyAnchors/returnType.kt create mode 100644 idea/testData/codeInsight/moveUpDown/classBodyDeclarations/propertyAnchors/returnType.kt.after diff --git a/idea/src/org/jetbrains/jet/plugin/codeInsight/upDownMover/AbstractJetUpDownMover.java b/idea/src/org/jetbrains/jet/plugin/codeInsight/upDownMover/AbstractJetUpDownMover.java index 5c1b3851294..c752befc5e4 100644 --- a/idea/src/org/jetbrains/jet/plugin/codeInsight/upDownMover/AbstractJetUpDownMover.java +++ b/idea/src/org/jetbrains/jet/plugin/codeInsight/upDownMover/AbstractJetUpDownMover.java @@ -8,6 +8,7 @@ import com.intellij.openapi.util.TextRange; import com.intellij.psi.PsiElement; import com.intellij.psi.PsiFile; import com.intellij.psi.PsiWhiteSpace; +import com.intellij.psi.util.PsiTreeUtil; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.jet.lang.psi.JetFile; @@ -51,6 +52,11 @@ public abstract class AbstractJetUpDownMover extends LineMover { return sibling; } + @Nullable + protected static PsiElement getSiblingOfType(@NotNull PsiElement element, boolean down, @NotNull Class type) { + return down ? PsiTreeUtil.getNextSiblingOfType(element, type) : PsiTreeUtil.getPrevSiblingOfType(element, type); + } + @Nullable protected static PsiElement firstNonWhiteSibling(@NotNull LineRange lineRange, boolean down) { return firstNonWhiteElement(down ? lineRange.lastElement.getNextSibling() : lineRange.firstElement.getPrevSibling(), down); diff --git a/idea/src/org/jetbrains/jet/plugin/codeInsight/upDownMover/JetDeclarationMover.java b/idea/src/org/jetbrains/jet/plugin/codeInsight/upDownMover/JetDeclarationMover.java index d1ecaedb468..f31dbe9bbf8 100644 --- a/idea/src/org/jetbrains/jet/plugin/codeInsight/upDownMover/JetDeclarationMover.java +++ b/idea/src/org/jetbrains/jet/plugin/codeInsight/upDownMover/JetDeclarationMover.java @@ -49,9 +49,6 @@ public class JetDeclarationMover extends AbstractJetUpDownMover { PsiElement equalsToken = function.getEqualsToken(); if (equalsToken != null) memberSuspects.add(equalsToken); - JetParameterList parameterList = function.getValueParameterList(); - if (parameterList != null) memberSuspects.add(parameterList); - JetTypeParameterList typeParameterList = function.getTypeParameterList(); if (typeParameterList != null) memberSuspects.add(typeParameterList); @@ -120,6 +117,9 @@ public class JetDeclarationMover extends AbstractJetUpDownMover { if (element == null) return null; JetDeclaration declaration = PsiTreeUtil.getParentOfType(element, JetDeclaration.class, false); + if (declaration instanceof JetTypeParameter) { + return getMovableDeclaration(declaration.getParent()); + } return PsiTreeUtil.instanceOf(PsiTreeUtil.getParentOfType(declaration, DECLARATION_CONTAINER_CLASSES), diff --git a/idea/src/org/jetbrains/jet/plugin/codeInsight/upDownMover/JetExpressionMover.java b/idea/src/org/jetbrains/jet/plugin/codeInsight/upDownMover/JetExpressionMover.java index 828335213ad..bed8538821f 100644 --- a/idea/src/org/jetbrains/jet/plugin/codeInsight/upDownMover/JetExpressionMover.java +++ b/idea/src/org/jetbrains/jet/plugin/codeInsight/upDownMover/JetExpressionMover.java @@ -291,6 +291,23 @@ public class JetExpressionMover extends AbstractJetUpDownMover { return sourceRange; } + @Nullable + private static PsiElement getMovableElement(@NotNull PsiElement element) { + return PsiTreeUtil.getNonStrictParentOfType(element, MOVABLE_ELEMENT_CLASSES); + } + + // return true to forbid the move + // return false to permit the move + // return null to fall back to default line mover behavior + private static Boolean isForbiddenMove(@NotNull PsiElement element, boolean down) { + if (element instanceof JetParameter) { + PsiElement sibling = getSiblingOfType(element, down, element.getClass()); + return (sibling != null) ? null : true; + } + + return false; + } + @Override public boolean checkAvailable(@NotNull Editor editor, @NotNull PsiFile file, @NotNull MoveInfo info, boolean down) { if (!super.checkAvailable(editor, file, info, down)) return false; @@ -309,12 +326,22 @@ public class JetExpressionMover extends AbstractJetUpDownMover { if (psiRange == null) return false; //noinspection unchecked - PsiElement firstElement = PsiTreeUtil.getNonStrictParentOfType(psiRange.getFirst(), MOVABLE_ELEMENT_CLASSES); - if (firstElement == null) return false; + PsiElement firstElement = getMovableElement(psiRange.getFirst()); + PsiElement lastElement = getMovableElement(psiRange.getSecond()); - //noinspection unchecked - PsiElement lastElement = PsiTreeUtil.getNonStrictParentOfType(psiRange.getSecond(), MOVABLE_ELEMENT_CLASSES); - if (lastElement == null) return false; + if (firstElement == null || lastElement == null) return false; + + Boolean forbidFirst = isForbiddenMove(firstElement, down); + Boolean forbidLast = isForbiddenMove(lastElement, down); + + if (forbidFirst == null || forbidLast == null) { + return true; + } + + if (forbidFirst || forbidLast) { + info.toMove2 = null; + return true; + } LineRange sourceRange = getSourceRange(firstElement, lastElement, editor); if (sourceRange == null) return false; diff --git a/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/functionAnchors/keyword.kt b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/functionAnchors/keyword.kt new file mode 100644 index 00000000000..6150efb0be3 --- /dev/null +++ b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/functionAnchors/keyword.kt @@ -0,0 +1,9 @@ +// MOVE: down +class A { + fun foo() { + + } + class B { + + } +} \ No newline at end of file diff --git a/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/functionAnchors/keyword.kt.after b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/functionAnchors/keyword.kt.after new file mode 100644 index 00000000000..d616e7db69a --- /dev/null +++ b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/functionAnchors/keyword.kt.after @@ -0,0 +1,9 @@ +// MOVE: down +class A { + class B { + fun foo() { + + } + + } +} \ No newline at end of file diff --git a/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/functionAnchors/name.kt b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/functionAnchors/name.kt new file mode 100644 index 00000000000..6150efb0be3 --- /dev/null +++ b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/functionAnchors/name.kt @@ -0,0 +1,9 @@ +// MOVE: down +class A { + fun foo() { + + } + class B { + + } +} \ No newline at end of file diff --git a/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/functionAnchors/name.kt.after b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/functionAnchors/name.kt.after new file mode 100644 index 00000000000..d616e7db69a --- /dev/null +++ b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/functionAnchors/name.kt.after @@ -0,0 +1,9 @@ +// MOVE: down +class A { + class B { + fun foo() { + + } + + } +} \ No newline at end of file diff --git a/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/functionAnchors/returnType.kt b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/functionAnchors/returnType.kt new file mode 100644 index 00000000000..5f82e152611 --- /dev/null +++ b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/functionAnchors/returnType.kt @@ -0,0 +1,9 @@ +// MOVE: down +class A { + fun foo(): Unit { + + } + class B { + + } +} \ No newline at end of file diff --git a/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/functionAnchors/returnType.kt.after b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/functionAnchors/returnType.kt.after new file mode 100644 index 00000000000..47e320d8329 --- /dev/null +++ b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/functionAnchors/returnType.kt.after @@ -0,0 +1,9 @@ +// MOVE: down +class A { + class B { + fun foo(): Unit { + + } + + } +} \ No newline at end of file diff --git a/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/functionAnchors/typeParams1.kt b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/functionAnchors/typeParams1.kt new file mode 100644 index 00000000000..76b00ab230e --- /dev/null +++ b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/functionAnchors/typeParams1.kt @@ -0,0 +1,15 @@ +// MOVE: down +class A { + fun foo<T, + U, + W>( + b: Int, + a: Int, + c: Int + ) { + + } + class B { + + } +} \ No newline at end of file diff --git a/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/functionAnchors/typeParams1.kt.after b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/functionAnchors/typeParams1.kt.after new file mode 100644 index 00000000000..5599dc1ec8d --- /dev/null +++ b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/functionAnchors/typeParams1.kt.after @@ -0,0 +1,15 @@ +// MOVE: down +class A { + class B { + fun foo<T, + U, + W>( + b: Int, + a: Int, + c: Int + ) { + + } + + } +} \ No newline at end of file diff --git a/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/functionAnchors/typeParams2.kt b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/functionAnchors/typeParams2.kt new file mode 100644 index 00000000000..06d46bf4afe --- /dev/null +++ b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/functionAnchors/typeParams2.kt @@ -0,0 +1,15 @@ +// MOVE: down +class A { + fun foo, + W>( + b: Int, + a: Int, + c: Int + ) { + + } + class B { + + } +} \ No newline at end of file diff --git a/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/functionAnchors/typeParams2.kt.after b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/functionAnchors/typeParams2.kt.after new file mode 100644 index 00000000000..717f68b8366 --- /dev/null +++ b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/functionAnchors/typeParams2.kt.after @@ -0,0 +1,15 @@ +// MOVE: down +class A { + class B { + fun foo, + W>( + b: Int, + a: Int, + c: Int + ) { + + } + + } +} \ No newline at end of file diff --git a/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/functionAnchors/typeParams3.kt b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/functionAnchors/typeParams3.kt new file mode 100644 index 00000000000..57ea5dd84da --- /dev/null +++ b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/functionAnchors/typeParams3.kt @@ -0,0 +1,15 @@ +// MOVE: down +class A { + fun foo>( + b: Int, + a: Int, + c: Int + ) { + + } + class B { + + } +} \ No newline at end of file diff --git a/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/functionAnchors/typeParams3.kt.after b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/functionAnchors/typeParams3.kt.after new file mode 100644 index 00000000000..8fe9444b7d8 --- /dev/null +++ b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/functionAnchors/typeParams3.kt.after @@ -0,0 +1,15 @@ +// MOVE: down +class A { + class B { + fun foo>( + b: Int, + a: Int, + c: Int + ) { + + } + + } +} \ No newline at end of file diff --git a/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/functionAnchors/valueParams1.kt b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/functionAnchors/valueParams1.kt new file mode 100644 index 00000000000..ac59006eaae --- /dev/null +++ b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/functionAnchors/valueParams1.kt @@ -0,0 +1,16 @@ +// MOVE: down +// MOVER_CLASS: org.jetbrains.jet.plugin.codeInsight.upDownMover.JetExpressionMover +class A { + fun foo( + b: Int, + a: Int, + c: Int + ) { + + } + class B { + + } +} \ No newline at end of file diff --git a/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/functionAnchors/valueParams1.kt.after b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/functionAnchors/valueParams1.kt.after new file mode 100644 index 00000000000..061c5220a57 --- /dev/null +++ b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/functionAnchors/valueParams1.kt.after @@ -0,0 +1,16 @@ +// MOVE: down +// MOVER_CLASS: org.jetbrains.jet.plugin.codeInsight.upDownMover.JetExpressionMover +class A { + fun foo( + a: Int, + b: Int, + c: Int + ) { + + } + class B { + + } +} \ No newline at end of file diff --git a/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/functionAnchors/valueParams2.kt b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/functionAnchors/valueParams2.kt new file mode 100644 index 00000000000..4300aa586f3 --- /dev/null +++ b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/functionAnchors/valueParams2.kt @@ -0,0 +1,16 @@ +// MOVE: down +// MOVER_CLASS: org.jetbrains.jet.plugin.codeInsight.upDownMover.JetExpressionMover +class A { + fun foo( + b: Int, + a: Int, + c: Int + ) { + + } + class B { + + } +} \ No newline at end of file diff --git a/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/functionAnchors/valueParams2.kt.after b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/functionAnchors/valueParams2.kt.after new file mode 100644 index 00000000000..ed71321452d --- /dev/null +++ b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/functionAnchors/valueParams2.kt.after @@ -0,0 +1,16 @@ +// MOVE: down +// MOVER_CLASS: org.jetbrains.jet.plugin.codeInsight.upDownMover.JetExpressionMover +class A { + fun foo( + b: Int, + c: Int + a: Int, + ) { + + } + class B { + + } +} \ No newline at end of file diff --git a/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/functionAnchors/valueParams3.kt b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/functionAnchors/valueParams3.kt new file mode 100644 index 00000000000..eb98175f5ba --- /dev/null +++ b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/functionAnchors/valueParams3.kt @@ -0,0 +1,16 @@ +// MOVE: up +// MOVER_CLASS: org.jetbrains.jet.plugin.codeInsight.upDownMover.JetExpressionMover +class A { + fun foo( + a: Int, + b: Int, + c: Int + ) { + + } + class B { + + } +} \ No newline at end of file diff --git a/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/functionAnchors/valueParams3.kt.after b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/functionAnchors/valueParams3.kt.after new file mode 100644 index 00000000000..d8a000b41a3 --- /dev/null +++ b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/functionAnchors/valueParams3.kt.after @@ -0,0 +1,16 @@ +// MOVE: up +// MOVER_CLASS: org.jetbrains.jet.plugin.codeInsight.upDownMover.JetExpressionMover +class A { + fun foo( + b: Int, + a: Int, + c: Int + ) { + + } + class B { + + } +} \ No newline at end of file diff --git a/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/functionAnchors/valueParams4.kt b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/functionAnchors/valueParams4.kt new file mode 100644 index 00000000000..e46e747c672 --- /dev/null +++ b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/functionAnchors/valueParams4.kt @@ -0,0 +1,16 @@ +// MOVE: up +// MOVER_CLASS: org.jetbrains.jet.plugin.codeInsight.upDownMover.JetExpressionMover +class A { + fun foo( + b: Int, + c: Int + a: Int, + ) { + + } + class B { + + } +} \ No newline at end of file diff --git a/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/functionAnchors/valueParams4.kt.after b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/functionAnchors/valueParams4.kt.after new file mode 100644 index 00000000000..73fef7e9453 --- /dev/null +++ b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/functionAnchors/valueParams4.kt.after @@ -0,0 +1,16 @@ +// MOVE: up +// MOVER_CLASS: org.jetbrains.jet.plugin.codeInsight.upDownMover.JetExpressionMover +class A { + fun foo( + b: Int, + a: Int, + c: Int + ) { + + } + class B { + + } +} \ No newline at end of file diff --git a/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/functionAnchors/valueParams5.kt b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/functionAnchors/valueParams5.kt new file mode 100644 index 00000000000..706e5b82cb1 --- /dev/null +++ b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/functionAnchors/valueParams5.kt @@ -0,0 +1,17 @@ +// MOVE: down +// MOVER_CLASS: org.jetbrains.jet.plugin.codeInsight.upDownMover.JetExpressionMover +// IS_APPLICABLE: false +class A { + fun foo( + b: Int, + c: Int + a: Int, + ) { + + } + class B { + + } +} \ No newline at end of file diff --git a/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/functionAnchors/valueParams6.kt b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/functionAnchors/valueParams6.kt new file mode 100644 index 00000000000..9fad3970685 --- /dev/null +++ b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/functionAnchors/valueParams6.kt @@ -0,0 +1,17 @@ +// MOVE: up +// MOVER_CLASS: org.jetbrains.jet.plugin.codeInsight.upDownMover.JetExpressionMover +// IS_APPLICABLE: false +class A { + fun foo( + b: Int, + c: Int + a: Int, + ) { + + } + class B { + + } +} \ No newline at end of file diff --git a/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/propertyAnchors/keyword.kt b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/propertyAnchors/keyword.kt new file mode 100644 index 00000000000..c13119db2c6 --- /dev/null +++ b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/propertyAnchors/keyword.kt @@ -0,0 +1,13 @@ +// MOVE: down +class A { + val x: String + get() { + return "" + } + set(v: String) { + + } + class B { + + } +} \ No newline at end of file diff --git a/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/propertyAnchors/keyword.kt.after b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/propertyAnchors/keyword.kt.after new file mode 100644 index 00000000000..cc22dcc2c56 --- /dev/null +++ b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/propertyAnchors/keyword.kt.after @@ -0,0 +1,13 @@ +// MOVE: down +class A { + class B { + val x: String + get() { + return "" + } + set(v: String) { + + } + + } +} \ No newline at end of file diff --git a/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/propertyAnchors/name.kt b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/propertyAnchors/name.kt new file mode 100644 index 00000000000..93950581d05 --- /dev/null +++ b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/propertyAnchors/name.kt @@ -0,0 +1,13 @@ +// MOVE: down +class A { + val x: String + get() { + return "" + } + set(v: String) { + + } + class B { + + } +} \ No newline at end of file diff --git a/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/propertyAnchors/name.kt.after b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/propertyAnchors/name.kt.after new file mode 100644 index 00000000000..cd15135fd3d --- /dev/null +++ b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/propertyAnchors/name.kt.after @@ -0,0 +1,13 @@ +// MOVE: down +class A { + class B { + val x: String + get() { + return "" + } + set(v: String) { + + } + + } +} \ No newline at end of file diff --git a/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/propertyAnchors/returnType.kt b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/propertyAnchors/returnType.kt new file mode 100644 index 00000000000..22720ebaa89 --- /dev/null +++ b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/propertyAnchors/returnType.kt @@ -0,0 +1,13 @@ +// MOVE: down +class A { + val x: String + get() { + return "" + } + set(v: String) { + + } + class B { + + } +} \ No newline at end of file diff --git a/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/propertyAnchors/returnType.kt.after b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/propertyAnchors/returnType.kt.after new file mode 100644 index 00000000000..a735c09f511 --- /dev/null +++ b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/propertyAnchors/returnType.kt.after @@ -0,0 +1,13 @@ +// MOVE: down +class A { + class B { + val x: String + get() { + return "" + } + set(v: String) { + + } + + } +} \ No newline at end of file diff --git a/idea/tests/org/jetbrains/jet/plugin/codeInsight/moveUpDown/AbstractCodeMoverTest.java b/idea/tests/org/jetbrains/jet/plugin/codeInsight/moveUpDown/AbstractCodeMoverTest.java index 329bf8489e8..53ade244493 100644 --- a/idea/tests/org/jetbrains/jet/plugin/codeInsight/moveUpDown/AbstractCodeMoverTest.java +++ b/idea/tests/org/jetbrains/jet/plugin/codeInsight/moveUpDown/AbstractCodeMoverTest.java @@ -39,7 +39,7 @@ public abstract class AbstractCodeMoverTest extends LightCodeInsightTestCase { doTest(path, JetExpressionMover.class); } - private void doTest(@NotNull String path, @NotNull Class moverClass) throws Exception { + private void doTest(@NotNull String path, @NotNull Class defaultMoverClass) throws Exception { configureByFile(path); String fileText = FileUtil.loadFile(new File(path)); @@ -69,8 +69,13 @@ public abstract class AbstractCodeMoverTest extends LightCodeInsightTestCase { } } + String moverClassName = InTextDirectivesUtils.findStringWithPrefixes(fileText, "// MOVER_CLASS: "); + if (moverClassName == null) { + moverClassName = defaultMoverClass.getName(); + } + assertTrue("No mover found", actualMover != null); - assertEquals("Unmatched movers", moverClass, actualMover.getClass()); + assertEquals("Unmatched movers", moverClassName, actualMover.getClass().getName()); assertEquals("Invalid applicability", isApplicableExpected, info.toMove2 != null); if (isApplicableExpected) { diff --git a/idea/tests/org/jetbrains/jet/plugin/codeInsight/moveUpDown/CodeMoverTestGenerated.java b/idea/tests/org/jetbrains/jet/plugin/codeInsight/moveUpDown/CodeMoverTestGenerated.java index 6b4ca6785ef..c7c96ca17f1 100644 --- a/idea/tests/org/jetbrains/jet/plugin/codeInsight/moveUpDown/CodeMoverTestGenerated.java +++ b/idea/tests/org/jetbrains/jet/plugin/codeInsight/moveUpDown/CodeMoverTestGenerated.java @@ -33,7 +33,7 @@ import org.jetbrains.jet.plugin.codeInsight.moveUpDown.AbstractCodeMoverTest; @InnerTestClasses({CodeMoverTestGenerated.ClassBodyDeclarations.class, CodeMoverTestGenerated.ClosingBraces.class, CodeMoverTestGenerated.Expressions.class}) public class CodeMoverTestGenerated extends AbstractCodeMoverTest { @TestMetadata("idea/testData/codeInsight/moveUpDown/classBodyDeclarations") - @InnerTestClasses({ClassBodyDeclarations.Accessors.class, ClassBodyDeclarations.Class.class, ClassBodyDeclarations.ClassInitializer.class, ClassBodyDeclarations.Enums.class, ClassBodyDeclarations.Function.class, ClassBodyDeclarations.Property.class}) + @InnerTestClasses({ClassBodyDeclarations.Accessors.class, ClassBodyDeclarations.Class.class, ClassBodyDeclarations.ClassInitializer.class, ClassBodyDeclarations.Enums.class, ClassBodyDeclarations.Function.class, ClassBodyDeclarations.FunctionAnchors.class, ClassBodyDeclarations.Property.class, ClassBodyDeclarations.PropertyAnchors.class}) public static class ClassBodyDeclarations extends AbstractCodeMoverTest { public void testAllFilesPresentInClassBodyDeclarations() throws Exception { JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.GenerateTests", new File("idea/testData/codeInsight/moveUpDown/classBodyDeclarations"), Pattern.compile("^(.+)\\.kt$"), true); @@ -349,6 +349,74 @@ public class CodeMoverTestGenerated extends AbstractCodeMoverTest { } + @TestMetadata("idea/testData/codeInsight/moveUpDown/classBodyDeclarations/functionAnchors") + public static class FunctionAnchors extends AbstractCodeMoverTest { + public void testAllFilesPresentInFunctionAnchors() throws Exception { + JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.GenerateTests", new File("idea/testData/codeInsight/moveUpDown/classBodyDeclarations/functionAnchors"), Pattern.compile("^(.+)\\.kt$"), true); + } + + @TestMetadata("keyword.kt") + public void testKeyword() throws Exception { + doTestClassBodyDeclaration("idea/testData/codeInsight/moveUpDown/classBodyDeclarations/functionAnchors/keyword.kt"); + } + + @TestMetadata("name.kt") + public void testName() throws Exception { + doTestClassBodyDeclaration("idea/testData/codeInsight/moveUpDown/classBodyDeclarations/functionAnchors/name.kt"); + } + + @TestMetadata("returnType.kt") + public void testReturnType() throws Exception { + doTestClassBodyDeclaration("idea/testData/codeInsight/moveUpDown/classBodyDeclarations/functionAnchors/returnType.kt"); + } + + @TestMetadata("typeParams1.kt") + public void testTypeParams1() throws Exception { + doTestClassBodyDeclaration("idea/testData/codeInsight/moveUpDown/classBodyDeclarations/functionAnchors/typeParams1.kt"); + } + + @TestMetadata("typeParams2.kt") + public void testTypeParams2() throws Exception { + doTestClassBodyDeclaration("idea/testData/codeInsight/moveUpDown/classBodyDeclarations/functionAnchors/typeParams2.kt"); + } + + @TestMetadata("typeParams3.kt") + public void testTypeParams3() throws Exception { + doTestClassBodyDeclaration("idea/testData/codeInsight/moveUpDown/classBodyDeclarations/functionAnchors/typeParams3.kt"); + } + + @TestMetadata("valueParams1.kt") + public void testValueParams1() throws Exception { + doTestClassBodyDeclaration("idea/testData/codeInsight/moveUpDown/classBodyDeclarations/functionAnchors/valueParams1.kt"); + } + + @TestMetadata("valueParams2.kt") + public void testValueParams2() throws Exception { + doTestClassBodyDeclaration("idea/testData/codeInsight/moveUpDown/classBodyDeclarations/functionAnchors/valueParams2.kt"); + } + + @TestMetadata("valueParams3.kt") + public void testValueParams3() throws Exception { + doTestClassBodyDeclaration("idea/testData/codeInsight/moveUpDown/classBodyDeclarations/functionAnchors/valueParams3.kt"); + } + + @TestMetadata("valueParams4.kt") + public void testValueParams4() throws Exception { + doTestClassBodyDeclaration("idea/testData/codeInsight/moveUpDown/classBodyDeclarations/functionAnchors/valueParams4.kt"); + } + + @TestMetadata("valueParams5.kt") + public void testValueParams5() throws Exception { + doTestClassBodyDeclaration("idea/testData/codeInsight/moveUpDown/classBodyDeclarations/functionAnchors/valueParams5.kt"); + } + + @TestMetadata("valueParams6.kt") + public void testValueParams6() throws Exception { + doTestClassBodyDeclaration("idea/testData/codeInsight/moveUpDown/classBodyDeclarations/functionAnchors/valueParams6.kt"); + } + + } + @TestMetadata("idea/testData/codeInsight/moveUpDown/classBodyDeclarations/property") public static class Property extends AbstractCodeMoverTest { public void testAllFilesPresentInProperty() throws Exception { @@ -437,6 +505,29 @@ public class CodeMoverTestGenerated extends AbstractCodeMoverTest { } + @TestMetadata("idea/testData/codeInsight/moveUpDown/classBodyDeclarations/propertyAnchors") + public static class PropertyAnchors extends AbstractCodeMoverTest { + public void testAllFilesPresentInPropertyAnchors() throws Exception { + JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.GenerateTests", new File("idea/testData/codeInsight/moveUpDown/classBodyDeclarations/propertyAnchors"), Pattern.compile("^(.+)\\.kt$"), true); + } + + @TestMetadata("keyword.kt") + public void testKeyword() throws Exception { + doTestClassBodyDeclaration("idea/testData/codeInsight/moveUpDown/classBodyDeclarations/propertyAnchors/keyword.kt"); + } + + @TestMetadata("name.kt") + public void testName() throws Exception { + doTestClassBodyDeclaration("idea/testData/codeInsight/moveUpDown/classBodyDeclarations/propertyAnchors/name.kt"); + } + + @TestMetadata("returnType.kt") + public void testReturnType() throws Exception { + doTestClassBodyDeclaration("idea/testData/codeInsight/moveUpDown/classBodyDeclarations/propertyAnchors/returnType.kt"); + } + + } + public static Test innerSuite() { TestSuite suite = new TestSuite("ClassBodyDeclarations"); suite.addTestSuite(ClassBodyDeclarations.class); @@ -445,7 +536,9 @@ public class CodeMoverTestGenerated extends AbstractCodeMoverTest { suite.addTestSuite(ClassInitializer.class); suite.addTestSuite(Enums.class); suite.addTestSuite(Function.class); + suite.addTestSuite(FunctionAnchors.class); suite.addTestSuite(Property.class); + suite.addTestSuite(PropertyAnchors.class); return suite; } } From 2cc163cd902f27abb5fa333fe80c1ac9ceed1fe8 Mon Sep 17 00:00:00 2001 From: Alexey Sedunov Date: Fri, 31 May 2013 19:19:57 +0400 Subject: [PATCH 207/249] Replace triple booleans with enums --- .../upDownMover/JetExpressionMover.java | 67 +++++++++++-------- 1 file changed, 39 insertions(+), 28 deletions(-) diff --git a/idea/src/org/jetbrains/jet/plugin/codeInsight/upDownMover/JetExpressionMover.java b/idea/src/org/jetbrains/jet/plugin/codeInsight/upDownMover/JetExpressionMover.java index bed8538821f..5d12af20cb8 100644 --- a/idea/src/org/jetbrains/jet/plugin/codeInsight/upDownMover/JetExpressionMover.java +++ b/idea/src/org/jetbrains/jet/plugin/codeInsight/upDownMover/JetExpressionMover.java @@ -54,7 +54,7 @@ public class JetExpressionMover extends AbstractJetUpDownMover { return file.findElementAt(lineStartOffset + lineText.indexOf('}')); } - private static boolean checkForMovableDownClosingBrace( + private static BraceStatus checkForMovableDownClosingBrace( @NotNull PsiElement closingBrace, @NotNull PsiElement block, @NotNull Editor editor, @@ -78,7 +78,7 @@ public class JetExpressionMover extends AbstractJetUpDownMover { } while (current != null && !(PsiTreeUtil.instanceOf(current, BLOCKLIKE_ELEMENT_CLASSES))); - if (nextExpression == null) return false; + if (nextExpression == null) return BraceStatus.NOT_MOVABLE; Document doc = editor.getDocument(); @@ -86,10 +86,10 @@ public class JetExpressionMover extends AbstractJetUpDownMover { info.toMove2 = new LineRange(nextElement, nextExpression); info.indentSource = true; - return true; + return BraceStatus.MOVABLE; } - private static boolean checkForMovableUpClosingBrace( + private static BraceStatus checkForMovableUpClosingBrace( @NotNull PsiElement closingBrace, PsiElement block, @NotNull Editor editor, @@ -97,7 +97,7 @@ public class JetExpressionMover extends AbstractJetUpDownMover { ) { //noinspection unchecked PsiElement prev = JetPsiUtil.getLastChildByType(block, JetExpression.class); - if (prev == null) return false; + if (prev == null) return BraceStatus.NOT_MOVABLE; Document doc = editor.getDocument(); @@ -105,35 +105,42 @@ public class JetExpressionMover extends AbstractJetUpDownMover { info.toMove2 = new LineRange(prev, prev, doc); info.indentSource = true; - return true; + return BraceStatus.MOVABLE; + } + + private static enum BraceStatus { + NOT_FOUND, + MOVABLE, + NOT_MOVABLE } // Returns null if standalone closing brace is not found - private static Boolean checkForMovableClosingBrace( + private static BraceStatus checkForMovableClosingBrace( @NotNull Editor editor, @NotNull PsiFile file, @NotNull MoveInfo info, boolean down ) { PsiElement closingBrace = getStandaloneClosingBrace(file, editor); - if (closingBrace == null) return null; + if (closingBrace == null) return BraceStatus.NOT_FOUND; PsiElement blockLikeElement = closingBrace.getParent(); - if (!(blockLikeElement instanceof JetBlockExpression)) return false; - if (blockLikeElement.getParent() instanceof JetWhenEntry) return false; + if (!(blockLikeElement instanceof JetBlockExpression)) return BraceStatus.NOT_MOVABLE; + if (blockLikeElement.getParent() instanceof JetWhenEntry) return BraceStatus.NOT_MOVABLE; PsiElement enclosingExpression = PsiTreeUtil.getParentOfType(blockLikeElement, JetExpression.class); - if (enclosingExpression instanceof JetDoWhileExpression) return false; + if (enclosingExpression instanceof JetDoWhileExpression) return BraceStatus.NOT_MOVABLE; if (enclosingExpression instanceof JetIfExpression) { JetIfExpression ifExpression = (JetIfExpression) enclosingExpression; - if (blockLikeElement == ifExpression.getThen() && ifExpression.getElse() != null) return false; + if (blockLikeElement == ifExpression.getThen() && ifExpression.getElse() != null) return BraceStatus.NOT_MOVABLE; } - return down ? checkForMovableDownClosingBrace(closingBrace, blockLikeElement, editor, info) : - checkForMovableUpClosingBrace(closingBrace, blockLikeElement, editor, info); + return down + ? checkForMovableDownClosingBrace(closingBrace, blockLikeElement, editor, info) + : checkForMovableUpClosingBrace(closingBrace, blockLikeElement, editor, info); } @Nullable @@ -296,28 +303,32 @@ public class JetExpressionMover extends AbstractJetUpDownMover { return PsiTreeUtil.getNonStrictParentOfType(element, MOVABLE_ELEMENT_CLASSES); } - // return true to forbid the move - // return false to permit the move - // return null to fall back to default line mover behavior - private static Boolean isForbiddenMove(@NotNull PsiElement element, boolean down) { + private static enum MoveStatus { + DEFAULT, + FORBIDDEN, + PERMITTED + } + + private static MoveStatus getMoveStatus(@NotNull PsiElement element, boolean down) { if (element instanceof JetParameter) { PsiElement sibling = getSiblingOfType(element, down, element.getClass()); - return (sibling != null) ? null : true; + return (sibling != null) ? MoveStatus.DEFAULT : MoveStatus.FORBIDDEN; } - return false; + return MoveStatus.PERMITTED; } @Override public boolean checkAvailable(@NotNull Editor editor, @NotNull PsiFile file, @NotNull MoveInfo info, boolean down) { if (!super.checkAvailable(editor, file, info, down)) return false; - Boolean closingBraceWin = checkForMovableClosingBrace(editor, file, info, down); - if (closingBraceWin != null) { - if (!closingBraceWin) { + switch (checkForMovableClosingBrace(editor, file, info, down)) { + case NOT_MOVABLE: { info.toMove2 = null; + return true; } - return true; + case MOVABLE: return true; + default: break; } LineRange oldRange = info.toMove; @@ -331,14 +342,14 @@ public class JetExpressionMover extends AbstractJetUpDownMover { if (firstElement == null || lastElement == null) return false; - Boolean forbidFirst = isForbiddenMove(firstElement, down); - Boolean forbidLast = isForbiddenMove(lastElement, down); + MoveStatus firstMoveStatus = getMoveStatus(firstElement, down); + MoveStatus lastMoveStatus = getMoveStatus(lastElement, down); - if (forbidFirst == null || forbidLast == null) { + if (firstMoveStatus == MoveStatus.DEFAULT || lastMoveStatus == MoveStatus.DEFAULT) { return true; } - if (forbidFirst || forbidLast) { + if (firstMoveStatus == MoveStatus.FORBIDDEN || lastMoveStatus == MoveStatus.FORBIDDEN) { info.toMove2 = null; return true; } From 30e333c67085d598df3dd963ba955b42da75ef42 Mon Sep 17 00:00:00 2001 From: Alexey Sedunov Date: Fri, 31 May 2013 19:23:27 +0400 Subject: [PATCH 208/249] Allow to move "when entry" at closing brace --- .../upDownMover/JetExpressionMover.java | 4 ++-- .../moveUpDown/closingBraces/when/whenEntry2.kt | 1 - .../closingBraces/when/whenEntry2.kt.after | 16 ++++++++++++++++ .../moveUpDown/closingBraces/when/whenEntry3.kt | 1 - .../closingBraces/when/whenEntry3.kt.after | 16 ++++++++++++++++ .../moveUpDown/closingBraces/when/whenEntry4.kt | 1 - .../closingBraces/when/whenEntry4.kt.after | 16 ++++++++++++++++ 7 files changed, 50 insertions(+), 5 deletions(-) create mode 100644 idea/testData/codeInsight/moveUpDown/closingBraces/when/whenEntry2.kt.after create mode 100644 idea/testData/codeInsight/moveUpDown/closingBraces/when/whenEntry3.kt.after create mode 100644 idea/testData/codeInsight/moveUpDown/closingBraces/when/whenEntry4.kt.after diff --git a/idea/src/org/jetbrains/jet/plugin/codeInsight/upDownMover/JetExpressionMover.java b/idea/src/org/jetbrains/jet/plugin/codeInsight/upDownMover/JetExpressionMover.java index 5d12af20cb8..3f6b65a0a93 100644 --- a/idea/src/org/jetbrains/jet/plugin/codeInsight/upDownMover/JetExpressionMover.java +++ b/idea/src/org/jetbrains/jet/plugin/codeInsight/upDownMover/JetExpressionMover.java @@ -23,7 +23,7 @@ public class JetExpressionMover extends AbstractJetUpDownMover { @SuppressWarnings("FieldMayBeFinal") private static Class[] BLOCKLIKE_ELEMENT_CLASSES = - {JetBlockExpression.class, JetWhenExpression.class, JetPropertyAccessor.class, JetClassBody.class, JetFile.class}; + {JetBlockExpression.class, JetWhenExpression.class, JetClassBody.class, JetFile.class}; @SuppressWarnings("FieldMayBeFinal") private static Class[] FUNCTIONLIKE_ELEMENT_CLASSES = @@ -126,7 +126,7 @@ public class JetExpressionMover extends AbstractJetUpDownMover { PsiElement blockLikeElement = closingBrace.getParent(); if (!(blockLikeElement instanceof JetBlockExpression)) return BraceStatus.NOT_MOVABLE; - if (blockLikeElement.getParent() instanceof JetWhenEntry) return BraceStatus.NOT_MOVABLE; + if (blockLikeElement.getParent() instanceof JetWhenEntry) return BraceStatus.NOT_FOUND; PsiElement enclosingExpression = PsiTreeUtil.getParentOfType(blockLikeElement, JetExpression.class); diff --git a/idea/testData/codeInsight/moveUpDown/closingBraces/when/whenEntry2.kt b/idea/testData/codeInsight/moveUpDown/closingBraces/when/whenEntry2.kt index a8f199fbc69..b3d25d5f744 100644 --- a/idea/testData/codeInsight/moveUpDown/closingBraces/when/whenEntry2.kt +++ b/idea/testData/codeInsight/moveUpDown/closingBraces/when/whenEntry2.kt @@ -1,4 +1,3 @@ -// IS_APPLICABLE: false // MOVE: up fun foo(n: Int) { diff --git a/idea/testData/codeInsight/moveUpDown/closingBraces/when/whenEntry2.kt.after b/idea/testData/codeInsight/moveUpDown/closingBraces/when/whenEntry2.kt.after new file mode 100644 index 00000000000..e23769f7213 --- /dev/null +++ b/idea/testData/codeInsight/moveUpDown/closingBraces/when/whenEntry2.kt.after @@ -0,0 +1,16 @@ +// MOVE: up + +fun foo(n: Int) { + when (n) { + 0 -> { + + } + else -> { + + } + 1 -> { + + } + } + val x = "" +} \ No newline at end of file diff --git a/idea/testData/codeInsight/moveUpDown/closingBraces/when/whenEntry3.kt b/idea/testData/codeInsight/moveUpDown/closingBraces/when/whenEntry3.kt index e357586805d..d66681a0572 100644 --- a/idea/testData/codeInsight/moveUpDown/closingBraces/when/whenEntry3.kt +++ b/idea/testData/codeInsight/moveUpDown/closingBraces/when/whenEntry3.kt @@ -1,4 +1,3 @@ -// IS_APPLICABLE: false // MOVE: down fun foo(n: Int) { diff --git a/idea/testData/codeInsight/moveUpDown/closingBraces/when/whenEntry3.kt.after b/idea/testData/codeInsight/moveUpDown/closingBraces/when/whenEntry3.kt.after new file mode 100644 index 00000000000..ea3b376f7c6 --- /dev/null +++ b/idea/testData/codeInsight/moveUpDown/closingBraces/when/whenEntry3.kt.after @@ -0,0 +1,16 @@ +// MOVE: down + +fun foo(n: Int) { + when (n) { + 0 -> { + + } + else -> { + + } + 1 -> { + + } + } + val x = "" +} \ No newline at end of file diff --git a/idea/testData/codeInsight/moveUpDown/closingBraces/when/whenEntry4.kt b/idea/testData/codeInsight/moveUpDown/closingBraces/when/whenEntry4.kt index b54c1574f67..39fe51c4565 100644 --- a/idea/testData/codeInsight/moveUpDown/closingBraces/when/whenEntry4.kt +++ b/idea/testData/codeInsight/moveUpDown/closingBraces/when/whenEntry4.kt @@ -1,4 +1,3 @@ -// IS_APPLICABLE: false // MOVE: up fun foo(n: Int) { diff --git a/idea/testData/codeInsight/moveUpDown/closingBraces/when/whenEntry4.kt.after b/idea/testData/codeInsight/moveUpDown/closingBraces/when/whenEntry4.kt.after new file mode 100644 index 00000000000..529d20f9b75 --- /dev/null +++ b/idea/testData/codeInsight/moveUpDown/closingBraces/when/whenEntry4.kt.after @@ -0,0 +1,16 @@ +// MOVE: up + +fun foo(n: Int) { + when (n) { + 1 -> { + + } + 0 -> { + + } + else -> { + + } + } + val x = "" +} \ No newline at end of file From cda940f4153acfbebd468312b5ba500702f10cb0 Mon Sep 17 00:00:00 2001 From: Alexey Sedunov Date: Mon, 3 Jun 2013 17:03:24 +0400 Subject: [PATCH 209/249] Add support of "braceless" blocks --- .../upDownMover/AbstractJetUpDownMover.java | 38 --------- .../upDownMover/JetExpressionMover.java | 81 ++++++++++++++++--- .../moveUpDown/expressions/lambda1.kt | 9 +++ .../moveUpDown/expressions/lambda1.kt.after | 9 +++ .../moveUpDown/expressions/lambda2.kt | 10 +++ .../moveUpDown/expressions/lambda3.kt | 10 +++ .../moveUpDown/expressions/lambda3.kt.after | 10 +++ .../moveUpDown/CodeMoverTestGenerated.java | 15 ++++ 8 files changed, 134 insertions(+), 48 deletions(-) create mode 100644 idea/testData/codeInsight/moveUpDown/expressions/lambda1.kt create mode 100644 idea/testData/codeInsight/moveUpDown/expressions/lambda1.kt.after create mode 100644 idea/testData/codeInsight/moveUpDown/expressions/lambda2.kt create mode 100644 idea/testData/codeInsight/moveUpDown/expressions/lambda3.kt create mode 100644 idea/testData/codeInsight/moveUpDown/expressions/lambda3.kt.after diff --git a/idea/src/org/jetbrains/jet/plugin/codeInsight/upDownMover/AbstractJetUpDownMover.java b/idea/src/org/jetbrains/jet/plugin/codeInsight/upDownMover/AbstractJetUpDownMover.java index c752befc5e4..9605c588294 100644 --- a/idea/src/org/jetbrains/jet/plugin/codeInsight/upDownMover/AbstractJetUpDownMover.java +++ b/idea/src/org/jetbrains/jet/plugin/codeInsight/upDownMover/AbstractJetUpDownMover.java @@ -2,12 +2,9 @@ package org.jetbrains.jet.plugin.codeInsight.upDownMover; import com.intellij.codeInsight.editorActions.moveUpDown.LineMover; import com.intellij.codeInsight.editorActions.moveUpDown.LineRange; -import com.intellij.openapi.editor.Document; import com.intellij.openapi.editor.Editor; -import com.intellij.openapi.util.TextRange; import com.intellij.psi.PsiElement; import com.intellij.psi.PsiFile; -import com.intellij.psi.PsiWhiteSpace; import com.intellij.psi.util.PsiTreeUtil; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -17,41 +14,6 @@ public abstract class AbstractJetUpDownMover extends LineMover { protected AbstractJetUpDownMover() { } - protected static PsiElement adjustWhiteSpaceSibling( - @NotNull Editor editor, - @NotNull LineRange sourceRange, - @NotNull MoveInfo info, - boolean down - ) { - PsiElement sibling = down ? sourceRange.lastElement.getNextSibling() : sourceRange.firstElement.getPrevSibling(); - - if (sibling instanceof PsiWhiteSpace) { - Document doc = editor.getDocument(); - TextRange spaceRange = sibling.getTextRange(); - - int startLine = doc.getLineNumber(spaceRange.getStartOffset()); - int endLine = doc.getLineNumber(spaceRange.getEndOffset()); - - if (endLine - startLine > 1) { - int nearLine = down ? sourceRange.endLine : sourceRange.startLine - 1; - - info.toMove = sourceRange; - info.toMove2 = new LineRange(nearLine, nearLine + 1); - - return null; - } - - sibling = firstNonWhiteElement(sibling, down); - } - - if (sibling == null) { - info.toMove2 = null; - return null; - } - - return sibling; - } - @Nullable protected static PsiElement getSiblingOfType(@NotNull PsiElement element, boolean down, @NotNull Class type) { return down ? PsiTreeUtil.getNextSiblingOfType(element, type) : PsiTreeUtil.getPrevSiblingOfType(element, type); diff --git a/idea/src/org/jetbrains/jet/plugin/codeInsight/upDownMover/JetExpressionMover.java b/idea/src/org/jetbrains/jet/plugin/codeInsight/upDownMover/JetExpressionMover.java index 3f6b65a0a93..5909b1ba488 100644 --- a/idea/src/org/jetbrains/jet/plugin/codeInsight/upDownMover/JetExpressionMover.java +++ b/idea/src/org/jetbrains/jet/plugin/codeInsight/upDownMover/JetExpressionMover.java @@ -8,6 +8,7 @@ import com.intellij.openapi.util.TextRange; import com.intellij.psi.PsiComment; import com.intellij.psi.PsiElement; import com.intellij.psi.PsiFile; +import com.intellij.psi.PsiWhiteSpace; import com.intellij.psi.util.PsiTreeUtil; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -181,15 +182,13 @@ public class JetExpressionMover extends AbstractJetUpDownMover { // moving out of code block if (sibling.getNode().getElementType() == (down ? JetTokens.RBRACE : JetTokens.LBRACE)) { PsiElement parent = sibling.getParent(); - if (!(parent instanceof JetBlockExpression)) return null; - - JetBlockExpression block = (JetBlockExpression) parent; + if (!(parent instanceof JetBlockExpression || parent instanceof JetFunctionLiteral)) return null; JetBlockExpression newBlock = findClosestBlock(sibling, down); if (newBlock == null) return null; - if (PsiTreeUtil.isAncestor(newBlock, block, true)) { - PsiElement outermostParent = JetPsiUtil.getOutermostParent(block, newBlock, true); + if (PsiTreeUtil.isAncestor(newBlock, parent, true)) { + PsiElement outermostParent = JetPsiUtil.getOutermostParent(parent, newBlock, true); if (down) { end = outermostParent; @@ -212,7 +211,7 @@ public class JetExpressionMover extends AbstractJetUpDownMover { //noinspection unchecked JetElement blockLikeElement = JetPsiUtil.getOutermostJetElement(sibling, down, JetBlockExpression.class, JetWhenExpression.class, JetClassBody.class); if (blockLikeElement != null && - !(PsiTreeUtil.instanceOf(blockLikeElement, FUNCTIONLIKE_ELEMENT_CLASSES))) { + !(PsiTreeUtil.instanceOf(blockLikeElement.getParent(), FUNCTIONLIKE_ELEMENT_CLASSES))) { if (blockLikeElement instanceof JetWhenExpression) { //noinspection unchecked blockLikeElement = JetPsiUtil.getOutermostJetElement(blockLikeElement, down, JetBlockExpression.class); @@ -299,8 +298,15 @@ public class JetExpressionMover extends AbstractJetUpDownMover { } @Nullable - private static PsiElement getMovableElement(@NotNull PsiElement element) { - return PsiTreeUtil.getNonStrictParentOfType(element, MOVABLE_ELEMENT_CLASSES); + private static PsiElement getMovableElement(@NotNull PsiElement element, boolean lookRight) { + PsiElement movableElement = PsiTreeUtil.getNonStrictParentOfType(element, MOVABLE_ELEMENT_CLASSES); + if (movableElement == null) return null; + + if (isBracelessBlock(movableElement)) { + movableElement = firstNonWhiteElement(lookRight ? movableElement.getLastChild() : movableElement.getFirstChild(), !lookRight); + } + + return movableElement; } private static enum MoveStatus { @@ -318,6 +324,61 @@ public class JetExpressionMover extends AbstractJetUpDownMover { return MoveStatus.PERMITTED; } + private static boolean isBracelessBlock(@NotNull PsiElement element) { + if (!(element instanceof JetBlockExpression)) return false; + + JetBlockExpression block = (JetBlockExpression) element; + + return block.getLBrace() == null && block.getRBrace() == null; + } + + protected static PsiElement adjustWhiteSpaceSibling( + @NotNull Editor editor, + @NotNull LineRange sourceRange, + @NotNull MoveInfo info, + boolean down + ) { + PsiElement element = down ? sourceRange.lastElement : sourceRange.firstElement; + PsiElement sibling = down ? element.getNextSibling() : element.getPrevSibling(); + + PsiElement whiteSpaceTestSubject = sibling; + if (sibling == null) { + PsiElement parent = element.getParent(); + if (parent != null && isBracelessBlock(parent)) { + whiteSpaceTestSubject = down ? parent.getNextSibling() : parent.getPrevSibling(); + } + } + + if (whiteSpaceTestSubject instanceof PsiWhiteSpace) { + Document doc = editor.getDocument(); + TextRange spaceRange = whiteSpaceTestSubject.getTextRange(); + + int startLine = doc.getLineNumber(spaceRange.getStartOffset()); + int endLine = doc.getLineNumber(spaceRange.getEndOffset()); + + if (endLine - startLine > 1) { + int nearLine = down ? sourceRange.endLine : sourceRange.startLine - 1; + + info.toMove = sourceRange; + info.toMove2 = new LineRange(nearLine, nearLine + 1); + info.indentTarget = false; + + return null; + } + + if (sibling != null) { + sibling = firstNonWhiteElement(sibling, down); + } + } + + if (sibling == null) { + info.toMove2 = null; + return null; + } + + return sibling; + } + @Override public boolean checkAvailable(@NotNull Editor editor, @NotNull PsiFile file, @NotNull MoveInfo info, boolean down) { if (!super.checkAvailable(editor, file, info, down)) return false; @@ -337,8 +398,8 @@ public class JetExpressionMover extends AbstractJetUpDownMover { if (psiRange == null) return false; //noinspection unchecked - PsiElement firstElement = getMovableElement(psiRange.getFirst()); - PsiElement lastElement = getMovableElement(psiRange.getSecond()); + PsiElement firstElement = getMovableElement(psiRange.getFirst(), false); + PsiElement lastElement = getMovableElement(psiRange.getSecond(), true); if (firstElement == null || lastElement == null) return false; diff --git a/idea/testData/codeInsight/moveUpDown/expressions/lambda1.kt b/idea/testData/codeInsight/moveUpDown/expressions/lambda1.kt new file mode 100644 index 00000000000..26b312d0bac --- /dev/null +++ b/idea/testData/codeInsight/moveUpDown/expressions/lambda1.kt @@ -0,0 +1,9 @@ +// MOVE: down +val t = baz( + a, + b, + c +) { + val v = "" + val w = "" +} \ No newline at end of file diff --git a/idea/testData/codeInsight/moveUpDown/expressions/lambda1.kt.after b/idea/testData/codeInsight/moveUpDown/expressions/lambda1.kt.after new file mode 100644 index 00000000000..da4389c585a --- /dev/null +++ b/idea/testData/codeInsight/moveUpDown/expressions/lambda1.kt.after @@ -0,0 +1,9 @@ +// MOVE: down +val t = baz( + a, + b, + c +) { + val w = "" + val v = "" +} \ No newline at end of file diff --git a/idea/testData/codeInsight/moveUpDown/expressions/lambda2.kt b/idea/testData/codeInsight/moveUpDown/expressions/lambda2.kt new file mode 100644 index 00000000000..f7acc8c8ac8 --- /dev/null +++ b/idea/testData/codeInsight/moveUpDown/expressions/lambda2.kt @@ -0,0 +1,10 @@ +// MOVE: up +// IS_APPLICABLE: false +val t = baz( + a, + b, + c +) { + val v = "" + val w = "" +} \ No newline at end of file diff --git a/idea/testData/codeInsight/moveUpDown/expressions/lambda3.kt b/idea/testData/codeInsight/moveUpDown/expressions/lambda3.kt new file mode 100644 index 00000000000..ad70ab1e36b --- /dev/null +++ b/idea/testData/codeInsight/moveUpDown/expressions/lambda3.kt @@ -0,0 +1,10 @@ +// MOVE: up +val t = baz( + a, + b, + c +) { + + val v = "" + val w = "" +} \ No newline at end of file diff --git a/idea/testData/codeInsight/moveUpDown/expressions/lambda3.kt.after b/idea/testData/codeInsight/moveUpDown/expressions/lambda3.kt.after new file mode 100644 index 00000000000..dfcb8d8ba87 --- /dev/null +++ b/idea/testData/codeInsight/moveUpDown/expressions/lambda3.kt.after @@ -0,0 +1,10 @@ +// MOVE: up +val t = baz( + a, + b, + c +) { + val v = "" + + val w = "" +} \ No newline at end of file diff --git a/idea/tests/org/jetbrains/jet/plugin/codeInsight/moveUpDown/CodeMoverTestGenerated.java b/idea/tests/org/jetbrains/jet/plugin/codeInsight/moveUpDown/CodeMoverTestGenerated.java index c7c96ca17f1..8172b77ac32 100644 --- a/idea/tests/org/jetbrains/jet/plugin/codeInsight/moveUpDown/CodeMoverTestGenerated.java +++ b/idea/tests/org/jetbrains/jet/plugin/codeInsight/moveUpDown/CodeMoverTestGenerated.java @@ -728,6 +728,21 @@ public class CodeMoverTestGenerated extends AbstractCodeMoverTest { doTestExpression("idea/testData/codeInsight/moveUpDown/expressions/if4.kt"); } + @TestMetadata("lambda1.kt") + public void testLambda1() throws Exception { + doTestExpression("idea/testData/codeInsight/moveUpDown/expressions/lambda1.kt"); + } + + @TestMetadata("lambda2.kt") + public void testLambda2() throws Exception { + doTestExpression("idea/testData/codeInsight/moveUpDown/expressions/lambda2.kt"); + } + + @TestMetadata("lambda3.kt") + public void testLambda3() throws Exception { + doTestExpression("idea/testData/codeInsight/moveUpDown/expressions/lambda3.kt"); + } + @TestMetadata("when1.kt") public void testWhen1() throws Exception { doTestExpression("idea/testData/codeInsight/moveUpDown/expressions/when1.kt"); From a78822ddba44dab6493545cf0a5e612286c5392a Mon Sep 17 00:00:00 2001 From: Alexey Sedunov Date: Tue, 4 Jun 2013 14:14:46 +0400 Subject: [PATCH 210/249] Unify getSourceRange() for declaration and expression movers --- .../upDownMover/AbstractJetUpDownMover.java | 40 +++++++++ .../upDownMover/JetDeclarationMover.java | 84 +++++-------------- .../upDownMover/JetExpressionMover.java | 57 +++---------- 3 files changed, 75 insertions(+), 106 deletions(-) diff --git a/idea/src/org/jetbrains/jet/plugin/codeInsight/upDownMover/AbstractJetUpDownMover.java b/idea/src/org/jetbrains/jet/plugin/codeInsight/upDownMover/AbstractJetUpDownMover.java index 9605c588294..a97f06c754a 100644 --- a/idea/src/org/jetbrains/jet/plugin/codeInsight/upDownMover/AbstractJetUpDownMover.java +++ b/idea/src/org/jetbrains/jet/plugin/codeInsight/upDownMover/AbstractJetUpDownMover.java @@ -3,6 +3,7 @@ package org.jetbrains.jet.plugin.codeInsight.upDownMover; import com.intellij.codeInsight.editorActions.moveUpDown.LineMover; import com.intellij.codeInsight.editorActions.moveUpDown.LineRange; import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.util.Pair; import com.intellij.psi.PsiElement; import com.intellij.psi.PsiFile; import com.intellij.psi.util.PsiTreeUtil; @@ -14,6 +15,45 @@ public abstract class AbstractJetUpDownMover extends LineMover { protected AbstractJetUpDownMover() { } + protected abstract boolean checkSourceElement(@NotNull PsiElement element); + protected abstract LineRange getElementSourceLineRange(@NotNull PsiElement element, @NotNull Editor editor, @NotNull LineRange oldRange); + + @Nullable + protected LineRange getSourceRange(@NotNull PsiElement firstElement, @NotNull PsiElement lastElement, @NotNull Editor editor, LineRange oldRange) { + if (firstElement == lastElement) { + LineRange sourceRange = getElementSourceLineRange(firstElement, editor, oldRange); + + if (sourceRange != null) { + sourceRange.firstElement = sourceRange.lastElement = firstElement; + } + + return sourceRange; + } + + PsiElement parent = PsiTreeUtil.findCommonParent(firstElement, lastElement); + if (parent == null) return null; + + Pair combinedRange = getElementRange(parent, firstElement, lastElement); + + if (combinedRange == null + || !checkSourceElement(combinedRange.first) + || !checkSourceElement(combinedRange.second)) { + return null; + } + + LineRange lineRange1 = getElementSourceLineRange(combinedRange.first, editor, oldRange); + if (lineRange1 == null) return null; + + LineRange lineRange2 = getElementSourceLineRange(combinedRange.second, editor, oldRange); + if (lineRange2 == null) return null; + + LineRange sourceRange = new LineRange(lineRange1.startLine, lineRange2.endLine); + sourceRange.firstElement = combinedRange.first; + sourceRange.lastElement = combinedRange.second; + + return sourceRange; + } + @Nullable protected static PsiElement getSiblingOfType(@NotNull PsiElement element, boolean down, @NotNull Class type) { return down ? PsiTreeUtil.getNextSiblingOfType(element, type) : PsiTreeUtil.getPrevSiblingOfType(element, type); diff --git a/idea/src/org/jetbrains/jet/plugin/codeInsight/upDownMover/JetDeclarationMover.java b/idea/src/org/jetbrains/jet/plugin/codeInsight/upDownMover/JetDeclarationMover.java index f31dbe9bbf8..eb5fdc3cfeb 100644 --- a/idea/src/org/jetbrains/jet/plugin/codeInsight/upDownMover/JetDeclarationMover.java +++ b/idea/src/org/jetbrains/jet/plugin/codeInsight/upDownMover/JetDeclarationMover.java @@ -79,34 +79,6 @@ public class JetDeclarationMover extends AbstractJetUpDownMover { return memberSuspects; } - @Nullable - private static LineRange adjustDeclarationRange( - @NotNull JetDeclaration declaration, - @NotNull Editor editor, - @NotNull LineRange lineRange - ) { - Document doc = editor.getDocument(); - TextRange textRange = declaration.getTextRange(); - if (doc.getTextLength() < textRange.getEndOffset()) return null; - - int startLine = editor.offsetToLogicalPosition(textRange.getStartOffset()).line; - int endLine = editor.offsetToLogicalPosition(textRange.getEndOffset()).line + 1; - - if (startLine == lineRange.startLine || startLine == lineRange.endLine - || endLine == lineRange.startLine || endLine == lineRange.endLine) { - return new LineRange(startLine, endLine); - } - - TextRange lineTextRange = new TextRange(doc.getLineStartOffset(lineRange.startLine), - doc.getLineEndOffset(lineRange.endLine)); - for (PsiElement anchor : getDeclarationAnchors(declaration)) { - TextRange suspectTextRange = anchor.getTextRange(); - if (suspectTextRange != null && lineTextRange.intersects(suspectTextRange)) return new LineRange(startLine, endLine); - } - - return null; - } - private static final Class[] DECLARATION_CONTAINER_CLASSES = {JetClassBody.class, JetClassInitializer.class, JetFunction.class, JetPropertyAccessor.class, JetFile.class}; @@ -126,45 +98,35 @@ public class JetDeclarationMover extends AbstractJetUpDownMover { CLASSBODYLIKE_DECLARATION_CONTAINER_CLASSES) ? declaration : null; } - @Nullable - private static LineRange getSourceRange( - @NotNull JetDeclaration firstDecl, - @NotNull JetDeclaration lastDecl, - @NotNull Editor editor, - @NotNull LineRange oldRange - ) { - if (firstDecl == lastDecl) { - LineRange range = adjustDeclarationRange(firstDecl, editor, oldRange); + @Override + protected boolean checkSourceElement(@NotNull PsiElement element) { + return element instanceof JetDeclaration; + } - if (range != null) { - range.firstElement = range.lastElement = firstDecl; - } + @Override + protected LineRange getElementSourceLineRange(@NotNull PsiElement element, @NotNull Editor editor, @NotNull LineRange oldRange) { + JetDeclaration declaration = (JetDeclaration) element; - return range; + Document doc = editor.getDocument(); + TextRange textRange = declaration.getTextRange(); + if (doc.getTextLength() < textRange.getEndOffset()) return null; + + int startLine = editor.offsetToLogicalPosition(textRange.getStartOffset()).line; + int endLine = editor.offsetToLogicalPosition(textRange.getEndOffset()).line + 1; + + if (startLine == oldRange.startLine || startLine == oldRange.endLine + || endLine == oldRange.startLine || endLine == oldRange.endLine) { + return new LineRange(startLine, endLine); } - PsiElement parent = PsiTreeUtil.findCommonParent(firstDecl, lastDecl); - if (parent == null) return null; - - Pair combinedRange = getElementRange(parent, firstDecl, lastDecl); - - if (combinedRange == null - || !(combinedRange.first instanceof JetDeclaration) - || !(combinedRange.second instanceof JetDeclaration)) { - return null; + TextRange lineTextRange = new TextRange(doc.getLineStartOffset(oldRange.startLine), + doc.getLineEndOffset(oldRange.endLine)); + for (PsiElement anchor : getDeclarationAnchors(declaration)) { + TextRange suspectTextRange = anchor.getTextRange(); + if (suspectTextRange != null && lineTextRange.intersects(suspectTextRange)) return new LineRange(startLine, endLine); } - LineRange lineRange1 = adjustDeclarationRange((JetDeclaration) combinedRange.getFirst(), editor, oldRange); - if (lineRange1 == null) return null; - - LineRange lineRange2 = adjustDeclarationRange((JetDeclaration) combinedRange.getSecond(), editor, oldRange); - if (lineRange2 == null) return null; - - LineRange range = new LineRange(lineRange1.startLine, lineRange2.endLine); - range.firstElement = combinedRange.getFirst(); - range.lastElement = combinedRange.getSecond(); - - return range; + return null; } @Nullable diff --git a/idea/src/org/jetbrains/jet/plugin/codeInsight/upDownMover/JetExpressionMover.java b/idea/src/org/jetbrains/jet/plugin/codeInsight/upDownMover/JetExpressionMover.java index 5909b1ba488..81d4d544464 100644 --- a/idea/src/org/jetbrains/jet/plugin/codeInsight/upDownMover/JetExpressionMover.java +++ b/idea/src/org/jetbrains/jet/plugin/codeInsight/upDownMover/JetExpressionMover.java @@ -30,17 +30,6 @@ public class JetExpressionMover extends AbstractJetUpDownMover { private static Class[] FUNCTIONLIKE_ELEMENT_CLASSES = {JetFunction.class, JetPropertyAccessor.class, JetClassInitializer.class}; - @Nullable - private static LineRange getLineRange(@NotNull PsiElement element, @NotNull Editor editor) { - TextRange textRange = element.getTextRange(); - if (editor.getDocument().getTextLength() < textRange.getEndOffset()) return null; - - int startLine = editor.offsetToLogicalPosition(textRange.getStartOffset()).line; - int endLine = editor.offsetToLogicalPosition(textRange.getEndOffset()).line + 1; - - return new LineRange(startLine, endLine); - } - @Nullable private static PsiElement getStandaloneClosingBrace(@NotNull PsiFile file, @NotNull Editor editor) { LineRange range = getLineRangeFromSelection(editor); @@ -259,42 +248,20 @@ public class JetExpressionMover extends AbstractJetUpDownMover { return null; } - @Nullable - private static LineRange getSourceRange(@NotNull PsiElement firstElement, @NotNull PsiElement lastElement, @NotNull Editor editor) { - if (firstElement == lastElement) { - //noinspection ConstantConditions - LineRange sourceRange = getLineRange(firstElement, editor); + @Override + protected boolean checkSourceElement(@NotNull PsiElement element) { + return PsiTreeUtil.instanceOf(element, MOVABLE_ELEMENT_CLASSES); + } - if (sourceRange != null) { - sourceRange.firstElement = sourceRange.lastElement = firstElement; - } + @Override + protected LineRange getElementSourceLineRange(@NotNull PsiElement element, @NotNull Editor editor, @NotNull LineRange oldRange) { + TextRange textRange = element.getTextRange(); + if (editor.getDocument().getTextLength() < textRange.getEndOffset()) return null; - return sourceRange; - } + int startLine = editor.offsetToLogicalPosition(textRange.getStartOffset()).line; + int endLine = editor.offsetToLogicalPosition(textRange.getEndOffset()).line + 1; - //noinspection ConstantConditions - PsiElement parent = PsiTreeUtil.findCommonParent(firstElement, lastElement); - if (parent == null) return null; - - Pair combinedRange = getElementRange(parent, firstElement, lastElement); - - if (combinedRange == null - || !(PsiTreeUtil.instanceOf(combinedRange.first, MOVABLE_ELEMENT_CLASSES)) - || !(PsiTreeUtil.instanceOf(combinedRange.second, MOVABLE_ELEMENT_CLASSES))) { - return null; - } - - LineRange lineRange1 = getLineRange(combinedRange.first, editor); - if (lineRange1 == null) return null; - - LineRange lineRange2 = getLineRange(combinedRange.second, editor); - if (lineRange2 == null) return null; - - LineRange sourceRange = new LineRange(lineRange1.startLine, lineRange2.endLine); - sourceRange.firstElement = combinedRange.first; - sourceRange.lastElement = combinedRange.second; - - return sourceRange; + return new LineRange(startLine, endLine); } @Nullable @@ -415,7 +382,7 @@ public class JetExpressionMover extends AbstractJetUpDownMover { return true; } - LineRange sourceRange = getSourceRange(firstElement, lastElement, editor); + LineRange sourceRange = getSourceRange(firstElement, lastElement, editor, oldRange); if (sourceRange == null) return false; PsiElement sibling = adjustWhiteSpaceSibling(editor, sourceRange, info, down); From 7805ee01eba74ba3782a650ad2fcdb75b9efcce9 Mon Sep 17 00:00:00 2001 From: Alexey Sedunov Date: Tue, 4 Jun 2013 15:35:43 +0400 Subject: [PATCH 211/249] Fix moving of value parameters and arguments --- .../jetbrains/jet/lang/psi/JetPsiFactory.java | 7 ++ .../upDownMover/AbstractJetUpDownMover.java | 5 + .../upDownMover/JetExpressionMover.java | 95 ++++++++++++++----- .../functionAnchors/valueArgs1.kt | 7 ++ .../functionAnchors/valueArgs1.kt.after | 7 ++ .../functionAnchors/valueArgs2.kt | 7 ++ .../functionAnchors/valueArgs2.kt.after | 7 ++ .../functionAnchors/valueArgs3.kt | 8 ++ .../functionAnchors/valueArgs4.kt | 7 ++ .../functionAnchors/valueArgs4.kt.after | 7 ++ .../functionAnchors/valueArgs5.kt | 7 ++ .../functionAnchors/valueArgs5.kt.after | 7 ++ .../functionAnchors/valueArgs6.kt | 8 ++ .../functionAnchors/valueParams2.kt.after | 6 +- .../moveUpDown/AbstractCodeMoverTest.java | 13 ++- .../moveUpDown/CodeMoverTestGenerated.java | 30 ++++++ 16 files changed, 200 insertions(+), 28 deletions(-) create mode 100644 idea/testData/codeInsight/moveUpDown/classBodyDeclarations/functionAnchors/valueArgs1.kt create mode 100644 idea/testData/codeInsight/moveUpDown/classBodyDeclarations/functionAnchors/valueArgs1.kt.after create mode 100644 idea/testData/codeInsight/moveUpDown/classBodyDeclarations/functionAnchors/valueArgs2.kt create mode 100644 idea/testData/codeInsight/moveUpDown/classBodyDeclarations/functionAnchors/valueArgs2.kt.after create mode 100644 idea/testData/codeInsight/moveUpDown/classBodyDeclarations/functionAnchors/valueArgs3.kt create mode 100644 idea/testData/codeInsight/moveUpDown/classBodyDeclarations/functionAnchors/valueArgs4.kt create mode 100644 idea/testData/codeInsight/moveUpDown/classBodyDeclarations/functionAnchors/valueArgs4.kt.after create mode 100644 idea/testData/codeInsight/moveUpDown/classBodyDeclarations/functionAnchors/valueArgs5.kt create mode 100644 idea/testData/codeInsight/moveUpDown/classBodyDeclarations/functionAnchors/valueArgs5.kt.after create mode 100644 idea/testData/codeInsight/moveUpDown/classBodyDeclarations/functionAnchors/valueArgs6.kt diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetPsiFactory.java b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetPsiFactory.java index c9f83314700..22a15e9a39f 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetPsiFactory.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetPsiFactory.java @@ -73,6 +73,13 @@ public class JetPsiFactory { return star; } + @NotNull + public static PsiElement createComma(Project project) { + PsiElement comma = createType(project, "T").findElementAt(3); + assert comma != null; + return comma; + } + //the pair contains the first and the last elements of a range public static Pair createColonAndWhiteSpaces(Project project) { JetProperty property = createProperty(project, "val x : Int"); diff --git a/idea/src/org/jetbrains/jet/plugin/codeInsight/upDownMover/AbstractJetUpDownMover.java b/idea/src/org/jetbrains/jet/plugin/codeInsight/upDownMover/AbstractJetUpDownMover.java index a97f06c754a..1e81b14fa56 100644 --- a/idea/src/org/jetbrains/jet/plugin/codeInsight/upDownMover/AbstractJetUpDownMover.java +++ b/idea/src/org/jetbrains/jet/plugin/codeInsight/upDownMover/AbstractJetUpDownMover.java @@ -64,6 +64,11 @@ public abstract class AbstractJetUpDownMover extends LineMover { return firstNonWhiteElement(down ? lineRange.lastElement.getNextSibling() : lineRange.firstElement.getPrevSibling(), down); } + @Nullable + protected static PsiElement firstNonWhiteSibling(@NotNull PsiElement element, boolean down) { + return firstNonWhiteElement(down ? element.getNextSibling() : element.getPrevSibling(), down); + } + @Override public boolean checkAvailable(@NotNull Editor editor, @NotNull PsiFile file, @NotNull MoveInfo info, boolean down) { return (file instanceof JetFile) && super.checkAvailable(editor, file, info, down); diff --git a/idea/src/org/jetbrains/jet/plugin/codeInsight/upDownMover/JetExpressionMover.java b/idea/src/org/jetbrains/jet/plugin/codeInsight/upDownMover/JetExpressionMover.java index 81d4d544464..6dea19786ba 100644 --- a/idea/src/org/jetbrains/jet/plugin/codeInsight/upDownMover/JetExpressionMover.java +++ b/idea/src/org/jetbrains/jet/plugin/codeInsight/upDownMover/JetExpressionMover.java @@ -5,10 +5,7 @@ import com.intellij.openapi.editor.Document; import com.intellij.openapi.editor.Editor; import com.intellij.openapi.util.Pair; import com.intellij.openapi.util.TextRange; -import com.intellij.psi.PsiComment; -import com.intellij.psi.PsiElement; -import com.intellij.psi.PsiFile; -import com.intellij.psi.PsiWhiteSpace; +import com.intellij.psi.*; import com.intellij.psi.util.PsiTreeUtil; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -20,7 +17,7 @@ public class JetExpressionMover extends AbstractJetUpDownMover { } @SuppressWarnings("FieldMayBeFinal") - private static Class[] MOVABLE_ELEMENT_CLASSES = {JetExpression.class, JetWhenEntry.class, PsiComment.class}; + private static Class[] MOVABLE_ELEMENT_CLASSES = {JetExpression.class, JetWhenEntry.class, JetValueArgument.class, PsiComment.class}; @SuppressWarnings("FieldMayBeFinal") private static Class[] BLOCKLIKE_ELEMENT_CLASSES = @@ -231,12 +228,35 @@ public class JetExpressionMover extends AbstractJetUpDownMover { } @Nullable - private static LineRange getTargetRange( + private LineRange getValueParamOrArgTargetRange(@NotNull Editor editor, @NotNull PsiElement elementToCheck, @NotNull PsiElement sibling, boolean down) { + PsiElement next = sibling; + + if (next.getNode().getElementType() == JetTokens.COMMA) { + next = firstNonWhiteSibling(next, down); + } + + LineRange range = (next instanceof JetParameter || next instanceof JetValueArgument) + ? new LineRange(next, next, editor.getDocument()) + : null; + + if (range != null) { + parametersOrArgsToMove = new Pair(elementToCheck, next); + } + + return range; + } + + @Nullable + private LineRange getTargetRange( @NotNull Editor editor, @Nullable PsiElement elementToCheck, @NotNull PsiElement sibling, boolean down ) { + if (elementToCheck instanceof JetParameter || elementToCheck instanceof JetValueArgument) { + return getValueParamOrArgTargetRange(editor, elementToCheck, sibling, down); + } + if (elementToCheck instanceof JetExpression || elementToCheck instanceof PsiComment) { return getExpressionTargetRange(editor, sibling, down); } @@ -276,19 +296,16 @@ public class JetExpressionMover extends AbstractJetUpDownMover { return movableElement; } - private static enum MoveStatus { - DEFAULT, - FORBIDDEN, - PERMITTED + private static boolean isLastOfItsKind(@NotNull PsiElement element, boolean down) { + return getSiblingOfType(element, down, element.getClass()) == null; } - private static MoveStatus getMoveStatus(@NotNull PsiElement element, boolean down) { - if (element instanceof JetParameter) { - PsiElement sibling = getSiblingOfType(element, down, element.getClass()); - return (sibling != null) ? MoveStatus.DEFAULT : MoveStatus.FORBIDDEN; + private static boolean isForbiddenMove(@NotNull PsiElement element, boolean down) { + if (element instanceof JetParameter || element instanceof JetValueArgument) { + return isLastOfItsKind(element, down); } - return MoveStatus.PERMITTED; + return false; } private static boolean isBracelessBlock(@NotNull PsiElement element) { @@ -348,6 +365,8 @@ public class JetExpressionMover extends AbstractJetUpDownMover { @Override public boolean checkAvailable(@NotNull Editor editor, @NotNull PsiFile file, @NotNull MoveInfo info, boolean down) { + parametersOrArgsToMove = null; + if (!super.checkAvailable(editor, file, info, down)) return false; switch (checkForMovableClosingBrace(editor, file, info, down)) { @@ -370,16 +389,13 @@ public class JetExpressionMover extends AbstractJetUpDownMover { if (firstElement == null || lastElement == null) return false; - MoveStatus firstMoveStatus = getMoveStatus(firstElement, down); - MoveStatus lastMoveStatus = getMoveStatus(lastElement, down); - - if (firstMoveStatus == MoveStatus.DEFAULT || lastMoveStatus == MoveStatus.DEFAULT) { + if (isForbiddenMove(firstElement, down) || isForbiddenMove(lastElement, down)) { + info.toMove2 = null; return true; } - if (firstMoveStatus == MoveStatus.FORBIDDEN || lastMoveStatus == MoveStatus.FORBIDDEN) { - info.toMove2 = null; - return true; + if ((firstElement instanceof JetParameter || firstElement instanceof JetValueArgument) && PsiTreeUtil.isAncestor(lastElement, firstElement, false)) { + lastElement = firstElement; } LineRange sourceRange = getSourceRange(firstElement, lastElement, editor, oldRange); @@ -394,4 +410,39 @@ public class JetExpressionMover extends AbstractJetUpDownMover { info.toMove2 = getTargetRange(editor, sourceRange.firstElement, sibling, down); return true; } + + @Nullable + private Pair parametersOrArgsToMove; + + private static PsiElement getComma(@NotNull PsiElement element) { + PsiElement sibling = firstNonWhiteSibling(element, true); + return sibling != null && (sibling.getNode().getElementType() == JetTokens.COMMA) ? sibling : null; + } + + private static void fixCommaIfNeeded(@NotNull PsiElement element, boolean willBeLast) { + PsiElement comma = getComma(element); + if (willBeLast && comma != null) { + comma.delete(); + } + else if (!willBeLast && comma == null) { + PsiElement parent = element.getParent(); + assert parent != null; + + parent.addAfter(JetPsiFactory.createComma(parent.getProject()), element); + } + } + + @Override + public void beforeMove(@NotNull Editor editor, @NotNull MoveInfo info, boolean down) { + if (parametersOrArgsToMove != null) { + PsiElement element1 = parametersOrArgsToMove.first; + PsiElement element2 = parametersOrArgsToMove.second; + + fixCommaIfNeeded(element1, down && isLastOfItsKind(element2, true)); + fixCommaIfNeeded(element2, !down && isLastOfItsKind(element1, true)); + + //noinspection ConstantConditions + PsiDocumentManager.getInstance(editor.getProject()).doPostponedOperationsAndUnblockDocument(editor.getDocument()); + } + } } diff --git a/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/functionAnchors/valueArgs1.kt b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/functionAnchors/valueArgs1.kt new file mode 100644 index 00000000000..7b11f2e4d49 --- /dev/null +++ b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/functionAnchors/valueArgs1.kt @@ -0,0 +1,7 @@ +// MOVE: down +// MOVER_CLASS: org.jetbrains.jet.plugin.codeInsight.upDownMover.JetExpressionMover +val x = foo( + a, + b, + c +) \ No newline at end of file diff --git a/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/functionAnchors/valueArgs1.kt.after b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/functionAnchors/valueArgs1.kt.after new file mode 100644 index 00000000000..f9c60de097e --- /dev/null +++ b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/functionAnchors/valueArgs1.kt.after @@ -0,0 +1,7 @@ +// MOVE: down +// MOVER_CLASS: org.jetbrains.jet.plugin.codeInsight.upDownMover.JetExpressionMover +val x = foo( + b, + a, + c +) \ No newline at end of file diff --git a/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/functionAnchors/valueArgs2.kt b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/functionAnchors/valueArgs2.kt new file mode 100644 index 00000000000..f9c60de097e --- /dev/null +++ b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/functionAnchors/valueArgs2.kt @@ -0,0 +1,7 @@ +// MOVE: down +// MOVER_CLASS: org.jetbrains.jet.plugin.codeInsight.upDownMover.JetExpressionMover +val x = foo( + b, + a, + c +) \ No newline at end of file diff --git a/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/functionAnchors/valueArgs2.kt.after b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/functionAnchors/valueArgs2.kt.after new file mode 100644 index 00000000000..3db2d20f7ac --- /dev/null +++ b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/functionAnchors/valueArgs2.kt.after @@ -0,0 +1,7 @@ +// MOVE: down +// MOVER_CLASS: org.jetbrains.jet.plugin.codeInsight.upDownMover.JetExpressionMover +val x = foo( + b, + c, + a +) \ No newline at end of file diff --git a/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/functionAnchors/valueArgs3.kt b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/functionAnchors/valueArgs3.kt new file mode 100644 index 00000000000..6bd9df3b1dc --- /dev/null +++ b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/functionAnchors/valueArgs3.kt @@ -0,0 +1,8 @@ +// MOVE: down +// MOVER_CLASS: org.jetbrains.jet.plugin.codeInsight.upDownMover.JetExpressionMover +// IS_APPLICABLE: false +val x = foo( + b, + c, + a +) \ No newline at end of file diff --git a/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/functionAnchors/valueArgs4.kt b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/functionAnchors/valueArgs4.kt new file mode 100644 index 00000000000..b08d329c8b9 --- /dev/null +++ b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/functionAnchors/valueArgs4.kt @@ -0,0 +1,7 @@ +// MOVE: up +// MOVER_CLASS: org.jetbrains.jet.plugin.codeInsight.upDownMover.JetExpressionMover +val x = foo( + b, + c, + a +) \ No newline at end of file diff --git a/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/functionAnchors/valueArgs4.kt.after b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/functionAnchors/valueArgs4.kt.after new file mode 100644 index 00000000000..ec326d77a59 --- /dev/null +++ b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/functionAnchors/valueArgs4.kt.after @@ -0,0 +1,7 @@ +// MOVE: up +// MOVER_CLASS: org.jetbrains.jet.plugin.codeInsight.upDownMover.JetExpressionMover +val x = foo( + b, + a, + c +) \ No newline at end of file diff --git a/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/functionAnchors/valueArgs5.kt b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/functionAnchors/valueArgs5.kt new file mode 100644 index 00000000000..ec326d77a59 --- /dev/null +++ b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/functionAnchors/valueArgs5.kt @@ -0,0 +1,7 @@ +// MOVE: up +// MOVER_CLASS: org.jetbrains.jet.plugin.codeInsight.upDownMover.JetExpressionMover +val x = foo( + b, + a, + c +) \ No newline at end of file diff --git a/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/functionAnchors/valueArgs5.kt.after b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/functionAnchors/valueArgs5.kt.after new file mode 100644 index 00000000000..5a760ce3e34 --- /dev/null +++ b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/functionAnchors/valueArgs5.kt.after @@ -0,0 +1,7 @@ +// MOVE: up +// MOVER_CLASS: org.jetbrains.jet.plugin.codeInsight.upDownMover.JetExpressionMover +val x = foo( + a, + b, + c +) \ No newline at end of file diff --git a/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/functionAnchors/valueArgs6.kt b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/functionAnchors/valueArgs6.kt new file mode 100644 index 00000000000..abfadee7eeb --- /dev/null +++ b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/functionAnchors/valueArgs6.kt @@ -0,0 +1,8 @@ +// MOVE: up +// MOVER_CLASS: org.jetbrains.jet.plugin.codeInsight.upDownMover.JetExpressionMover +// IS_APPLICABLE: false +val x = foo( + a, + b, + c +) \ No newline at end of file diff --git a/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/functionAnchors/valueParams2.kt.after b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/functionAnchors/valueParams2.kt.after index ed71321452d..216202bc19c 100644 --- a/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/functionAnchors/valueParams2.kt.after +++ b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/functionAnchors/valueParams2.kt.after @@ -5,9 +5,9 @@ class A { U, W>( b: Int, - c: Int - a: Int, - ) { + c: Int, + a: Int + ) { } class B { diff --git a/idea/tests/org/jetbrains/jet/plugin/codeInsight/moveUpDown/AbstractCodeMoverTest.java b/idea/tests/org/jetbrains/jet/plugin/codeInsight/moveUpDown/AbstractCodeMoverTest.java index 53ade244493..c4dd225c1cb 100644 --- a/idea/tests/org/jetbrains/jet/plugin/codeInsight/moveUpDown/AbstractCodeMoverTest.java +++ b/idea/tests/org/jetbrains/jet/plugin/codeInsight/moveUpDown/AbstractCodeMoverTest.java @@ -19,9 +19,11 @@ package org.jetbrains.jet.plugin.codeInsight.moveUpDown; import com.intellij.codeInsight.editorActions.moveUpDown.MoveStatementDownAction; import com.intellij.codeInsight.editorActions.moveUpDown.MoveStatementUpAction; import com.intellij.codeInsight.editorActions.moveUpDown.StatementUpDownMover; +import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.editor.actionSystem.EditorAction; import com.intellij.openapi.extensions.Extensions; import com.intellij.openapi.util.io.FileUtil; +import com.intellij.psi.PsiDocumentManager; import com.intellij.testFramework.LightCodeInsightTestCase; import org.jetbrains.annotations.NotNull; import org.jetbrains.jet.InTextDirectivesUtils; @@ -83,9 +85,14 @@ public abstract class AbstractCodeMoverTest extends LightCodeInsightTestCase { } } - private void invokeAndCheck(@NotNull String path, boolean down) { - EditorAction action = down ? new MoveStatementDownAction() : new MoveStatementUpAction(); - action.actionPerformed(getEditor(), getCurrentEditorDataContext()); + private void invokeAndCheck(@NotNull String path, final boolean down) { + ApplicationManager.getApplication().runWriteAction(new Runnable() { + @Override + public void run() { + EditorAction action = down ? new MoveStatementDownAction() : new MoveStatementUpAction(); + action.actionPerformed(getEditor(), getCurrentEditorDataContext()); + } + }); checkResultByFile(path + ".after"); } diff --git a/idea/tests/org/jetbrains/jet/plugin/codeInsight/moveUpDown/CodeMoverTestGenerated.java b/idea/tests/org/jetbrains/jet/plugin/codeInsight/moveUpDown/CodeMoverTestGenerated.java index 8172b77ac32..c7ca70b13a4 100644 --- a/idea/tests/org/jetbrains/jet/plugin/codeInsight/moveUpDown/CodeMoverTestGenerated.java +++ b/idea/tests/org/jetbrains/jet/plugin/codeInsight/moveUpDown/CodeMoverTestGenerated.java @@ -385,6 +385,36 @@ public class CodeMoverTestGenerated extends AbstractCodeMoverTest { doTestClassBodyDeclaration("idea/testData/codeInsight/moveUpDown/classBodyDeclarations/functionAnchors/typeParams3.kt"); } + @TestMetadata("valueArgs1.kt") + public void testValueArgs1() throws Exception { + doTestClassBodyDeclaration("idea/testData/codeInsight/moveUpDown/classBodyDeclarations/functionAnchors/valueArgs1.kt"); + } + + @TestMetadata("valueArgs2.kt") + public void testValueArgs2() throws Exception { + doTestClassBodyDeclaration("idea/testData/codeInsight/moveUpDown/classBodyDeclarations/functionAnchors/valueArgs2.kt"); + } + + @TestMetadata("valueArgs3.kt") + public void testValueArgs3() throws Exception { + doTestClassBodyDeclaration("idea/testData/codeInsight/moveUpDown/classBodyDeclarations/functionAnchors/valueArgs3.kt"); + } + + @TestMetadata("valueArgs4.kt") + public void testValueArgs4() throws Exception { + doTestClassBodyDeclaration("idea/testData/codeInsight/moveUpDown/classBodyDeclarations/functionAnchors/valueArgs4.kt"); + } + + @TestMetadata("valueArgs5.kt") + public void testValueArgs5() throws Exception { + doTestClassBodyDeclaration("idea/testData/codeInsight/moveUpDown/classBodyDeclarations/functionAnchors/valueArgs5.kt"); + } + + @TestMetadata("valueArgs6.kt") + public void testValueArgs6() throws Exception { + doTestClassBodyDeclaration("idea/testData/codeInsight/moveUpDown/classBodyDeclarations/functionAnchors/valueArgs6.kt"); + } + @TestMetadata("valueParams1.kt") public void testValueParams1() throws Exception { doTestClassBodyDeclaration("idea/testData/codeInsight/moveUpDown/classBodyDeclarations/functionAnchors/valueParams1.kt"); From 62bdb370149b75d73b70564f1c2774e71d50e786 Mon Sep 17 00:00:00 2001 From: Alexey Sedunov Date: Tue, 4 Jun 2013 18:23:30 +0400 Subject: [PATCH 212/249] Do not move closing brace in function-like elements --- .../upDownMover/JetExpressionMover.java | 14 ++++----- .../closingBraces/function/function1.kt | 10 ++++++ .../closingBraces/function/function1.kt.after | 10 ++++++ .../closingBraces/function/function2.kt | 10 ++++++ .../closingBraces/function/function2.kt.after | 10 ++++++ .../closingBraces/function/function3.kt | 10 ++++++ .../closingBraces/function/function3.kt.after | 10 ++++++ .../closingBraces/function/function4.kt | 10 ++++++ .../closingBraces/function/function4.kt.after | 10 ++++++ .../moveUpDown/CodeMoverTestGenerated.java | 31 ++++++++++++++++++- 10 files changed, 117 insertions(+), 8 deletions(-) create mode 100644 idea/testData/codeInsight/moveUpDown/closingBraces/function/function1.kt create mode 100644 idea/testData/codeInsight/moveUpDown/closingBraces/function/function1.kt.after create mode 100644 idea/testData/codeInsight/moveUpDown/closingBraces/function/function2.kt create mode 100644 idea/testData/codeInsight/moveUpDown/closingBraces/function/function2.kt.after create mode 100644 idea/testData/codeInsight/moveUpDown/closingBraces/function/function3.kt create mode 100644 idea/testData/codeInsight/moveUpDown/closingBraces/function/function3.kt.after create mode 100644 idea/testData/codeInsight/moveUpDown/closingBraces/function/function4.kt create mode 100644 idea/testData/codeInsight/moveUpDown/closingBraces/function/function4.kt.after diff --git a/idea/src/org/jetbrains/jet/plugin/codeInsight/upDownMover/JetExpressionMover.java b/idea/src/org/jetbrains/jet/plugin/codeInsight/upDownMover/JetExpressionMover.java index 6dea19786ba..438622f1c8b 100644 --- a/idea/src/org/jetbrains/jet/plugin/codeInsight/upDownMover/JetExpressionMover.java +++ b/idea/src/org/jetbrains/jet/plugin/codeInsight/upDownMover/JetExpressionMover.java @@ -16,15 +16,12 @@ public class JetExpressionMover extends AbstractJetUpDownMover { public JetExpressionMover() { } - @SuppressWarnings("FieldMayBeFinal") - private static Class[] MOVABLE_ELEMENT_CLASSES = {JetExpression.class, JetWhenEntry.class, JetValueArgument.class, PsiComment.class}; + private final static Class[] MOVABLE_ELEMENT_CLASSES = {JetExpression.class, JetWhenEntry.class, JetValueArgument.class, PsiComment.class}; - @SuppressWarnings("FieldMayBeFinal") - private static Class[] BLOCKLIKE_ELEMENT_CLASSES = + private final static Class[] BLOCKLIKE_ELEMENT_CLASSES = {JetBlockExpression.class, JetWhenExpression.class, JetClassBody.class, JetFile.class}; - @SuppressWarnings("FieldMayBeFinal") - private static Class[] FUNCTIONLIKE_ELEMENT_CLASSES = + private final static Class[] FUNCTIONLIKE_ELEMENT_CLASSES = {JetFunction.class, JetPropertyAccessor.class, JetClassInitializer.class}; @Nullable @@ -113,7 +110,10 @@ public class JetExpressionMover extends AbstractJetUpDownMover { PsiElement blockLikeElement = closingBrace.getParent(); if (!(blockLikeElement instanceof JetBlockExpression)) return BraceStatus.NOT_MOVABLE; - if (blockLikeElement.getParent() instanceof JetWhenEntry) return BraceStatus.NOT_FOUND; + + PsiElement blockParent = blockLikeElement.getParent(); + if (blockParent instanceof JetWhenEntry) return BraceStatus.NOT_FOUND; + if (PsiTreeUtil.instanceOf(blockParent, FUNCTIONLIKE_ELEMENT_CLASSES)) return BraceStatus.NOT_FOUND; PsiElement enclosingExpression = PsiTreeUtil.getParentOfType(blockLikeElement, JetExpression.class); diff --git a/idea/testData/codeInsight/moveUpDown/closingBraces/function/function1.kt b/idea/testData/codeInsight/moveUpDown/closingBraces/function/function1.kt new file mode 100644 index 00000000000..43c0955ee28 --- /dev/null +++ b/idea/testData/codeInsight/moveUpDown/closingBraces/function/function1.kt @@ -0,0 +1,10 @@ +// MOVE: down +fun foo() { + val x = "" + + fun bar() { + + } + + val y = "" +} \ No newline at end of file diff --git a/idea/testData/codeInsight/moveUpDown/closingBraces/function/function1.kt.after b/idea/testData/codeInsight/moveUpDown/closingBraces/function/function1.kt.after new file mode 100644 index 00000000000..d4a61584b82 --- /dev/null +++ b/idea/testData/codeInsight/moveUpDown/closingBraces/function/function1.kt.after @@ -0,0 +1,10 @@ +// MOVE: down +fun foo() { + val x = "" + + + fun bar() { + + } + val y = "" +} \ No newline at end of file diff --git a/idea/testData/codeInsight/moveUpDown/closingBraces/function/function2.kt b/idea/testData/codeInsight/moveUpDown/closingBraces/function/function2.kt new file mode 100644 index 00000000000..6a0f188cc34 --- /dev/null +++ b/idea/testData/codeInsight/moveUpDown/closingBraces/function/function2.kt @@ -0,0 +1,10 @@ +// MOVE: up +fun foo() { + val x = "" + + fun bar() { + + } + + val y = "" +} \ No newline at end of file diff --git a/idea/testData/codeInsight/moveUpDown/closingBraces/function/function2.kt.after b/idea/testData/codeInsight/moveUpDown/closingBraces/function/function2.kt.after new file mode 100644 index 00000000000..d97ba5d9700 --- /dev/null +++ b/idea/testData/codeInsight/moveUpDown/closingBraces/function/function2.kt.after @@ -0,0 +1,10 @@ +// MOVE: up +fun foo() { + val x = "" + fun bar() { + + } + + + val y = "" +} \ No newline at end of file diff --git a/idea/testData/codeInsight/moveUpDown/closingBraces/function/function3.kt b/idea/testData/codeInsight/moveUpDown/closingBraces/function/function3.kt new file mode 100644 index 00000000000..d4a61584b82 --- /dev/null +++ b/idea/testData/codeInsight/moveUpDown/closingBraces/function/function3.kt @@ -0,0 +1,10 @@ +// MOVE: down +fun foo() { + val x = "" + + + fun bar() { + + } + val y = "" +} \ No newline at end of file diff --git a/idea/testData/codeInsight/moveUpDown/closingBraces/function/function3.kt.after b/idea/testData/codeInsight/moveUpDown/closingBraces/function/function3.kt.after new file mode 100644 index 00000000000..a1c6e7fe4df --- /dev/null +++ b/idea/testData/codeInsight/moveUpDown/closingBraces/function/function3.kt.after @@ -0,0 +1,10 @@ +// MOVE: down +fun foo() { + val x = "" + + + val y = "" + fun bar() { + + } +} \ No newline at end of file diff --git a/idea/testData/codeInsight/moveUpDown/closingBraces/function/function4.kt b/idea/testData/codeInsight/moveUpDown/closingBraces/function/function4.kt new file mode 100644 index 00000000000..d97ba5d9700 --- /dev/null +++ b/idea/testData/codeInsight/moveUpDown/closingBraces/function/function4.kt @@ -0,0 +1,10 @@ +// MOVE: up +fun foo() { + val x = "" + fun bar() { + + } + + + val y = "" +} \ No newline at end of file diff --git a/idea/testData/codeInsight/moveUpDown/closingBraces/function/function4.kt.after b/idea/testData/codeInsight/moveUpDown/closingBraces/function/function4.kt.after new file mode 100644 index 00000000000..c1a02f68d84 --- /dev/null +++ b/idea/testData/codeInsight/moveUpDown/closingBraces/function/function4.kt.after @@ -0,0 +1,10 @@ +// MOVE: up +fun foo() { + fun bar() { + + } + val x = "" + + + val y = "" +} \ No newline at end of file diff --git a/idea/tests/org/jetbrains/jet/plugin/codeInsight/moveUpDown/CodeMoverTestGenerated.java b/idea/tests/org/jetbrains/jet/plugin/codeInsight/moveUpDown/CodeMoverTestGenerated.java index c7ca70b13a4..244b9db74ff 100644 --- a/idea/tests/org/jetbrains/jet/plugin/codeInsight/moveUpDown/CodeMoverTestGenerated.java +++ b/idea/tests/org/jetbrains/jet/plugin/codeInsight/moveUpDown/CodeMoverTestGenerated.java @@ -574,7 +574,7 @@ public class CodeMoverTestGenerated extends AbstractCodeMoverTest { } @TestMetadata("idea/testData/codeInsight/moveUpDown/closingBraces") - @InnerTestClasses({ClosingBraces.For.class, ClosingBraces.If.class, ClosingBraces.Nested.class, ClosingBraces.When.class, ClosingBraces.While.class}) + @InnerTestClasses({ClosingBraces.For.class, ClosingBraces.Function.class, ClosingBraces.If.class, ClosingBraces.Nested.class, ClosingBraces.When.class, ClosingBraces.While.class}) public static class ClosingBraces extends AbstractCodeMoverTest { public void testAllFilesPresentInClosingBraces() throws Exception { JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.GenerateTests", new File("idea/testData/codeInsight/moveUpDown/closingBraces"), Pattern.compile("^(.+)\\.kt$"), true); @@ -598,6 +598,34 @@ public class CodeMoverTestGenerated extends AbstractCodeMoverTest { } + @TestMetadata("idea/testData/codeInsight/moveUpDown/closingBraces/function") + public static class Function extends AbstractCodeMoverTest { + public void testAllFilesPresentInFunction() throws Exception { + JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.GenerateTests", new File("idea/testData/codeInsight/moveUpDown/closingBraces/function"), Pattern.compile("^(.+)\\.kt$"), true); + } + + @TestMetadata("function1.kt") + public void testFunction1() throws Exception { + doTestExpression("idea/testData/codeInsight/moveUpDown/closingBraces/function/function1.kt"); + } + + @TestMetadata("function2.kt") + public void testFunction2() throws Exception { + doTestExpression("idea/testData/codeInsight/moveUpDown/closingBraces/function/function2.kt"); + } + + @TestMetadata("function3.kt") + public void testFunction3() throws Exception { + doTestExpression("idea/testData/codeInsight/moveUpDown/closingBraces/function/function3.kt"); + } + + @TestMetadata("function4.kt") + public void testFunction4() throws Exception { + doTestExpression("idea/testData/codeInsight/moveUpDown/closingBraces/function/function4.kt"); + } + + } + @TestMetadata("idea/testData/codeInsight/moveUpDown/closingBraces/if") public static class If extends AbstractCodeMoverTest { public void testAllFilesPresentInIf() throws Exception { @@ -714,6 +742,7 @@ public class CodeMoverTestGenerated extends AbstractCodeMoverTest { TestSuite suite = new TestSuite("ClosingBraces"); suite.addTestSuite(ClosingBraces.class); suite.addTestSuite(For.class); + suite.addTestSuite(Function.class); suite.addTestSuite(If.class); suite.addTestSuite(Nested.class); suite.addTestSuite(When.class); From ef2af3a4e8b2297d0042d4b8a913ca9505733681 Mon Sep 17 00:00:00 2001 From: Alexey Sedunov Date: Wed, 5 Jun 2013 16:03:51 +0400 Subject: [PATCH 213/249] Fix brace node extraction from class initializer --- .../org/jetbrains/jet/lang/psi/JetClassInitializer.java | 7 +++---- .../codeInsight/upDownMover/JetDeclarationMover.java | 5 ++++- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetClassInitializer.java b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetClassInitializer.java index 3d40cdd11c1..0f681f4ba1e 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetClassInitializer.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetClassInitializer.java @@ -44,10 +44,9 @@ public class JetClassInitializer extends JetDeclarationImpl implements JetStatem return body; } - @NotNull + @Nullable public PsiElement getOpenBraceNode() { - ASTNode openBraceNode = getNode().findChildByType(JetTokens.LBRACE); - assert openBraceNode != null; - return openBraceNode.getPsi(); + JetExpression body = getBody(); + return (body instanceof JetBlockExpression) ? ((JetBlockExpression) body).getLBrace() : null; } } diff --git a/idea/src/org/jetbrains/jet/plugin/codeInsight/upDownMover/JetDeclarationMover.java b/idea/src/org/jetbrains/jet/plugin/codeInsight/upDownMover/JetDeclarationMover.java index eb5fdc3cfeb..ae95da053c8 100644 --- a/idea/src/org/jetbrains/jet/plugin/codeInsight/upDownMover/JetDeclarationMover.java +++ b/idea/src/org/jetbrains/jet/plugin/codeInsight/upDownMover/JetDeclarationMover.java @@ -35,7 +35,10 @@ public class JetDeclarationMover extends AbstractJetUpDownMover { new JetVisitorVoid() { @Override public void visitAnonymousInitializer(JetClassInitializer initializer) { - memberSuspects.add(initializer.getOpenBraceNode()); + PsiElement brace = initializer.getOpenBraceNode(); + if (brace != null) { + memberSuspects.add(brace); + } } @Override From f41584c7abd55e62b52eefe449e1d7a28d56061b Mon Sep 17 00:00:00 2001 From: Svetlana Isakova Date: Wed, 5 Jun 2013 15:27:12 +0400 Subject: [PATCH 214/249] tests added for inference for delegated properties --- .../inference/extensionGet.kt | 33 +++++++++++++++++++ .../inference/extensionProperty.kt | 17 ++++++++++ .../checkers/JetDiagnosticsTestGenerated.java | 10 ++++++ 3 files changed, 60 insertions(+) create mode 100644 compiler/testData/diagnostics/tests/delegatedProperty/inference/extensionGet.kt create mode 100644 compiler/testData/diagnostics/tests/delegatedProperty/inference/extensionProperty.kt diff --git a/compiler/testData/diagnostics/tests/delegatedProperty/inference/extensionGet.kt b/compiler/testData/diagnostics/tests/delegatedProperty/inference/extensionGet.kt new file mode 100644 index 00000000000..835be3527de --- /dev/null +++ b/compiler/testData/diagnostics/tests/delegatedProperty/inference/extensionGet.kt @@ -0,0 +1,33 @@ +package foo + +class A1 { + val a: String by MyProperty1() +} + +class MyProperty1 {} +fun MyProperty1.get(thisRef: Any?, desc: PropertyMetadata): String { + throw Exception("$thisRef $desc") +} + +//-------------------- + +class A2 { + val a: String by MyProperty2() +} + +class MyProperty2 {} +fun MyProperty2.get(thisRef: Any?, desc: PropertyMetadata): T { + throw Exception("$thisRef $desc") +} + +//-------------------- + +class A3 { + val a: String by MyProperty3() + + class MyProperty3 {} + + fun MyProperty3.get(thisRef: Any?, desc: PropertyMetadata): T { + throw Exception("$thisRef $desc") + } +} \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/delegatedProperty/inference/extensionProperty.kt b/compiler/testData/diagnostics/tests/delegatedProperty/inference/extensionProperty.kt new file mode 100644 index 00000000000..a03a8e12390 --- /dev/null +++ b/compiler/testData/diagnostics/tests/delegatedProperty/inference/extensionProperty.kt @@ -0,0 +1,17 @@ +package foo + +open class A { + val B.w: Int by MyProperty() +} + +val A.e: Int by MyProperty() + +class B { + val A.f: Int by MyProperty() +} + +class MyProperty { + public fun get(thisRef: R, desc: PropertyMetadata): T { + throw Exception("$thisRef $desc") + } +} diff --git a/compiler/tests/org/jetbrains/jet/checkers/JetDiagnosticsTestGenerated.java b/compiler/tests/org/jetbrains/jet/checkers/JetDiagnosticsTestGenerated.java index c95d768f16c..7c04c0905b5 100644 --- a/compiler/tests/org/jetbrains/jet/checkers/JetDiagnosticsTestGenerated.java +++ b/compiler/tests/org/jetbrains/jet/checkers/JetDiagnosticsTestGenerated.java @@ -2065,6 +2065,16 @@ public class JetDiagnosticsTestGenerated extends AbstractDiagnosticsTestWithEage doTest("compiler/testData/diagnostics/tests/delegatedProperty/inference/differentDelegatedExpressions.kt"); } + @TestMetadata("extensionGet.kt") + public void testExtensionGet() throws Exception { + doTest("compiler/testData/diagnostics/tests/delegatedProperty/inference/extensionGet.kt"); + } + + @TestMetadata("extensionProperty.kt") + public void testExtensionProperty() throws Exception { + doTest("compiler/testData/diagnostics/tests/delegatedProperty/inference/extensionProperty.kt"); + } + @TestMetadata("noErrorsForImplicitConstraints.kt") public void testNoErrorsForImplicitConstraints() throws Exception { doTest("compiler/testData/diagnostics/tests/delegatedProperty/inference/noErrorsForImplicitConstraints.kt"); From 12ef42b6ae58fb82cfe5fc4915e7936cd0f55511 Mon Sep 17 00:00:00 2001 From: Svetlana Isakova Date: Thu, 6 Jun 2013 16:30:43 +0400 Subject: [PATCH 215/249] small refactoring --- .../jet/lang/resolve/BodyResolver.java | 28 ++++++++++--------- 1 file changed, 15 insertions(+), 13 deletions(-) diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/BodyResolver.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/BodyResolver.java index 2a050a21880..02355cdc21d 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/BodyResolver.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/BodyResolver.java @@ -551,20 +551,21 @@ public class BodyResolver { } addConstraintForThisValue(constraintSystem, descriptor); } - if (propertyDescriptor.isVar()) { - OverloadResolutionResults setMethodResults = - DelegatedPropertyUtils.getDelegatedPropertyConventionMethod( - propertyDescriptor, delegateExpression, returnType, expressionTypingServices, - traceToResolveConventionMethods, accessorScope, false); + if (!propertyDescriptor.isVar()) return; - if (conventionMethodFound(setMethodResults)) { - FunctionDescriptor descriptor = setMethodResults.getResultingDescriptor(); - List valueParameters = descriptor.getValueParameters(); - if (valueParameters.size() == 3) { - ValueParameterDescriptor valueParameterForThis = valueParameters.get(2); - constraintSystem.addSubtypeConstraint(expectedType, valueParameterForThis.getType(), ConstraintPosition.FROM_COMPLETER); - addConstraintForThisValue(constraintSystem, descriptor); - } + OverloadResolutionResults setMethodResults = + DelegatedPropertyUtils.getDelegatedPropertyConventionMethod( + propertyDescriptor, delegateExpression, returnType, expressionTypingServices, + traceToResolveConventionMethods, accessorScope, false); + + if (conventionMethodFound(setMethodResults)) { + FunctionDescriptor descriptor = setMethodResults.getResultingDescriptor(); + List valueParameters = descriptor.getValueParameters(); + if (valueParameters.size() == 3) { + ValueParameterDescriptor valueParameterForThis = valueParameters.get(2); + + constraintSystem.addSubtypeConstraint(expectedType, valueParameterForThis.getType(), ConstraintPosition.FROM_COMPLETER); + addConstraintForThisValue(constraintSystem, descriptor); } } } @@ -585,6 +586,7 @@ public class BodyResolver { List valueParameters = resultingDescriptor.getValueParameters(); if (valueParameters.isEmpty()) return; ValueParameterDescriptor valueParameterForThis = valueParameters.get(0); + constraintSystem.addSubtypeConstraint(typeOfThis, valueParameterForThis.getType(), ConstraintPosition.FROM_COMPLETER); } }; From 4e6ec64d9a0ad049cad0faf0d6f93cf4ae51aeef Mon Sep 17 00:00:00 2001 From: Svetlana Isakova Date: Wed, 5 Jun 2013 20:29:24 +0400 Subject: [PATCH 216/249] changed resolution candidates order for foo() first try 'this.foo()', then 'foo()' --- .../jet/lang/resolve/calls/tasks/TaskPrioritizer.java | 2 +- .../preferImplicitThisToNoReceiver.resolve | 6 ++++++ 2 files changed, 7 insertions(+), 1 deletion(-) create mode 100644 compiler/testData/resolve/candidatesPriority/preferImplicitThisToNoReceiver.resolve diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/tasks/TaskPrioritizer.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/tasks/TaskPrioritizer.java index 2dc46115b2d..20272763406 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/tasks/TaskPrioritizer.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/tasks/TaskPrioritizer.java @@ -181,11 +181,11 @@ public class TaskPrioritizer { TaskPrioritizer.splitLexicallyLocalDescriptors(functions, scope.getContainingDeclaration(), locals, nonlocals); result.addLocalExtensions(locals); - result.addNonLocalExtensions(nonlocals); for (ReceiverValue implicitReceiver : implicitReceivers) { doComputeTasks(scope, implicitReceiver, name, result, context, callableDescriptorCollector); } + result.addNonLocalExtensions(nonlocals); } } diff --git a/compiler/testData/resolve/candidatesPriority/preferImplicitThisToNoReceiver.resolve b/compiler/testData/resolve/candidatesPriority/preferImplicitThisToNoReceiver.resolve new file mode 100644 index 00000000000..b23a3255a79 --- /dev/null +++ b/compiler/testData/resolve/candidatesPriority/preferImplicitThisToNoReceiver.resolve @@ -0,0 +1,6 @@ +fun ~A.foo~A.foo() = 1 +fun foo() = 2 + +class A { + fun test() = `A.foo`foo() +} \ No newline at end of file From ca88a01e1dc09f5146df9a1c3aca8cac5b30b00b Mon Sep 17 00:00:00 2001 From: Svetlana Isakova Date: Wed, 5 Jun 2013 20:31:47 +0400 Subject: [PATCH 217/249] no 'dangling function literal' check for nested calls --- .../jet/lang/resolve/calls/CallResolver.java | 3 ++- .../DanglingFunctionLiteral.kt | 0 .../NoDanglingFunctionLiteralForNestedCalls.kt | 11 +++++++++++ .../jet/checkers/JetDiagnosticsTestGenerated.java | 15 ++++++++++----- 4 files changed, 23 insertions(+), 6 deletions(-) rename compiler/testData/diagnostics/tests/{ => functionLiterals}/DanglingFunctionLiteral.kt (100%) create mode 100644 compiler/testData/diagnostics/tests/functionLiterals/NoDanglingFunctionLiteralForNestedCalls.kt 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 39bf46044f7..d40bfda16b4 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 @@ -477,7 +477,8 @@ public class CallResolver { // } ImmutableSet someFailed = ImmutableSet.of(OverloadResolutionResults.Code.MANY_FAILED_CANDIDATES, OverloadResolutionResults.Code.SINGLE_CANDIDATE_ARGUMENT_MISMATCH); - if (someFailed.contains(results.getResultCode()) && !task.call.getFunctionLiteralArguments().isEmpty()) { + if (someFailed.contains(results.getResultCode()) && !task.call.getFunctionLiteralArguments().isEmpty() + && task.resolveMode == ResolveMode.TOP_LEVEL_CALL) { //For nested calls there are no such cases // We have some candidates that failed for some reason // And we have a suspect: the function literal argument // Now, we try to remove this argument and see if it helps diff --git a/compiler/testData/diagnostics/tests/DanglingFunctionLiteral.kt b/compiler/testData/diagnostics/tests/functionLiterals/DanglingFunctionLiteral.kt similarity index 100% rename from compiler/testData/diagnostics/tests/DanglingFunctionLiteral.kt rename to compiler/testData/diagnostics/tests/functionLiterals/DanglingFunctionLiteral.kt diff --git a/compiler/testData/diagnostics/tests/functionLiterals/NoDanglingFunctionLiteralForNestedCalls.kt b/compiler/testData/diagnostics/tests/functionLiterals/NoDanglingFunctionLiteralForNestedCalls.kt new file mode 100644 index 00000000000..655667c2aa3 --- /dev/null +++ b/compiler/testData/diagnostics/tests/functionLiterals/NoDanglingFunctionLiteralForNestedCalls.kt @@ -0,0 +1,11 @@ +package baz + +fun test() { + foo(1) {} + + foo( foo(1) {} ) //here +} + +fun foo(i: Int) {} + +fun foo() : (i : () -> Unit) -> Unit = {} diff --git a/compiler/tests/org/jetbrains/jet/checkers/JetDiagnosticsTestGenerated.java b/compiler/tests/org/jetbrains/jet/checkers/JetDiagnosticsTestGenerated.java index 7c04c0905b5..0d258ad49d2 100644 --- a/compiler/tests/org/jetbrains/jet/checkers/JetDiagnosticsTestGenerated.java +++ b/compiler/tests/org/jetbrains/jet/checkers/JetDiagnosticsTestGenerated.java @@ -169,11 +169,6 @@ public class JetDiagnosticsTestGenerated extends AbstractDiagnosticsTestWithEage doTest("compiler/testData/diagnostics/tests/CyclicHierarchy.kt"); } - @TestMetadata("DanglingFunctionLiteral.kt") - public void testDanglingFunctionLiteral() throws Exception { - doTest("compiler/testData/diagnostics/tests/DanglingFunctionLiteral.kt"); - } - @TestMetadata("DefaultValuesTypechecking.kt") public void testDefaultValuesTypechecking() throws Exception { doTest("compiler/testData/diagnostics/tests/DefaultValuesTypechecking.kt"); @@ -2300,6 +2295,11 @@ public class JetDiagnosticsTestGenerated extends AbstractDiagnosticsTestWithEage JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.GenerateTests", new File("compiler/testData/diagnostics/tests/functionLiterals"), Pattern.compile("^(.+)\\.kt$"), true); } + @TestMetadata("DanglingFunctionLiteral.kt") + public void testDanglingFunctionLiteral() throws Exception { + doTest("compiler/testData/diagnostics/tests/functionLiterals/DanglingFunctionLiteral.kt"); + } + @TestMetadata("ExpectedParameterTypeMismatchVariance.kt") public void testExpectedParameterTypeMismatchVariance() throws Exception { doTest("compiler/testData/diagnostics/tests/functionLiterals/ExpectedParameterTypeMismatchVariance.kt"); @@ -2315,6 +2315,11 @@ public class JetDiagnosticsTestGenerated extends AbstractDiagnosticsTestWithEage doTest("compiler/testData/diagnostics/tests/functionLiterals/kt2906.kt"); } + @TestMetadata("NoDanglingFunctionLiteralForNestedCalls.kt") + public void testNoDanglingFunctionLiteralForNestedCalls() throws Exception { + doTest("compiler/testData/diagnostics/tests/functionLiterals/NoDanglingFunctionLiteralForNestedCalls.kt"); + } + @TestMetadata("unusedLiteral.kt") public void testUnusedLiteral() throws Exception { doTest("compiler/testData/diagnostics/tests/functionLiterals/unusedLiteral.kt"); From fc0077cf9bb02be60cc1535a144813eb4d199228 Mon Sep 17 00:00:00 2001 From: Svetlana Isakova Date: Wed, 5 Jun 2013 20:33:21 +0400 Subject: [PATCH 218/249] removed explicit type arguments from delegation tests where possible --- .../test/properties/delegation/DelegationTest.kt | 2 +- .../properties/delegation/MapDelegationTest.kt | 16 ++++++++-------- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/libraries/stdlib/test/properties/delegation/DelegationTest.kt b/libraries/stdlib/test/properties/delegation/DelegationTest.kt index 4098956d993..0dcde1d12c3 100644 --- a/libraries/stdlib/test/properties/delegation/DelegationTest.kt +++ b/libraries/stdlib/test/properties/delegation/DelegationTest.kt @@ -25,7 +25,7 @@ class DelegationTest(): DelegationTestBase() { } public class TestNotNullVar(val a1: String, val b1: T): WithBox { - var a: String by Delegates.notNull() + var a: String by Delegates.notNull() var b by Delegates.notNull() override fun box(): String { diff --git a/libraries/stdlib/test/properties/delegation/MapDelegationTest.kt b/libraries/stdlib/test/properties/delegation/MapDelegationTest.kt index b6df3fc21fb..5b714fa1bc8 100644 --- a/libraries/stdlib/test/properties/delegation/MapDelegationTest.kt +++ b/libraries/stdlib/test/properties/delegation/MapDelegationTest.kt @@ -66,8 +66,8 @@ class TestMapValWithDifferentTypes(): WithBox { class TestMapVarWithDifferentTypes(): WithBox { val map: HashMap = hashMapOf("a" to "a", "b" to 1, "c" to A(1), "d" to "d") - var a by Delegates.mapVar(map) - var b by Delegates.mapVar(map) + var a: String by Delegates.mapVar(map) + var b: Int by Delegates.mapVar(map) var c by Delegates.mapVar(map) var d by Delegates.mapVar(map) @@ -100,7 +100,7 @@ class TestNullableKey: WithBox { class TestMapPropertyString(): WithBox { val map = hashMapOf("a" to "a", "b" to "b", "c" to "c":Any?) - val a by Delegates.mapVal(map) + val a: String by Delegates.mapVal(map) var b by Delegates.mapVar(map) val c by Delegates.mapVal(map) @@ -115,9 +115,9 @@ class TestMapPropertyString(): WithBox { class TestMapValWithDefault(): WithBox { val map = hashMapOf() - val a by Delegates.mapVal(map, default = { ref, desc -> "aDefault" }) - val b by FixedMapVal(map, default = { ref, desc -> "bDefault" }, key = {"b"}) - val c by FixedMapVal(map, default = { ref, desc -> "cDefault" }, key = { desc -> desc.name }) + val a: String by Delegates.mapVal(map, default = { ref, desc -> "aDefault" }) + val b: String by FixedMapVal(map, default = { (ref: TestMapValWithDefault, desc: String) -> "bDefault" }, key = {"b"}) + val c: String by FixedMapVal(map, default = { (ref: TestMapValWithDefault, desc: String) -> "cDefault" }, key = { desc -> desc.name }) override fun box(): String { if (a != "aDefault") return "fail at 'a'" @@ -130,8 +130,8 @@ class TestMapValWithDefault(): WithBox { class TestMapVarWithDefault(): WithBox { val map = hashMapOf() var a: String by Delegates.mapVar(map, default = {ref, desc -> "aDefault" }) - var b: String by FixedMapVar(map, default = {ref, desc -> "bDefault" }, key = {"b"}) - var c: String by FixedMapVar(map, default = {ref, desc -> "cDefault" }, key = { desc -> desc.name }) + var b: String by FixedMapVar(map, default = {(ref: Any?, desc: String) -> "bDefault" }, key = {"b"}) + var c: String by FixedMapVar(map, default = {(ref: Any?, desc: String) -> "cDefault" }, key = { desc -> desc.name }) override fun box(): String { if (a != "aDefault") return "fail at 'a'" From 92424edb29455e785820c39adb2e9564f0ecc863 Mon Sep 17 00:00:00 2001 From: Svetlana Isakova Date: Thu, 6 Jun 2013 15:22:49 +0400 Subject: [PATCH 219/249] refactoring extracted variables added method 'replaceCall' to ResolutionTask removed unused parameter --- .../jet/lang/resolve/calls/CallResolver.java | 35 ++++++++++--------- .../resolve/calls/tasks/ResolutionTask.java | 6 ++++ 2 files changed, 24 insertions(+), 17 deletions(-) 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 d40bfda16b4..5a1b5923a77 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 @@ -403,7 +403,7 @@ public class CallResolver { for (ResolutionTask task : prioritizedTasks) { TemporaryBindingTrace taskTrace = TemporaryBindingTrace.create(context.trace, "trace to resolve a task for", task.reference); OverloadResolutionResultsImpl results = performResolutionGuardedForExtraFunctionLiteralArguments( - task.replaceBindingTrace(taskTrace), callTransformer, context.trace); + task.replaceBindingTrace(taskTrace), callTransformer); if (results.isSuccess() || results.isAmbiguity()) { taskTrace.commit(); @@ -456,9 +456,9 @@ public class CallResolver { @NotNull private OverloadResolutionResultsImpl performResolutionGuardedForExtraFunctionLiteralArguments( @NotNull ResolutionTask task, - @NotNull CallTransformer callTransformer, - @NotNull BindingTrace traceForResolutionCache) { - OverloadResolutionResultsImpl results = performResolution(task, callTransformer, traceForResolutionCache); + @NotNull CallTransformer callTransformer + ) { + OverloadResolutionResultsImpl results = performResolution(task, callTransformer); // If resolution fails, we should check for some of the following situations: // class A { @@ -482,17 +482,18 @@ public class CallResolver { // We have some candidates that failed for some reason // And we have a suspect: the function literal argument // Now, we try to remove this argument and see if it helps - ResolutionTask newTask = new ResolutionTask(task.getCandidates(), task.reference, task.tracing, - TemporaryBindingTrace.create(task.trace, "trace for resolution guarded for extra function literal arguments"), - task.scope, new DelegatingCall(task.call) { - @NotNull - @Override - public List getFunctionLiteralArguments() { - return Collections.emptyList(); - } - }, task.expectedType, task.dataFlowInfo, task.resolveMode, task.checkArguments, - task.expressionPosition, task.resolutionResultsCache); - OverloadResolutionResultsImpl resultsWithFunctionLiteralsStripped = performResolution(newTask, callTransformer, traceForResolutionCache); + DelegatingCall callWithoutFLArgs = new DelegatingCall(task.call) { + @NotNull + @Override + public List getFunctionLiteralArguments() { + return Collections.emptyList(); + } + }; + TemporaryBindingTrace temporaryTrace = + TemporaryBindingTrace.create(task.trace, "trace for resolution guarded for extra function literal arguments"); + ResolutionTask newTask = task.replaceBindingTrace(temporaryTrace).replaceCall(callWithoutFLArgs); + + OverloadResolutionResultsImpl resultsWithFunctionLiteralsStripped = performResolution(newTask, callTransformer); if (resultsWithFunctionLiteralsStripped.isSuccess() || resultsWithFunctionLiteralsStripped.isAmbiguity()) { task.tracing.danglingFunctionLiteralArgumentSuspected(task.trace, task.call.getFunctionLiteralArguments()); } @@ -504,8 +505,8 @@ public class CallResolver { @NotNull private OverloadResolutionResultsImpl performResolution( @NotNull ResolutionTask task, - @NotNull CallTransformer callTransformer, - @NotNull BindingTrace traceForResolutionCache) { + @NotNull CallTransformer callTransformer + ) { for (ResolutionCandidate resolutionCandidate : task.getCandidates()) { TemporaryBindingTrace candidateTrace = TemporaryBindingTrace.create( diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/tasks/ResolutionTask.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/tasks/ResolutionTask.java index 49fa57a12f6..9ac1869200a 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/tasks/ResolutionTask.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/tasks/ResolutionTask.java @@ -100,6 +100,12 @@ public class ResolutionTask extends C return this; } + public ResolutionTask replaceCall(@NotNull Call newCall) { + return new ResolutionTask( + candidates, reference, tracing, trace, scope, newCall, expectedType, dataFlowInfo, resolveMode, checkArguments, + expressionPosition, resolutionResultsCache); + } + public interface DescriptorCheckStrategy { boolean performAdvancedChecks(D descriptor, BindingTrace trace, TracingStrategy tracing); } From 9731ff499ec876d3fe161916cdde7894092bf8d2 Mon Sep 17 00:00:00 2001 From: Svetlana Isakova Date: Thu, 6 Jun 2013 16:17:06 +0400 Subject: [PATCH 220/249] added generator for resolve tests --- .../jet/resolve/AbstractResolveTest.java | 38 ++ .../resolve/ExtensibleResolveTestCase.java | 4 +- .../jetbrains/jet/resolve/JetResolveTest.java | 89 ----- .../jet/resolve/JetResolveTestGenerated.java | 349 ++++++++++++++++++ .../jet/generators/tests/GenerateTests.java | 8 + 5 files changed, 398 insertions(+), 90 deletions(-) create mode 100644 compiler/tests/org/jetbrains/jet/resolve/AbstractResolveTest.java delete mode 100644 compiler/tests/org/jetbrains/jet/resolve/JetResolveTest.java create mode 100644 compiler/tests/org/jetbrains/jet/resolve/JetResolveTestGenerated.java diff --git a/compiler/tests/org/jetbrains/jet/resolve/AbstractResolveTest.java b/compiler/tests/org/jetbrains/jet/resolve/AbstractResolveTest.java new file mode 100644 index 00000000000..9ff36414900 --- /dev/null +++ b/compiler/tests/org/jetbrains/jet/resolve/AbstractResolveTest.java @@ -0,0 +1,38 @@ +/* + * Copyright 2010-2013 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.jetbrains.jet.resolve; + +import com.intellij.openapi.project.Project; +import org.jetbrains.jet.lang.psi.JetFile; + +public abstract class AbstractResolveTest extends ExtensibleResolveTestCase { + + @Override + protected ExpectedResolveData getExpectedResolveData() { + Project project = getProject(); + + return new ExpectedResolveData( + JetExpectedResolveDataUtil.prepareDefaultNameToDescriptors(project), + JetExpectedResolveDataUtil.prepareDefaultNameToDeclaration(project), + getEnvironment()) { + @Override + protected JetFile createJetFile(String fileName, String text) { + return createCheckAndReturnPsiFile(fileName, null, text); + } + }; + } +} diff --git a/compiler/tests/org/jetbrains/jet/resolve/ExtensibleResolveTestCase.java b/compiler/tests/org/jetbrains/jet/resolve/ExtensibleResolveTestCase.java index 6784d4ebb0a..85aa4611ff7 100644 --- a/compiler/tests/org/jetbrains/jet/resolve/ExtensibleResolveTestCase.java +++ b/compiler/tests/org/jetbrains/jet/resolve/ExtensibleResolveTestCase.java @@ -23,6 +23,7 @@ import org.jetbrains.jet.JetTestUtils; import org.jetbrains.jet.cli.jvm.compiler.JetCoreEnvironment; import org.jetbrains.jet.lang.psi.JetFile; +import java.io.File; import java.util.List; public abstract class ExtensibleResolveTestCase extends JetLiteFixture { @@ -48,7 +49,8 @@ public abstract class ExtensibleResolveTestCase extends JetLiteFixture { protected abstract ExpectedResolveData getExpectedResolveData(); protected void doTest(@NonNls String filePath) throws Exception { - String text = loadFile(filePath); + File file = new File(filePath); + String text = JetTestUtils.doLoadFile(file); List files = JetTestUtils.createTestFiles("file.kt", text, new JetTestUtils.TestFileFactory() { @Override public JetFile create(String fileName, String text) { diff --git a/compiler/tests/org/jetbrains/jet/resolve/JetResolveTest.java b/compiler/tests/org/jetbrains/jet/resolve/JetResolveTest.java deleted file mode 100644 index 5ba19c671cb..00000000000 --- a/compiler/tests/org/jetbrains/jet/resolve/JetResolveTest.java +++ /dev/null @@ -1,89 +0,0 @@ -/* - * Copyright 2010-2013 JetBrains s.r.o. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.jetbrains.jet.resolve; - -import com.intellij.openapi.application.PathManager; -import com.intellij.openapi.project.Project; -import junit.framework.Test; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.jet.JetTestCaseBuilder; -import org.jetbrains.jet.lang.psi.JetFile; -import org.jetbrains.jet.parsing.JetParsingTest; - -import java.io.File; - -@SuppressWarnings("JUnitTestCaseWithNoTests") -public class JetResolveTest extends ExtensibleResolveTestCase { - - private final String path; - private final String name; - - @SuppressWarnings("JUnitTestCaseWithNonTrivialConstructors") - public JetResolveTest(String path, String name) { - this.path = path; - this.name = name; - } - - @Override - protected ExpectedResolveData getExpectedResolveData() { - Project project = getProject(); - - return new ExpectedResolveData( - JetExpectedResolveDataUtil.prepareDefaultNameToDescriptors(project), - JetExpectedResolveDataUtil.prepareDefaultNameToDeclaration(project), - getEnvironment()) { - @Override - protected JetFile createJetFile(String fileName, String text) { - return createCheckAndReturnPsiFile(fileName, null, text); - } - }; - } - - @Override - protected String getTestDataPath() { - return getHomeDirectory() + "/compiler/testData"; - } - - private static String getHomeDirectory() { - String resourceRoot = PathManager.getResourceRoot(JetParsingTest.class, "/org/jetbrains/jet/parsing/JetParsingTest.class"); - assertNotNull(resourceRoot); - - return new File(resourceRoot).getParentFile().getParentFile().getParent(); - } - - @Override - public String getName() { - return "test" + name; - } - - @Override - protected void runTest() throws Throwable { - doTest(path); - } - - public static Test suite() { - return JetTestCaseBuilder.suiteForDirectory(getHomeDirectory() + "/compiler/testData/", "/resolve/", - true, JetTestCaseBuilder.filterByExtension("resolve"), - new JetTestCaseBuilder.NamedTestFactory() { - @NotNull - @Override - public Test createTest(@NotNull String dataPath, @NotNull String name, @NotNull File file) { - return new JetResolveTest(dataPath + "/" + name + ".resolve", name); - } - }); - } -} diff --git a/compiler/tests/org/jetbrains/jet/resolve/JetResolveTestGenerated.java b/compiler/tests/org/jetbrains/jet/resolve/JetResolveTestGenerated.java new file mode 100644 index 00000000000..07c283377e1 --- /dev/null +++ b/compiler/tests/org/jetbrains/jet/resolve/JetResolveTestGenerated.java @@ -0,0 +1,349 @@ +/* + * Copyright 2010-2013 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.jetbrains.jet.resolve; + +import junit.framework.Assert; +import junit.framework.Test; +import junit.framework.TestSuite; + +import java.io.File; +import java.util.regex.Pattern; +import org.jetbrains.jet.JetTestUtils; +import org.jetbrains.jet.test.InnerTestClasses; +import org.jetbrains.jet.test.TestMetadata; + +import org.jetbrains.jet.resolve.AbstractResolveTest; + +/** This class is generated by {@link org.jetbrains.jet.generators.tests.GenerateTests}. DO NOT MODIFY MANUALLY */ +@SuppressWarnings("all") +@TestMetadata("compiler/testData/resolve") +@InnerTestClasses({JetResolveTestGenerated.CandidatesPriority.class, JetResolveTestGenerated.DelegatedProperty.class, JetResolveTestGenerated.Imports.class, JetResolveTestGenerated.Labels.class, JetResolveTestGenerated.Regressions.class, JetResolveTestGenerated.Varargs.class}) +public class JetResolveTestGenerated extends AbstractResolveTest { + public void testAllFilesPresentInResolve() throws Exception { + JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.GenerateTests", new File("compiler/testData/resolve"), Pattern.compile("^(.+)\\.resolve$"), true); + } + + @TestMetadata("Basic.resolve") + public void testBasic() throws Exception { + doTest("compiler/testData/resolve/Basic.resolve"); + } + + @TestMetadata("ClassObjects.resolve") + public void testClassObjects() throws Exception { + doTest("compiler/testData/resolve/ClassObjects.resolve"); + } + + @TestMetadata("Classifiers.resolve") + public void testClassifiers() throws Exception { + doTest("compiler/testData/resolve/Classifiers.resolve"); + } + + @TestMetadata("ErrorSupertype.resolve") + public void testErrorSupertype() throws Exception { + doTest("compiler/testData/resolve/ErrorSupertype.resolve"); + } + + @TestMetadata("ExtensionFunctions.resolve") + public void testExtensionFunctions() throws Exception { + doTest("compiler/testData/resolve/ExtensionFunctions.resolve"); + } + + @TestMetadata("FunctionVariable.resolve") + public void testFunctionVariable() throws Exception { + doTest("compiler/testData/resolve/FunctionVariable.resolve"); + } + + @TestMetadata("kt304.resolve") + public void testKt304() throws Exception { + doTest("compiler/testData/resolve/kt304.resolve"); + } + + @TestMetadata("LocalObjects.resolve") + public void testLocalObjects() throws Exception { + doTest("compiler/testData/resolve/LocalObjects.resolve"); + } + + @TestMetadata("Namespaces.resolve") + public void testNamespaces() throws Exception { + doTest("compiler/testData/resolve/Namespaces.resolve"); + } + + @TestMetadata("NestedObjects.resolve") + public void testNestedObjects() throws Exception { + doTest("compiler/testData/resolve/NestedObjects.resolve"); + } + + @TestMetadata("NoReferenceForErrorAnnotation.resolve") + public void testNoReferenceForErrorAnnotation() throws Exception { + doTest("compiler/testData/resolve/NoReferenceForErrorAnnotation.resolve"); + } + + @TestMetadata("Objects.resolve") + public void testObjects() throws Exception { + doTest("compiler/testData/resolve/Objects.resolve"); + } + + @TestMetadata("PrimaryConstructorParameters.resolve") + public void testPrimaryConstructorParameters() throws Exception { + doTest("compiler/testData/resolve/PrimaryConstructorParameters.resolve"); + } + + @TestMetadata("PrimaryConstructors.resolve") + public void testPrimaryConstructors() throws Exception { + doTest("compiler/testData/resolve/PrimaryConstructors.resolve"); + } + + @TestMetadata("Projections.resolve") + public void testProjections() throws Exception { + doTest("compiler/testData/resolve/Projections.resolve"); + } + + @TestMetadata("ResolveOfInfixExpressions.resolve") + public void testResolveOfInfixExpressions() throws Exception { + doTest("compiler/testData/resolve/ResolveOfInfixExpressions.resolve"); + } + + @TestMetadata("ResolveToJava.resolve") + public void testResolveToJava() throws Exception { + doTest("compiler/testData/resolve/ResolveToJava.resolve"); + } + + @TestMetadata("ResolveToJava2.resolve") + public void testResolveToJava2() throws Exception { + doTest("compiler/testData/resolve/ResolveToJava2.resolve"); + } + + @TestMetadata("ResolveToJava3.resolve") + public void testResolveToJava3() throws Exception { + doTest("compiler/testData/resolve/ResolveToJava3.resolve"); + } + + @TestMetadata("ResolveToJavaTypeTransform.resolve") + public void testResolveToJavaTypeTransform() throws Exception { + doTest("compiler/testData/resolve/ResolveToJavaTypeTransform.resolve"); + } + + @TestMetadata("ScopeInteraction.resolve") + public void testScopeInteraction() throws Exception { + doTest("compiler/testData/resolve/ScopeInteraction.resolve"); + } + + @TestMetadata("StringTemplates.resolve") + public void testStringTemplates() throws Exception { + doTest("compiler/testData/resolve/StringTemplates.resolve"); + } + + @TestMetadata("Super.resolve") + public void testSuper() throws Exception { + doTest("compiler/testData/resolve/Super.resolve"); + } + + @TestMetadata("TryCatch.resolve") + public void testTryCatch() throws Exception { + doTest("compiler/testData/resolve/TryCatch.resolve"); + } + + @TestMetadata("compiler/testData/resolve/candidatesPriority") + public static class CandidatesPriority extends AbstractResolveTest { + public void testAllFilesPresentInCandidatesPriority() throws Exception { + JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.GenerateTests", new File("compiler/testData/resolve/candidatesPriority"), Pattern.compile("^(.+)\\.resolve$"), true); + } + + @TestMetadata("preferImplicitThisToNoReceiver.resolve") + public void testPreferImplicitThisToNoReceiver() throws Exception { + doTest("compiler/testData/resolve/candidatesPriority/preferImplicitThisToNoReceiver.resolve"); + } + + } + + @TestMetadata("compiler/testData/resolve/delegatedProperty") + public static class DelegatedProperty extends AbstractResolveTest { + public void testAllFilesPresentInDelegatedProperty() throws Exception { + JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.GenerateTests", new File("compiler/testData/resolve/delegatedProperty"), Pattern.compile("^(.+)\\.resolve$"), true); + } + + @TestMetadata("delegationByCall.resolve") + public void testDelegationByCall() throws Exception { + doTest("compiler/testData/resolve/delegatedProperty/delegationByCall.resolve"); + } + + @TestMetadata("delegationByConstructor.resolve") + public void testDelegationByConstructor() throws Exception { + doTest("compiler/testData/resolve/delegatedProperty/delegationByConstructor.resolve"); + } + + @TestMetadata("delegationByFun.resolve") + public void testDelegationByFun() throws Exception { + doTest("compiler/testData/resolve/delegatedProperty/delegationByFun.resolve"); + } + + @TestMetadata("delegationByObject.resolve") + public void testDelegationByObject() throws Exception { + doTest("compiler/testData/resolve/delegatedProperty/delegationByObject.resolve"); + } + + @TestMetadata("delegationByProperty.resolve") + public void testDelegationByProperty() throws Exception { + doTest("compiler/testData/resolve/delegatedProperty/delegationByProperty.resolve"); + } + + @TestMetadata("delegationInClass.resolve") + public void testDelegationInClass() throws Exception { + doTest("compiler/testData/resolve/delegatedProperty/delegationInClass.resolve"); + } + + @TestMetadata("localDelegation.resolve") + public void testLocalDelegation() throws Exception { + doTest("compiler/testData/resolve/delegatedProperty/localDelegation.resolve"); + } + + } + + @TestMetadata("compiler/testData/resolve/imports") + public static class Imports extends AbstractResolveTest { + public void testAllFilesPresentInImports() throws Exception { + JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.GenerateTests", new File("compiler/testData/resolve/imports"), Pattern.compile("^(.+)\\.resolve$"), true); + } + + @TestMetadata("ImportConflictAllPackage.resolve") + public void testImportConflictAllPackage() throws Exception { + doTest("compiler/testData/resolve/imports/ImportConflictAllPackage.resolve"); + } + + @TestMetadata("ImportConflictBetweenImportedAndRootPackage.resolve") + public void testImportConflictBetweenImportedAndRootPackage() throws Exception { + doTest("compiler/testData/resolve/imports/ImportConflictBetweenImportedAndRootPackage.resolve"); + } + + @TestMetadata("ImportConflictBetweenImportedAndSamePackage.resolve") + public void testImportConflictBetweenImportedAndSamePackage() throws Exception { + doTest("compiler/testData/resolve/imports/ImportConflictBetweenImportedAndSamePackage.resolve"); + } + + @TestMetadata("ImportConflictForFunctions.resolve") + public void testImportConflictForFunctions() throws Exception { + doTest("compiler/testData/resolve/imports/ImportConflictForFunctions.resolve"); + } + + @TestMetadata("ImportConflictPackageAndClass.resolve") + public void testImportConflictPackageAndClass() throws Exception { + doTest("compiler/testData/resolve/imports/ImportConflictPackageAndClass.resolve"); + } + + @TestMetadata("ImportConflictSameNameClass.resolve") + public void testImportConflictSameNameClass() throws Exception { + doTest("compiler/testData/resolve/imports/ImportConflictSameNameClass.resolve"); + } + + @TestMetadata("ImportConflictWithClassObject.resolve") + public void testImportConflictWithClassObject() throws Exception { + doTest("compiler/testData/resolve/imports/ImportConflictWithClassObject.resolve"); + } + + @TestMetadata("ImportConflictWithInFileClass.resolve") + public void testImportConflictWithInFileClass() throws Exception { + doTest("compiler/testData/resolve/imports/ImportConflictWithInFileClass.resolve"); + } + + @TestMetadata("ImportConflictWithInnerClass.resolve") + public void testImportConflictWithInnerClass() throws Exception { + doTest("compiler/testData/resolve/imports/ImportConflictWithInnerClass.resolve"); + } + + @TestMetadata("ImportConflictsWithMappedToJava.resolve") + public void testImportConflictsWithMappedToJava() throws Exception { + doTest("compiler/testData/resolve/imports/ImportConflictsWithMappedToJava.resolve"); + } + + @TestMetadata("ImportNonBlockingAnalysis.resolve") + public void testImportNonBlockingAnalysis() throws Exception { + doTest("compiler/testData/resolve/imports/ImportNonBlockingAnalysis.resolve"); + } + + @TestMetadata("ImportResolveOrderStable.resolve") + public void testImportResolveOrderStable() throws Exception { + doTest("compiler/testData/resolve/imports/ImportResolveOrderStable.resolve"); + } + + } + + @TestMetadata("compiler/testData/resolve/labels") + public static class Labels extends AbstractResolveTest { + public void testAllFilesPresentInLabels() throws Exception { + JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.GenerateTests", new File("compiler/testData/resolve/labels"), Pattern.compile("^(.+)\\.resolve$"), true); + } + + @TestMetadata("labelForPropertyInGetter.resolve") + public void testLabelForPropertyInGetter() throws Exception { + doTest("compiler/testData/resolve/labels/labelForPropertyInGetter.resolve"); + } + + @TestMetadata("labelForPropertyInSetter.resolve") + public void testLabelForPropertyInSetter() throws Exception { + doTest("compiler/testData/resolve/labels/labelForPropertyInSetter.resolve"); + } + + } + + @TestMetadata("compiler/testData/resolve/regressions") + public static class Regressions extends AbstractResolveTest { + public void testAllFilesPresentInRegressions() throws Exception { + JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.GenerateTests", new File("compiler/testData/resolve/regressions"), Pattern.compile("^(.+)\\.resolve$"), true); + } + + @TestMetadata("kt300.resolve") + public void testKt300() throws Exception { + doTest("compiler/testData/resolve/regressions/kt300.resolve"); + } + + } + + @TestMetadata("compiler/testData/resolve/varargs") + public static class Varargs extends AbstractResolveTest { + public void testAllFilesPresentInVarargs() throws Exception { + JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.GenerateTests", new File("compiler/testData/resolve/varargs"), Pattern.compile("^(.+)\\.resolve$"), true); + } + + @TestMetadata("MoreSpecificVarargsOfEqualLength.resolve") + public void testMoreSpecificVarargsOfEqualLength() throws Exception { + doTest("compiler/testData/resolve/varargs/MoreSpecificVarargsOfEqualLength.resolve"); + } + + @TestMetadata("NilaryVsVararg.resolve") + public void testNilaryVsVararg() throws Exception { + doTest("compiler/testData/resolve/varargs/NilaryVsVararg.resolve"); + } + + @TestMetadata("UnaryVsVararg.resolve") + public void testUnaryVsVararg() throws Exception { + doTest("compiler/testData/resolve/varargs/UnaryVsVararg.resolve"); + } + + } + + public static Test suite() { + TestSuite suite = new TestSuite("JetResolveTestGenerated"); + suite.addTestSuite(JetResolveTestGenerated.class); + suite.addTestSuite(CandidatesPriority.class); + suite.addTestSuite(DelegatedProperty.class); + suite.addTestSuite(Imports.class); + suite.addTestSuite(Labels.class); + suite.addTestSuite(Regressions.class); + suite.addTestSuite(Varargs.class); + return suite; + } +} diff --git a/generators/org/jetbrains/jet/generators/tests/GenerateTests.java b/generators/org/jetbrains/jet/generators/tests/GenerateTests.java index 08afc8565f7..aa82e896ad7 100644 --- a/generators/org/jetbrains/jet/generators/tests/GenerateTests.java +++ b/generators/org/jetbrains/jet/generators/tests/GenerateTests.java @@ -45,6 +45,7 @@ import org.jetbrains.jet.plugin.hierarchy.AbstractHierarchyTest; import org.jetbrains.jet.plugin.highlighter.AbstractDeprecatedHighlightingTest; import org.jetbrains.jet.plugin.quickfix.AbstractQuickFixMultiFileTest; import org.jetbrains.jet.plugin.quickfix.AbstractQuickFixTest; +import org.jetbrains.jet.resolve.AbstractResolveTest; import org.jetbrains.jet.test.generator.SimpleTestClassModel; import org.jetbrains.jet.test.generator.TestClassModel; import org.jetbrains.jet.test.generator.TestGenerator; @@ -80,6 +81,13 @@ public class GenerateTests { testModel("compiler/testData/diagnostics/tests/script", true, "ktscript", "doTest") ); + generateTest( + "compiler/tests/", + "JetResolveTestGenerated", + AbstractResolveTest.class, + testModel("compiler/testData/resolve", true, "resolve", "doTest") + ); + GenerateRangesCodegenTestData.main(args); generateTest( From 66dc6a975dca9dd9e0302ebd7844980ba77b0a44 Mon Sep 17 00:00:00 2001 From: Svetlana Isakova Date: Thu, 6 Jun 2013 16:23:00 +0400 Subject: [PATCH 221/249] better message if a resolve test fails --- .../tests/org/jetbrains/jet/resolve/ExpectedResolveData.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/tests/org/jetbrains/jet/resolve/ExpectedResolveData.java b/compiler/tests/org/jetbrains/jet/resolve/ExpectedResolveData.java index 0b2ca100c4f..ed226db868a 100644 --- a/compiler/tests/org/jetbrains/jet/resolve/ExpectedResolveData.java +++ b/compiler/tests/org/jetbrains/jet/resolve/ExpectedResolveData.java @@ -303,7 +303,7 @@ public abstract class ExpectedResolveData { else { assertEquals( "Reference `" + name + "`" + renderReferenceInContext(reference) + " is resolved into " + actualName + ".", - expected, actual); + expected.getText(), actual.getText()); } } From 9601762b2cdd4fc3bae614b12389c9f7ee2a17e2 Mon Sep 17 00:00:00 2001 From: Evgeny Gerashchenko Date: Thu, 6 Jun 2013 19:18:47 +0400 Subject: [PATCH 222/249] Subclassed from PsiClassHolderFileStub. --- .../psi/stubs/impl/PsiJetFileStubImpl.java | 20 ++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/psi/stubs/impl/PsiJetFileStubImpl.java b/compiler/frontend/src/org/jetbrains/jet/lang/psi/stubs/impl/PsiJetFileStubImpl.java index fc04bea18a1..c46c0e1d84a 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/psi/stubs/impl/PsiJetFileStubImpl.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/psi/stubs/impl/PsiJetFileStubImpl.java @@ -16,14 +16,21 @@ package org.jetbrains.jet.lang.psi.stubs.impl; +import com.google.common.collect.Lists; +import com.intellij.psi.PsiClass; +import com.intellij.psi.impl.java.stubs.PsiClassStub; +import com.intellij.psi.stubs.PsiClassHolderFileStub; import com.intellij.psi.stubs.PsiFileStubImpl; +import com.intellij.psi.stubs.StubElement; import com.intellij.psi.tree.IStubFileElementType; import com.intellij.util.io.StringRef; import org.jetbrains.jet.lang.psi.JetFile; import org.jetbrains.jet.lang.psi.stubs.PsiJetFileStub; import org.jetbrains.jet.lang.psi.stubs.elements.JetStubElementTypes; -public class PsiJetFileStubImpl extends PsiFileStubImpl implements PsiJetFileStub { +import java.util.List; + +public class PsiJetFileStubImpl extends PsiFileStubImpl implements PsiJetFileStub, PsiClassHolderFileStub { private final StringRef packageName; private final boolean isScript; @@ -65,4 +72,15 @@ public class PsiJetFileStubImpl extends PsiFileStubImpl implements PsiJ return builder.toString(); } + + @Override + public PsiClass[] getClasses() { + List result = Lists.newArrayList(); + for (StubElement child : getChildrenStubs()) { + if (child instanceof PsiClassStub) { + result.add((PsiClass) child.getPsi()); + } + } + return result.toArray(new PsiClass[result.size()]); + } } From 203dd93a7ad2ca75e7ec50e0194a6add47cb690a Mon Sep 17 00:00:00 2001 From: Evgeny Gerashchenko Date: Thu, 6 Jun 2013 21:19:02 +0400 Subject: [PATCH 223/249] Not loading SAM adapters from compiled Kotlin classes. --- .../resolve/java/resolver/JavaFunctionResolver.java | 4 +++- compiler/testData/loadKotlin/fun/NoSamAdapter.txt | 7 +++++++ compiler/testData/loadKotlin/fun/NoSamConstructor.txt | 5 +++++ compiler/testData/loadKotlin/fun/noSamAdapter.kt | 8 ++++++++ compiler/testData/loadKotlin/fun/noSamConstructor.kt | 5 +++++ .../jvm/compiler/LoadCompiledKotlinTestGenerated.java | 10 ++++++++++ .../LazyResolveNamespaceComparingTestGenerated.java | 10 ++++++++++ 7 files changed, 48 insertions(+), 1 deletion(-) create mode 100644 compiler/testData/loadKotlin/fun/NoSamAdapter.txt create mode 100644 compiler/testData/loadKotlin/fun/NoSamConstructor.txt create mode 100644 compiler/testData/loadKotlin/fun/noSamAdapter.kt create mode 100644 compiler/testData/loadKotlin/fun/noSamConstructor.kt diff --git a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/resolver/JavaFunctionResolver.java b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/resolver/JavaFunctionResolver.java index b85f90e7b20..8372ed45dc2 100644 --- a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/resolver/JavaFunctionResolver.java +++ b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/resolver/JavaFunctionResolver.java @@ -280,7 +280,9 @@ public final class JavaFunctionResolver { if (function != null) { functionsFromCurrent.add(function); - ContainerUtil.addIfNotNull(functionsFromCurrent, resolveSamAdapter(function)); + if (!DescriptorResolverUtils.isKotlinClass(psiClass)) { + ContainerUtil.addIfNotNull(functionsFromCurrent, resolveSamAdapter(function)); + } } } diff --git a/compiler/testData/loadKotlin/fun/NoSamAdapter.txt b/compiler/testData/loadKotlin/fun/NoSamAdapter.txt new file mode 100644 index 00000000000..311635dec88 --- /dev/null +++ b/compiler/testData/loadKotlin/fun/NoSamAdapter.txt @@ -0,0 +1,7 @@ +package test + +internal fun foo(/*0*/ r: java.lang.Runnable): jet.Unit + +public trait TaskObject { + internal abstract fun foo(/*0*/ r: java.lang.Runnable): jet.Unit +} diff --git a/compiler/testData/loadKotlin/fun/NoSamConstructor.txt b/compiler/testData/loadKotlin/fun/NoSamConstructor.txt new file mode 100644 index 00000000000..8afb2805767 --- /dev/null +++ b/compiler/testData/loadKotlin/fun/NoSamConstructor.txt @@ -0,0 +1,5 @@ +package test + +public trait Runnable { + internal abstract fun run(): jet.Unit +} diff --git a/compiler/testData/loadKotlin/fun/noSamAdapter.kt b/compiler/testData/loadKotlin/fun/noSamAdapter.kt new file mode 100644 index 00000000000..56722ba6d48 --- /dev/null +++ b/compiler/testData/loadKotlin/fun/noSamAdapter.kt @@ -0,0 +1,8 @@ +package test + +public trait TaskObject { + fun foo(r: Runnable) +} + +fun foo(r: Runnable) { +} \ No newline at end of file diff --git a/compiler/testData/loadKotlin/fun/noSamConstructor.kt b/compiler/testData/loadKotlin/fun/noSamConstructor.kt new file mode 100644 index 00000000000..91cd7ae7e6d --- /dev/null +++ b/compiler/testData/loadKotlin/fun/noSamConstructor.kt @@ -0,0 +1,5 @@ +package test + +public trait Runnable { + fun run() +} \ No newline at end of file diff --git a/compiler/tests/org/jetbrains/jet/jvm/compiler/LoadCompiledKotlinTestGenerated.java b/compiler/tests/org/jetbrains/jet/jvm/compiler/LoadCompiledKotlinTestGenerated.java index 89e993dc3e8..595eeab747e 100644 --- a/compiler/tests/org/jetbrains/jet/jvm/compiler/LoadCompiledKotlinTestGenerated.java +++ b/compiler/tests/org/jetbrains/jet/jvm/compiler/LoadCompiledKotlinTestGenerated.java @@ -414,6 +414,16 @@ public class LoadCompiledKotlinTestGenerated extends AbstractLoadCompiledKotlinT JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.GenerateTests", new File("compiler/testData/loadKotlin/fun"), Pattern.compile("^(.+)\\.kt$"), true); } + @TestMetadata("NoSamAdapter.kt") + public void testNoSamAdapter() throws Exception { + doTestWithAccessors("compiler/testData/loadKotlin/fun/NoSamAdapter.kt"); + } + + @TestMetadata("NoSamConstructor.kt") + public void testNoSamConstructor() throws Exception { + doTestWithAccessors("compiler/testData/loadKotlin/fun/NoSamConstructor.kt"); + } + @TestMetadata("PropagateDeepSubclass.kt") public void testPropagateDeepSubclass() throws Exception { doTestWithAccessors("compiler/testData/loadKotlin/fun/PropagateDeepSubclass.kt"); diff --git a/compiler/tests/org/jetbrains/jet/lang/resolve/lazy/LazyResolveNamespaceComparingTestGenerated.java b/compiler/tests/org/jetbrains/jet/lang/resolve/lazy/LazyResolveNamespaceComparingTestGenerated.java index b2bcdbb32bf..e26cdf37436 100644 --- a/compiler/tests/org/jetbrains/jet/lang/resolve/lazy/LazyResolveNamespaceComparingTestGenerated.java +++ b/compiler/tests/org/jetbrains/jet/lang/resolve/lazy/LazyResolveNamespaceComparingTestGenerated.java @@ -416,6 +416,16 @@ public class LazyResolveNamespaceComparingTestGenerated extends AbstractLazyReso JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.GenerateTests", new File("compiler/testData/loadKotlin/fun"), Pattern.compile("^(.+)\\.kt$"), true); } + @TestMetadata("NoSamAdapter.kt") + public void testNoSamAdapter() throws Exception { + doTestCheckingPrimaryConstructorsAndAccessors("compiler/testData/loadKotlin/fun/NoSamAdapter.kt"); + } + + @TestMetadata("NoSamConstructor.kt") + public void testNoSamConstructor() throws Exception { + doTestCheckingPrimaryConstructorsAndAccessors("compiler/testData/loadKotlin/fun/NoSamConstructor.kt"); + } + @TestMetadata("PropagateDeepSubclass.kt") public void testPropagateDeepSubclass() throws Exception { doTestCheckingPrimaryConstructorsAndAccessors("compiler/testData/loadKotlin/fun/PropagateDeepSubclass.kt"); From 5965904c0f4dce3ea079741e60aeef5fd14ca8c5 Mon Sep 17 00:00:00 2001 From: Evgeny Gerashchenko Date: Thu, 6 Jun 2013 21:57:35 +0400 Subject: [PATCH 224/249] Fixed filename case. --- .../testData/loadKotlin/fun/{noSamAdapter.kt => NoSamAdapter.kt} | 0 .../loadKotlin/fun/{noSamConstructor.kt => NoSamConstructor.kt} | 0 2 files changed, 0 insertions(+), 0 deletions(-) rename compiler/testData/loadKotlin/fun/{noSamAdapter.kt => NoSamAdapter.kt} (100%) rename compiler/testData/loadKotlin/fun/{noSamConstructor.kt => NoSamConstructor.kt} (100%) diff --git a/compiler/testData/loadKotlin/fun/noSamAdapter.kt b/compiler/testData/loadKotlin/fun/NoSamAdapter.kt similarity index 100% rename from compiler/testData/loadKotlin/fun/noSamAdapter.kt rename to compiler/testData/loadKotlin/fun/NoSamAdapter.kt diff --git a/compiler/testData/loadKotlin/fun/noSamConstructor.kt b/compiler/testData/loadKotlin/fun/NoSamConstructor.kt similarity index 100% rename from compiler/testData/loadKotlin/fun/noSamConstructor.kt rename to compiler/testData/loadKotlin/fun/NoSamConstructor.kt From afa3ead16046e504083a2763dbbf83d625b2db39 Mon Sep 17 00:00:00 2001 From: "Natalia.Ukhorskaya" Date: Thu, 6 Jun 2013 19:28:18 +0400 Subject: [PATCH 225/249] Add kotlin annotations for android SDK --- .../accessibilityservice/annotations.xml | 23 + .../android/accounts/annotations.xml | 122 + .../android/animation/annotations.xml | 245 ++ .../android/annotations.xml | 482 +++ .../android/app/admin/annotations.xml | 71 + .../android/app/annotations.xml | 1382 +++++++ .../android/app/backup/annotations.xml | 56 + .../android/appwidget/annotations.xml | 122 + .../android/bluetooth/annotations.xml | 155 + .../android/content/annotations.xml | 1508 +++++++ .../android/content/pm/annotations.xml | 338 ++ .../android/content/res/annotations.xml | 134 + .../android/database/annotations.xml | 320 ++ .../android/database/sqlite/annotations.xml | 104 + .../android/drm/annotations.xml | 32 + .../android/gesture/annotations.xml | 131 + .../android/graphics/annotations.xml | 239 ++ .../android/graphics/drawable/annotations.xml | 89 + .../android/hardware/annotations.xml | 239 ++ .../android/hardware/display/annotations.xml | 11 + .../android/hardware/input/annotations.xml | 11 + .../android/hardware/usb/annotations.xml | 71 + .../inputmethodservice/annotations.xml | 173 + .../android/location/annotations.xml | 35 + .../android/media/annotations.xml | 179 + .../android/media/audiofx/annotations.xml | 26 + .../android/media/effect/annotations.xml | 83 + .../android/net/annotations.xml | 320 ++ .../android/net/http/annotations.xml | 47 + .../android/net/nsd/annotations.xml | 17 + .../android/net/sip/annotations.xml | 11 + .../android/net/wifi/annotations.xml | 125 + .../android/net/wifi/p2p/annotations.xml | 47 + .../android/net/wifi/p2p/nsd/annotations.xml | 8 + .../android/nfc/annotations.xml | 56 + .../android/nfc/tech/annotations.xml | 56 + .../android/opengl/annotations.xml | 8 + .../android/os/annotations.xml | 548 +++ .../android/preference/annotations.xml | 344 ++ .../android/provider/annotations.xml | 3611 +++++++++++++++++ .../android/renderscript/annotations.xml | 320 ++ .../android/security/annotations.xml | 14 + .../android/service/dreams/annotations.xml | 35 + .../service/textservice/annotations.xml | 14 + .../android/service/wallpaper/annotations.xml | 23 + .../android/speech/annotations.xml | 131 + .../android/speech/tts/annotations.xml | 77 + .../android/telephony/annotations.xml | 68 + .../android/telephony/gsm/annotations.xml | 17 + .../android/test/annotations.xml | 53 + .../android/test/mock/annotations.xml | 77 + .../android/text/annotations.xml | 593 +++ .../android/text/format/annotations.xml | 104 + .../android/text/method/annotations.xml | 515 +++ .../android/text/style/annotations.xml | 341 ++ .../android/text/util/annotations.xml | 74 + .../android/util/annotations.xml | 230 ++ .../view/accessibility/annotations.xml | 71 + .../android/view/animation/annotations.xml | 116 + .../android/view/annotations.xml | 974 +++++ .../android/view/inputmethod/annotations.xml | 98 + .../android/view/textservice/annotations.xml | 41 + .../android/webkit/annotations.xml | 194 + .../android/widget/annotations.xml | 1838 +++++++++ build.xml | 46 +- .../org/jetbrains/jet/utils/KotlinPaths.java | 3 + .../jet/utils/KotlinPathsFromHomeDir.java | 6 + .../src/org/jetbrains/jet/utils/PathUtil.java | 1 + .../AbsentJdkAnnotationsNotifications.java | 29 +- .../versions/KotlinRuntimeLibraryUtil.java | 23 +- 70 files changed, 17683 insertions(+), 22 deletions(-) create mode 100644 android-sdk-annotations/android/accessibilityservice/annotations.xml create mode 100644 android-sdk-annotations/android/accounts/annotations.xml create mode 100644 android-sdk-annotations/android/animation/annotations.xml create mode 100644 android-sdk-annotations/android/annotations.xml create mode 100644 android-sdk-annotations/android/app/admin/annotations.xml create mode 100644 android-sdk-annotations/android/app/annotations.xml create mode 100644 android-sdk-annotations/android/app/backup/annotations.xml create mode 100644 android-sdk-annotations/android/appwidget/annotations.xml create mode 100644 android-sdk-annotations/android/bluetooth/annotations.xml create mode 100644 android-sdk-annotations/android/content/annotations.xml create mode 100644 android-sdk-annotations/android/content/pm/annotations.xml create mode 100644 android-sdk-annotations/android/content/res/annotations.xml create mode 100644 android-sdk-annotations/android/database/annotations.xml create mode 100644 android-sdk-annotations/android/database/sqlite/annotations.xml create mode 100644 android-sdk-annotations/android/drm/annotations.xml create mode 100644 android-sdk-annotations/android/gesture/annotations.xml create mode 100644 android-sdk-annotations/android/graphics/annotations.xml create mode 100644 android-sdk-annotations/android/graphics/drawable/annotations.xml create mode 100644 android-sdk-annotations/android/hardware/annotations.xml create mode 100644 android-sdk-annotations/android/hardware/display/annotations.xml create mode 100644 android-sdk-annotations/android/hardware/input/annotations.xml create mode 100644 android-sdk-annotations/android/hardware/usb/annotations.xml create mode 100644 android-sdk-annotations/android/inputmethodservice/annotations.xml create mode 100644 android-sdk-annotations/android/location/annotations.xml create mode 100644 android-sdk-annotations/android/media/annotations.xml create mode 100644 android-sdk-annotations/android/media/audiofx/annotations.xml create mode 100644 android-sdk-annotations/android/media/effect/annotations.xml create mode 100644 android-sdk-annotations/android/net/annotations.xml create mode 100644 android-sdk-annotations/android/net/http/annotations.xml create mode 100644 android-sdk-annotations/android/net/nsd/annotations.xml create mode 100644 android-sdk-annotations/android/net/sip/annotations.xml create mode 100644 android-sdk-annotations/android/net/wifi/annotations.xml create mode 100644 android-sdk-annotations/android/net/wifi/p2p/annotations.xml create mode 100644 android-sdk-annotations/android/net/wifi/p2p/nsd/annotations.xml create mode 100644 android-sdk-annotations/android/nfc/annotations.xml create mode 100644 android-sdk-annotations/android/nfc/tech/annotations.xml create mode 100644 android-sdk-annotations/android/opengl/annotations.xml create mode 100644 android-sdk-annotations/android/os/annotations.xml create mode 100644 android-sdk-annotations/android/preference/annotations.xml create mode 100644 android-sdk-annotations/android/provider/annotations.xml create mode 100644 android-sdk-annotations/android/renderscript/annotations.xml create mode 100644 android-sdk-annotations/android/security/annotations.xml create mode 100644 android-sdk-annotations/android/service/dreams/annotations.xml create mode 100644 android-sdk-annotations/android/service/textservice/annotations.xml create mode 100644 android-sdk-annotations/android/service/wallpaper/annotations.xml create mode 100644 android-sdk-annotations/android/speech/annotations.xml create mode 100644 android-sdk-annotations/android/speech/tts/annotations.xml create mode 100644 android-sdk-annotations/android/telephony/annotations.xml create mode 100644 android-sdk-annotations/android/telephony/gsm/annotations.xml create mode 100644 android-sdk-annotations/android/test/annotations.xml create mode 100644 android-sdk-annotations/android/test/mock/annotations.xml create mode 100644 android-sdk-annotations/android/text/annotations.xml create mode 100644 android-sdk-annotations/android/text/format/annotations.xml create mode 100644 android-sdk-annotations/android/text/method/annotations.xml create mode 100644 android-sdk-annotations/android/text/style/annotations.xml create mode 100644 android-sdk-annotations/android/text/util/annotations.xml create mode 100644 android-sdk-annotations/android/util/annotations.xml create mode 100644 android-sdk-annotations/android/view/accessibility/annotations.xml create mode 100644 android-sdk-annotations/android/view/animation/annotations.xml create mode 100644 android-sdk-annotations/android/view/annotations.xml create mode 100644 android-sdk-annotations/android/view/inputmethod/annotations.xml create mode 100644 android-sdk-annotations/android/view/textservice/annotations.xml create mode 100644 android-sdk-annotations/android/webkit/annotations.xml create mode 100644 android-sdk-annotations/android/widget/annotations.xml diff --git a/android-sdk-annotations/android/accessibilityservice/annotations.xml b/android-sdk-annotations/android/accessibilityservice/annotations.xml new file mode 100644 index 00000000000..9b98b61de2f --- /dev/null +++ b/android-sdk-annotations/android/accessibilityservice/annotations.xml @@ -0,0 +1,23 @@ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/android-sdk-annotations/android/accounts/annotations.xml b/android-sdk-annotations/android/accounts/annotations.xml new file mode 100644 index 00000000000..9cf8d0b8363 --- /dev/null +++ b/android-sdk-annotations/android/accounts/annotations.xml @@ -0,0 +1,122 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/android-sdk-annotations/android/animation/annotations.xml b/android-sdk-annotations/android/animation/annotations.xml new file mode 100644 index 00000000000..75b0c657d7c --- /dev/null +++ b/android-sdk-annotations/android/animation/annotations.xml @@ -0,0 +1,245 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/android-sdk-annotations/android/annotations.xml b/android-sdk-annotations/android/annotations.xml new file mode 100644 index 00000000000..dcfa0be771d --- /dev/null +++ b/android-sdk-annotations/android/annotations.xml @@ -0,0 +1,482 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/android-sdk-annotations/android/app/admin/annotations.xml b/android-sdk-annotations/android/app/admin/annotations.xml new file mode 100644 index 00000000000..7bd01b15c7c --- /dev/null +++ b/android-sdk-annotations/android/app/admin/annotations.xml @@ -0,0 +1,71 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/android-sdk-annotations/android/app/annotations.xml b/android-sdk-annotations/android/app/annotations.xml new file mode 100644 index 00000000000..3ee7d0ed7a1 --- /dev/null +++ b/android-sdk-annotations/android/app/annotations.xml @@ -0,0 +1,1382 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/android-sdk-annotations/android/app/backup/annotations.xml b/android-sdk-annotations/android/app/backup/annotations.xml new file mode 100644 index 00000000000..d865378ddc1 --- /dev/null +++ b/android-sdk-annotations/android/app/backup/annotations.xml @@ -0,0 +1,56 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/android-sdk-annotations/android/appwidget/annotations.xml b/android-sdk-annotations/android/appwidget/annotations.xml new file mode 100644 index 00000000000..20c35c2d587 --- /dev/null +++ b/android-sdk-annotations/android/appwidget/annotations.xml @@ -0,0 +1,122 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/android-sdk-annotations/android/bluetooth/annotations.xml b/android-sdk-annotations/android/bluetooth/annotations.xml new file mode 100644 index 00000000000..5ababfffabd --- /dev/null +++ b/android-sdk-annotations/android/bluetooth/annotations.xml @@ -0,0 +1,155 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/android-sdk-annotations/android/content/annotations.xml b/android-sdk-annotations/android/content/annotations.xml new file mode 100644 index 00000000000..05fb4a96d92 --- /dev/null +++ b/android-sdk-annotations/android/content/annotations.xml @@ -0,0 +1,1508 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/android-sdk-annotations/android/content/pm/annotations.xml b/android-sdk-annotations/android/content/pm/annotations.xml new file mode 100644 index 00000000000..b459da13da2 --- /dev/null +++ b/android-sdk-annotations/android/content/pm/annotations.xml @@ -0,0 +1,338 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/android-sdk-annotations/android/content/res/annotations.xml b/android-sdk-annotations/android/content/res/annotations.xml new file mode 100644 index 00000000000..829e62db0f5 --- /dev/null +++ b/android-sdk-annotations/android/content/res/annotations.xml @@ -0,0 +1,134 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/android-sdk-annotations/android/database/annotations.xml b/android-sdk-annotations/android/database/annotations.xml new file mode 100644 index 00000000000..64acee34fa1 --- /dev/null +++ b/android-sdk-annotations/android/database/annotations.xml @@ -0,0 +1,320 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/android-sdk-annotations/android/database/sqlite/annotations.xml b/android-sdk-annotations/android/database/sqlite/annotations.xml new file mode 100644 index 00000000000..474be512e5c --- /dev/null +++ b/android-sdk-annotations/android/database/sqlite/annotations.xml @@ -0,0 +1,104 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/android-sdk-annotations/android/drm/annotations.xml b/android-sdk-annotations/android/drm/annotations.xml new file mode 100644 index 00000000000..6b2edc40397 --- /dev/null +++ b/android-sdk-annotations/android/drm/annotations.xml @@ -0,0 +1,32 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/android-sdk-annotations/android/gesture/annotations.xml b/android-sdk-annotations/android/gesture/annotations.xml new file mode 100644 index 00000000000..4a8e94217e9 --- /dev/null +++ b/android-sdk-annotations/android/gesture/annotations.xml @@ -0,0 +1,131 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/android-sdk-annotations/android/graphics/annotations.xml b/android-sdk-annotations/android/graphics/annotations.xml new file mode 100644 index 00000000000..02d45da29d9 --- /dev/null +++ b/android-sdk-annotations/android/graphics/annotations.xml @@ -0,0 +1,239 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/android-sdk-annotations/android/graphics/drawable/annotations.xml b/android-sdk-annotations/android/graphics/drawable/annotations.xml new file mode 100644 index 00000000000..02a2dfec34d --- /dev/null +++ b/android-sdk-annotations/android/graphics/drawable/annotations.xml @@ -0,0 +1,89 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/android-sdk-annotations/android/hardware/annotations.xml b/android-sdk-annotations/android/hardware/annotations.xml new file mode 100644 index 00000000000..164924d635d --- /dev/null +++ b/android-sdk-annotations/android/hardware/annotations.xml @@ -0,0 +1,239 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/android-sdk-annotations/android/hardware/display/annotations.xml b/android-sdk-annotations/android/hardware/display/annotations.xml new file mode 100644 index 00000000000..5c4ddc3a9a1 --- /dev/null +++ b/android-sdk-annotations/android/hardware/display/annotations.xml @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/android-sdk-annotations/android/hardware/input/annotations.xml b/android-sdk-annotations/android/hardware/input/annotations.xml new file mode 100644 index 00000000000..327463d9206 --- /dev/null +++ b/android-sdk-annotations/android/hardware/input/annotations.xml @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/android-sdk-annotations/android/hardware/usb/annotations.xml b/android-sdk-annotations/android/hardware/usb/annotations.xml new file mode 100644 index 00000000000..b6d00e5b249 --- /dev/null +++ b/android-sdk-annotations/android/hardware/usb/annotations.xml @@ -0,0 +1,71 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/android-sdk-annotations/android/inputmethodservice/annotations.xml b/android-sdk-annotations/android/inputmethodservice/annotations.xml new file mode 100644 index 00000000000..e2bad5b4fad --- /dev/null +++ b/android-sdk-annotations/android/inputmethodservice/annotations.xml @@ -0,0 +1,173 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/android-sdk-annotations/android/location/annotations.xml b/android-sdk-annotations/android/location/annotations.xml new file mode 100644 index 00000000000..5fe2d948d3a --- /dev/null +++ b/android-sdk-annotations/android/location/annotations.xml @@ -0,0 +1,35 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/android-sdk-annotations/android/media/annotations.xml b/android-sdk-annotations/android/media/annotations.xml new file mode 100644 index 00000000000..657e37bcdd6 --- /dev/null +++ b/android-sdk-annotations/android/media/annotations.xml @@ -0,0 +1,179 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/android-sdk-annotations/android/media/audiofx/annotations.xml b/android-sdk-annotations/android/media/audiofx/annotations.xml new file mode 100644 index 00000000000..b7eecd69e99 --- /dev/null +++ b/android-sdk-annotations/android/media/audiofx/annotations.xml @@ -0,0 +1,26 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/android-sdk-annotations/android/media/effect/annotations.xml b/android-sdk-annotations/android/media/effect/annotations.xml new file mode 100644 index 00000000000..bed3b6dcae7 --- /dev/null +++ b/android-sdk-annotations/android/media/effect/annotations.xml @@ -0,0 +1,83 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/android-sdk-annotations/android/net/annotations.xml b/android-sdk-annotations/android/net/annotations.xml new file mode 100644 index 00000000000..031101e8123 --- /dev/null +++ b/android-sdk-annotations/android/net/annotations.xml @@ -0,0 +1,320 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/android-sdk-annotations/android/net/http/annotations.xml b/android-sdk-annotations/android/net/http/annotations.xml new file mode 100644 index 00000000000..bb6827c1f0b --- /dev/null +++ b/android-sdk-annotations/android/net/http/annotations.xml @@ -0,0 +1,47 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/android-sdk-annotations/android/net/nsd/annotations.xml b/android-sdk-annotations/android/net/nsd/annotations.xml new file mode 100644 index 00000000000..853b32b5c83 --- /dev/null +++ b/android-sdk-annotations/android/net/nsd/annotations.xml @@ -0,0 +1,17 @@ + + + + + + + + + + + + + + + + + diff --git a/android-sdk-annotations/android/net/sip/annotations.xml b/android-sdk-annotations/android/net/sip/annotations.xml new file mode 100644 index 00000000000..b687fe84911 --- /dev/null +++ b/android-sdk-annotations/android/net/sip/annotations.xml @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/android-sdk-annotations/android/net/wifi/annotations.xml b/android-sdk-annotations/android/net/wifi/annotations.xml new file mode 100644 index 00000000000..ce007264d94 --- /dev/null +++ b/android-sdk-annotations/android/net/wifi/annotations.xml @@ -0,0 +1,125 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/android-sdk-annotations/android/net/wifi/p2p/annotations.xml b/android-sdk-annotations/android/net/wifi/p2p/annotations.xml new file mode 100644 index 00000000000..ba43eeebd8b --- /dev/null +++ b/android-sdk-annotations/android/net/wifi/p2p/annotations.xml @@ -0,0 +1,47 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/android-sdk-annotations/android/net/wifi/p2p/nsd/annotations.xml b/android-sdk-annotations/android/net/wifi/p2p/nsd/annotations.xml new file mode 100644 index 00000000000..c35eb7feaf0 --- /dev/null +++ b/android-sdk-annotations/android/net/wifi/p2p/nsd/annotations.xml @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/android-sdk-annotations/android/nfc/annotations.xml b/android-sdk-annotations/android/nfc/annotations.xml new file mode 100644 index 00000000000..a5c951e89a6 --- /dev/null +++ b/android-sdk-annotations/android/nfc/annotations.xml @@ -0,0 +1,56 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/android-sdk-annotations/android/nfc/tech/annotations.xml b/android-sdk-annotations/android/nfc/tech/annotations.xml new file mode 100644 index 00000000000..9575f22d273 --- /dev/null +++ b/android-sdk-annotations/android/nfc/tech/annotations.xml @@ -0,0 +1,56 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/android-sdk-annotations/android/opengl/annotations.xml b/android-sdk-annotations/android/opengl/annotations.xml new file mode 100644 index 00000000000..d68a5c67d84 --- /dev/null +++ b/android-sdk-annotations/android/opengl/annotations.xml @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/android-sdk-annotations/android/os/annotations.xml b/android-sdk-annotations/android/os/annotations.xml new file mode 100644 index 00000000000..243c9871f5d --- /dev/null +++ b/android-sdk-annotations/android/os/annotations.xml @@ -0,0 +1,548 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/android-sdk-annotations/android/preference/annotations.xml b/android-sdk-annotations/android/preference/annotations.xml new file mode 100644 index 00000000000..0a76aa87d07 --- /dev/null +++ b/android-sdk-annotations/android/preference/annotations.xml @@ -0,0 +1,344 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/android-sdk-annotations/android/provider/annotations.xml b/android-sdk-annotations/android/provider/annotations.xml new file mode 100644 index 00000000000..1265fc81ab3 --- /dev/null +++ b/android-sdk-annotations/android/provider/annotations.xml @@ -0,0 +1,3611 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/android-sdk-annotations/android/renderscript/annotations.xml b/android-sdk-annotations/android/renderscript/annotations.xml new file mode 100644 index 00000000000..ffa6a355cd7 --- /dev/null +++ b/android-sdk-annotations/android/renderscript/annotations.xml @@ -0,0 +1,320 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/android-sdk-annotations/android/security/annotations.xml b/android-sdk-annotations/android/security/annotations.xml new file mode 100644 index 00000000000..af2e35ec98d --- /dev/null +++ b/android-sdk-annotations/android/security/annotations.xml @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + diff --git a/android-sdk-annotations/android/service/dreams/annotations.xml b/android-sdk-annotations/android/service/dreams/annotations.xml new file mode 100644 index 00000000000..2c05d018f33 --- /dev/null +++ b/android-sdk-annotations/android/service/dreams/annotations.xml @@ -0,0 +1,35 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/android-sdk-annotations/android/service/textservice/annotations.xml b/android-sdk-annotations/android/service/textservice/annotations.xml new file mode 100644 index 00000000000..76d6ad5468e --- /dev/null +++ b/android-sdk-annotations/android/service/textservice/annotations.xml @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + diff --git a/android-sdk-annotations/android/service/wallpaper/annotations.xml b/android-sdk-annotations/android/service/wallpaper/annotations.xml new file mode 100644 index 00000000000..b78b5b2e27a --- /dev/null +++ b/android-sdk-annotations/android/service/wallpaper/annotations.xml @@ -0,0 +1,23 @@ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/android-sdk-annotations/android/speech/annotations.xml b/android-sdk-annotations/android/speech/annotations.xml new file mode 100644 index 00000000000..5baff6bbc92 --- /dev/null +++ b/android-sdk-annotations/android/speech/annotations.xml @@ -0,0 +1,131 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/android-sdk-annotations/android/speech/tts/annotations.xml b/android-sdk-annotations/android/speech/tts/annotations.xml new file mode 100644 index 00000000000..0fbaa39db1f --- /dev/null +++ b/android-sdk-annotations/android/speech/tts/annotations.xml @@ -0,0 +1,77 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/android-sdk-annotations/android/telephony/annotations.xml b/android-sdk-annotations/android/telephony/annotations.xml new file mode 100644 index 00000000000..f688c5ef93f --- /dev/null +++ b/android-sdk-annotations/android/telephony/annotations.xml @@ -0,0 +1,68 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/android-sdk-annotations/android/telephony/gsm/annotations.xml b/android-sdk-annotations/android/telephony/gsm/annotations.xml new file mode 100644 index 00000000000..a912ed620f0 --- /dev/null +++ b/android-sdk-annotations/android/telephony/gsm/annotations.xml @@ -0,0 +1,17 @@ + + + + + + + + + + + + + + + + + diff --git a/android-sdk-annotations/android/test/annotations.xml b/android-sdk-annotations/android/test/annotations.xml new file mode 100644 index 00000000000..ca807da0e7a --- /dev/null +++ b/android-sdk-annotations/android/test/annotations.xml @@ -0,0 +1,53 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/android-sdk-annotations/android/test/mock/annotations.xml b/android-sdk-annotations/android/test/mock/annotations.xml new file mode 100644 index 00000000000..24c0ebe5cb2 --- /dev/null +++ b/android-sdk-annotations/android/test/mock/annotations.xml @@ -0,0 +1,77 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/android-sdk-annotations/android/text/annotations.xml b/android-sdk-annotations/android/text/annotations.xml new file mode 100644 index 00000000000..143df089083 --- /dev/null +++ b/android-sdk-annotations/android/text/annotations.xml @@ -0,0 +1,593 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/android-sdk-annotations/android/text/format/annotations.xml b/android-sdk-annotations/android/text/format/annotations.xml new file mode 100644 index 00000000000..80535397756 --- /dev/null +++ b/android-sdk-annotations/android/text/format/annotations.xml @@ -0,0 +1,104 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/android-sdk-annotations/android/text/method/annotations.xml b/android-sdk-annotations/android/text/method/annotations.xml new file mode 100644 index 00000000000..1e07ec158ba --- /dev/null +++ b/android-sdk-annotations/android/text/method/annotations.xml @@ -0,0 +1,515 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/android-sdk-annotations/android/text/style/annotations.xml b/android-sdk-annotations/android/text/style/annotations.xml new file mode 100644 index 00000000000..d84d506a830 --- /dev/null +++ b/android-sdk-annotations/android/text/style/annotations.xml @@ -0,0 +1,341 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/android-sdk-annotations/android/text/util/annotations.xml b/android-sdk-annotations/android/text/util/annotations.xml new file mode 100644 index 00000000000..a96fb684377 --- /dev/null +++ b/android-sdk-annotations/android/text/util/annotations.xml @@ -0,0 +1,74 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/android-sdk-annotations/android/util/annotations.xml b/android-sdk-annotations/android/util/annotations.xml new file mode 100644 index 00000000000..6e4ff52fdc1 --- /dev/null +++ b/android-sdk-annotations/android/util/annotations.xml @@ -0,0 +1,230 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/android-sdk-annotations/android/view/accessibility/annotations.xml b/android-sdk-annotations/android/view/accessibility/annotations.xml new file mode 100644 index 00000000000..cd1e6c65cf9 --- /dev/null +++ b/android-sdk-annotations/android/view/accessibility/annotations.xml @@ -0,0 +1,71 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/android-sdk-annotations/android/view/animation/annotations.xml b/android-sdk-annotations/android/view/animation/annotations.xml new file mode 100644 index 00000000000..47888488fd3 --- /dev/null +++ b/android-sdk-annotations/android/view/animation/annotations.xml @@ -0,0 +1,116 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/android-sdk-annotations/android/view/annotations.xml b/android-sdk-annotations/android/view/annotations.xml new file mode 100644 index 00000000000..2c577d91e44 --- /dev/null +++ b/android-sdk-annotations/android/view/annotations.xml @@ -0,0 +1,974 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/android-sdk-annotations/android/view/inputmethod/annotations.xml b/android-sdk-annotations/android/view/inputmethod/annotations.xml new file mode 100644 index 00000000000..53609ab7c39 --- /dev/null +++ b/android-sdk-annotations/android/view/inputmethod/annotations.xml @@ -0,0 +1,98 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/android-sdk-annotations/android/view/textservice/annotations.xml b/android-sdk-annotations/android/view/textservice/annotations.xml new file mode 100644 index 00000000000..a4608991a52 --- /dev/null +++ b/android-sdk-annotations/android/view/textservice/annotations.xml @@ -0,0 +1,41 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/android-sdk-annotations/android/webkit/annotations.xml b/android-sdk-annotations/android/webkit/annotations.xml new file mode 100644 index 00000000000..184bb9d508a --- /dev/null +++ b/android-sdk-annotations/android/webkit/annotations.xml @@ -0,0 +1,194 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/android-sdk-annotations/android/widget/annotations.xml b/android-sdk-annotations/android/widget/annotations.xml new file mode 100644 index 00000000000..cecb0d554c8 --- /dev/null +++ b/android-sdk-annotations/android/widget/annotations.xml @@ -0,0 +1,1838 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/build.xml b/build.xml index 90421ff0b54..2e02f85ee9a 100644 --- a/build.xml +++ b/build.xml @@ -441,20 +441,38 @@ - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -541,11 +559,11 @@ + depends="clean,init,prepareDist,compileGenerators,invokeGenerators,preloader,compiler,compilerSources,antTools,jdkAnnotations,androidSdkAnnotations,annotationsExt,runtime,jslib,j2kConverter"/> + depends="clean,init,prepareDist,preloader,compiler_quick,antTools,jdkAnnotations,androidSdkAnnotations,annotationsExt,runtime,jslib,j2kConverter"/> getKey() { return KEY; } + + private static boolean isAndroidSdk(@NotNull Sdk sdk) { + return sdk.getSdkType().getName().equals("Android SDK"); + } } diff --git a/idea/src/org/jetbrains/jet/plugin/versions/KotlinRuntimeLibraryUtil.java b/idea/src/org/jetbrains/jet/plugin/versions/KotlinRuntimeLibraryUtil.java index 074a4d04938..9dc4016221b 100644 --- a/idea/src/org/jetbrains/jet/plugin/versions/KotlinRuntimeLibraryUtil.java +++ b/idea/src/org/jetbrains/jet/plugin/versions/KotlinRuntimeLibraryUtil.java @@ -88,13 +88,20 @@ public class KotlinRuntimeLibraryUtil { } public static void addJdkAnnotations(@NotNull Module module) { + addAnnotations(module, PathUtil.getKotlinPathsForIdeaPlugin().getJdkAnnotationsPath()); + } + + public static void addAndroidSdkAnnotations(@NotNull Module module) { + addAnnotations(module, PathUtil.getKotlinPathsForIdeaPlugin().getAndroidSdkAnnotationsPath()); + } + + private static void addAnnotations(@NotNull Module module, @NotNull File annotationsPath) { Sdk sdk = ModuleRootManager.getInstance(module).getSdk(); if (sdk == null) { return; } - File annotationsIoFile = PathUtil.getKotlinPathsForIdeaPlugin().getJdkAnnotationsPath(); - if (annotationsIoFile.exists()) { - VirtualFile jdkAnnotationsJar = LocalFileSystem.getInstance().findFileByIoFile(annotationsIoFile); + if (annotationsPath.exists()) { + VirtualFile jdkAnnotationsJar = LocalFileSystem.getInstance().findFileByIoFile(annotationsPath); if (jdkAnnotationsJar != null) { SdkModificator modificator = sdk.getSdkModificator(); modificator.addRoot(JarFileSystem.getInstance().getJarRootForLocalFile(jdkAnnotationsJar), @@ -105,13 +112,21 @@ public class KotlinRuntimeLibraryUtil { } public static boolean jdkAnnotationsArePresent(@NotNull Module module) { + return areAnnotationsPresent(module, PathUtil.JDK_ANNOTATIONS_JAR); + } + + public static boolean androidSdkAnnotationsArePresent(@NotNull Module module) { + return areAnnotationsPresent(module, PathUtil.ANDROID_SDK_ANNOTATIONS_JAR); + } + + private static boolean areAnnotationsPresent(@NotNull Module module, @NotNull final String jarFileName) { Sdk sdk = ModuleRootManager.getInstance(module).getSdk(); if (sdk == null) return false; return ContainerUtil.exists(sdk.getRootProvider().getFiles(AnnotationOrderRootType.getInstance()), new Condition() { @Override public boolean value(VirtualFile file) { - return PathUtil.JDK_ANNOTATIONS_JAR.equals(file.getName()); + return jarFileName.equals(file.getName()); } }); } From d9860876f5cb9d85c76f039f7457dbed21545558 Mon Sep 17 00:00:00 2001 From: "Natalia.Ukhorskaya" Date: Thu, 6 Jun 2013 19:28:59 +0400 Subject: [PATCH 226/249] Remove redundant clearDir in build.xml --- build.xml | 2 -- 1 file changed, 2 deletions(-) diff --git a/build.xml b/build.xml index 2e02f85ee9a..a0ea4b8d843 100644 --- a/build.xml +++ b/build.xml @@ -439,8 +439,6 @@ - - From 857ba92996d1ec704af11304a62385d46abd75d9 Mon Sep 17 00:00:00 2001 From: Alexey Sedunov Date: Thu, 6 Jun 2013 15:33:56 +0400 Subject: [PATCH 227/249] Remove unjustified annotations --- jdk-annotations/java/security/annotations.xml | 6 -- jdk-annotations/java/util/annotations.xml | 66 ------------------- jdk-annotations/javax/swing/annotations.xml | 6 -- 3 files changed, 78 deletions(-) diff --git a/jdk-annotations/java/security/annotations.xml b/jdk-annotations/java/security/annotations.xml index c49555d6008..e40e6678d93 100644 --- a/jdk-annotations/java/security/annotations.xml +++ b/jdk-annotations/java/security/annotations.xml @@ -348,12 +348,6 @@ - - - - - - diff --git a/jdk-annotations/java/util/annotations.xml b/jdk-annotations/java/util/annotations.xml index 1138f99e005..b80ae57f71d 100644 --- a/jdk-annotations/java/util/annotations.xml +++ b/jdk-annotations/java/util/annotations.xml @@ -115,12 +115,6 @@ - - - - - - @@ -153,18 +147,12 @@ - - - - - - @@ -1976,12 +1964,6 @@ - - - - - - @@ -2000,18 +1982,9 @@ - - - - - - - - - @@ -2172,12 +2145,6 @@ - - - - - - @@ -2223,12 +2190,6 @@ - - - - - - @@ -2256,12 +2217,6 @@ - - - - - - @@ -2781,12 +2736,6 @@ - - - - - - @@ -2825,9 +2774,6 @@ - - - @@ -3488,12 +3434,6 @@ - - - - - - @@ -3650,12 +3590,6 @@ - - - - - - diff --git a/jdk-annotations/javax/swing/annotations.xml b/jdk-annotations/javax/swing/annotations.xml index 092e9be6dd2..7119120364c 100644 --- a/jdk-annotations/javax/swing/annotations.xml +++ b/jdk-annotations/javax/swing/annotations.xml @@ -3264,12 +3264,6 @@ - - - - - - From 70b4fb48bc9cbd01dcc3bdfa63bf189063b9ac87 Mon Sep 17 00:00:00 2001 From: Alexey Sedunov Date: Fri, 7 Jun 2013 15:40:12 +0400 Subject: [PATCH 228/249] Add file parameter to Transformer --- .../AbstractCodeTransformationIntention.java | 3 ++- .../branchedTransformations/FoldableKind.java | 11 ++++++----- .../branchedTransformations/UnfoldableKind.java | 9 +++++---- .../branchedTransformations/core/Transformer.java | 3 ++- .../intentions/EliminateWhenSubjectIntention.java | 3 ++- .../intentions/FlattenWhenIntention.java | 3 ++- .../intentions/IfToWhenIntention.java | 3 ++- .../intentions/IntroduceWhenSubjectIntention.java | 3 ++- .../intentions/WhenToIfIntention.java | 3 ++- 9 files changed, 25 insertions(+), 16 deletions(-) diff --git a/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/AbstractCodeTransformationIntention.java b/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/AbstractCodeTransformationIntention.java index f30ceb3a156..4358b53dc57 100644 --- a/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/AbstractCodeTransformationIntention.java +++ b/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/AbstractCodeTransformationIntention.java @@ -26,6 +26,7 @@ import com.intellij.util.IncorrectOperationException; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.jet.lang.psi.JetElement; +import org.jetbrains.jet.lang.psi.JetFile; import org.jetbrains.jet.lang.psi.JetPsiUtil; import org.jetbrains.jet.plugin.JetBundle; import org.jetbrains.jet.plugin.codeInsight.codeTransformations.branchedTransformations.core.Transformer; @@ -63,6 +64,6 @@ public abstract class AbstractCodeTransformationIntention assert target != null : "Intention is not applicable"; - transformer.transform(target, editor); + transformer.transform(target, editor, (JetFile) file); } } diff --git a/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/FoldableKind.java b/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/FoldableKind.java index e8503d216c0..4f1cfabb32a 100644 --- a/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/FoldableKind.java +++ b/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/FoldableKind.java @@ -19,6 +19,7 @@ package org.jetbrains.jet.plugin.codeInsight.codeTransformations.branchedTransfo import com.intellij.openapi.editor.Editor; import com.intellij.psi.PsiElement; import org.jetbrains.annotations.NotNull; +import org.jetbrains.jet.lang.psi.JetFile; import org.jetbrains.jet.lang.psi.JetIfExpression; import org.jetbrains.jet.lang.psi.JetWhenExpression; import org.jetbrains.jet.plugin.codeInsight.codeTransformations.branchedTransformations.core.Transformer; @@ -26,31 +27,31 @@ import org.jetbrains.jet.plugin.codeInsight.codeTransformations.branchedTransfor public enum FoldableKind implements Transformer { IF_TO_ASSIGNMENT("fold.if.to.assignment") { @Override - public void transform(@NotNull PsiElement element, @NotNull Editor editor) { + public void transform(@NotNull PsiElement element, @NotNull Editor editor, @NotNull JetFile file) { BranchedFoldingUtils.foldIfExpressionWithAssignments((JetIfExpression) element); } }, IF_TO_RETURN("fold.if.to.return") { @Override - public void transform(@NotNull PsiElement element, @NotNull Editor editor) { + public void transform(@NotNull PsiElement element, @NotNull Editor editor, @NotNull JetFile file) { BranchedFoldingUtils.foldIfExpressionWithReturns((JetIfExpression) element); } }, IF_TO_RETURN_ASYMMETRICALLY("fold.if.to.return") { @Override - public void transform(@NotNull PsiElement element, @NotNull Editor editor) { + public void transform(@NotNull PsiElement element, @NotNull Editor editor, @NotNull JetFile file) { BranchedFoldingUtils.foldIfExpressionWithAsymmetricReturns((JetIfExpression) element); } }, WHEN_TO_ASSIGNMENT("fold.when.to.assignment") { @Override - public void transform(@NotNull PsiElement element, @NotNull Editor editor) { + public void transform(@NotNull PsiElement element, @NotNull Editor editor, @NotNull JetFile file) { BranchedFoldingUtils.foldWhenExpressionWithAssignments((JetWhenExpression) element); } }, WHEN_TO_RETURN("fold.when.to.return") { @Override - public void transform(@NotNull PsiElement element, @NotNull Editor editor) { + public void transform(@NotNull PsiElement element, @NotNull Editor editor, @NotNull JetFile file) { BranchedFoldingUtils.foldWhenExpressionWithReturns((JetWhenExpression) element); } }; diff --git a/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/UnfoldableKind.java b/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/UnfoldableKind.java index 07bf3f3134f..86ed5e5b5e6 100644 --- a/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/UnfoldableKind.java +++ b/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/UnfoldableKind.java @@ -20,31 +20,32 @@ import com.intellij.openapi.editor.Editor; import com.intellij.psi.PsiElement; import org.jetbrains.annotations.NotNull; import org.jetbrains.jet.lang.psi.JetBinaryExpression; +import org.jetbrains.jet.lang.psi.JetFile; import org.jetbrains.jet.lang.psi.JetReturnExpression; import org.jetbrains.jet.plugin.codeInsight.codeTransformations.branchedTransformations.core.Transformer; public enum UnfoldableKind implements Transformer { ASSIGNMENT_TO_IF("unfold.assignment.to.if") { @Override - public void transform(@NotNull PsiElement element, @NotNull Editor editor) { + public void transform(@NotNull PsiElement element, @NotNull Editor editor, JetFile file) { BranchedUnfoldingUtils.unfoldAssignmentToIf((JetBinaryExpression) element, editor); } }, RETURN_TO_IF("unfold.return.to.if") { @Override - public void transform(@NotNull PsiElement element, @NotNull Editor editor) { + public void transform(@NotNull PsiElement element, @NotNull Editor editor, JetFile file) { BranchedUnfoldingUtils.unfoldReturnToIf((JetReturnExpression) element); } }, ASSIGNMENT_TO_WHEN("unfold.assignment.to.when") { @Override - public void transform(@NotNull PsiElement element, @NotNull Editor editor) { + public void transform(@NotNull PsiElement element, @NotNull Editor editor, JetFile file) { BranchedUnfoldingUtils.unfoldAssignmentToWhen((JetBinaryExpression) element, editor); } }, RETURN_TO_WHEN("unfold.return.to.when") { @Override - public void transform(@NotNull PsiElement element, @NotNull Editor editor) { + public void transform(@NotNull PsiElement element, @NotNull Editor editor, JetFile file) { BranchedUnfoldingUtils.unfoldReturnToWhen((JetReturnExpression) element); } }; diff --git a/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/core/Transformer.java b/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/core/Transformer.java index 82f5154f2aa..956ee756b1a 100644 --- a/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/core/Transformer.java +++ b/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/core/Transformer.java @@ -19,9 +19,10 @@ package org.jetbrains.jet.plugin.codeInsight.codeTransformations.branchedTransfo import com.intellij.openapi.editor.Editor; import com.intellij.psi.PsiElement; import org.jetbrains.annotations.NotNull; +import org.jetbrains.jet.lang.psi.JetFile; public interface Transformer { @NotNull String getKey(); - void transform(@NotNull PsiElement element, @NotNull Editor editor); + void transform(@NotNull PsiElement element, @NotNull Editor editor, @NotNull JetFile file); } diff --git a/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/intentions/EliminateWhenSubjectIntention.java b/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/intentions/EliminateWhenSubjectIntention.java index 225a36b770a..9c2dd1c00af 100644 --- a/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/intentions/EliminateWhenSubjectIntention.java +++ b/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/intentions/EliminateWhenSubjectIntention.java @@ -5,6 +5,7 @@ import com.intellij.openapi.editor.Editor; import com.intellij.psi.PsiElement; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import org.jetbrains.jet.lang.psi.JetFile; import org.jetbrains.jet.lang.psi.JetWhenExpression; import org.jetbrains.jet.plugin.codeInsight.codeTransformations.branchedTransformations.AbstractCodeTransformationIntention; import org.jetbrains.jet.plugin.codeInsight.codeTransformations.branchedTransformations.WhenUtils; @@ -19,7 +20,7 @@ public class EliminateWhenSubjectIntention extends AbstractCodeTransformationInt } @Override - public void transform(@NotNull PsiElement element, @NotNull Editor editor) { + public void transform(@NotNull PsiElement element, @NotNull Editor editor, @NotNull JetFile file) { WhenUtils.eliminateWhenSubject((JetWhenExpression) element); } }; diff --git a/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/intentions/FlattenWhenIntention.java b/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/intentions/FlattenWhenIntention.java index 6cc9dc00320..bd2a4ac55e7 100644 --- a/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/intentions/FlattenWhenIntention.java +++ b/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/intentions/FlattenWhenIntention.java @@ -5,6 +5,7 @@ import com.intellij.openapi.editor.Editor; import com.intellij.psi.PsiElement; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; +import org.jetbrains.jet.lang.psi.JetFile; import org.jetbrains.jet.lang.psi.JetWhenExpression; import org.jetbrains.jet.plugin.codeInsight.codeTransformations.branchedTransformations.AbstractCodeTransformationIntention; import org.jetbrains.jet.plugin.codeInsight.codeTransformations.branchedTransformations.WhenUtils; @@ -19,7 +20,7 @@ public class FlattenWhenIntention extends AbstractCodeTransformationIntention Date: Fri, 7 Jun 2013 15:43:58 +0400 Subject: [PATCH 229/249] Add code transformations for if/when in local property initializers --- .../jetbrains/jet/lang/psi/JetPsiUtil.java | 5 + .../jet/generators/tests/GenerateTests.java | 2 + .../after.kt.template | 6 + .../before.kt.template | 5 + .../description.html | 5 + .../after.kt.template | 6 + .../before.kt.template | 5 + .../description.html | 5 + idea/src/META-INF/plugin.xml | 10 ++ .../jetbrains/jet/plugin/JetBundle.properties | 4 + .../BranchedUnfoldingUtils.java | 124 ++++++++++++++++-- .../UnfoldableKind.java | 13 ++ .../UnfoldBranchedExpressionIntention.java | 12 ++ .../unfolding/propertyToIf/nestedIfs.kt | 19 +++ .../unfolding/propertyToIf/nestedIfs.kt.after | 20 +++ .../unfolding/propertyToIf/nestedIfs2.kt | 19 +++ .../propertyToIf/nestedIfs2.kt.after | 20 +++ .../propertyToIf/nonLocalProperty.kt | 2 + .../propertyToIf/nonLocalProperty2.kt | 2 + .../unfolding/propertyToIf/simpleIf.kt | 5 + .../unfolding/propertyToIf/simpleIf.kt.after | 6 + .../unfolding/propertyToIf/simpleIf2.kt | 5 + .../unfolding/propertyToIf/simpleIf2.kt.after | 6 + .../propertyToIf/simpleIfWithBlocks.kt | 11 ++ .../propertyToIf/simpleIfWithBlocks.kt.after | 12 ++ .../propertyToIf/simpleIfWithBlocks2.kt | 11 ++ .../propertyToIf/simpleIfWithBlocks2.kt.after | 12 ++ .../propertyToIf/simpleIfWithType.kt | 5 + .../propertyToIf/simpleIfWithType.kt.after | 6 + .../propertyToWhen/nonLocalProperty.kt | 8 ++ .../propertyToWhen/nonLocalProperty2.kt | 8 ++ .../unfolding/propertyToWhen/simpleWhen.kt | 9 ++ .../propertyToWhen/simpleWhen.kt.after | 10 ++ .../unfolding/propertyToWhen/simpleWhen2.kt | 9 ++ .../propertyToWhen/simpleWhen2.kt.after | 10 ++ .../propertyToWhen/simpleWhenWithBlocks.kt | 14 ++ .../simpleWhenWithBlocks.kt.after | 15 +++ .../propertyToWhen/simpleWhenWithBlocks2.kt | 14 ++ .../simpleWhenWithBlocks2.kt.after | 15 +++ .../propertyToWhen/simpleWhenWithType.kt | 9 ++ .../simpleWhenWithType.kt.after | 10 ++ .../AbstractCodeTransformationTest.java | 8 ++ .../CodeTransformationsTestGenerated.java | 100 +++++++++++++- 43 files changed, 592 insertions(+), 10 deletions(-) create mode 100644 idea/resources/intentionDescriptions/UnfoldBranchedExpressionIntentionUnfoldPropertyToIfIntention/after.kt.template create mode 100644 idea/resources/intentionDescriptions/UnfoldBranchedExpressionIntentionUnfoldPropertyToIfIntention/before.kt.template create mode 100644 idea/resources/intentionDescriptions/UnfoldBranchedExpressionIntentionUnfoldPropertyToIfIntention/description.html create mode 100644 idea/resources/intentionDescriptions/UnfoldBranchedExpressionIntentionUnfoldPropertyToWhenIntention/after.kt.template create mode 100644 idea/resources/intentionDescriptions/UnfoldBranchedExpressionIntentionUnfoldPropertyToWhenIntention/before.kt.template create mode 100644 idea/resources/intentionDescriptions/UnfoldBranchedExpressionIntentionUnfoldPropertyToWhenIntention/description.html create mode 100644 idea/testData/codeInsight/codeTransformations/branched/unfolding/propertyToIf/nestedIfs.kt create mode 100644 idea/testData/codeInsight/codeTransformations/branched/unfolding/propertyToIf/nestedIfs.kt.after create mode 100644 idea/testData/codeInsight/codeTransformations/branched/unfolding/propertyToIf/nestedIfs2.kt create mode 100644 idea/testData/codeInsight/codeTransformations/branched/unfolding/propertyToIf/nestedIfs2.kt.after create mode 100644 idea/testData/codeInsight/codeTransformations/branched/unfolding/propertyToIf/nonLocalProperty.kt create mode 100644 idea/testData/codeInsight/codeTransformations/branched/unfolding/propertyToIf/nonLocalProperty2.kt create mode 100644 idea/testData/codeInsight/codeTransformations/branched/unfolding/propertyToIf/simpleIf.kt create mode 100644 idea/testData/codeInsight/codeTransformations/branched/unfolding/propertyToIf/simpleIf.kt.after create mode 100644 idea/testData/codeInsight/codeTransformations/branched/unfolding/propertyToIf/simpleIf2.kt create mode 100644 idea/testData/codeInsight/codeTransformations/branched/unfolding/propertyToIf/simpleIf2.kt.after create mode 100644 idea/testData/codeInsight/codeTransformations/branched/unfolding/propertyToIf/simpleIfWithBlocks.kt create mode 100644 idea/testData/codeInsight/codeTransformations/branched/unfolding/propertyToIf/simpleIfWithBlocks.kt.after create mode 100644 idea/testData/codeInsight/codeTransformations/branched/unfolding/propertyToIf/simpleIfWithBlocks2.kt create mode 100644 idea/testData/codeInsight/codeTransformations/branched/unfolding/propertyToIf/simpleIfWithBlocks2.kt.after create mode 100644 idea/testData/codeInsight/codeTransformations/branched/unfolding/propertyToIf/simpleIfWithType.kt create mode 100644 idea/testData/codeInsight/codeTransformations/branched/unfolding/propertyToIf/simpleIfWithType.kt.after create mode 100644 idea/testData/codeInsight/codeTransformations/branched/unfolding/propertyToWhen/nonLocalProperty.kt create mode 100644 idea/testData/codeInsight/codeTransformations/branched/unfolding/propertyToWhen/nonLocalProperty2.kt create mode 100644 idea/testData/codeInsight/codeTransformations/branched/unfolding/propertyToWhen/simpleWhen.kt create mode 100644 idea/testData/codeInsight/codeTransformations/branched/unfolding/propertyToWhen/simpleWhen.kt.after create mode 100644 idea/testData/codeInsight/codeTransformations/branched/unfolding/propertyToWhen/simpleWhen2.kt create mode 100644 idea/testData/codeInsight/codeTransformations/branched/unfolding/propertyToWhen/simpleWhen2.kt.after create mode 100644 idea/testData/codeInsight/codeTransformations/branched/unfolding/propertyToWhen/simpleWhenWithBlocks.kt create mode 100644 idea/testData/codeInsight/codeTransformations/branched/unfolding/propertyToWhen/simpleWhenWithBlocks.kt.after create mode 100644 idea/testData/codeInsight/codeTransformations/branched/unfolding/propertyToWhen/simpleWhenWithBlocks2.kt create mode 100644 idea/testData/codeInsight/codeTransformations/branched/unfolding/propertyToWhen/simpleWhenWithBlocks2.kt.after create mode 100644 idea/testData/codeInsight/codeTransformations/branched/unfolding/propertyToWhen/simpleWhenWithType.kt create mode 100644 idea/testData/codeInsight/codeTransformations/branched/unfolding/propertyToWhen/simpleWhenWithType.kt.after diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetPsiUtil.java b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetPsiUtil.java index 7f1f7e3093e..829fc43661d 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetPsiUtil.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetPsiUtil.java @@ -743,6 +743,11 @@ public class JetPsiUtil { return element != null ? element.getText() : ""; } + @Nullable + public static String getNullableText(@Nullable PsiElement element) { + return element != null ? element.getText() : null; + } + /** * CommentUtilCore.isComment fails if element inside comment. * diff --git a/generators/org/jetbrains/jet/generators/tests/GenerateTests.java b/generators/org/jetbrains/jet/generators/tests/GenerateTests.java index aa82e896ad7..15be16c3bc8 100644 --- a/generators/org/jetbrains/jet/generators/tests/GenerateTests.java +++ b/generators/org/jetbrains/jet/generators/tests/GenerateTests.java @@ -330,6 +330,8 @@ public class GenerateTests { testModel("idea/testData/codeInsight/codeTransformations/branched/folding/whenToReturn", "doTestFoldWhenToReturn"), testModel("idea/testData/codeInsight/codeTransformations/branched/unfolding/assignmentToIf", "doTestUnfoldAssignmentToIf"), testModel("idea/testData/codeInsight/codeTransformations/branched/unfolding/assignmentToWhen", "doTestUnfoldAssignmentToWhen"), + testModel("idea/testData/codeInsight/codeTransformations/branched/unfolding/propertyToIf", "doTestUnfoldPropertyToIf"), + testModel("idea/testData/codeInsight/codeTransformations/branched/unfolding/propertyToWhen", "doTestUnfoldPropertyToWhen"), testModel("idea/testData/codeInsight/codeTransformations/branched/unfolding/returnToIf", "doTestUnfoldReturnToIf"), testModel("idea/testData/codeInsight/codeTransformations/branched/unfolding/returnToWhen", "doTestUnfoldReturnToWhen"), testModel("idea/testData/codeInsight/codeTransformations/branched/ifWhen/ifToWhen", "doTestIfToWhen"), diff --git a/idea/resources/intentionDescriptions/UnfoldBranchedExpressionIntentionUnfoldPropertyToIfIntention/after.kt.template b/idea/resources/intentionDescriptions/UnfoldBranchedExpressionIntentionUnfoldPropertyToIfIntention/after.kt.template new file mode 100644 index 00000000000..34512084beb --- /dev/null +++ b/idea/resources/intentionDescriptions/UnfoldBranchedExpressionIntentionUnfoldPropertyToIfIntention/after.kt.template @@ -0,0 +1,6 @@ +val res: String +if (ok) { + res = "ok" +} else { + res = "failed" +} \ No newline at end of file diff --git a/idea/resources/intentionDescriptions/UnfoldBranchedExpressionIntentionUnfoldPropertyToIfIntention/before.kt.template b/idea/resources/intentionDescriptions/UnfoldBranchedExpressionIntentionUnfoldPropertyToIfIntention/before.kt.template new file mode 100644 index 00000000000..f2a32466d14 --- /dev/null +++ b/idea/resources/intentionDescriptions/UnfoldBranchedExpressionIntentionUnfoldPropertyToIfIntention/before.kt.template @@ -0,0 +1,5 @@ +val res = if (ok) { + "ok" +} else { + "failed" +} \ No newline at end of file diff --git a/idea/resources/intentionDescriptions/UnfoldBranchedExpressionIntentionUnfoldPropertyToIfIntention/description.html b/idea/resources/intentionDescriptions/UnfoldBranchedExpressionIntentionUnfoldPropertyToIfIntention/description.html new file mode 100644 index 00000000000..275b2797db0 --- /dev/null +++ b/idea/resources/intentionDescriptions/UnfoldBranchedExpressionIntentionUnfoldPropertyToIfIntention/description.html @@ -0,0 +1,5 @@ + + +This intention converts property with 'if' initializer to uninitialized property followed by 'if' expression where each branch is terminated with assignment + + \ No newline at end of file diff --git a/idea/resources/intentionDescriptions/UnfoldBranchedExpressionIntentionUnfoldPropertyToWhenIntention/after.kt.template b/idea/resources/intentionDescriptions/UnfoldBranchedExpressionIntentionUnfoldPropertyToWhenIntention/after.kt.template new file mode 100644 index 00000000000..996d8f0a33f --- /dev/null +++ b/idea/resources/intentionDescriptions/UnfoldBranchedExpressionIntentionUnfoldPropertyToWhenIntention/after.kt.template @@ -0,0 +1,6 @@ +val res: String +when (n) { + 1 -> res = "one" + 2 -> res = "two" + else -> res = "many" +} \ No newline at end of file diff --git a/idea/resources/intentionDescriptions/UnfoldBranchedExpressionIntentionUnfoldPropertyToWhenIntention/before.kt.template b/idea/resources/intentionDescriptions/UnfoldBranchedExpressionIntentionUnfoldPropertyToWhenIntention/before.kt.template new file mode 100644 index 00000000000..59545857270 --- /dev/null +++ b/idea/resources/intentionDescriptions/UnfoldBranchedExpressionIntentionUnfoldPropertyToWhenIntention/before.kt.template @@ -0,0 +1,5 @@ +val res = when (n) { + 1 -> "one" + 2 -> "two" + else -> "many" +} \ No newline at end of file diff --git a/idea/resources/intentionDescriptions/UnfoldBranchedExpressionIntentionUnfoldPropertyToWhenIntention/description.html b/idea/resources/intentionDescriptions/UnfoldBranchedExpressionIntentionUnfoldPropertyToWhenIntention/description.html new file mode 100644 index 00000000000..258d62e13d2 --- /dev/null +++ b/idea/resources/intentionDescriptions/UnfoldBranchedExpressionIntentionUnfoldPropertyToWhenIntention/description.html @@ -0,0 +1,5 @@ + + +This intention converts property with 'when' initializer to uninitialized property followed by 'when' expression where each branch is terminated with assignment + + \ No newline at end of file diff --git a/idea/src/META-INF/plugin.xml b/idea/src/META-INF/plugin.xml index 1148214b80e..02374c1d6e9 100644 --- a/idea/src/META-INF/plugin.xml +++ b/idea/src/META-INF/plugin.xml @@ -331,11 +331,21 @@ Kotlin + + org.jetbrains.jet.plugin.codeInsight.codeTransformations.branchedTransformations.intentions.UnfoldBranchedExpressionIntention$UnfoldPropertyToIfIntention + Kotlin + + org.jetbrains.jet.plugin.codeInsight.codeTransformations.branchedTransformations.intentions.UnfoldBranchedExpressionIntention$UnfoldAssignmentToWhenIntention Kotlin + + org.jetbrains.jet.plugin.codeInsight.codeTransformations.branchedTransformations.intentions.UnfoldBranchedExpressionIntention$UnfoldPropertyToWhenIntention + Kotlin + + org.jetbrains.jet.plugin.codeInsight.codeTransformations.branchedTransformations.intentions.UnfoldBranchedExpressionIntention$UnfoldReturnToIfIntention Kotlin diff --git a/idea/src/org/jetbrains/jet/plugin/JetBundle.properties b/idea/src/org/jetbrains/jet/plugin/JetBundle.properties index a68d3edbb91..53f164cac48 100644 --- a/idea/src/org/jetbrains/jet/plugin/JetBundle.properties +++ b/idea/src/org/jetbrains/jet/plugin/JetBundle.properties @@ -171,12 +171,16 @@ fold.when.to.call=Replace 'when' expression with method call fold.when.to.call.family=Replace 'when' Expression with Method Call unfold.assignment.to.if=Replace assignment with 'if' expression unfold.assignment.to.if.family=Replace Assignment with 'if' Expression +unfold.property.to.if=Replace property initializer with 'if' expression +unfold.property.to.if.family=Replace Property Initializer with 'if' Expression unfold.return.to.if=Replace return with 'if' expression unfold.return.to.if.family=Replace Return with 'if' Expression unfold.call.to.if=Replace method call with 'if' expression unfold.call.to.if.family=Replace Method Call with 'if' Expression unfold.assignment.to.when=Replace assignment with 'when' expression unfold.assignment.to.when.family=Replace Assignment with 'when' Expression +unfold.property.to.when=Replace property initializer with 'when' expression +unfold.property.to.when.family=Replace Property Initializer with 'when' Expression unfold.return.to.when=Replace return with 'when' expression unfold.return.to.when.family=Replace Return with 'when' Expression unfold.call.to.when=Replace method call with 'when' expression diff --git a/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/BranchedUnfoldingUtils.java b/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/BranchedUnfoldingUtils.java index 755ce457657..61ca1c961bf 100644 --- a/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/BranchedUnfoldingUtils.java +++ b/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/BranchedUnfoldingUtils.java @@ -22,6 +22,13 @@ import com.intellij.psi.PsiElement; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.jet.lang.psi.*; +import org.jetbrains.jet.lang.resolve.BindingContext; +import org.jetbrains.jet.lang.types.JetType; +import org.jetbrains.jet.plugin.codeInsight.ReferenceToClassesShortening; +import org.jetbrains.jet.plugin.project.AnalyzerFacadeWithCache; +import org.jetbrains.jet.renderer.DescriptorRenderer; + +import java.util.Collections; public class BranchedUnfoldingUtils { private BranchedUnfoldingUtils() { @@ -36,7 +43,7 @@ public class BranchedUnfoldingUtils { if (root == null) return null; if (JetPsiUtil.isAssignment(root)) { - JetBinaryExpression assignment = (JetBinaryExpression)root; + JetBinaryExpression assignment = (JetBinaryExpression) root; assertNotNull(assignment.getLeft()); @@ -45,29 +52,41 @@ public class BranchedUnfoldingUtils { if (rhs instanceof JetWhenExpression && JetPsiUtil.checkWhenExpressionHasSingleElse((JetWhenExpression) rhs)) { return UnfoldableKind.ASSIGNMENT_TO_WHEN; } - } else if (root instanceof JetReturnExpression) { - JetExpression resultExpr = ((JetReturnExpression)root).getReturnedExpression(); + } + else if (root instanceof JetReturnExpression) { + JetExpression resultExpr = ((JetReturnExpression) root).getReturnedExpression(); if (resultExpr instanceof JetIfExpression) return UnfoldableKind.RETURN_TO_IF; if (resultExpr instanceof JetWhenExpression && JetPsiUtil.checkWhenExpressionHasSingleElse((JetWhenExpression) resultExpr)) { return UnfoldableKind.RETURN_TO_WHEN; } } + else if (root instanceof JetProperty) { + JetProperty property = (JetProperty) root; + if (!property.isLocal()) return null; + + JetExpression initializer = property.getInitializer(); + + if (initializer instanceof JetIfExpression) return UnfoldableKind.PROPERTY_TO_IF; + if (initializer instanceof JetWhenExpression && JetPsiUtil.checkWhenExpressionHasSingleElse((JetWhenExpression) initializer)) { + return UnfoldableKind.PROPERTY_TO_WHEN; + } + } return null; } public static final String UNFOLD_WITHOUT_CHECK = "Expression must be checked before unfolding"; - private static void assertNotNull(JetExpression expression) { - assert expression != null : UNFOLD_WITHOUT_CHECK; + private static void assertNotNull(Object value) { + assert value != null : UNFOLD_WITHOUT_CHECK; } public static void unfoldAssignmentToIf(@NotNull JetBinaryExpression assignment, @NotNull Editor editor) { Project project = assignment.getProject(); String op = assignment.getOperationReference().getText(); JetExpression lhs = assignment.getLeft(); - JetIfExpression ifExpression = (JetIfExpression)assignment.getRight(); + JetIfExpression ifExpression = (JetIfExpression) assignment.getRight(); assertNotNull(ifExpression); @@ -93,7 +112,7 @@ public class BranchedUnfoldingUtils { Project project = assignment.getProject(); String op = assignment.getOperationReference().getText(); JetExpression lhs = assignment.getLeft(); - JetWhenExpression whenExpression = (JetWhenExpression)assignment.getRight(); + JetWhenExpression whenExpression = (JetWhenExpression) assignment.getRight(); assertNotNull(whenExpression); @@ -114,9 +133,96 @@ public class BranchedUnfoldingUtils { editor.getCaretModel().moveToOffset(resultElement.getTextOffset()); } + private static JetType getPropertyTypeIfNeeded(@NotNull JetProperty property, @NotNull JetFile file) { + if (property.getTypeRef() != null) return null; + return AnalyzerFacadeWithCache.analyzeFileWithCache(file).getBindingContext().get(BindingContext.EXPRESSION_TYPE, property.getInitializer()); + } + + protected interface PropertyUnfolder { + void processInitializer(@NotNull T newInitializer, @NotNull JetExpression propertyRef, @NotNull Project project); + } + + protected static final PropertyUnfolder IF_EXPRESSION_PROPERTY_UNFOLDER = new PropertyUnfolder() { + @Override + public void processInitializer( + @NotNull JetIfExpression newInitializer, @NotNull JetExpression propertyRef, @NotNull Project project + ) { + JetExpression thenExpr = getOutermostLastBlockElement(newInitializer.getThen()); + JetExpression elseExpr = getOutermostLastBlockElement(newInitializer.getElse()); + + assertNotNull(thenExpr); + assertNotNull(elseExpr); + + thenExpr.replace(JetPsiFactory.createBinaryExpression(project, propertyRef, "=", thenExpr)); + elseExpr.replace(JetPsiFactory.createBinaryExpression(project, propertyRef, "=", elseExpr)); + } + }; + + protected static final PropertyUnfolder WHEN_EXPRESSION_PROPERTY_UNFOLDER = new PropertyUnfolder() { + @Override + public void processInitializer( + @NotNull JetWhenExpression newInitializer, @NotNull JetExpression propertyRef, @NotNull Project project + ) { + for (JetWhenEntry entry : newInitializer.getEntries()) { + JetExpression currExpr = getOutermostLastBlockElement(entry.getExpression()); + + assertNotNull(currExpr); + + //noinspection ConstantConditions + currExpr.replace(JetPsiFactory.createBinaryExpression(project, propertyRef, "=", currExpr)); + } + } + }; + + private static void unfoldProperty( + @NotNull JetProperty property, @NotNull JetFile file, PropertyUnfolder unfolder + ) { + Project project = property.getProject(); + + PsiElement parent = property.getParent(); + assertNotNull(parent); + + //noinspection unchecked + T initializer = (T) property.getInitializer(); + assertNotNull(initializer); + + JetSimpleNameExpression propertyName = JetPsiFactory.createSimpleName(project, property.getName()); + + //noinspection ConstantConditions, unchecked + T newInitializer = (T) initializer.copy(); + + unfolder.processInitializer(newInitializer, propertyName, project); + + parent.addAfter(newInitializer, property); + parent.addAfter(JetPsiFactory.createNewLine(project), property); + + //noinspection ConstantConditions + JetType inferredType = getPropertyTypeIfNeeded(property, file); + + String typeStr = inferredType != null + ? DescriptorRenderer.TEXT.renderType(inferredType) + : JetPsiUtil.getNullableText(property.getTypeRef()); + + property = (JetProperty) property.replace( + JetPsiFactory.createProperty(project, property.getName(), typeStr, property.isVar()) + ); + + if (inferredType != null) { + ReferenceToClassesShortening.compactReferenceToClasses(Collections.singletonList(property.getTypeRef())); + } + } + + public static void unfoldPropertyToIf(@NotNull JetProperty property, @NotNull JetFile file) { + unfoldProperty(property, file, IF_EXPRESSION_PROPERTY_UNFOLDER); + } + + public static void unfoldPropertyToWhen(@NotNull JetProperty property, @NotNull JetFile file) { + unfoldProperty(property, file, WHEN_EXPRESSION_PROPERTY_UNFOLDER); + } + public static void unfoldReturnToIf(@NotNull JetReturnExpression returnExpression) { Project project = returnExpression.getProject(); - JetIfExpression ifExpression = (JetIfExpression)returnExpression.getReturnedExpression(); + JetIfExpression ifExpression = (JetIfExpression) returnExpression.getReturnedExpression(); assertNotNull(ifExpression); @@ -137,7 +243,7 @@ public class BranchedUnfoldingUtils { public static void unfoldReturnToWhen(@NotNull JetReturnExpression returnExpression) { Project project = returnExpression.getProject(); - JetWhenExpression whenExpression = (JetWhenExpression)returnExpression.getReturnedExpression(); + JetWhenExpression whenExpression = (JetWhenExpression) returnExpression.getReturnedExpression(); assertNotNull(whenExpression); diff --git a/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/UnfoldableKind.java b/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/UnfoldableKind.java index 86ed5e5b5e6..5a78db9b0d0 100644 --- a/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/UnfoldableKind.java +++ b/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/UnfoldableKind.java @@ -21,6 +21,7 @@ import com.intellij.psi.PsiElement; import org.jetbrains.annotations.NotNull; import org.jetbrains.jet.lang.psi.JetBinaryExpression; import org.jetbrains.jet.lang.psi.JetFile; +import org.jetbrains.jet.lang.psi.JetProperty; import org.jetbrains.jet.lang.psi.JetReturnExpression; import org.jetbrains.jet.plugin.codeInsight.codeTransformations.branchedTransformations.core.Transformer; @@ -31,6 +32,12 @@ public enum UnfoldableKind implements Transformer { BranchedUnfoldingUtils.unfoldAssignmentToIf((JetBinaryExpression) element, editor); } }, + PROPERTY_TO_IF("unfold.property.to.if") { + @Override + public void transform(@NotNull PsiElement element, @NotNull Editor editor, JetFile file) { + BranchedUnfoldingUtils.unfoldPropertyToIf((JetProperty) element, file); + } + }, RETURN_TO_IF("unfold.return.to.if") { @Override public void transform(@NotNull PsiElement element, @NotNull Editor editor, JetFile file) { @@ -43,6 +50,12 @@ public enum UnfoldableKind implements Transformer { BranchedUnfoldingUtils.unfoldAssignmentToWhen((JetBinaryExpression) element, editor); } }, + PROPERTY_TO_WHEN("unfold.property.to.when") { + @Override + public void transform(@NotNull PsiElement element, @NotNull Editor editor, JetFile file) { + BranchedUnfoldingUtils.unfoldPropertyToWhen((JetProperty) element, file); + } + }, RETURN_TO_WHEN("unfold.return.to.when") { @Override public void transform(@NotNull PsiElement element, @NotNull Editor editor, JetFile file) { diff --git a/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/intentions/UnfoldBranchedExpressionIntention.java b/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/intentions/UnfoldBranchedExpressionIntention.java index 40cf4066f8d..dae76bfdaf4 100644 --- a/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/intentions/UnfoldBranchedExpressionIntention.java +++ b/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/intentions/UnfoldBranchedExpressionIntention.java @@ -42,12 +42,24 @@ public abstract class UnfoldBranchedExpressionIntention extends AbstractCodeTran } } + public static class UnfoldPropertyToIfIntention extends UnfoldBranchedExpressionIntention { + public UnfoldPropertyToIfIntention() { + super(UnfoldableKind.PROPERTY_TO_IF); + } + } + public static class UnfoldAssignmentToWhenIntention extends UnfoldBranchedExpressionIntention { public UnfoldAssignmentToWhenIntention() { super(UnfoldableKind.ASSIGNMENT_TO_WHEN); } } + public static class UnfoldPropertyToWhenIntention extends UnfoldBranchedExpressionIntention { + public UnfoldPropertyToWhenIntention() { + super(UnfoldableKind.PROPERTY_TO_WHEN); + } + } + public static class UnfoldReturnToIfIntention extends UnfoldBranchedExpressionIntention { public UnfoldReturnToIfIntention() { super(UnfoldableKind.RETURN_TO_IF); diff --git a/idea/testData/codeInsight/codeTransformations/branched/unfolding/propertyToIf/nestedIfs.kt b/idea/testData/codeInsight/codeTransformations/branched/unfolding/propertyToIf/nestedIfs.kt new file mode 100644 index 00000000000..d66fa1da47d --- /dev/null +++ b/idea/testData/codeInsight/codeTransformations/branched/unfolding/propertyToIf/nestedIfs.kt @@ -0,0 +1,19 @@ +fun test(n: Int): String? { + val res = if (n == 1) { + if (3 > 2) { + println("***") + "one" + } else { + println("***") + "???" + } + } else if (n == 2) { + println("***") + null + } else { + println("***") + "too many" + } + + return res +} \ No newline at end of file diff --git a/idea/testData/codeInsight/codeTransformations/branched/unfolding/propertyToIf/nestedIfs.kt.after b/idea/testData/codeInsight/codeTransformations/branched/unfolding/propertyToIf/nestedIfs.kt.after new file mode 100644 index 00000000000..c0344100f46 --- /dev/null +++ b/idea/testData/codeInsight/codeTransformations/branched/unfolding/propertyToIf/nestedIfs.kt.after @@ -0,0 +1,20 @@ +fun test(n: Int): String? { + val res: String? + if (n == 1) { + res = if (3 > 2) { + println("***") + "one" + } else { + println("***") + "???" + } + } else res = if (n == 2) { + println("***") + null + } else { + println("***") + "too many" + } + + return res +} \ No newline at end of file diff --git a/idea/testData/codeInsight/codeTransformations/branched/unfolding/propertyToIf/nestedIfs2.kt b/idea/testData/codeInsight/codeTransformations/branched/unfolding/propertyToIf/nestedIfs2.kt new file mode 100644 index 00000000000..f395889d491 --- /dev/null +++ b/idea/testData/codeInsight/codeTransformations/branched/unfolding/propertyToIf/nestedIfs2.kt @@ -0,0 +1,19 @@ +fun test(n: Int): String? { + var res = if (n == 1) { + if (3 > 2) { + println("***") + "one" + } else { + println("***") + "???" + } + } else if (n == 2) { + println("***") + null + } else { + println("***") + "too many" + } + + return res +} \ No newline at end of file diff --git a/idea/testData/codeInsight/codeTransformations/branched/unfolding/propertyToIf/nestedIfs2.kt.after b/idea/testData/codeInsight/codeTransformations/branched/unfolding/propertyToIf/nestedIfs2.kt.after new file mode 100644 index 00000000000..f560c0b982b --- /dev/null +++ b/idea/testData/codeInsight/codeTransformations/branched/unfolding/propertyToIf/nestedIfs2.kt.after @@ -0,0 +1,20 @@ +fun test(n: Int): String? { + var res: String? + if (n == 1) { + res = if (3 > 2) { + println("***") + "one" + } else { + println("***") + "???" + } + } else res = if (n == 2) { + println("***") + null + } else { + println("***") + "too many" + } + + return res +} \ No newline at end of file diff --git a/idea/testData/codeInsight/codeTransformations/branched/unfolding/propertyToIf/nonLocalProperty.kt b/idea/testData/codeInsight/codeTransformations/branched/unfolding/propertyToIf/nonLocalProperty.kt new file mode 100644 index 00000000000..b35d6d646b5 --- /dev/null +++ b/idea/testData/codeInsight/codeTransformations/branched/unfolding/propertyToIf/nonLocalProperty.kt @@ -0,0 +1,2 @@ +// IS_APPLICABLE: false +val x = if (false) "0" else "1" \ No newline at end of file diff --git a/idea/testData/codeInsight/codeTransformations/branched/unfolding/propertyToIf/nonLocalProperty2.kt b/idea/testData/codeInsight/codeTransformations/branched/unfolding/propertyToIf/nonLocalProperty2.kt new file mode 100644 index 00000000000..b737d711db2 --- /dev/null +++ b/idea/testData/codeInsight/codeTransformations/branched/unfolding/propertyToIf/nonLocalProperty2.kt @@ -0,0 +1,2 @@ +// IS_APPLICABLE: false +var x = if (false) "0" else "1" \ No newline at end of file diff --git a/idea/testData/codeInsight/codeTransformations/branched/unfolding/propertyToIf/simpleIf.kt b/idea/testData/codeInsight/codeTransformations/branched/unfolding/propertyToIf/simpleIf.kt new file mode 100644 index 00000000000..06caf0f8f29 --- /dev/null +++ b/idea/testData/codeInsight/codeTransformations/branched/unfolding/propertyToIf/simpleIf.kt @@ -0,0 +1,5 @@ +fun test(n: Int): String { + val res = if (n == 1) "one" else "two" + + return res +} \ No newline at end of file diff --git a/idea/testData/codeInsight/codeTransformations/branched/unfolding/propertyToIf/simpleIf.kt.after b/idea/testData/codeInsight/codeTransformations/branched/unfolding/propertyToIf/simpleIf.kt.after new file mode 100644 index 00000000000..7025c616a42 --- /dev/null +++ b/idea/testData/codeInsight/codeTransformations/branched/unfolding/propertyToIf/simpleIf.kt.after @@ -0,0 +1,6 @@ +fun test(n: Int): String { + val res: String + if (n == 1) res = "one" else res = "two" + + return res +} \ No newline at end of file diff --git a/idea/testData/codeInsight/codeTransformations/branched/unfolding/propertyToIf/simpleIf2.kt b/idea/testData/codeInsight/codeTransformations/branched/unfolding/propertyToIf/simpleIf2.kt new file mode 100644 index 00000000000..a93f206354c --- /dev/null +++ b/idea/testData/codeInsight/codeTransformations/branched/unfolding/propertyToIf/simpleIf2.kt @@ -0,0 +1,5 @@ +fun test(n: Int): String { + var res = if (n == 1) "one" else "two" + + return res +} \ No newline at end of file diff --git a/idea/testData/codeInsight/codeTransformations/branched/unfolding/propertyToIf/simpleIf2.kt.after b/idea/testData/codeInsight/codeTransformations/branched/unfolding/propertyToIf/simpleIf2.kt.after new file mode 100644 index 00000000000..7e2a0315bd6 --- /dev/null +++ b/idea/testData/codeInsight/codeTransformations/branched/unfolding/propertyToIf/simpleIf2.kt.after @@ -0,0 +1,6 @@ +fun test(n: Int): String { + var res: String + if (n == 1) res = "one" else res = "two" + + return res +} \ No newline at end of file diff --git a/idea/testData/codeInsight/codeTransformations/branched/unfolding/propertyToIf/simpleIfWithBlocks.kt b/idea/testData/codeInsight/codeTransformations/branched/unfolding/propertyToIf/simpleIfWithBlocks.kt new file mode 100644 index 00000000000..3bc95c25fd9 --- /dev/null +++ b/idea/testData/codeInsight/codeTransformations/branched/unfolding/propertyToIf/simpleIfWithBlocks.kt @@ -0,0 +1,11 @@ +fun test(n: Int): String { + val res = if (n == 1) { + println("***") + "one" + } else { + println("***") + "two" + } + + return res +} \ No newline at end of file diff --git a/idea/testData/codeInsight/codeTransformations/branched/unfolding/propertyToIf/simpleIfWithBlocks.kt.after b/idea/testData/codeInsight/codeTransformations/branched/unfolding/propertyToIf/simpleIfWithBlocks.kt.after new file mode 100644 index 00000000000..d1471a6142e --- /dev/null +++ b/idea/testData/codeInsight/codeTransformations/branched/unfolding/propertyToIf/simpleIfWithBlocks.kt.after @@ -0,0 +1,12 @@ +fun test(n: Int): String { + val res: String + if (n == 1) { + println("***") + res = "one" + } else { + println("***") + res = "two" + } + + return res +} \ No newline at end of file diff --git a/idea/testData/codeInsight/codeTransformations/branched/unfolding/propertyToIf/simpleIfWithBlocks2.kt b/idea/testData/codeInsight/codeTransformations/branched/unfolding/propertyToIf/simpleIfWithBlocks2.kt new file mode 100644 index 00000000000..acfe1239167 --- /dev/null +++ b/idea/testData/codeInsight/codeTransformations/branched/unfolding/propertyToIf/simpleIfWithBlocks2.kt @@ -0,0 +1,11 @@ +fun test(n: Int): String { + var res = if (n == 1) { + println("***") + "one" + } else { + println("***") + "two" + } + + return res +} \ No newline at end of file diff --git a/idea/testData/codeInsight/codeTransformations/branched/unfolding/propertyToIf/simpleIfWithBlocks2.kt.after b/idea/testData/codeInsight/codeTransformations/branched/unfolding/propertyToIf/simpleIfWithBlocks2.kt.after new file mode 100644 index 00000000000..c16a32371c6 --- /dev/null +++ b/idea/testData/codeInsight/codeTransformations/branched/unfolding/propertyToIf/simpleIfWithBlocks2.kt.after @@ -0,0 +1,12 @@ +fun test(n: Int): String { + var res: String + if (n == 1) { + println("***") + res = "one" + } else { + println("***") + res = "two" + } + + return res +} \ No newline at end of file diff --git a/idea/testData/codeInsight/codeTransformations/branched/unfolding/propertyToIf/simpleIfWithType.kt b/idea/testData/codeInsight/codeTransformations/branched/unfolding/propertyToIf/simpleIfWithType.kt new file mode 100644 index 00000000000..207ba54f08a --- /dev/null +++ b/idea/testData/codeInsight/codeTransformations/branched/unfolding/propertyToIf/simpleIfWithType.kt @@ -0,0 +1,5 @@ +fun test(n: Int): String { + val res: jet.String = if (n == 1) "one" else "two" + + return res +} \ No newline at end of file diff --git a/idea/testData/codeInsight/codeTransformations/branched/unfolding/propertyToIf/simpleIfWithType.kt.after b/idea/testData/codeInsight/codeTransformations/branched/unfolding/propertyToIf/simpleIfWithType.kt.after new file mode 100644 index 00000000000..3460d3bda79 --- /dev/null +++ b/idea/testData/codeInsight/codeTransformations/branched/unfolding/propertyToIf/simpleIfWithType.kt.after @@ -0,0 +1,6 @@ +fun test(n: Int): String { + val res: jet.String + if (n == 1) res = "one" else res = "two" + + return res +} \ No newline at end of file diff --git a/idea/testData/codeInsight/codeTransformations/branched/unfolding/propertyToWhen/nonLocalProperty.kt b/idea/testData/codeInsight/codeTransformations/branched/unfolding/propertyToWhen/nonLocalProperty.kt new file mode 100644 index 00000000000..a52943c29b9 --- /dev/null +++ b/idea/testData/codeInsight/codeTransformations/branched/unfolding/propertyToWhen/nonLocalProperty.kt @@ -0,0 +1,8 @@ +// IS_APPLICABLE: false +val n = 10 + +val res = when(n) { + 1 -> "one" + 2 -> "two" + else -> null +} \ No newline at end of file diff --git a/idea/testData/codeInsight/codeTransformations/branched/unfolding/propertyToWhen/nonLocalProperty2.kt b/idea/testData/codeInsight/codeTransformations/branched/unfolding/propertyToWhen/nonLocalProperty2.kt new file mode 100644 index 00000000000..52eaadb5516 --- /dev/null +++ b/idea/testData/codeInsight/codeTransformations/branched/unfolding/propertyToWhen/nonLocalProperty2.kt @@ -0,0 +1,8 @@ +// IS_APPLICABLE: false +val n = 10 + +var res = when(n) { + 1 -> "one" + 2 -> "two" + else -> null +} \ No newline at end of file diff --git a/idea/testData/codeInsight/codeTransformations/branched/unfolding/propertyToWhen/simpleWhen.kt b/idea/testData/codeInsight/codeTransformations/branched/unfolding/propertyToWhen/simpleWhen.kt new file mode 100644 index 00000000000..16796a9ac4a --- /dev/null +++ b/idea/testData/codeInsight/codeTransformations/branched/unfolding/propertyToWhen/simpleWhen.kt @@ -0,0 +1,9 @@ +fun test(n: Int): String? { + val res = when(n) { + 1 -> "one" + 2 -> "two" + else -> null + } + + return res +} \ No newline at end of file diff --git a/idea/testData/codeInsight/codeTransformations/branched/unfolding/propertyToWhen/simpleWhen.kt.after b/idea/testData/codeInsight/codeTransformations/branched/unfolding/propertyToWhen/simpleWhen.kt.after new file mode 100644 index 00000000000..d0be88b8b7f --- /dev/null +++ b/idea/testData/codeInsight/codeTransformations/branched/unfolding/propertyToWhen/simpleWhen.kt.after @@ -0,0 +1,10 @@ +fun test(n: Int): String? { + val res: String? + when(n) { + 1 -> res = "one" + 2 -> res = "two" + else -> res = null + } + + return res +} \ No newline at end of file diff --git a/idea/testData/codeInsight/codeTransformations/branched/unfolding/propertyToWhen/simpleWhen2.kt b/idea/testData/codeInsight/codeTransformations/branched/unfolding/propertyToWhen/simpleWhen2.kt new file mode 100644 index 00000000000..c4595f97b71 --- /dev/null +++ b/idea/testData/codeInsight/codeTransformations/branched/unfolding/propertyToWhen/simpleWhen2.kt @@ -0,0 +1,9 @@ +fun test(n: Int): String? { + var res = when(n) { + 1 -> "one" + 2 -> "two" + else -> null + } + + return res +} \ No newline at end of file diff --git a/idea/testData/codeInsight/codeTransformations/branched/unfolding/propertyToWhen/simpleWhen2.kt.after b/idea/testData/codeInsight/codeTransformations/branched/unfolding/propertyToWhen/simpleWhen2.kt.after new file mode 100644 index 00000000000..a0dd0c4c2c8 --- /dev/null +++ b/idea/testData/codeInsight/codeTransformations/branched/unfolding/propertyToWhen/simpleWhen2.kt.after @@ -0,0 +1,10 @@ +fun test(n: Int): String? { + var res: String? + when(n) { + 1 -> res = "one" + 2 -> res = "two" + else -> res = null + } + + return res +} \ No newline at end of file diff --git a/idea/testData/codeInsight/codeTransformations/branched/unfolding/propertyToWhen/simpleWhenWithBlocks.kt b/idea/testData/codeInsight/codeTransformations/branched/unfolding/propertyToWhen/simpleWhenWithBlocks.kt new file mode 100644 index 00000000000..f2f5f133833 --- /dev/null +++ b/idea/testData/codeInsight/codeTransformations/branched/unfolding/propertyToWhen/simpleWhenWithBlocks.kt @@ -0,0 +1,14 @@ +fun test(n: Int): String { + val res = when (n) { + 1 -> { + println("***") + "one" + } + else -> { + println("***") + "two" + } + } + + return res +} \ No newline at end of file diff --git a/idea/testData/codeInsight/codeTransformations/branched/unfolding/propertyToWhen/simpleWhenWithBlocks.kt.after b/idea/testData/codeInsight/codeTransformations/branched/unfolding/propertyToWhen/simpleWhenWithBlocks.kt.after new file mode 100644 index 00000000000..b900cde5fc2 --- /dev/null +++ b/idea/testData/codeInsight/codeTransformations/branched/unfolding/propertyToWhen/simpleWhenWithBlocks.kt.after @@ -0,0 +1,15 @@ +fun test(n: Int): String { + val res: String + when (n) { + 1 -> { + println("***") + res = "one" + } + else -> { + println("***") + res = "two" + } + } + + return res +} \ No newline at end of file diff --git a/idea/testData/codeInsight/codeTransformations/branched/unfolding/propertyToWhen/simpleWhenWithBlocks2.kt b/idea/testData/codeInsight/codeTransformations/branched/unfolding/propertyToWhen/simpleWhenWithBlocks2.kt new file mode 100644 index 00000000000..fad0c972531 --- /dev/null +++ b/idea/testData/codeInsight/codeTransformations/branched/unfolding/propertyToWhen/simpleWhenWithBlocks2.kt @@ -0,0 +1,14 @@ +fun test(n: Int): String { + var res = when (n) { + 1 -> { + println("***") + "one" + } + else -> { + println("***") + "two" + } + } + + return res +} \ No newline at end of file diff --git a/idea/testData/codeInsight/codeTransformations/branched/unfolding/propertyToWhen/simpleWhenWithBlocks2.kt.after b/idea/testData/codeInsight/codeTransformations/branched/unfolding/propertyToWhen/simpleWhenWithBlocks2.kt.after new file mode 100644 index 00000000000..4487e97042d --- /dev/null +++ b/idea/testData/codeInsight/codeTransformations/branched/unfolding/propertyToWhen/simpleWhenWithBlocks2.kt.after @@ -0,0 +1,15 @@ +fun test(n: Int): String { + var res: String + when (n) { + 1 -> { + println("***") + res = "one" + } + else -> { + println("***") + res = "two" + } + } + + return res +} \ No newline at end of file diff --git a/idea/testData/codeInsight/codeTransformations/branched/unfolding/propertyToWhen/simpleWhenWithType.kt b/idea/testData/codeInsight/codeTransformations/branched/unfolding/propertyToWhen/simpleWhenWithType.kt new file mode 100644 index 00000000000..81fc08d943f --- /dev/null +++ b/idea/testData/codeInsight/codeTransformations/branched/unfolding/propertyToWhen/simpleWhenWithType.kt @@ -0,0 +1,9 @@ +fun test(n: Int): String? { + val res: jet.String? = when(n) { + 1 -> "one" + 2 -> "two" + else -> null + } + + return res +} \ No newline at end of file diff --git a/idea/testData/codeInsight/codeTransformations/branched/unfolding/propertyToWhen/simpleWhenWithType.kt.after b/idea/testData/codeInsight/codeTransformations/branched/unfolding/propertyToWhen/simpleWhenWithType.kt.after new file mode 100644 index 00000000000..7bf0f8006d3 --- /dev/null +++ b/idea/testData/codeInsight/codeTransformations/branched/unfolding/propertyToWhen/simpleWhenWithType.kt.after @@ -0,0 +1,10 @@ +fun test(n: Int): String? { + val res: jet.String? + when(n) { + 1 -> res = "one" + 2 -> res = "two" + else -> res = null + } + + return res +} \ No newline at end of file diff --git a/idea/tests/org/jetbrains/jet/plugin/codeInsight/codeTransformations/AbstractCodeTransformationTest.java b/idea/tests/org/jetbrains/jet/plugin/codeInsight/codeTransformations/AbstractCodeTransformationTest.java index c0db705a380..918cfc7349c 100644 --- a/idea/tests/org/jetbrains/jet/plugin/codeInsight/codeTransformations/AbstractCodeTransformationTest.java +++ b/idea/tests/org/jetbrains/jet/plugin/codeInsight/codeTransformations/AbstractCodeTransformationTest.java @@ -54,6 +54,14 @@ public abstract class AbstractCodeTransformationTest extends LightCodeInsightTes doTest(path, new UnfoldBranchedExpressionIntention.UnfoldAssignmentToWhenIntention()); } + public void doTestUnfoldPropertyToIf(@NotNull String path) throws Exception { + doTest(path, new UnfoldBranchedExpressionIntention.UnfoldPropertyToIfIntention()); + } + + public void doTestUnfoldPropertyToWhen(@NotNull String path) throws Exception { + doTest(path, new UnfoldBranchedExpressionIntention.UnfoldPropertyToWhenIntention()); + } + public void doTestUnfoldReturnToIf(@NotNull String path) throws Exception { doTest(path, new UnfoldBranchedExpressionIntention.UnfoldReturnToIfIntention()); } diff --git a/idea/tests/org/jetbrains/jet/plugin/codeInsight/codeTransformations/CodeTransformationsTestGenerated.java b/idea/tests/org/jetbrains/jet/plugin/codeInsight/codeTransformations/CodeTransformationsTestGenerated.java index ab6c63001dd..e13ed3d5a4c 100644 --- a/idea/tests/org/jetbrains/jet/plugin/codeInsight/codeTransformations/CodeTransformationsTestGenerated.java +++ b/idea/tests/org/jetbrains/jet/plugin/codeInsight/codeTransformations/CodeTransformationsTestGenerated.java @@ -30,7 +30,7 @@ import org.jetbrains.jet.plugin.codeInsight.codeTransformations.AbstractCodeTran /** This class is generated by {@link org.jetbrains.jet.generators.tests.GenerateTests}. DO NOT MODIFY MANUALLY */ @SuppressWarnings("all") -@InnerTestClasses({CodeTransformationsTestGenerated.IfToAssignment.class, CodeTransformationsTestGenerated.IfToReturn.class, CodeTransformationsTestGenerated.IfToReturnAsymmetrically.class, CodeTransformationsTestGenerated.WhenToAssignment.class, CodeTransformationsTestGenerated.WhenToReturn.class, CodeTransformationsTestGenerated.AssignmentToIf.class, CodeTransformationsTestGenerated.AssignmentToWhen.class, CodeTransformationsTestGenerated.ReturnToIf.class, CodeTransformationsTestGenerated.ReturnToWhen.class, CodeTransformationsTestGenerated.IfToWhen.class, CodeTransformationsTestGenerated.WhenToIf.class, CodeTransformationsTestGenerated.Flatten.class, CodeTransformationsTestGenerated.IntroduceSubject.class, CodeTransformationsTestGenerated.EliminateSubject.class}) +@InnerTestClasses({CodeTransformationsTestGenerated.IfToAssignment.class, CodeTransformationsTestGenerated.IfToReturn.class, CodeTransformationsTestGenerated.IfToReturnAsymmetrically.class, CodeTransformationsTestGenerated.WhenToAssignment.class, CodeTransformationsTestGenerated.WhenToReturn.class, CodeTransformationsTestGenerated.AssignmentToIf.class, CodeTransformationsTestGenerated.AssignmentToWhen.class, CodeTransformationsTestGenerated.PropertyToIf.class, CodeTransformationsTestGenerated.PropertyToWhen.class, CodeTransformationsTestGenerated.ReturnToIf.class, CodeTransformationsTestGenerated.ReturnToWhen.class, CodeTransformationsTestGenerated.IfToWhen.class, CodeTransformationsTestGenerated.WhenToIf.class, CodeTransformationsTestGenerated.Flatten.class, CodeTransformationsTestGenerated.IntroduceSubject.class, CodeTransformationsTestGenerated.EliminateSubject.class}) public class CodeTransformationsTestGenerated extends AbstractCodeTransformationTest { @TestMetadata("idea/testData/codeInsight/codeTransformations/branched/folding/ifToAssignment") public static class IfToAssignment extends AbstractCodeTransformationTest { @@ -263,6 +263,102 @@ public class CodeTransformationsTestGenerated extends AbstractCodeTransformation } + @TestMetadata("idea/testData/codeInsight/codeTransformations/branched/unfolding/propertyToIf") + public static class PropertyToIf extends AbstractCodeTransformationTest { + public void testAllFilesPresentInPropertyToIf() throws Exception { + JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.GenerateTests", new File("idea/testData/codeInsight/codeTransformations/branched/unfolding/propertyToIf"), Pattern.compile("^(.+)\\.kt$"), true); + } + + @TestMetadata("nestedIfs.kt") + public void testNestedIfs() throws Exception { + doTestUnfoldPropertyToIf("idea/testData/codeInsight/codeTransformations/branched/unfolding/propertyToIf/nestedIfs.kt"); + } + + @TestMetadata("nestedIfs2.kt") + public void testNestedIfs2() throws Exception { + doTestUnfoldPropertyToIf("idea/testData/codeInsight/codeTransformations/branched/unfolding/propertyToIf/nestedIfs2.kt"); + } + + @TestMetadata("nonLocalProperty.kt") + public void testNonLocalProperty() throws Exception { + doTestUnfoldPropertyToIf("idea/testData/codeInsight/codeTransformations/branched/unfolding/propertyToIf/nonLocalProperty.kt"); + } + + @TestMetadata("nonLocalProperty2.kt") + public void testNonLocalProperty2() throws Exception { + doTestUnfoldPropertyToIf("idea/testData/codeInsight/codeTransformations/branched/unfolding/propertyToIf/nonLocalProperty2.kt"); + } + + @TestMetadata("simpleIf.kt") + public void testSimpleIf() throws Exception { + doTestUnfoldPropertyToIf("idea/testData/codeInsight/codeTransformations/branched/unfolding/propertyToIf/simpleIf.kt"); + } + + @TestMetadata("simpleIf2.kt") + public void testSimpleIf2() throws Exception { + doTestUnfoldPropertyToIf("idea/testData/codeInsight/codeTransformations/branched/unfolding/propertyToIf/simpleIf2.kt"); + } + + @TestMetadata("simpleIfWithBlocks.kt") + public void testSimpleIfWithBlocks() throws Exception { + doTestUnfoldPropertyToIf("idea/testData/codeInsight/codeTransformations/branched/unfolding/propertyToIf/simpleIfWithBlocks.kt"); + } + + @TestMetadata("simpleIfWithBlocks2.kt") + public void testSimpleIfWithBlocks2() throws Exception { + doTestUnfoldPropertyToIf("idea/testData/codeInsight/codeTransformations/branched/unfolding/propertyToIf/simpleIfWithBlocks2.kt"); + } + + @TestMetadata("simpleIfWithType.kt") + public void testSimpleIfWithType() throws Exception { + doTestUnfoldPropertyToIf("idea/testData/codeInsight/codeTransformations/branched/unfolding/propertyToIf/simpleIfWithType.kt"); + } + + } + + @TestMetadata("idea/testData/codeInsight/codeTransformations/branched/unfolding/propertyToWhen") + public static class PropertyToWhen extends AbstractCodeTransformationTest { + public void testAllFilesPresentInPropertyToWhen() throws Exception { + JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.GenerateTests", new File("idea/testData/codeInsight/codeTransformations/branched/unfolding/propertyToWhen"), Pattern.compile("^(.+)\\.kt$"), true); + } + + @TestMetadata("nonLocalProperty.kt") + public void testNonLocalProperty() throws Exception { + doTestUnfoldPropertyToWhen("idea/testData/codeInsight/codeTransformations/branched/unfolding/propertyToWhen/nonLocalProperty.kt"); + } + + @TestMetadata("nonLocalProperty2.kt") + public void testNonLocalProperty2() throws Exception { + doTestUnfoldPropertyToWhen("idea/testData/codeInsight/codeTransformations/branched/unfolding/propertyToWhen/nonLocalProperty2.kt"); + } + + @TestMetadata("simpleWhen.kt") + public void testSimpleWhen() throws Exception { + doTestUnfoldPropertyToWhen("idea/testData/codeInsight/codeTransformations/branched/unfolding/propertyToWhen/simpleWhen.kt"); + } + + @TestMetadata("simpleWhen2.kt") + public void testSimpleWhen2() throws Exception { + doTestUnfoldPropertyToWhen("idea/testData/codeInsight/codeTransformations/branched/unfolding/propertyToWhen/simpleWhen2.kt"); + } + + @TestMetadata("simpleWhenWithBlocks.kt") + public void testSimpleWhenWithBlocks() throws Exception { + doTestUnfoldPropertyToWhen("idea/testData/codeInsight/codeTransformations/branched/unfolding/propertyToWhen/simpleWhenWithBlocks.kt"); + } + + @TestMetadata("simpleWhenWithBlocks2.kt") + public void testSimpleWhenWithBlocks2() throws Exception { + doTestUnfoldPropertyToWhen("idea/testData/codeInsight/codeTransformations/branched/unfolding/propertyToWhen/simpleWhenWithBlocks2.kt"); + } + + @TestMetadata("simpleWhenWithType.kt") + public void testSimpleWhenWithType() throws Exception { + doTestUnfoldPropertyToWhen("idea/testData/codeInsight/codeTransformations/branched/unfolding/propertyToWhen/simpleWhenWithType.kt"); + } + + } + @TestMetadata("idea/testData/codeInsight/codeTransformations/branched/unfolding/returnToIf") public static class ReturnToIf extends AbstractCodeTransformationTest { public void testAllFilesPresentInReturnToIf() throws Exception { @@ -553,6 +649,8 @@ public class CodeTransformationsTestGenerated extends AbstractCodeTransformation suite.addTestSuite(WhenToReturn.class); suite.addTestSuite(AssignmentToIf.class); suite.addTestSuite(AssignmentToWhen.class); + suite.addTestSuite(PropertyToIf.class); + suite.addTestSuite(PropertyToWhen.class); suite.addTestSuite(ReturnToIf.class); suite.addTestSuite(ReturnToWhen.class); suite.addTestSuite(IfToWhen.class); From 3bd258ffa64c0026ff21cd3e8d851a8a7a4cb597 Mon Sep 17 00:00:00 2001 From: Nikolay Krasko Date: Wed, 22 May 2013 19:11:42 +0400 Subject: [PATCH 230/249] Refactoring: remove warnings --- .../tests/org/jetbrains/jet/JetTestCaseBuilder.java | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/compiler/tests/org/jetbrains/jet/JetTestCaseBuilder.java b/compiler/tests/org/jetbrains/jet/JetTestCaseBuilder.java index 4c2170204a8..545cb3deebb 100644 --- a/compiler/tests/org/jetbrains/jet/JetTestCaseBuilder.java +++ b/compiler/tests/org/jetbrains/jet/JetTestCaseBuilder.java @@ -38,7 +38,7 @@ public abstract class JetTestCaseBuilder { public static FilenameFilter filterByExtension(@NotNull final String... extensions) { return new FilenameFilter() { @Override - public boolean accept(File dir, String name) { + public boolean accept(@NotNull File dir, @NotNull String name) { for (String extension : extensions) { if (name.endsWith("." + extension)) return true; } @@ -52,7 +52,10 @@ public abstract class JetTestCaseBuilder { } public static String getHomeDirectory() { - return new File(PathManager.getResourceRoot(JetTestCaseBuilder.class, "/org/jetbrains/jet/JetTestCaseBuilder.class")).getParentFile().getParentFile().getParent(); + String resourceRoot = PathManager.getResourceRoot(JetTestCaseBuilder.class, "/org/jetbrains/jet/JetTestCaseBuilder.class"); + assert resourceRoot != null : "Failed to get root for class: " + JetTestCaseBuilder.class; + + return new File(resourceRoot).getParentFile().getParentFile().getParent(); } public interface NamedTestFactory { @NotNull Test createTest(@NotNull String dataPath, @NotNull String name, @NotNull File file); @@ -75,7 +78,7 @@ public abstract class JetTestCaseBuilder { public static FilenameFilter and(@NotNull final FilenameFilter a, @NotNull final FilenameFilter b) { return new FilenameFilter() { @Override - public boolean accept(File dir, String name) { + public boolean accept(@NotNull File dir, @NotNull String name) { return a.accept(dir, name) && b.accept(dir, name); } }; @@ -85,7 +88,7 @@ public abstract class JetTestCaseBuilder { File dir = new File(baseDataDir + dataPath); FileFilter dirFilter = new FileFilter() { @Override - public boolean accept(File pathname) { + public boolean accept(@NotNull File pathname) { return pathname.isDirectory(); } }; @@ -104,7 +107,6 @@ public abstract class JetTestCaseBuilder { List files = Arrays.asList(dir.listFiles(filter)); Collections.sort(files); for (File file : files) { - String fileName = file.getName(); String testName = FileUtil.getNameWithoutExtension(file); suite.addTest(factory.createTest(dataPath, testName, file)); } From a21f7dcf374556f043312a7699ca41f1b6edc2ae Mon Sep 17 00:00:00 2001 From: Nikolay Krasko Date: Mon, 3 Jun 2013 18:01:18 +0400 Subject: [PATCH 231/249] Fix warning --- .../src/org/jetbrains/jet/util/slicedmap/TrackingSlicedMap.java | 1 + 1 file changed, 1 insertion(+) diff --git a/compiler/frontend/src/org/jetbrains/jet/util/slicedmap/TrackingSlicedMap.java b/compiler/frontend/src/org/jetbrains/jet/util/slicedmap/TrackingSlicedMap.java index b8e0d5b3492..b2675f34abb 100644 --- a/compiler/frontend/src/org/jetbrains/jet/util/slicedmap/TrackingSlicedMap.java +++ b/compiler/frontend/src/org/jetbrains/jet/util/slicedmap/TrackingSlicedMap.java @@ -55,6 +55,7 @@ public class TrackingSlicedMap implements MutableSlicedMap { return delegate.getKeys(wrapSlice(slice)); } + @NotNull @Override public Iterator, ?>> iterator() { Map, Object> map = Maps.newHashMap(); From 9d71c372ceac6f0565374a9372ee6caaaa77085a Mon Sep 17 00:00:00 2001 From: Nikolay Krasko Date: Tue, 4 Jun 2013 14:13:14 +0400 Subject: [PATCH 232/249] Assert null pointer warning --- .../org/jetbrains/jet/lang/resolve/lazy/ScopeProvider.java | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/lazy/ScopeProvider.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/lazy/ScopeProvider.java index fe6ae1c0b80..318a347cc62 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/lazy/ScopeProvider.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/lazy/ScopeProvider.java @@ -149,7 +149,11 @@ public class ScopeProvider { return classDescriptor.getScopeForPropertyInitializerResolution(); } if (jetDeclaration instanceof JetEnumEntry) { - return ((LazyClassDescriptor) classDescriptor.getClassObjectDescriptor()).getScopeForMemberDeclarationResolution(); + LazyClassDescriptor descriptor = (LazyClassDescriptor) classDescriptor.getClassObjectDescriptor(); + assert descriptor != null : "There should be class object descriptor for enum class " + parentDeclaration.getText() + + " on entry " + jetDeclaration.getText(); + + return descriptor.getScopeForMemberDeclarationResolution(); } return classDescriptor.getScopeForMemberDeclarationResolution(); } From 4b50dbf01c1de172a1780fbe9efb1938085eebfb Mon Sep 17 00:00:00 2001 From: Nikolay Krasko Date: Tue, 4 Jun 2013 14:19:00 +0400 Subject: [PATCH 233/249] Better debug names for lazy scopes --- .../lazy/descriptors/LazyClassDescriptor.java | 32 ++++++++----------- 1 file changed, 14 insertions(+), 18 deletions(-) diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/lazy/descriptors/LazyClassDescriptor.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/lazy/descriptors/LazyClassDescriptor.java index f75541bfdcf..d0d4e108a57 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/lazy/descriptors/LazyClassDescriptor.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/lazy/descriptors/LazyClassDescriptor.java @@ -89,7 +89,6 @@ public class LazyClassDescriptor extends ClassDescriptorBase implements LazyDesc private final NotNullLazyValue scopeForMemberDeclarationResolution; private final NotNullLazyValue scopeForPropertyInitializerResolution; - public LazyClassDescriptor( @NotNull ResolveSession resolveSession, @NotNull DeclarationDescriptor containingDeclaration, @@ -108,6 +107,7 @@ public class LazyClassDescriptor extends ClassDescriptorBase implements LazyDesc classLikeInfo.getClassKind() != ClassKind.ENUM_CLASS ? classLikeInfo : noEnumEntries(classLikeInfo); this.declarationProvider = resolveSession.getDeclarationProviderFactory().getClassMemberDeclarationProvider(classLikeInfoForMembers); this.containingDeclaration = containingDeclaration; + this.unsubstitutedMemberScope = new LazyClassMemberScope(resolveSession, declarationProvider, this); this.unsubstitutedInnerClassesScope = new InnerClassesScopeWrapper(unsubstitutedMemberScope); @@ -182,18 +182,17 @@ public class LazyClassDescriptor extends ClassDescriptorBase implements LazyDesc @NotNull private JetScope computeScopeForClassHeaderResolution() { - WritableScopeImpl scope = new WritableScopeImpl( - JetScope.EMPTY, this, RedeclarationHandler.DO_NOTHING, "Class Header Resolution"); + WritableScopeImpl scope = new WritableScopeImpl(JetScope.EMPTY, this, RedeclarationHandler.DO_NOTHING, "Scope with type parameters for " + name); for (TypeParameterDescriptor typeParameterDescriptor : getTypeConstructor().getParameters()) { scope.addClassifierDescriptor(typeParameterDescriptor); } scope.changeLockLevel(WritableScope.LockLevel.READING); PsiElement scopeAnchor = declarationProvider.getOwnerInfo().getScopeAnchor(); - return new ChainedScope( - this, - "ScopeForClassHeaderResolution: " + getName(), - scope, getScopeProvider().getResolutionScopeForDeclaration(scopeAnchor)); + + return new ChainedScope(this, "ScopeForClassHeaderResolution: " + getName(), + scope, + getScopeProvider().getResolutionScopeForDeclaration(scopeAnchor)); } @NotNull @@ -203,15 +202,16 @@ public class LazyClassDescriptor extends ClassDescriptorBase implements LazyDesc @NotNull private JetScope computeScopeForMemberDeclarationResolution() { - WritableScopeImpl scope = new WritableScopeImpl( - JetScope.EMPTY, this, RedeclarationHandler.DO_NOTHING, "Member Declaration Resolution"); - scope.addLabeledDeclaration(this); - scope.changeLockLevel(WritableScope.LockLevel.READING); + WritableScopeImpl thisScope = new WritableScopeImpl(JetScope.EMPTY, this, RedeclarationHandler.DO_NOTHING, "Scope with 'this' for " + name); + thisScope.addLabeledDeclaration(this); + thisScope.changeLockLevel(WritableScope.LockLevel.READING); return new ChainedScope( this, "ScopeForMemberDeclarationResolution: " + getName(), - scope, getScopeForMemberLookup(), getScopeForClassHeaderResolution()); + thisScope, + getScopeForMemberLookup(), + getScopeForClassHeaderResolution()); } @NotNull @@ -224,14 +224,10 @@ public class LazyClassDescriptor extends ClassDescriptorBase implements LazyDesc ConstructorDescriptor primaryConstructor = getUnsubstitutedPrimaryConstructor(); if (primaryConstructor == null) return getScopeForMemberDeclarationResolution(); - WritableScopeImpl scope = new WritableScopeImpl( - JetScope.EMPTY, this, RedeclarationHandler.DO_NOTHING, "Property Initializer Resolution"); - - List parameters = primaryConstructor.getValueParameters(); - for (ValueParameterDescriptor valueParameterDescriptor : parameters) { + WritableScopeImpl scope = new WritableScopeImpl(JetScope.EMPTY, this, RedeclarationHandler.DO_NOTHING, "Scope with constructor parameters in " + name); + for (ValueParameterDescriptor valueParameterDescriptor : primaryConstructor.getValueParameters()) { scope.addVariableDescriptor(valueParameterDescriptor); } - scope.changeLockLevel(WritableScope.LockLevel.READING); return new ChainedScope( From a04ecb185ea41eeaebaa570a96db0754bd17aa7e Mon Sep 17 00:00:00 2001 From: Nikolay Krasko Date: Tue, 4 Jun 2013 15:03:57 +0400 Subject: [PATCH 234/249] Assert namespaces are found and remove null-pointer warning --- .../lazy/AbstractLazyResolveNamespaceComparingTest.java | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/compiler/tests/org/jetbrains/jet/lang/resolve/lazy/AbstractLazyResolveNamespaceComparingTest.java b/compiler/tests/org/jetbrains/jet/lang/resolve/lazy/AbstractLazyResolveNamespaceComparingTest.java index e749d412e7f..40f1d62812e 100644 --- a/compiler/tests/org/jetbrains/jet/lang/resolve/lazy/AbstractLazyResolveNamespaceComparingTest.java +++ b/compiler/tests/org/jetbrains/jet/lang/resolve/lazy/AbstractLazyResolveNamespaceComparingTest.java @@ -29,6 +29,7 @@ import org.jetbrains.jet.lang.resolve.name.FqName; import org.jetbrains.jet.lang.resolve.name.FqNameUnsafe; import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns; import org.jetbrains.jet.test.util.NamespaceComparator; +import org.junit.Assert; import java.io.File; import java.io.IOException; @@ -67,8 +68,12 @@ public abstract class AbstractLazyResolveNamespaceComparingTest extends KotlinTe ModuleDescriptor lazyModule = LazyResolveTestUtil.resolveLazily(files, getEnvironment()); FqName test = new FqName("test"); + NamespaceDescriptor actual = lazyModule.getNamespace(test); + Assert.assertNotNull("Namespace for name " + test + " is null after lazy resolve", actual); + NamespaceDescriptor expected = eagerModule.getNamespace(test); + Assert.assertNotNull("Namespace for name " + test + " is null after eager resolve", expected); File serializeResultsTo = new File(FileUtil.getNameWithoutExtension(testFileName) + ".txt"); From 37cd7eb1ba8f3c2ff0cdb81920be63ac5af255fa Mon Sep 17 00:00:00 2001 From: Nikolay Krasko Date: Tue, 4 Jun 2013 16:18:29 +0400 Subject: [PATCH 235/249] Allow resolve class declarations in class objects Use INACCESSIBLE_OUTER_CLASS_EXPRESSION error for marking already resolved elements #KT-3261 Fixed --- .../lang/resolve/TypeHierarchyResolver.java | 57 +++++-------------- .../jet/lang/resolve/lazy/ScopeProvider.java | 3 +- .../classes/classObjectsWithParentClasses.kt | 12 ++++ .../ClassObjectCannotAccessClassFields.kt | 2 +- .../innerConstructorFromClass.kt | 2 +- .../nestedConstructorFromClass.kt | 2 +- .../tests/inner/classesInClassObjectHeader.kt | 11 ++++ .../inner/innerClassesInStaticParameters.kt | 11 ++++ .../tests/inner/innerErrorForClassObjects.kt | 26 +++++++++ .../tests/inner/innerErrorForObjects.kt | 27 +++++++++ .../inner/resolvePackageClassInObjects.kt | 9 +++ .../inner/selfAnnotationForClassObject.kt | 9 +++ .../classObjectAnnotation.txt | 2 +- .../namespaceComparator/classObjectHeader.txt | 2 +- .../resolveFunctionInsideClassObject.kt | 9 +++ .../resolveFunctionInsideClassObject.txt | 11 ++++ .../classObject/InnerClassInClassObject.kt | 11 ++++ .../classObject/InnerClassInClassObject.txt | 19 +++++++ .../classObjectOuterResolve.resolve | 10 ++++ .../checkers/JetDiagnosticsTestGenerated.java | 30 ++++++++++ .../BlackBoxCodegenTestGenerated.java | 5 ++ .../LoadCompiledKotlinTestGenerated.java | 5 ++ ...esolveNamespaceComparingTestGenerated.java | 10 ++++ .../jet/resolve/JetResolveTestGenerated.java | 5 ++ 24 files changed, 239 insertions(+), 51 deletions(-) create mode 100644 compiler/testData/codegen/box/classes/classObjectsWithParentClasses.kt create mode 100644 compiler/testData/diagnostics/tests/inner/classesInClassObjectHeader.kt create mode 100644 compiler/testData/diagnostics/tests/inner/innerClassesInStaticParameters.kt create mode 100644 compiler/testData/diagnostics/tests/inner/innerErrorForClassObjects.kt create mode 100644 compiler/testData/diagnostics/tests/inner/innerErrorForObjects.kt create mode 100644 compiler/testData/diagnostics/tests/inner/resolvePackageClassInObjects.kt create mode 100644 compiler/testData/diagnostics/tests/inner/selfAnnotationForClassObject.kt create mode 100644 compiler/testData/lazyResolve/namespaceComparator/resolveFunctionInsideClassObject.kt create mode 100644 compiler/testData/lazyResolve/namespaceComparator/resolveFunctionInsideClassObject.txt create mode 100644 compiler/testData/loadKotlin/classObject/InnerClassInClassObject.kt create mode 100644 compiler/testData/loadKotlin/classObject/InnerClassInClassObject.txt create mode 100644 compiler/testData/resolve/candidatesPriority/classObjectOuterResolve.resolve diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/TypeHierarchyResolver.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/TypeHierarchyResolver.java index 4cf4a074da2..d8bac9bb6c9 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/TypeHierarchyResolver.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/TypeHierarchyResolver.java @@ -28,10 +28,7 @@ import org.jetbrains.jet.lang.descriptors.*; import org.jetbrains.jet.lang.descriptors.impl.*; import org.jetbrains.jet.lang.psi.*; import org.jetbrains.jet.lang.resolve.name.Name; -import org.jetbrains.jet.lang.resolve.scopes.JetScope; -import org.jetbrains.jet.lang.resolve.scopes.RedeclarationHandler; -import org.jetbrains.jet.lang.resolve.scopes.WritableScope; -import org.jetbrains.jet.lang.resolve.scopes.WriteThroughScope; +import org.jetbrains.jet.lang.resolve.scopes.*; import org.jetbrains.jet.lang.types.JetType; import org.jetbrains.jet.lang.types.SubstitutionUtils; import org.jetbrains.jet.lang.types.TypeConstructor; @@ -147,40 +144,6 @@ public class TypeHierarchyResolver { checkTypesInClassHeaders(); // Check bounds in the types used in generic bounds and supertype lists } - /** - * Use nearest class object scope or namespace scope - * - * @param declarationElement - * @param owner - * @return - */ - @SuppressWarnings("SuspiciousMethodCalls") - @NotNull - private JetScope getStaticScope(PsiElement declarationElement, @NotNull NamespaceLikeBuilder owner) { - DeclarationDescriptor ownerDescriptor = owner.getOwnerForChildren(); - if (ownerDescriptor instanceof NamespaceDescriptorImpl) { - return context.getNamespaceScopes().get(declarationElement.getContainingFile()); - } - - if (ownerDescriptor instanceof MutableClassDescriptor) { - MutableClassDescriptor classDescriptor = (MutableClassDescriptor) ownerDescriptor; - if (classDescriptor.getKind() == ClassKind.CLASS_OBJECT) { - return classDescriptor.getScopeForMemberResolution(); - } - - DeclarationDescriptor declaration = classDescriptor.getContainingDeclaration(); - if (declaration instanceof NamespaceDescriptorImpl) { - return getStaticScope(declarationElement, ((NamespaceDescriptorImpl) declaration).getBuilder()); - } - - if (declaration instanceof MutableClassDescriptorLite) { - return getStaticScope(declarationElement, ((MutableClassDescriptorLite) declaration).getBuilder()); - } - } - - return null; - } - @Nullable private Collection collectNamespacesAndClassifiers( @NotNull JetScope outerScope, @@ -517,7 +480,7 @@ public class TypeHierarchyResolver { MutableClassDescriptorLite classObjectDescriptor = ownerClassDescriptor.getClassObjectDescriptor(); assert classObjectDescriptor != null : enumEntry.getParent().getText(); - createClassDescriptorForEnumEntry(enumEntry, classObjectDescriptor.getBuilder()); + createClassDescriptorForEnumEntry(enumEntry, classObjectDescriptor); } @Override @@ -530,9 +493,11 @@ public class TypeHierarchyResolver { JetObjectDeclaration objectDeclaration = classObject.getObjectDeclaration(); if (objectDeclaration != null) { Name classObjectName = getClassObjectName(owner.getOwnerForChildren().getName()); - MutableClassDescriptor classObjectDescriptor = - createClassDescriptorForObject(objectDeclaration, owner, getStaticScope(classObject, owner), - classObjectName, ClassKind.CLASS_OBJECT); + + MutableClassDescriptor classObjectDescriptor = createClassDescriptorForObject( + objectDeclaration, owner, outerScope, + classObjectName, ClassKind.CLASS_OBJECT); + NamespaceLikeBuilder.ClassObjectStatus status = owner.setClassObjectDescriptor(classObjectDescriptor); switch (status) { case DUPLICATE: @@ -606,6 +571,7 @@ public class TypeHierarchyResolver { ) { MutableClassDescriptor mutableClassDescriptor = new MutableClassDescriptor( owner.getOwnerForChildren(), scope, kind, false, name); + context.getObjects().put(declaration, mutableClassDescriptor); JetScope classScope = mutableClassDescriptor.getScopeForMemberResolution(); @@ -619,10 +585,13 @@ public class TypeHierarchyResolver { private MutableClassDescriptor createClassDescriptorForEnumEntry( @NotNull JetEnumEntry declaration, - @NotNull NamespaceLikeBuilder owner + @NotNull MutableClassDescriptorLite classObjectDescriptor ) { + NamespaceLikeBuilder owner = classObjectDescriptor.getBuilder(); + MutableClassDescriptor mutableClassObjectDescriptor = (MutableClassDescriptor) classObjectDescriptor; + MutableClassDescriptor mutableClassDescriptor = new MutableClassDescriptor( - owner.getOwnerForChildren(), getStaticScope(declaration, owner), ClassKind.ENUM_ENTRY, + owner.getOwnerForChildren(), mutableClassObjectDescriptor.getScopeForMemberResolution(), ClassKind.ENUM_ENTRY, false, JetPsiUtil.safeName(declaration.getName())); context.getClasses().put(declaration, mutableClassDescriptor); diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/lazy/ScopeProvider.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/lazy/ScopeProvider.java index 318a347cc62..245e7c2bb95 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/lazy/ScopeProvider.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/lazy/ScopeProvider.java @@ -165,8 +165,7 @@ public class ScopeProvider { LazyClassDescriptor classObjectDescriptor = (LazyClassDescriptor) resolveSession.getClassObjectDescriptor(classObject).getContainingDeclaration(); - // During class object header resolve there should be no resolution for parent class generic params - return new InnerClassesScopeWrapper(classObjectDescriptor.getScopeForMemberDeclarationResolution()); + return classObjectDescriptor.getScopeForMemberDeclarationResolution(); } throw new IllegalStateException("Don't call this method for local declarations: " + jetDeclaration + " " + jetDeclaration.getText()); diff --git a/compiler/testData/codegen/box/classes/classObjectsWithParentClasses.kt b/compiler/testData/codegen/box/classes/classObjectsWithParentClasses.kt new file mode 100644 index 00000000000..c79a6babccf --- /dev/null +++ b/compiler/testData/codegen/box/classes/classObjectsWithParentClasses.kt @@ -0,0 +1,12 @@ +open class Test { + class object { + fun testStatic(ic: InnerClass): NotInnerClass = NotInnerClass(ic.value) + } + + fun test(): InnerClass = InnerClass(150) + + inner open class InnerClass(val value: Int) + open class NotInnerClass(val value: Int) +} + +fun box() = if (Test.testStatic(Test().test()).value == 150) "OK" else "FAIL" \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/ClassObjectCannotAccessClassFields.kt b/compiler/testData/diagnostics/tests/ClassObjectCannotAccessClassFields.kt index dc034c09650..49f50bbd546 100644 --- a/compiler/testData/diagnostics/tests/ClassObjectCannotAccessClassFields.kt +++ b/compiler/testData/diagnostics/tests/ClassObjectCannotAccessClassFields.kt @@ -4,6 +4,6 @@ class A() { val x = 1 class object { - val y = x + val y = x } } diff --git a/compiler/testData/diagnostics/tests/callableReference/innerConstructorFromClass.kt b/compiler/testData/diagnostics/tests/callableReference/innerConstructorFromClass.kt index 680ed70cb43..72a822aefa6 100644 --- a/compiler/testData/diagnostics/tests/callableReference/innerConstructorFromClass.kt +++ b/compiler/testData/diagnostics/tests/callableReference/innerConstructorFromClass.kt @@ -11,7 +11,7 @@ class A { class object { fun main() { - ::Inner + ::Inner val y = A::Inner y : KMemberFunction0 diff --git a/compiler/testData/diagnostics/tests/callableReference/nestedConstructorFromClass.kt b/compiler/testData/diagnostics/tests/callableReference/nestedConstructorFromClass.kt index 325393a0b2b..a51da3e20b5 100644 --- a/compiler/testData/diagnostics/tests/callableReference/nestedConstructorFromClass.kt +++ b/compiler/testData/diagnostics/tests/callableReference/nestedConstructorFromClass.kt @@ -11,7 +11,7 @@ class A { class object { fun main() { - ::Nested // KT-3261 + ::Nested val y = A::Nested y : KFunction0 diff --git a/compiler/testData/diagnostics/tests/inner/classesInClassObjectHeader.kt b/compiler/testData/diagnostics/tests/inner/classesInClassObjectHeader.kt new file mode 100644 index 00000000000..4426e63b9f8 --- /dev/null +++ b/compiler/testData/diagnostics/tests/inner/classesInClassObjectHeader.kt @@ -0,0 +1,11 @@ +class Test { + [`InnerAnnotation`InnerAnnotation] + class object : StaticClass(), InnerClass() { + + } + + annotation class InnerAnnotation + open class StaticClass + + open inner class InnerClass +} \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/inner/innerClassesInStaticParameters.kt b/compiler/testData/diagnostics/tests/inner/innerClassesInStaticParameters.kt new file mode 100644 index 00000000000..68798c8f33a --- /dev/null +++ b/compiler/testData/diagnostics/tests/inner/innerClassesInStaticParameters.kt @@ -0,0 +1,11 @@ +class Test { + class object { + fun test(t: TestInner) = 42 + } + + class TestStatic { + fun test(t: TestInner) = 42 + } + + inner class TestInner +} \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/inner/innerErrorForClassObjects.kt b/compiler/testData/diagnostics/tests/inner/innerErrorForClassObjects.kt new file mode 100644 index 00000000000..eac005ac624 --- /dev/null +++ b/compiler/testData/diagnostics/tests/inner/innerErrorForClassObjects.kt @@ -0,0 +1,26 @@ +open class SomeClass +class TestSome

{ + class object : SomeClass<P>() { + } +} + +class Test { + class object : InnerClass() { + val a = object: InnerClass() { + } + + fun more(): InnerClass { + val b = InnerClass() + + val testVal = inClass + foo() + + return b + } + } + + val inClass = 12 + fun foo() {} + + open inner class InnerClass +} \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/inner/innerErrorForObjects.kt b/compiler/testData/diagnostics/tests/inner/innerErrorForObjects.kt new file mode 100644 index 00000000000..95567aaf347 --- /dev/null +++ b/compiler/testData/diagnostics/tests/inner/innerErrorForObjects.kt @@ -0,0 +1,27 @@ +open class SomeClass +class TestSome

{ + object Some : SomeClass<P>() { + } +} + +class Test { + object Some : InnerClass() { + val a = object: InnerClass() { + } + + fun more(): InnerClass { + val b = InnerClass() + + val testVal = inClass + foo() + + return b + } + } + + val inClass = 12 + fun foo() { + } + + open inner class InnerClass +} \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/inner/resolvePackageClassInObjects.kt b/compiler/testData/diagnostics/tests/inner/resolvePackageClassInObjects.kt new file mode 100644 index 00000000000..d168e77b3dd --- /dev/null +++ b/compiler/testData/diagnostics/tests/inner/resolvePackageClassInObjects.kt @@ -0,0 +1,9 @@ +open class PackageTest + +class MoreTest() { + class object: PackageTest() { + + } + + object Some: PackageTest() +} \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/inner/selfAnnotationForClassObject.kt b/compiler/testData/diagnostics/tests/inner/selfAnnotationForClassObject.kt new file mode 100644 index 00000000000..668bf4eb8c8 --- /dev/null +++ b/compiler/testData/diagnostics/tests/inner/selfAnnotationForClassObject.kt @@ -0,0 +1,9 @@ +class Test { + [ClassObjectAnnotation] + [NestedAnnotation] + class object { + annotation class ClassObjectAnnotation + } + + annotation class NestedAnnotation +} \ No newline at end of file diff --git a/compiler/testData/lazyResolve/namespaceComparator/classObjectAnnotation.txt b/compiler/testData/lazyResolve/namespaceComparator/classObjectAnnotation.txt index 3d4931ae33e..ab574b211b5 100644 --- a/compiler/testData/lazyResolve/namespaceComparator/classObjectAnnotation.txt +++ b/compiler/testData/lazyResolve/namespaceComparator/classObjectAnnotation.txt @@ -3,7 +3,7 @@ package test internal final class Some { /*primary*/ public constructor Some() - [ERROR : Unresolved annotation type]() internal class object { + test.Some.TestAnnotation() internal class object { /*primary*/ private constructor () internal final annotation class TestAnnotation : jet.Annotation { diff --git a/compiler/testData/lazyResolve/namespaceComparator/classObjectHeader.txt b/compiler/testData/lazyResolve/namespaceComparator/classObjectHeader.txt index f65b6da44a1..2ca691d634e 100644 --- a/compiler/testData/lazyResolve/namespaceComparator/classObjectHeader.txt +++ b/compiler/testData/lazyResolve/namespaceComparator/classObjectHeader.txt @@ -5,7 +5,7 @@ internal fun testFun(/*0*/ a: jet.Int): jet.Int internal final class TestSome { /*primary*/ public constructor TestSome() - internal class object : test.ToResolve<[ERROR : P]> { + internal class object : test.ToResolve

{ /*primary*/ private constructor () } } diff --git a/compiler/testData/lazyResolve/namespaceComparator/resolveFunctionInsideClassObject.kt b/compiler/testData/lazyResolve/namespaceComparator/resolveFunctionInsideClassObject.kt new file mode 100644 index 00000000000..5040cae40d1 --- /dev/null +++ b/compiler/testData/lazyResolve/namespaceComparator/resolveFunctionInsideClassObject.kt @@ -0,0 +1,9 @@ +package test + +class Test { + fun test(): Int = 12 + + class object { + val a = test() // Check if resolver will be able to infer type of a variable + } +} \ No newline at end of file diff --git a/compiler/testData/lazyResolve/namespaceComparator/resolveFunctionInsideClassObject.txt b/compiler/testData/lazyResolve/namespaceComparator/resolveFunctionInsideClassObject.txt new file mode 100644 index 00000000000..84a88ca64f9 --- /dev/null +++ b/compiler/testData/lazyResolve/namespaceComparator/resolveFunctionInsideClassObject.txt @@ -0,0 +1,11 @@ +package test + +internal final class Test { + /*primary*/ public constructor Test() + internal final fun test(): jet.Int + + internal class object { + /*primary*/ private constructor () + internal final val a: jet.Int + } +} diff --git a/compiler/testData/loadKotlin/classObject/InnerClassInClassObject.kt b/compiler/testData/loadKotlin/classObject/InnerClassInClassObject.kt new file mode 100644 index 00000000000..d98b171f835 --- /dev/null +++ b/compiler/testData/loadKotlin/classObject/InnerClassInClassObject.kt @@ -0,0 +1,11 @@ +package test + +class TestFirst { + class object { + fun testing(a: InnerClass) = 45 + fun testing(a: NotInnerClass) = 45 + } + + inner class InnerClass + inner class NotInnerClass +} diff --git a/compiler/testData/loadKotlin/classObject/InnerClassInClassObject.txt b/compiler/testData/loadKotlin/classObject/InnerClassInClassObject.txt new file mode 100644 index 00000000000..ba01845e53e --- /dev/null +++ b/compiler/testData/loadKotlin/classObject/InnerClassInClassObject.txt @@ -0,0 +1,19 @@ +package test + +internal final class TestFirst { + /*primary*/ public constructor TestFirst() + + internal class object { + /*primary*/ private constructor () + internal final fun testing(/*0*/ a: test.TestFirst.InnerClass): jet.Int + internal final fun testing(/*0*/ a: test.TestFirst.NotInnerClass): jet.Int + } + + internal final inner class InnerClass { + /*primary*/ public constructor InnerClass() + } + + internal final inner class NotInnerClass { + /*primary*/ public constructor NotInnerClass() + } +} diff --git a/compiler/testData/resolve/candidatesPriority/classObjectOuterResolve.resolve b/compiler/testData/resolve/candidatesPriority/classObjectOuterResolve.resolve new file mode 100644 index 00000000000..7715cedc1e2 --- /dev/null +++ b/compiler/testData/resolve/candidatesPriority/classObjectOuterResolve.resolve @@ -0,0 +1,10 @@ +fun ~test~test() = 1 + +class Test { + class object { + fun call() = `test`test() + } + + fun test() = 2 +} + diff --git a/compiler/tests/org/jetbrains/jet/checkers/JetDiagnosticsTestGenerated.java b/compiler/tests/org/jetbrains/jet/checkers/JetDiagnosticsTestGenerated.java index 0d258ad49d2..c32e00daae0 100644 --- a/compiler/tests/org/jetbrains/jet/checkers/JetDiagnosticsTestGenerated.java +++ b/compiler/tests/org/jetbrains/jet/checkers/JetDiagnosticsTestGenerated.java @@ -3007,6 +3007,11 @@ public class JetDiagnosticsTestGenerated extends AbstractDiagnosticsTestWithEage JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.GenerateTests", new File("compiler/testData/diagnostics/tests/inner"), Pattern.compile("^(.+)\\.kt$"), true); } + @TestMetadata("classesInClassObjectHeader.kt") + public void testClassesInClassObjectHeader() throws Exception { + doTest("compiler/testData/diagnostics/tests/inner/classesInClassObjectHeader.kt"); + } + @TestMetadata("constructorAccess.kt") public void testConstructorAccess() throws Exception { doTest("compiler/testData/diagnostics/tests/inner/constructorAccess.kt"); @@ -3027,6 +3032,21 @@ public class JetDiagnosticsTestGenerated extends AbstractDiagnosticsTestWithEage doTest("compiler/testData/diagnostics/tests/inner/illegalModifier.kt"); } + @TestMetadata("innerClassesInStaticParameters.kt") + public void testInnerClassesInStaticParameters() throws Exception { + doTest("compiler/testData/diagnostics/tests/inner/innerClassesInStaticParameters.kt"); + } + + @TestMetadata("innerErrorForClassObjects.kt") + public void testInnerErrorForClassObjects() throws Exception { + doTest("compiler/testData/diagnostics/tests/inner/innerErrorForClassObjects.kt"); + } + + @TestMetadata("innerErrorForObjects.kt") + public void testInnerErrorForObjects() throws Exception { + doTest("compiler/testData/diagnostics/tests/inner/innerErrorForObjects.kt"); + } + @TestMetadata("innerThisSuper.kt") public void testInnerThisSuper() throws Exception { doTest("compiler/testData/diagnostics/tests/inner/innerThisSuper.kt"); @@ -3087,6 +3107,16 @@ public class JetDiagnosticsTestGenerated extends AbstractDiagnosticsTestWithEage doTest("compiler/testData/diagnostics/tests/inner/outerSuperClassMember.kt"); } + @TestMetadata("resolvePackageClassInObjects.kt") + public void testResolvePackageClassInObjects() throws Exception { + doTest("compiler/testData/diagnostics/tests/inner/resolvePackageClassInObjects.kt"); + } + + @TestMetadata("selfAnnotationForClassObject.kt") + public void testSelfAnnotationForClassObject() throws Exception { + doTest("compiler/testData/diagnostics/tests/inner/selfAnnotationForClassObject.kt"); + } + @TestMetadata("traits.kt") public void testTraits() throws Exception { doTest("compiler/testData/diagnostics/tests/inner/traits.kt"); diff --git a/compiler/tests/org/jetbrains/jet/codegen/generated/BlackBoxCodegenTestGenerated.java b/compiler/tests/org/jetbrains/jet/codegen/generated/BlackBoxCodegenTestGenerated.java index bd7388a1c49..0996939a371 100644 --- a/compiler/tests/org/jetbrains/jet/codegen/generated/BlackBoxCodegenTestGenerated.java +++ b/compiler/tests/org/jetbrains/jet/codegen/generated/BlackBoxCodegenTestGenerated.java @@ -680,6 +680,11 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest { doTest("compiler/testData/codegen/box/classes/classObjectNotOfEnum.kt"); } + @TestMetadata("classObjectsWithParentClasses.kt") + public void testClassObjectsWithParentClasses() throws Exception { + doTest("compiler/testData/codegen/box/classes/classObjectsWithParentClasses.kt"); + } + @TestMetadata("delegation2.kt") public void testDelegation2() throws Exception { doTest("compiler/testData/codegen/box/classes/delegation2.kt"); diff --git a/compiler/tests/org/jetbrains/jet/jvm/compiler/LoadCompiledKotlinTestGenerated.java b/compiler/tests/org/jetbrains/jet/jvm/compiler/LoadCompiledKotlinTestGenerated.java index 595eeab747e..a7eb520a901 100644 --- a/compiler/tests/org/jetbrains/jet/jvm/compiler/LoadCompiledKotlinTestGenerated.java +++ b/compiler/tests/org/jetbrains/jet/jvm/compiler/LoadCompiledKotlinTestGenerated.java @@ -259,6 +259,11 @@ public class LoadCompiledKotlinTestGenerated extends AbstractLoadCompiledKotlinT doTestWithAccessors("compiler/testData/loadKotlin/classObject/ClassObjectExtendsTraitWithTP.kt"); } + @TestMetadata("InnerClassInClassObject.kt") + public void testInnerClassInClassObject() throws Exception { + doTestWithAccessors("compiler/testData/loadKotlin/classObject/InnerClassInClassObject.kt"); + } + @TestMetadata("SimpleClassObject.kt") public void testSimpleClassObject() throws Exception { doTestWithAccessors("compiler/testData/loadKotlin/classObject/SimpleClassObject.kt"); diff --git a/compiler/tests/org/jetbrains/jet/lang/resolve/lazy/LazyResolveNamespaceComparingTestGenerated.java b/compiler/tests/org/jetbrains/jet/lang/resolve/lazy/LazyResolveNamespaceComparingTestGenerated.java index e26cdf37436..f7e249dfbe0 100644 --- a/compiler/tests/org/jetbrains/jet/lang/resolve/lazy/LazyResolveNamespaceComparingTestGenerated.java +++ b/compiler/tests/org/jetbrains/jet/lang/resolve/lazy/LazyResolveNamespaceComparingTestGenerated.java @@ -261,6 +261,11 @@ public class LazyResolveNamespaceComparingTestGenerated extends AbstractLazyReso doTestCheckingPrimaryConstructorsAndAccessors("compiler/testData/loadKotlin/classObject/ClassObjectExtendsTraitWithTP.kt"); } + @TestMetadata("InnerClassInClassObject.kt") + public void testInnerClassInClassObject() throws Exception { + doTestCheckingPrimaryConstructorsAndAccessors("compiler/testData/loadKotlin/classObject/InnerClassInClassObject.kt"); + } + @TestMetadata("SimpleClassObject.kt") public void testSimpleClassObject() throws Exception { doTestCheckingPrimaryConstructorsAndAccessors("compiler/testData/loadKotlin/classObject/SimpleClassObject.kt"); @@ -2137,6 +2142,11 @@ public class LazyResolveNamespaceComparingTestGenerated extends AbstractLazyReso doTestCheckingPrimaryConstructors("compiler/testData/lazyResolve/namespaceComparator/propertyClassFileDependencyRecursion.kt"); } + @TestMetadata("resolveFunctionInsideClassObject.kt") + public void testResolveFunctionInsideClassObject() throws Exception { + doTestCheckingPrimaryConstructors("compiler/testData/lazyResolve/namespaceComparator/resolveFunctionInsideClassObject.kt"); + } + @TestMetadata("sameClassNameResolve.kt") public void testSameClassNameResolve() throws Exception { doTestCheckingPrimaryConstructors("compiler/testData/lazyResolve/namespaceComparator/sameClassNameResolve.kt"); diff --git a/compiler/tests/org/jetbrains/jet/resolve/JetResolveTestGenerated.java b/compiler/tests/org/jetbrains/jet/resolve/JetResolveTestGenerated.java index 07c283377e1..677f28521d0 100644 --- a/compiler/tests/org/jetbrains/jet/resolve/JetResolveTestGenerated.java +++ b/compiler/tests/org/jetbrains/jet/resolve/JetResolveTestGenerated.java @@ -163,6 +163,11 @@ public class JetResolveTestGenerated extends AbstractResolveTest { JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.GenerateTests", new File("compiler/testData/resolve/candidatesPriority"), Pattern.compile("^(.+)\\.resolve$"), true); } + @TestMetadata("classObjectOuterResolve.resolve") + public void testClassObjectOuterResolve() throws Exception { + doTest("compiler/testData/resolve/candidatesPriority/classObjectOuterResolve.resolve"); + } + @TestMetadata("preferImplicitThisToNoReceiver.resolve") public void testPreferImplicitThisToNoReceiver() throws Exception { doTest("compiler/testData/resolve/candidatesPriority/preferImplicitThisToNoReceiver.resolve"); From 994107ee0a9a575bac1e2aa134c9e38eecf9c364 Mon Sep 17 00:00:00 2001 From: Nikolay Krasko Date: Tue, 4 Jun 2013 14:56:48 +0400 Subject: [PATCH 236/249] Mix class object scope to member resolution scope in lazy resolve --- .../impl/MutableClassDescriptor.java | 17 +---- .../lazy/descriptors/LazyClassDescriptor.java | 6 +- .../resolve/scopes/ClassObjectMixinScope.java | 48 ++++++++++++++ .../loadKotlin/class/ClassMemberConflict.kt | 44 +++++++++++++ .../loadKotlin/class/ClassMemberConflict.txt | 66 +++++++++++++++++++ .../classObject/ClassObjectPropertyInClass.kt | 9 +++ .../ClassObjectPropertyInClass.txt | 13 ++++ .../LoadCompiledKotlinTestGenerated.java | 10 +++ ...esolveNamespaceComparingTestGenerated.java | 10 +++ .../common/classObjectElementsInClass.kt | 13 ++++ .../JetBasicJSCompletionTestGenerated.java | 5 ++ .../JetBasicJavaCompletionTestGenerated.java | 5 ++ 12 files changed, 230 insertions(+), 16 deletions(-) create mode 100644 compiler/frontend/src/org/jetbrains/jet/lang/resolve/scopes/ClassObjectMixinScope.java create mode 100644 compiler/testData/loadKotlin/class/ClassMemberConflict.kt create mode 100644 compiler/testData/loadKotlin/class/ClassMemberConflict.txt create mode 100644 compiler/testData/loadKotlin/classObject/ClassObjectPropertyInClass.kt create mode 100644 compiler/testData/loadKotlin/classObject/ClassObjectPropertyInClass.txt create mode 100644 idea/testData/completion/basic/common/classObjectElementsInClass.kt diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/impl/MutableClassDescriptor.java b/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/impl/MutableClassDescriptor.java index 65cf9c13207..1a4c0997569 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/impl/MutableClassDescriptor.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/impl/MutableClassDescriptor.java @@ -26,7 +26,6 @@ import org.jetbrains.jet.lang.resolve.BindingTrace; import org.jetbrains.jet.lang.resolve.name.Name; import org.jetbrains.jet.lang.resolve.scopes.*; -import java.util.Collections; import java.util.List; import java.util.Set; @@ -224,7 +223,7 @@ public class MutableClassDescriptor extends MutableClassDescriptorLite { } @Override - public ClassObjectStatus setClassObjectDescriptor(@NotNull final MutableClassDescriptorLite classObjectDescriptor) { + public ClassObjectStatus setClassObjectDescriptor(@NotNull MutableClassDescriptorLite classObjectDescriptor) { ClassObjectStatus r = superBuilder.setClassObjectDescriptor(classObjectDescriptor); if (r != ClassObjectStatus.OK) { return r; @@ -232,19 +231,7 @@ public class MutableClassDescriptor extends MutableClassDescriptorLite { // Members of the class object are accessible from the class // The scope must be lazy, because classObjectDescriptor may not by fully built yet - scopeForMemberResolution.importScope(new AbstractScopeAdapter() { - @NotNull - @Override - protected JetScope getWorkerScope() { - return classObjectDescriptor.getDefaultType().getMemberScope(); - } - - @NotNull - @Override - public List getImplicitReceiversHierarchy() { - return Collections.singletonList(classObjectDescriptor.getThisAsReceiverParameter()); - } - }); + scopeForMemberResolution.importScope(new ClassObjectMixinScope(classObjectDescriptor)); return ClassObjectStatus.OK; } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/lazy/descriptors/LazyClassDescriptor.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/lazy/descriptors/LazyClassDescriptor.java index d0d4e108a57..57079753619 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/lazy/descriptors/LazyClassDescriptor.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/lazy/descriptors/LazyClassDescriptor.java @@ -206,12 +206,16 @@ public class LazyClassDescriptor extends ClassDescriptorBase implements LazyDesc thisScope.addLabeledDeclaration(this); thisScope.changeLockLevel(WritableScope.LockLevel.READING); + ClassDescriptor classObject = getClassObjectDescriptor(); + JetScope classObjectAdapterScope = (classObject != null) ? new ClassObjectMixinScope(classObject) : JetScope.EMPTY; + return new ChainedScope( this, "ScopeForMemberDeclarationResolution: " + getName(), thisScope, getScopeForMemberLookup(), - getScopeForClassHeaderResolution()); + getScopeForClassHeaderResolution(), + classObjectAdapterScope); } @NotNull diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/scopes/ClassObjectMixinScope.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/scopes/ClassObjectMixinScope.java new file mode 100644 index 00000000000..ea75f986945 --- /dev/null +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/scopes/ClassObjectMixinScope.java @@ -0,0 +1,48 @@ +/* + * Copyright 2010-2013 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.jetbrains.jet.lang.resolve.scopes; + +import org.jetbrains.annotations.NotNull; +import org.jetbrains.jet.lang.descriptors.ClassDescriptor; +import org.jetbrains.jet.lang.descriptors.ReceiverParameterDescriptor; + +import java.util.Collections; +import java.util.List; + +/** + * Members of the class object are accessible from the class. + * Scope lazily delegates requests to class object scope. + */ +public class ClassObjectMixinScope extends AbstractScopeAdapter { + private final ClassDescriptor classObjectDescriptor; + + public ClassObjectMixinScope(ClassDescriptor classObjectDescriptor) { + this.classObjectDescriptor = classObjectDescriptor; + } + + @NotNull + @Override + protected JetScope getWorkerScope() { + return classObjectDescriptor.getDefaultType().getMemberScope(); + } + + @NotNull + @Override + public List getImplicitReceiversHierarchy() { + return Collections.singletonList(classObjectDescriptor.getThisAsReceiverParameter()); + } +} diff --git a/compiler/testData/loadKotlin/class/ClassMemberConflict.kt b/compiler/testData/loadKotlin/class/ClassMemberConflict.kt new file mode 100644 index 00000000000..b69b0fd9e0e --- /dev/null +++ b/compiler/testData/loadKotlin/class/ClassMemberConflict.kt @@ -0,0 +1,44 @@ +package test + +class ConstructorTypeParamClassObjectTypeConflict { + class object { + trait test + } + + val some: test? = null +} + +class ConstructorTypeParamClassObjectConflict { + class object { + val test = 12 + } + + val some = test +} + +class TestConstructorParamClassObjectConflict(test: String) { + class object { + val test = 12 + } + + val some = test +} + + +class TestConstructorValClassObjectConflict(val test: String) { + class object { + val test = 12 + } + + val some = test +} + +class TestClassObjectAndClassConflict { + class object { + val bla = 12 + } + + val bla = "More" + + val some = bla +} \ No newline at end of file diff --git a/compiler/testData/loadKotlin/class/ClassMemberConflict.txt b/compiler/testData/loadKotlin/class/ClassMemberConflict.txt new file mode 100644 index 00000000000..93cb14458bc --- /dev/null +++ b/compiler/testData/loadKotlin/class/ClassMemberConflict.txt @@ -0,0 +1,66 @@ +package test + +internal final class ConstructorTypeParamClassObjectConflict { + /*primary*/ public constructor ConstructorTypeParamClassObjectConflict() + internal final val some: jet.Int + internal final fun (): jet.Int + + internal class object { + /*primary*/ private constructor () + internal final val test: jet.Int + internal final fun (): jet.Int + } +} + +internal final class ConstructorTypeParamClassObjectTypeConflict { + /*primary*/ public constructor ConstructorTypeParamClassObjectTypeConflict() + internal final val some: test? + internal final fun (): test? + + internal class object { + /*primary*/ private constructor () + + internal trait test { + } + } +} + +internal final class TestClassObjectAndClassConflict { + /*primary*/ public constructor TestClassObjectAndClassConflict() + internal final val bla: jet.String + internal final fun (): jet.String + internal final val some: jet.String + internal final fun (): jet.String + + internal class object { + /*primary*/ private constructor () + internal final val bla: jet.Int + internal final fun (): jet.Int + } +} + +internal final class TestConstructorParamClassObjectConflict { + /*primary*/ public constructor TestConstructorParamClassObjectConflict(/*0*/ test: jet.String) + internal final val some: jet.String + internal final fun (): jet.String + + internal class object { + /*primary*/ private constructor () + internal final val test: jet.Int + internal final fun (): jet.Int + } +} + +internal final class TestConstructorValClassObjectConflict { + /*primary*/ public constructor TestConstructorValClassObjectConflict(/*0*/ test: jet.String) + internal final val some: jet.String + internal final fun (): jet.String + internal final val test: jet.String + internal final fun (): jet.String + + internal class object { + /*primary*/ private constructor () + internal final val test: jet.Int + internal final fun (): jet.Int + } +} diff --git a/compiler/testData/loadKotlin/classObject/ClassObjectPropertyInClass.kt b/compiler/testData/loadKotlin/classObject/ClassObjectPropertyInClass.kt new file mode 100644 index 00000000000..9096414a0d5 --- /dev/null +++ b/compiler/testData/loadKotlin/classObject/ClassObjectPropertyInClass.kt @@ -0,0 +1,9 @@ +package test + +class A { + class object { + val some = 1 + } + + val other = some +} \ No newline at end of file diff --git a/compiler/testData/loadKotlin/classObject/ClassObjectPropertyInClass.txt b/compiler/testData/loadKotlin/classObject/ClassObjectPropertyInClass.txt new file mode 100644 index 00000000000..8396336163f --- /dev/null +++ b/compiler/testData/loadKotlin/classObject/ClassObjectPropertyInClass.txt @@ -0,0 +1,13 @@ +package test + +internal final class A { + /*primary*/ public constructor A() + internal final val other: jet.Int + internal final fun (): jet.Int + + internal class object { + /*primary*/ private constructor () + internal final val some: jet.Int + internal final fun (): jet.Int + } +} diff --git a/compiler/tests/org/jetbrains/jet/jvm/compiler/LoadCompiledKotlinTestGenerated.java b/compiler/tests/org/jetbrains/jet/jvm/compiler/LoadCompiledKotlinTestGenerated.java index a7eb520a901..191e3bb70de 100644 --- a/compiler/tests/org/jetbrains/jet/jvm/compiler/LoadCompiledKotlinTestGenerated.java +++ b/compiler/tests/org/jetbrains/jet/jvm/compiler/LoadCompiledKotlinTestGenerated.java @@ -58,6 +58,11 @@ public class LoadCompiledKotlinTestGenerated extends AbstractLoadCompiledKotlinT doTestWithAccessors("compiler/testData/loadKotlin/class/ClassInnerClass.kt"); } + @TestMetadata("ClassMemberConflict.kt") + public void testClassMemberConflict() throws Exception { + doTestWithAccessors("compiler/testData/loadKotlin/class/ClassMemberConflict.kt"); + } + @TestMetadata("ClassOutParam.kt") public void testClassOutParam() throws Exception { doTestWithAccessors("compiler/testData/loadKotlin/class/ClassOutParam.kt"); @@ -259,6 +264,11 @@ public class LoadCompiledKotlinTestGenerated extends AbstractLoadCompiledKotlinT doTestWithAccessors("compiler/testData/loadKotlin/classObject/ClassObjectExtendsTraitWithTP.kt"); } + @TestMetadata("ClassObjectPropertyInClass.kt") + public void testClassObjectPropertyInClass() throws Exception { + doTestWithAccessors("compiler/testData/loadKotlin/classObject/ClassObjectPropertyInClass.kt"); + } + @TestMetadata("InnerClassInClassObject.kt") public void testInnerClassInClassObject() throws Exception { doTestWithAccessors("compiler/testData/loadKotlin/classObject/InnerClassInClassObject.kt"); diff --git a/compiler/tests/org/jetbrains/jet/lang/resolve/lazy/LazyResolveNamespaceComparingTestGenerated.java b/compiler/tests/org/jetbrains/jet/lang/resolve/lazy/LazyResolveNamespaceComparingTestGenerated.java index f7e249dfbe0..4bf970ac668 100644 --- a/compiler/tests/org/jetbrains/jet/lang/resolve/lazy/LazyResolveNamespaceComparingTestGenerated.java +++ b/compiler/tests/org/jetbrains/jet/lang/resolve/lazy/LazyResolveNamespaceComparingTestGenerated.java @@ -60,6 +60,11 @@ public class LazyResolveNamespaceComparingTestGenerated extends AbstractLazyReso doTestCheckingPrimaryConstructorsAndAccessors("compiler/testData/loadKotlin/class/ClassInnerClass.kt"); } + @TestMetadata("ClassMemberConflict.kt") + public void testClassMemberConflict() throws Exception { + doTestCheckingPrimaryConstructorsAndAccessors("compiler/testData/loadKotlin/class/ClassMemberConflict.kt"); + } + @TestMetadata("ClassOutParam.kt") public void testClassOutParam() throws Exception { doTestCheckingPrimaryConstructorsAndAccessors("compiler/testData/loadKotlin/class/ClassOutParam.kt"); @@ -261,6 +266,11 @@ public class LazyResolveNamespaceComparingTestGenerated extends AbstractLazyReso doTestCheckingPrimaryConstructorsAndAccessors("compiler/testData/loadKotlin/classObject/ClassObjectExtendsTraitWithTP.kt"); } + @TestMetadata("ClassObjectPropertyInClass.kt") + public void testClassObjectPropertyInClass() throws Exception { + doTestCheckingPrimaryConstructorsAndAccessors("compiler/testData/loadKotlin/classObject/ClassObjectPropertyInClass.kt"); + } + @TestMetadata("InnerClassInClassObject.kt") public void testInnerClassInClassObject() throws Exception { doTestCheckingPrimaryConstructorsAndAccessors("compiler/testData/loadKotlin/classObject/InnerClassInClassObject.kt"); diff --git a/idea/testData/completion/basic/common/classObjectElementsInClass.kt b/idea/testData/completion/basic/common/classObjectElementsInClass.kt new file mode 100644 index 00000000000..ff9b87cf36a --- /dev/null +++ b/idea/testData/completion/basic/common/classObjectElementsInClass.kt @@ -0,0 +1,13 @@ +class Some { + class object { + val coProp = 12 + + fun coFun = 12 + } + + fun some() { + val a = co + } +} + +// EXIST: coProp, coFun \ No newline at end of file diff --git a/idea/tests/org/jetbrains/jet/completion/JetBasicJSCompletionTestGenerated.java b/idea/tests/org/jetbrains/jet/completion/JetBasicJSCompletionTestGenerated.java index 8671b450cf2..d842aa95c82 100644 --- a/idea/tests/org/jetbrains/jet/completion/JetBasicJSCompletionTestGenerated.java +++ b/idea/tests/org/jetbrains/jet/completion/JetBasicJSCompletionTestGenerated.java @@ -79,6 +79,11 @@ public class JetBasicJSCompletionTestGenerated extends AbstractJetJSCompletionTe doTest("idea/testData/completion/basic/common/CallLocalLambda.kt"); } + @TestMetadata("classObjectElementsInClass.kt") + public void testClassObjectElementsInClass() throws Exception { + doTest("idea/testData/completion/basic/common/classObjectElementsInClass.kt"); + } + @TestMetadata("ClassRedeclaration1.kt") public void testClassRedeclaration1() throws Exception { doTest("idea/testData/completion/basic/common/ClassRedeclaration1.kt"); diff --git a/idea/tests/org/jetbrains/jet/completion/JetBasicJavaCompletionTestGenerated.java b/idea/tests/org/jetbrains/jet/completion/JetBasicJavaCompletionTestGenerated.java index dd6a7d5a412..8dad2867c6c 100644 --- a/idea/tests/org/jetbrains/jet/completion/JetBasicJavaCompletionTestGenerated.java +++ b/idea/tests/org/jetbrains/jet/completion/JetBasicJavaCompletionTestGenerated.java @@ -79,6 +79,11 @@ public class JetBasicJavaCompletionTestGenerated extends AbstractJavaCompletionT doTest("idea/testData/completion/basic/common/CallLocalLambda.kt"); } + @TestMetadata("classObjectElementsInClass.kt") + public void testClassObjectElementsInClass() throws Exception { + doTest("idea/testData/completion/basic/common/classObjectElementsInClass.kt"); + } + @TestMetadata("ClassRedeclaration1.kt") public void testClassRedeclaration1() throws Exception { doTest("idea/testData/completion/basic/common/ClassRedeclaration1.kt"); From 27baad64c03852c6bfae11bd12880b173effab45 Mon Sep 17 00:00:00 2001 From: Nikolay Krasko Date: Tue, 4 Jun 2013 21:04:07 +0400 Subject: [PATCH 237/249] Fix recursion of checking type is supertype during resolving list of supertypes --- .../jet/lang/resolve/DescriptorResolver.java | 19 ++++++++++++++++++- .../jet/lang/resolve/TypeResolver.java | 3 ++- .../diagnostics/tests/inner/deepInnerClass.kt | 14 ++++++++++++++ .../checkers/JetDiagnosticsTestGenerated.java | 5 +++++ 4 files changed, 39 insertions(+), 2 deletions(-) create mode 100644 compiler/testData/diagnostics/tests/inner/deepInnerClass.kt diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/DescriptorResolver.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/DescriptorResolver.java index ff231209d09..ace7885a16f 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/DescriptorResolver.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/DescriptorResolver.java @@ -1470,14 +1470,31 @@ public class DescriptorResolver { @NotNull BindingTrace trace, @NotNull PsiElement reportErrorsOn, @NotNull ClassDescriptor target + ) { + return checkHasOuterClassInstance(scope, trace, reportErrorsOn, target, true); + } + + public static boolean checkHasOuterClassInstance( + @NotNull JetScope scope, + @NotNull BindingTrace trace, + @NotNull PsiElement reportErrorsOn, + @NotNull ClassDescriptor target, + boolean doSuperClassCheck ) { DeclarationDescriptor descriptor = getContainingClass(scope); + while (descriptor != null) { if (descriptor instanceof ClassDescriptor) { ClassDescriptor classDescriptor = (ClassDescriptor) descriptor; - if (isSubclass(classDescriptor, target)) { + + if (classDescriptor == target) { return true; } + + if (doSuperClassCheck && isSubclass(classDescriptor, target)) { + return true; + } + if (isStaticNestedClass(classDescriptor)) { trace.report(INACCESSIBLE_OUTER_CLASS_EXPRESSION.on(reportErrorsOn, classDescriptor)); return false; 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 8c2e1ae7c59..bf001ecf9bd 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/TypeResolver.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/TypeResolver.java @@ -123,7 +123,8 @@ public class TypeResolver { DeclarationDescriptor containing = typeParameterDescriptor.getContainingDeclaration(); if (containing instanceof ClassDescriptor) { - DescriptorResolver.checkHasOuterClassInstance(scope, trace, referenceExpression, (ClassDescriptor) containing); + // Type parameter can't be inherited from member of parent class, so we can skip subclass check + DescriptorResolver.checkHasOuterClassInstance(scope, trace, referenceExpression, (ClassDescriptor) containing, false); } } else if (classifierDescriptor instanceof ClassDescriptor) { diff --git a/compiler/testData/diagnostics/tests/inner/deepInnerClass.kt b/compiler/testData/diagnostics/tests/inner/deepInnerClass.kt new file mode 100644 index 00000000000..2ce0546c66b --- /dev/null +++ b/compiler/testData/diagnostics/tests/inner/deepInnerClass.kt @@ -0,0 +1,14 @@ +trait P + +class A { + class B { + fun test() { + class C() : PT> { + class object : P<W, T> { + } + + inner class D : PT> + } + } + } +} diff --git a/compiler/tests/org/jetbrains/jet/checkers/JetDiagnosticsTestGenerated.java b/compiler/tests/org/jetbrains/jet/checkers/JetDiagnosticsTestGenerated.java index c32e00daae0..6da64048a60 100644 --- a/compiler/tests/org/jetbrains/jet/checkers/JetDiagnosticsTestGenerated.java +++ b/compiler/tests/org/jetbrains/jet/checkers/JetDiagnosticsTestGenerated.java @@ -3017,6 +3017,11 @@ public class JetDiagnosticsTestGenerated extends AbstractDiagnosticsTestWithEage doTest("compiler/testData/diagnostics/tests/inner/constructorAccess.kt"); } + @TestMetadata("deepInnerClass.kt") + public void testDeepInnerClass() throws Exception { + doTest("compiler/testData/diagnostics/tests/inner/deepInnerClass.kt"); + } + @TestMetadata("enumEntries.kt") public void testEnumEntries() throws Exception { doTest("compiler/testData/diagnostics/tests/inner/enumEntries.kt"); From 4e67566e58d0432af9d217a130bad3f25701671e Mon Sep 17 00:00:00 2001 From: Nikolay Krasko Date: Wed, 5 Jun 2013 15:47:51 +0400 Subject: [PATCH 238/249] Add utility method for getting before and after text --- .../tests/org/jetbrains/jet/JetTestUtils.java | 24 +++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/compiler/tests/org/jetbrains/jet/JetTestUtils.java b/compiler/tests/org/jetbrains/jet/JetTestUtils.java index 6a3cbf89dbf..0278afdd7ae 100644 --- a/compiler/tests/org/jetbrains/jet/JetTestUtils.java +++ b/compiler/tests/org/jetbrains/jet/JetTestUtils.java @@ -24,6 +24,7 @@ import com.intellij.openapi.editor.Document; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.ShutDownTracker; import com.intellij.openapi.util.io.FileUtil; +import com.intellij.openapi.util.text.StringUtil; import com.intellij.openapi.vfs.CharsetToolkit; import com.intellij.psi.PsiFileFactory; import com.intellij.psi.impl.PsiFileFactoryImpl; @@ -402,6 +403,29 @@ public class JetTestUtils { return testFileFiles; } + public static List loadBeforeAfterText(String filePath) { + String content; + + try { + content = StringUtil.convertLineSeparators(FileUtil.loadFile(new File(filePath))); + } + catch (IOException e) { + throw new RuntimeException(e); + } + + List files = createTestFiles("", content, new TestFileFactory() { + @Override + public String create(String fileName, String text) { + int firstLineEnd = text.indexOf('\n'); + return StringUtil.trimTrailing(text.substring(firstLineEnd + 1)); + } + }); + + Assert.assertTrue("Exactly two files expected: ", files.size() == 2); + + return files; + } + public static String getLastCommentedLines(@NotNull Document document) { List resultLines = new ArrayList(); for (int i = document.getLineCount() - 1; i >= 0; i--) { From d50300dedc3a2300b2f722d73a304e4d5e7131e7 Mon Sep 17 00:00:00 2001 From: Nikolay Krasko Date: Fri, 7 Jun 2013 15:21:22 +0400 Subject: [PATCH 239/249] Navigate to super for objects --- .../jet/generators/tests/GenerateTests.java | 7 ++ .../codeInsight/GotoSuperActionHandler.java | 13 ++-- .../navigation/gotoSuper/ClassSimple.test | 6 ++ .../navigation/gotoSuper/FunctionSimple.test | 18 ++++++ .../navigation/gotoSuper/ObjectSimple.test | 6 ++ .../navigation/gotoSuper/PropertySimple.test | 14 ++++ .../navigation/gotoSuper/TraitSimple.test | 6 ++ .../navigation/JetAbstractGotoSuperTest.java | 41 ++++++++++++ .../navigation/JetGotoSuperTestGenerated.java | 64 +++++++++++++++++++ 9 files changed, 170 insertions(+), 5 deletions(-) create mode 100644 idea/testData/navigation/gotoSuper/ClassSimple.test create mode 100644 idea/testData/navigation/gotoSuper/FunctionSimple.test create mode 100644 idea/testData/navigation/gotoSuper/ObjectSimple.test create mode 100644 idea/testData/navigation/gotoSuper/PropertySimple.test create mode 100644 idea/testData/navigation/gotoSuper/TraitSimple.test create mode 100644 idea/tests/org/jetbrains/jet/plugin/navigation/JetAbstractGotoSuperTest.java create mode 100644 idea/tests/org/jetbrains/jet/plugin/navigation/JetGotoSuperTestGenerated.java diff --git a/generators/org/jetbrains/jet/generators/tests/GenerateTests.java b/generators/org/jetbrains/jet/generators/tests/GenerateTests.java index 15be16c3bc8..9e5468b3c6a 100644 --- a/generators/org/jetbrains/jet/generators/tests/GenerateTests.java +++ b/generators/org/jetbrains/jet/generators/tests/GenerateTests.java @@ -43,6 +43,7 @@ import org.jetbrains.jet.plugin.codeInsight.surroundWith.AbstractSurroundWithTes import org.jetbrains.jet.plugin.folding.AbstractKotlinFoldingTest; import org.jetbrains.jet.plugin.hierarchy.AbstractHierarchyTest; import org.jetbrains.jet.plugin.highlighter.AbstractDeprecatedHighlightingTest; +import org.jetbrains.jet.plugin.navigation.JetAbstractGotoSuperTest; import org.jetbrains.jet.plugin.quickfix.AbstractQuickFixMultiFileTest; import org.jetbrains.jet.plugin.quickfix.AbstractQuickFixTest; import org.jetbrains.jet.resolve.AbstractResolveTest; @@ -282,6 +283,12 @@ public class GenerateTests { AbstractJavaWithLibCompletionTest.class, testModel("idea/testData/completion/basic/custom", false, "doTestWithJar")); + generateTest( + "idea/tests", + "JetGotoSuperTestGenerated", + JetAbstractGotoSuperTest.class, + testModel("idea/testData/navigation/gotoSuper", false, "test", "doTest")); + generateTest( "idea/tests/", "QuickFixMultiFileTestGenerated", diff --git a/idea/src/org/jetbrains/jet/plugin/codeInsight/GotoSuperActionHandler.java b/idea/src/org/jetbrains/jet/plugin/codeInsight/GotoSuperActionHandler.java index bd7ef16d1cc..da4bc244c1a 100644 --- a/idea/src/org/jetbrains/jet/plugin/codeInsight/GotoSuperActionHandler.java +++ b/idea/src/org/jetbrains/jet/plugin/codeInsight/GotoSuperActionHandler.java @@ -51,14 +51,17 @@ public class GotoSuperActionHandler implements CodeInsightActionHandler { PsiElement element = file.findElementAt(editor.getCaretModel().getOffset()); if (element == null) return; - @SuppressWarnings("unchecked") JetNamedDeclaration funOrClass = - PsiTreeUtil.getParentOfType(element, JetNamedFunction.class, JetClass.class, JetProperty.class); - if (funOrClass == null) return; + @SuppressWarnings("unchecked") JetDeclaration declaration = + PsiTreeUtil.getParentOfType(element, + JetNamedFunction.class, + JetClass.class, + JetProperty.class, + JetObjectDeclaration.class); + if (declaration == null) return; final BindingContext bindingContext = WholeProjectAnalyzerFacade.analyzeProjectWithCacheOnAFile((JetFile) file).getBindingContext(); - DeclarationDescriptor descriptor = bindingContext.get(BindingContext.DECLARATION_TO_DESCRIPTOR, funOrClass); - + DeclarationDescriptor descriptor = bindingContext.get(BindingContext.DECLARATION_TO_DESCRIPTOR, declaration); Collection superDescriptors; String message; diff --git a/idea/testData/navigation/gotoSuper/ClassSimple.test b/idea/testData/navigation/gotoSuper/ClassSimple.test new file mode 100644 index 00000000000..ce53dfcb7c5 --- /dev/null +++ b/idea/testData/navigation/gotoSuper/ClassSimple.test @@ -0,0 +1,6 @@ +// FILE: before.kt +trait Some +class SomeObject: Some +// FILE: after.kt +trait Some +class SomeObject: Some \ No newline at end of file diff --git a/idea/testData/navigation/gotoSuper/FunctionSimple.test b/idea/testData/navigation/gotoSuper/FunctionSimple.test new file mode 100644 index 00000000000..d363f865f80 --- /dev/null +++ b/idea/testData/navigation/gotoSuper/FunctionSimple.test @@ -0,0 +1,18 @@ +// FILE: before.kt +trait Some { + fun test() +} +class SomeObject: Some { + override fun test() { + + } +} +// FILE: after.kt +trait Some { + fun test() +} +class SomeObject: Some { + override fun test() { + + } +} \ No newline at end of file diff --git a/idea/testData/navigation/gotoSuper/ObjectSimple.test b/idea/testData/navigation/gotoSuper/ObjectSimple.test new file mode 100644 index 00000000000..b21ccc71077 --- /dev/null +++ b/idea/testData/navigation/gotoSuper/ObjectSimple.test @@ -0,0 +1,6 @@ +// FILE: b.kt +trait Some +object SomeObject: Some +// FILE: a.kt +trait Some +object SomeObject: Some \ No newline at end of file diff --git a/idea/testData/navigation/gotoSuper/PropertySimple.test b/idea/testData/navigation/gotoSuper/PropertySimple.test new file mode 100644 index 00000000000..0282d13c6d4 --- /dev/null +++ b/idea/testData/navigation/gotoSuper/PropertySimple.test @@ -0,0 +1,14 @@ +// FILE: b.kt +trait Some { + val test: Int +} +class SomeObject: Some { + override val test: Int = 1 +} +// FILE: a.kt +trait Some { + val test: Int +} +class SomeObject: Some { + override val test: Int = 1 +} \ No newline at end of file diff --git a/idea/testData/navigation/gotoSuper/TraitSimple.test b/idea/testData/navigation/gotoSuper/TraitSimple.test new file mode 100644 index 00000000000..65c9f2ce61d --- /dev/null +++ b/idea/testData/navigation/gotoSuper/TraitSimple.test @@ -0,0 +1,6 @@ +// FILE: a.kt +open class First +trait Second: First +// FILE: b.kt +open class First +trait Second: First \ No newline at end of file diff --git a/idea/tests/org/jetbrains/jet/plugin/navigation/JetAbstractGotoSuperTest.java b/idea/tests/org/jetbrains/jet/plugin/navigation/JetAbstractGotoSuperTest.java new file mode 100644 index 00000000000..b3ef210ddc7 --- /dev/null +++ b/idea/tests/org/jetbrains/jet/plugin/navigation/JetAbstractGotoSuperTest.java @@ -0,0 +1,41 @@ +/* + * Copyright 2010-2013 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.jetbrains.jet.plugin.navigation; + +import com.intellij.codeInsight.CodeInsightActionHandler; +import com.intellij.openapi.actionSystem.ActionManager; +import com.intellij.testFramework.fixtures.LightCodeInsightFixtureTestCase; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.jet.JetTestUtils; +import org.jetbrains.jet.plugin.JetFileType; +import org.jetbrains.jet.plugin.PluginTestCaseBase; + +import java.io.File; +import java.util.List; + +public abstract class JetAbstractGotoSuperTest extends LightCodeInsightFixtureTestCase { + protected void doTest(String testPath) { + List parts = JetTestUtils.loadBeforeAfterText(testPath); + + myFixture.configureByText(JetFileType.INSTANCE, parts.get(0)); + + CodeInsightActionHandler gotoSuperAction = (CodeInsightActionHandler) ActionManager.getInstance().getAction("GotoSuperMethod"); + gotoSuperAction.invoke(getProject(), myFixture.getEditor(), myFixture.getFile()); + + myFixture.checkResult(parts.get(1)); + } +} \ No newline at end of file diff --git a/idea/tests/org/jetbrains/jet/plugin/navigation/JetGotoSuperTestGenerated.java b/idea/tests/org/jetbrains/jet/plugin/navigation/JetGotoSuperTestGenerated.java new file mode 100644 index 00000000000..f02b35b2d66 --- /dev/null +++ b/idea/tests/org/jetbrains/jet/plugin/navigation/JetGotoSuperTestGenerated.java @@ -0,0 +1,64 @@ +/* + * Copyright 2010-2013 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.jetbrains.jet.plugin.navigation; + +import junit.framework.Assert; +import junit.framework.Test; +import junit.framework.TestSuite; + +import java.io.File; +import java.util.regex.Pattern; +import org.jetbrains.jet.JetTestUtils; +import org.jetbrains.jet.test.InnerTestClasses; +import org.jetbrains.jet.test.TestMetadata; + +import org.jetbrains.jet.plugin.navigation.JetAbstractGotoSuperTest; + +/** This class is generated by {@link org.jetbrains.jet.generators.tests.GenerateTests}. DO NOT MODIFY MANUALLY */ +@SuppressWarnings("all") +@TestMetadata("idea/testData/navigation/gotoSuper") +public class JetGotoSuperTestGenerated extends JetAbstractGotoSuperTest { + public void testAllFilesPresentInGotoSuper() throws Exception { + JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.GenerateTests", new File("idea/testData/navigation/gotoSuper"), Pattern.compile("^(.+)\\.test$"), false); + } + + @TestMetadata("ClassSimple.test") + public void testClassSimple() throws Exception { + doTest("idea/testData/navigation/gotoSuper/ClassSimple.test"); + } + + @TestMetadata("FunctionSimple.test") + public void testFunctionSimple() throws Exception { + doTest("idea/testData/navigation/gotoSuper/FunctionSimple.test"); + } + + @TestMetadata("ObjectSimple.test") + public void testObjectSimple() throws Exception { + doTest("idea/testData/navigation/gotoSuper/ObjectSimple.test"); + } + + @TestMetadata("PropertySimple.test") + public void testPropertySimple() throws Exception { + doTest("idea/testData/navigation/gotoSuper/PropertySimple.test"); + } + + @TestMetadata("TraitSimple.test") + public void testTraitSimple() throws Exception { + doTest("idea/testData/navigation/gotoSuper/TraitSimple.test"); + } + +} From a6edc21c49b25b5225df449f167424256dd73912 Mon Sep 17 00:00:00 2001 From: Andrey Breslav Date: Fri, 7 Jun 2013 14:14:42 +0400 Subject: [PATCH 240/249] Validate descriptors loaded in tests --- ...actCompileKotlinAgainstCustomJavaTest.java | 2 + .../AbstractLoadCompiledKotlinTest.java | 5 + .../jvm/compiler/AbstractLoadJavaTest.java | 2 + .../jet/jvm/compiler/LoadDescriptorUtil.java | 11 +- .../jvm/compiler/LoadKotlinCustomTest.java | 3 +- .../AbstractLazyResolveDiagnosticsTest.java | 2 + ...ractLazyResolveNamespaceComparingTest.java | 3 + .../lazy/LazyResolveBuiltinClassesTest.java | 2 + .../lazy/LazyResolveStdlibLoadingTest.java | 2 + .../jet/test/util/DescriptorValidator.java | 506 ++++++++++++++++++ .../util/RecursiveDescriptorProcessor.java | 148 +++++ 11 files changed, 682 insertions(+), 4 deletions(-) create mode 100644 compiler/tests/org/jetbrains/jet/test/util/DescriptorValidator.java create mode 100644 compiler/tests/org/jetbrains/jet/test/util/RecursiveDescriptorProcessor.java diff --git a/compiler/tests/org/jetbrains/jet/jvm/compiler/AbstractCompileKotlinAgainstCustomJavaTest.java b/compiler/tests/org/jetbrains/jet/jvm/compiler/AbstractCompileKotlinAgainstCustomJavaTest.java index 9982f0808be..8a6f8df3a38 100644 --- a/compiler/tests/org/jetbrains/jet/jvm/compiler/AbstractCompileKotlinAgainstCustomJavaTest.java +++ b/compiler/tests/org/jetbrains/jet/jvm/compiler/AbstractCompileKotlinAgainstCustomJavaTest.java @@ -34,6 +34,7 @@ import org.jetbrains.jet.lang.resolve.BindingContext; import org.jetbrains.jet.lang.resolve.java.AnalyzerFacadeForJVM; import org.jetbrains.jet.lang.resolve.name.FqName; import org.jetbrains.jet.test.TestCaseWithTmpdir; +import org.jetbrains.jet.test.util.DescriptorValidator; import org.jetbrains.jet.test.util.NamespaceComparator; import org.junit.Assert; @@ -70,6 +71,7 @@ public abstract class AbstractCompileKotlinAgainstCustomJavaTest extends TestCas NamespaceDescriptor namespaceDescriptor = bindingContext.get(BindingContext.FQNAME_TO_NAMESPACE_DESCRIPTOR, namespaceFqn); assertNotNull("Failed to find namespace: " + namespaceFqn, namespaceDescriptor); + DescriptorValidator.validate(namespaceDescriptor); compareNamespaceWithFile(namespaceDescriptor, NamespaceComparator.DONT_INCLUDE_METHODS_OF_OBJECT, expectedFile); } diff --git a/compiler/tests/org/jetbrains/jet/jvm/compiler/AbstractLoadCompiledKotlinTest.java b/compiler/tests/org/jetbrains/jet/jvm/compiler/AbstractLoadCompiledKotlinTest.java index c9c3adaf9e8..a32f2ad7a0a 100644 --- a/compiler/tests/org/jetbrains/jet/jvm/compiler/AbstractLoadCompiledKotlinTest.java +++ b/compiler/tests/org/jetbrains/jet/jvm/compiler/AbstractLoadCompiledKotlinTest.java @@ -23,6 +23,7 @@ import org.jetbrains.jet.analyzer.AnalyzeExhaust; import org.jetbrains.jet.lang.descriptors.NamespaceDescriptor; import org.jetbrains.jet.lang.resolve.BindingContext; import org.jetbrains.jet.test.TestCaseWithTmpdir; +import org.jetbrains.jet.test.util.DescriptorValidator; import org.jetbrains.jet.test.util.NamespaceComparator; import java.io.File; @@ -55,8 +56,12 @@ public abstract class AbstractLoadCompiledKotlinTest extends TestCaseWithTmpdir TEST_PACKAGE_FQNAME); assert namespaceFromSource != null; Assert.assertEquals("test", namespaceFromSource.getName().asString()); + + DescriptorValidator.validate(namespaceFromSource); + NamespaceDescriptor namespaceFromClass = LoadDescriptorUtil.loadTestNamespaceAndBindingContextFromJavaRoot( tmpdir, getTestRootDisposable(), ConfigurationKind.JDK_ONLY).first; + compareNamespaces(namespaceFromSource, namespaceFromClass, NamespaceComparator.DONT_INCLUDE_METHODS_OF_OBJECT .checkPrimaryConstructors(true) diff --git a/compiler/tests/org/jetbrains/jet/jvm/compiler/AbstractLoadJavaTest.java b/compiler/tests/org/jetbrains/jet/jvm/compiler/AbstractLoadJavaTest.java index 2c2435d95ae..f4809446297 100644 --- a/compiler/tests/org/jetbrains/jet/jvm/compiler/AbstractLoadJavaTest.java +++ b/compiler/tests/org/jetbrains/jet/jvm/compiler/AbstractLoadJavaTest.java @@ -42,6 +42,7 @@ import org.jetbrains.jet.lang.resolve.java.AnalyzerFacadeForJVM; import org.jetbrains.jet.lang.resolve.java.DescriptorSearchRule; import org.jetbrains.jet.lang.resolve.java.JavaDescriptorResolver; import org.jetbrains.jet.test.TestCaseWithTmpdir; +import org.jetbrains.jet.test.util.DescriptorValidator; import org.junit.Assert; import java.io.File; @@ -164,6 +165,7 @@ public abstract class AbstractLoadJavaTest extends TestCaseWithTmpdir { LoadDescriptorUtil.TEST_PACKAGE_FQNAME, DescriptorSearchRule.INCLUDE_KOTLIN); assert namespaceDescriptor != null : "Test namespace not found"; + DescriptorValidator.validate(namespaceDescriptor); checkJavaNamespace(expectedFile, namespaceDescriptor, trace.getBindingContext(), DONT_INCLUDE_METHODS_OF_OBJECT); } diff --git a/compiler/tests/org/jetbrains/jet/jvm/compiler/LoadDescriptorUtil.java b/compiler/tests/org/jetbrains/jet/jvm/compiler/LoadDescriptorUtil.java index 914a028735b..22f22563599 100644 --- a/compiler/tests/org/jetbrains/jet/jvm/compiler/LoadDescriptorUtil.java +++ b/compiler/tests/org/jetbrains/jet/jvm/compiler/LoadDescriptorUtil.java @@ -28,9 +28,9 @@ import org.jetbrains.jet.analyzer.AnalyzeExhaust; import org.jetbrains.jet.cli.jvm.compiler.CompileEnvironmentUtil; import org.jetbrains.jet.cli.jvm.compiler.JetCoreEnvironment; import org.jetbrains.jet.codegen.ClassFileFactory; -import org.jetbrains.jet.codegen.state.GenerationState; import org.jetbrains.jet.codegen.GenerationUtils; import org.jetbrains.jet.codegen.forTestCompile.ForTestCompileRuntime; +import org.jetbrains.jet.codegen.state.GenerationState; import org.jetbrains.jet.config.CompilerConfiguration; import org.jetbrains.jet.di.InjectorForJavaSemanticServices; import org.jetbrains.jet.lang.descriptors.NamespaceDescriptor; @@ -42,13 +42,15 @@ import org.jetbrains.jet.lang.resolve.java.DescriptorSearchRule; import org.jetbrains.jet.lang.resolve.java.JavaDescriptorResolver; import org.jetbrains.jet.lang.resolve.name.FqName; import org.jetbrains.jet.lang.resolve.name.Name; +import org.jetbrains.jet.test.util.DescriptorValidator; import java.io.File; import java.io.IOException; -import java.util.*; +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; import static org.jetbrains.jet.JetTestUtils.createEnvironmentWithMockJdkAndIdeaAnnotations; -import static org.jetbrains.jet.lang.psi.JetPsiFactory.createFile; public final class LoadDescriptorUtil { @@ -105,6 +107,8 @@ public final class LoadDescriptorUtil { NamespaceDescriptor namespaceDescriptor = javaDescriptorResolver.resolveNamespace(TEST_PACKAGE_FQNAME, DescriptorSearchRule.ERROR_IF_FOUND_IN_KOTLIN); assert namespaceDescriptor != null; + + DescriptorValidator.validate(namespaceDescriptor); return Pair.create(namespaceDescriptor, injector.getBindingTrace().getBindingContext()); } @@ -137,6 +141,7 @@ public final class LoadDescriptorUtil { NamespaceDescriptor namespace = fileAndExhaust.getExhaust().getBindingContext().get(BindingContext.FQNAME_TO_NAMESPACE_DESCRIPTOR, TEST_PACKAGE_FQNAME); assert namespace != null: TEST_PACKAGE_FQNAME + " package not found in " + ktFile.getName(); + DescriptorValidator.validate(namespace); return namespace; } diff --git a/compiler/tests/org/jetbrains/jet/jvm/compiler/LoadKotlinCustomTest.java b/compiler/tests/org/jetbrains/jet/jvm/compiler/LoadKotlinCustomTest.java index 35b1121ad78..7d990d68ca5 100644 --- a/compiler/tests/org/jetbrains/jet/jvm/compiler/LoadKotlinCustomTest.java +++ b/compiler/tests/org/jetbrains/jet/jvm/compiler/LoadKotlinCustomTest.java @@ -22,6 +22,7 @@ import org.jetbrains.jet.analyzer.AnalyzeExhaust; import org.jetbrains.jet.lang.descriptors.NamespaceDescriptor; import org.jetbrains.jet.lang.resolve.BindingContext; import org.jetbrains.jet.test.TestCaseWithTmpdir; +import org.jetbrains.jet.test.util.DescriptorValidator; import org.jetbrains.jet.test.util.NamespaceComparator; import java.io.File; @@ -44,7 +45,6 @@ public final class LoadKotlinCustomTest extends TestCaseWithTmpdir { throws Exception { NamespaceDescriptor namespaceFromClass = compileKotlinAndLoadTestNamespaceDescriptorFromBinary(kotlinFile, tmpdir, myTestRootDisposable, ConfigurationKind.JDK_ONLY); - compareNamespaceWithFile(namespaceFromClass, DONT_INCLUDE_METHODS_OF_OBJECT, expectedFile); } @@ -54,6 +54,7 @@ public final class LoadKotlinCustomTest extends TestCaseWithTmpdir { NamespaceDescriptor namespaceFromSource = exhaust.getBindingContext().get(BindingContext.FQNAME_TO_NAMESPACE_DESCRIPTOR, TEST_PACKAGE_FQNAME); assert namespaceFromSource != null; + DescriptorValidator.validate(namespaceFromSource); compareNamespaceWithFile(namespaceFromSource, NamespaceComparator.DONT_INCLUDE_METHODS_OF_OBJECT.checkPrimaryConstructors(true), expectedFile); } diff --git a/compiler/tests/org/jetbrains/jet/lang/resolve/lazy/AbstractLazyResolveDiagnosticsTest.java b/compiler/tests/org/jetbrains/jet/lang/resolve/lazy/AbstractLazyResolveDiagnosticsTest.java index 273be52f1bf..6cea9ee3eb0 100644 --- a/compiler/tests/org/jetbrains/jet/lang/resolve/lazy/AbstractLazyResolveDiagnosticsTest.java +++ b/compiler/tests/org/jetbrains/jet/lang/resolve/lazy/AbstractLazyResolveDiagnosticsTest.java @@ -26,6 +26,7 @@ import org.jetbrains.jet.lang.psi.JetFile; import org.jetbrains.jet.lang.resolve.name.FqName; import org.jetbrains.jet.lang.resolve.name.FqNameUnsafe; import org.jetbrains.jet.lang.resolve.name.Name; +import org.jetbrains.jet.test.util.DescriptorValidator; import java.io.File; import java.util.List; @@ -46,6 +47,7 @@ public abstract class AbstractLazyResolveDiagnosticsTest extends AbstractJetDiag String path = JetTestUtils.getFilePath(new File(FileUtil.getRelativePath(TEST_DATA_DIR, testDataFile))); NamespaceDescriptor expected = eagerModule.getNamespace(FqName.ROOT); NamespaceDescriptor actual = lazyModule.getNamespace(FqName.ROOT); + DescriptorValidator.validate(expected, actual); String txtFileRelativePath = path.replaceAll("\\.kt$|\\.ktscript", ".txt"); File txtFile = new File("compiler/testData/lazyResolve/diagnostics/" + txtFileRelativePath); diff --git a/compiler/tests/org/jetbrains/jet/lang/resolve/lazy/AbstractLazyResolveNamespaceComparingTest.java b/compiler/tests/org/jetbrains/jet/lang/resolve/lazy/AbstractLazyResolveNamespaceComparingTest.java index 40f1d62812e..9b8368f3500 100644 --- a/compiler/tests/org/jetbrains/jet/lang/resolve/lazy/AbstractLazyResolveNamespaceComparingTest.java +++ b/compiler/tests/org/jetbrains/jet/lang/resolve/lazy/AbstractLazyResolveNamespaceComparingTest.java @@ -28,6 +28,7 @@ import org.jetbrains.jet.lang.psi.JetPsiFactory; import org.jetbrains.jet.lang.resolve.name.FqName; import org.jetbrains.jet.lang.resolve.name.FqNameUnsafe; import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns; +import org.jetbrains.jet.test.util.DescriptorValidator; import org.jetbrains.jet.test.util.NamespaceComparator; import org.junit.Assert; @@ -77,6 +78,8 @@ public abstract class AbstractLazyResolveNamespaceComparingTest extends KotlinTe File serializeResultsTo = new File(FileUtil.getNameWithoutExtension(testFileName) + ".txt"); + DescriptorValidator.validate(expected, actual); + NamespaceComparator.compareNamespaces( expected, actual, NamespaceComparator.DONT_INCLUDE_METHODS_OF_OBJECT.filterRecursion( new Predicate() { diff --git a/compiler/tests/org/jetbrains/jet/lang/resolve/lazy/LazyResolveBuiltinClassesTest.java b/compiler/tests/org/jetbrains/jet/lang/resolve/lazy/LazyResolveBuiltinClassesTest.java index 8ab6f04fc53..ba8e3e12dbe 100644 --- a/compiler/tests/org/jetbrains/jet/lang/resolve/lazy/LazyResolveBuiltinClassesTest.java +++ b/compiler/tests/org/jetbrains/jet/lang/resolve/lazy/LazyResolveBuiltinClassesTest.java @@ -20,6 +20,7 @@ import org.jetbrains.jet.ConfigurationKind; import org.jetbrains.jet.cli.jvm.compiler.JetCoreEnvironment; import org.jetbrains.jet.lang.descriptors.NamespaceDescriptor; import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns; +import org.jetbrains.jet.test.util.DescriptorValidator; import org.junit.Test; import java.io.File; @@ -36,6 +37,7 @@ public class LazyResolveBuiltinClassesTest extends KotlinTestWithEnvironment { @Test public void testBuiltIns() throws Exception { NamespaceDescriptor builtInsPackage = KotlinBuiltIns.getInstance().getBuiltInsPackage(); + DescriptorValidator.validate(builtInsPackage); compareNamespaceWithFile(builtInsPackage, RECURSIVE, new File("compiler/testData/builtin-classes.txt")); } } diff --git a/compiler/tests/org/jetbrains/jet/lang/resolve/lazy/LazyResolveStdlibLoadingTest.java b/compiler/tests/org/jetbrains/jet/lang/resolve/lazy/LazyResolveStdlibLoadingTest.java index ad1460fb3aa..f79c704bf2f 100644 --- a/compiler/tests/org/jetbrains/jet/lang/resolve/lazy/LazyResolveStdlibLoadingTest.java +++ b/compiler/tests/org/jetbrains/jet/lang/resolve/lazy/LazyResolveStdlibLoadingTest.java @@ -29,6 +29,7 @@ import org.jetbrains.jet.lang.psi.JetFile; import org.jetbrains.jet.lang.psi.JetPsiFactory; import org.jetbrains.jet.lang.resolve.name.FqName; import org.jetbrains.jet.lang.resolve.name.Name; +import org.jetbrains.jet.test.util.DescriptorValidator; import org.jetbrains.jet.test.util.NamespaceComparator; import java.io.File; @@ -59,6 +60,7 @@ public class LazyResolveStdlibLoadingTest extends KotlinTestWithEnvironmentManag for (Name name : namespaceShortNames) { NamespaceDescriptor eager = module.getNamespace(FqName.topLevel(name)); NamespaceDescriptor lazy = lazyModule.getNamespace(FqName.topLevel(name)); + DescriptorValidator.validate(eager, lazy); NamespaceComparator.compareNamespaces(eager, lazy, NamespaceComparator.RECURSIVE, null); } } diff --git a/compiler/tests/org/jetbrains/jet/test/util/DescriptorValidator.java b/compiler/tests/org/jetbrains/jet/test/util/DescriptorValidator.java new file mode 100644 index 00000000000..afc2079f311 --- /dev/null +++ b/compiler/tests/org/jetbrains/jet/test/util/DescriptorValidator.java @@ -0,0 +1,506 @@ +/* + * Copyright 2010-2013 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.jetbrains.jet.test.util; + +import com.google.common.collect.Lists; +import junit.framework.Assert; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import org.jetbrains.jet.lang.descriptors.*; +import org.jetbrains.jet.lang.resolve.scopes.JetScope; +import org.jetbrains.jet.lang.types.ErrorUtils; +import org.jetbrains.jet.lang.types.JetType; + +import java.io.PrintStream; +import java.util.Arrays; +import java.util.Collection; +import java.util.List; + +public class DescriptorValidator { + + private DescriptorValidator() {} + + public static void validate(DeclarationDescriptor... descriptors) { + validate(Arrays.asList(descriptors)); + } + + public static void validate(@NotNull Collection descriptors) { + DiagnosticCollectorForTests collector = new DiagnosticCollectorForTests(); + for (DeclarationDescriptor descriptor : descriptors) { + validate(descriptor, collector); + } + collector.done(); + } + + public static void validate(@NotNull Collection descriptors, @NotNull DiagnosticCollector collector) { + for (DeclarationDescriptor descriptor : descriptors) { + validate(descriptor, collector); + } + } + + public static void validate(@NotNull DeclarationDescriptor descriptor, @NotNull DiagnosticCollector collector) { + RecursiveDescriptorProcessor.process(descriptor, collector, ValidationVisitor.INSTANCE); + } + + public interface DiagnosticCollector { + + void report(@NotNull Diagnostic diagnostic); + } + + private static void report(@NotNull DiagnosticCollector collector, @NotNull DeclarationDescriptor descriptor, @NotNull String message) { + collector.report(new Diagnostic(descriptor, message)); + } + + private static class ValidationVisitor implements DeclarationDescriptorVisitor { + + public static final ValidationVisitor INSTANCE = new ValidationVisitor(); + + private ValidationVisitor() {} + + private static void validateScope(@NotNull JetScope scope, @NotNull DiagnosticCollector collector) { + for (DeclarationDescriptor descriptor : scope.getAllDescriptors()) { + descriptor.accept(new ScopeValidatorVisitor(collector), scope); + } + } + + private static void validateType( + @NotNull DeclarationDescriptor descriptor, + @Nullable JetType type, + @NotNull DiagnosticCollector collector + ) { + if (type == null) { + report(collector, descriptor, "No type"); + return; + } + + if (ErrorUtils.isErrorType(type)) { + report(collector, descriptor, "Error type: " + type); + return; + } + + validateScope(type.getMemberScope(), collector); + } + + private static void validateReturnType(CallableDescriptor descriptor, DiagnosticCollector collector) { + validateType(descriptor, descriptor.getReturnType(), collector); + } + + private static void validateTypeParameters(DiagnosticCollector collector, List parameters) { + for (int i = 0; i < parameters.size(); i++) { + TypeParameterDescriptor typeParameterDescriptor = parameters.get(i); + if (typeParameterDescriptor.getIndex() != i) { + report(collector, typeParameterDescriptor, "Incorrect index: " + typeParameterDescriptor.getIndex() + " but must be " + i); + } + } + } + + private static void validateValueParameters(DiagnosticCollector collector, List parameters) { + for (int i = 0; i < parameters.size(); i++) { + ValueParameterDescriptor valueParameterDescriptor = parameters.get(i); + if (valueParameterDescriptor.getIndex() != i) { + report(collector, valueParameterDescriptor, "Incorrect index: " + valueParameterDescriptor.getIndex() + " but must be " + i); + } + } + } + + private static void validateTypes( + DeclarationDescriptor descriptor, + DiagnosticCollector collector, + Collection types + ) { + for (JetType type : types) { + validateType(descriptor, type, collector); + } + } + + private static void validateCallable(CallableDescriptor descriptor, DiagnosticCollector collector) { + validateReturnType(descriptor, collector); + validateTypeParameters(collector, descriptor.getTypeParameters()); + validateValueParameters(collector, descriptor.getValueParameters()); + } + + private static void assertEquals( + DeclarationDescriptor descriptor, + DiagnosticCollector collector, + String name, + T expected, + T actual + ) { + if (!expected.equals(actual)) { + report(collector, descriptor, "Wrong " + name + ": " + actual + " must be " + expected); + } + } + + private static void validateAccessor( + PropertyDescriptor descriptor, + DiagnosticCollector collector, + PropertyAccessorDescriptor accessor, + String name + ) { + // TODO + //assertEquals(accessor, collector, name + " visibility", descriptor.getVisibility(), accessor.getVisibility()); + //assertEquals(accessor, collector, name + " modality", descriptor.getModality(), accessor.getModality()); + assertEquals(accessor, collector, "corresponding property", descriptor, accessor.getCorrespondingProperty()); + } + + @Override + public Boolean visitNamespaceDescriptor( + NamespaceDescriptor descriptor, DiagnosticCollector collector + ) { + validateScope(descriptor.getMemberScope(), collector); + return true; + } + + @Override + public Boolean visitVariableDescriptor( + VariableDescriptor descriptor, DiagnosticCollector collector + ) { + validateReturnType(descriptor, collector); + return true; + } + + @Override + public Boolean visitFunctionDescriptor( + FunctionDescriptor descriptor, DiagnosticCollector collector + ) { + validateCallable(descriptor, collector); + return true; + } + + @Override + public Boolean visitTypeParameterDescriptor( + TypeParameterDescriptor descriptor, DiagnosticCollector collector + ) { + validateTypes(descriptor, collector, descriptor.getUpperBounds()); + return true; + } + + @Override + public Boolean visitClassDescriptor( + ClassDescriptor descriptor, DiagnosticCollector collector + ) { + validateTypeParameters(collector, descriptor.getTypeConstructor().getParameters()); + validateTypes(descriptor, collector, descriptor.getTypeConstructor().getSupertypes()); + + validateType(descriptor, descriptor.getDefaultType(), collector); + + validateScope(descriptor.getUnsubstitutedInnerClassesScope(), collector); + + List primary = Lists.newArrayList(); + for (ConstructorDescriptor constructorDescriptor : descriptor.getConstructors()) { + if (constructorDescriptor.isPrimary()) { + primary.add(constructorDescriptor); + } + } + if (primary.size() > 1) { + report(collector, descriptor, "Many primary constructors: " + primary); + } + + ConstructorDescriptor primaryConstructor = descriptor.getUnsubstitutedPrimaryConstructor(); + if (primaryConstructor != null) { + if (!descriptor.getConstructors().contains(primaryConstructor)) { + report(collector, primaryConstructor, + "Primary constructor not in getConstructors() result: " + descriptor.getConstructors()); + } + } + + return true; + } + + @Override + public Boolean visitModuleDeclaration( + ModuleDescriptor descriptor, DiagnosticCollector collector + ) { + return true; + } + + @Override + public Boolean visitConstructorDescriptor( + ConstructorDescriptor constructorDescriptor, DiagnosticCollector collector + ) { + visitFunctionDescriptor(constructorDescriptor, collector); + + assertEquals(constructorDescriptor, collector, + "return type", + constructorDescriptor.getContainingDeclaration().getDefaultType(), + constructorDescriptor.getReturnType()); + + return true; + } + + @Override + public Boolean visitScriptDescriptor( + ScriptDescriptor scriptDescriptor, DiagnosticCollector collector + ) { + return true; + } + + @Override + public Boolean visitPropertyDescriptor( + PropertyDescriptor descriptor, DiagnosticCollector collector + ) { + validateCallable(descriptor, collector); + + PropertyGetterDescriptor getter = descriptor.getGetter(); + if (getter != null) { + assertEquals(getter, collector, "getter return type", descriptor.getType(), getter.getReturnType()); + validateAccessor(descriptor, collector, getter, "getter"); + } + + PropertySetterDescriptor setter = descriptor.getSetter(); + if (setter != null) { + assertEquals(setter, collector, "setter parameter count", 1, setter.getValueParameters().size()); + assertEquals(setter, collector, "setter parameter type", descriptor.getType(), setter.getValueParameters().get(0).getType()); + } + + return true; + } + + @Override + public Boolean visitValueParameterDescriptor( + ValueParameterDescriptor descriptor, DiagnosticCollector collector + ) { + visitVariableDescriptor(descriptor, collector); + return true; + } + + @Override + public Boolean visitPropertyGetterDescriptor( + PropertyGetterDescriptor descriptor, DiagnosticCollector collector + ) { + return visitFunctionDescriptor(descriptor, collector); + } + + @Override + public Boolean visitPropertySetterDescriptor( + PropertySetterDescriptor descriptor, DiagnosticCollector collector + ) { + return visitFunctionDescriptor(descriptor, collector); + } + + @Override + public Boolean visitReceiverParameterDescriptor( + ReceiverParameterDescriptor descriptor, DiagnosticCollector collector + ) { + validateType(descriptor, descriptor.getType(), collector); + + if (!descriptor.getValue().exists()) { + report(collector, descriptor, "Receiver value does not exist: " + descriptor.getValue()); + } + return true; + } + + } + + private static class ScopeValidatorVisitor implements DeclarationDescriptorVisitor { + private final DiagnosticCollector collector; + + public ScopeValidatorVisitor(DiagnosticCollector collector) { + this.collector = collector; + } + + private void report(DeclarationDescriptor expected, String message) { + DescriptorValidator.report(collector, expected, message); + } + + private void assertFound( + @NotNull JetScope scope, + @NotNull DeclarationDescriptor expected, + @Nullable DeclarationDescriptor found + ) { + if (found == null) { + report(expected, "Not found in " + scope); + } + if (expected != found) { + report(expected, "Lookup error in " + scope + ": " + found); + } + } + + private void assertFound( + @NotNull JetScope scope, + @NotNull DeclarationDescriptor expected, + @NotNull Collection found + ) { + if (!found.contains(expected)) { + report(expected, "Not found in " + scope + ": " + found); + } + } + + @Override + public Void visitNamespaceDescriptor( + NamespaceDescriptor descriptor, JetScope scope + ) { + assertFound(scope, descriptor, scope.getNamespace(descriptor.getName())); + return null; + } + + @Override + public Void visitVariableDescriptor( + VariableDescriptor descriptor, JetScope scope + ) { + assertFound(scope, descriptor, scope.getProperties(descriptor.getName())); + return null; + } + + @Override + public Void visitFunctionDescriptor( + FunctionDescriptor descriptor, JetScope scope + ) { + assertFound(scope, descriptor, scope.getFunctions(descriptor.getName())); + return null; + } + + @Override + public Void visitTypeParameterDescriptor( + TypeParameterDescriptor descriptor, JetScope scope + ) { + assertFound(scope, descriptor, scope.getClassifier(descriptor.getName())); + return null; + } + + @Override + public Void visitClassDescriptor( + ClassDescriptor descriptor, JetScope scope + ) { + if (descriptor.getKind().isObject()) { + assertFound(scope, descriptor, scope.getObjectDescriptor(descriptor.getName())); + } + else { + assertFound(scope, descriptor, scope.getClassifier(descriptor.getName())); + } + return null; + } + + @Override + public Void visitModuleDeclaration( + ModuleDescriptor descriptor, JetScope scope + ) { + report(descriptor, "Module found in scope: " + scope); + return null; + } + + @Override + public Void visitConstructorDescriptor( + ConstructorDescriptor descriptor, JetScope scope + ) { + report(descriptor, "Constructor found in scope: " + scope); + return null; + } + + @Override + public Void visitScriptDescriptor( + ScriptDescriptor descriptor, JetScope scope + ) { + report(descriptor, "Script found in scope: " + scope); + return null; + } + + @Override + public Void visitPropertyDescriptor( + PropertyDescriptor descriptor, JetScope scope + ) { + return visitVariableDescriptor(descriptor, scope); + } + + @Override + public Void visitValueParameterDescriptor( + ValueParameterDescriptor descriptor, JetScope scope + ) { + return visitVariableDescriptor(descriptor, scope); + } + + @Override + public Void visitPropertyGetterDescriptor( + PropertyGetterDescriptor descriptor, JetScope scope + ) { + report(descriptor, "Getter found in scope: " + scope); + return null; + } + + @Override + public Void visitPropertySetterDescriptor( + PropertySetterDescriptor descriptor, JetScope scope + ) { + report(descriptor, "Setter found in scope: " + scope); + return null; + } + + @Override + public Void visitReceiverParameterDescriptor( + ReceiverParameterDescriptor descriptor, JetScope scope + ) { + report(descriptor, "Receiver parameter found in scope: " + scope); + return null; + } + } + + public static class Diagnostic { + + private final DeclarationDescriptor descriptor; + private final String message; + private final Throwable stackTrace; + + private Diagnostic(@NotNull DeclarationDescriptor descriptor, @NotNull String message) { + this.descriptor = descriptor; + this.message = message; + this.stackTrace = new Throwable(); + } + + @NotNull + public DeclarationDescriptor getDescriptor() { + return descriptor; + } + + @NotNull + public String getMessage() { + return message; + } + + @NotNull + public Throwable getStackTrace() { + return stackTrace; + } + + public void printStackTrace(@NotNull PrintStream out) { + out.println(descriptor); + out.println(message); + stackTrace.printStackTrace(out); + } + + @Override + public String toString() { + return descriptor + " > " + message; + } + } + + private static class DiagnosticCollectorForTests implements DiagnosticCollector { + private boolean errorsFound = false; + + @Override + public void report(@NotNull Diagnostic diagnostic) { + diagnostic.printStackTrace(System.err); + errorsFound = true; + } + + public void done() { + if (errorsFound) { + Assert.fail("Descriptor validation failed (see messages above)"); + } + } + } + +} diff --git a/compiler/tests/org/jetbrains/jet/test/util/RecursiveDescriptorProcessor.java b/compiler/tests/org/jetbrains/jet/test/util/RecursiveDescriptorProcessor.java new file mode 100644 index 00000000000..18e524e46bc --- /dev/null +++ b/compiler/tests/org/jetbrains/jet/test/util/RecursiveDescriptorProcessor.java @@ -0,0 +1,148 @@ +/* + * Copyright 2010-2013 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.jetbrains.jet.test.util; + +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import org.jetbrains.jet.lang.descriptors.*; +import org.jetbrains.jet.lang.resolve.name.FqName; + +import java.util.Collection; +import java.util.Collections; + +public class RecursiveDescriptorProcessor { + public static boolean process( + @NotNull Collection descriptors, + D data, + @NotNull DeclarationDescriptorVisitor visitor + ) { + RecursiveVisitor recursive = new RecursiveVisitor(visitor); + for (DeclarationDescriptor descriptor : descriptors) { + if (!descriptor.accept(visitor, data)) { + return false; + } + descriptor.accept(recursive, data); + } + return true; + } + + public static boolean process( + @NotNull DeclarationDescriptor descriptor, + D data, + @NotNull DeclarationDescriptorVisitor visitor + ) { + return process(Collections.singletonList(descriptor), data, visitor); + } + + private static class RecursiveVisitor implements DeclarationDescriptorVisitor { + + private final DeclarationDescriptorVisitor worker; + + private RecursiveVisitor(@NotNull DeclarationDescriptorVisitor worker) { + this.worker = worker; + } + + private boolean doProcess(Collection descriptors, D data) { + return process(descriptors, data, worker); + } + + private boolean doProcess(@Nullable DeclarationDescriptor receiverParameter, D data) { + if (receiverParameter == null) { + return true; + } + return receiverParameter.accept(worker, data); + } + + private boolean processCallable(CallableDescriptor descriptor, D data) { + return doProcess(descriptor.getTypeParameters(), data) + && doProcess(descriptor.getReceiverParameter(), data) + && doProcess(descriptor.getValueParameters(), data); + } + + @Override + public Boolean visitNamespaceDescriptor(NamespaceDescriptor descriptor, D data) { + return doProcess(descriptor.getMemberScope().getAllDescriptors(), data); + } + + @Override + public Boolean visitVariableDescriptor(VariableDescriptor descriptor, D data) { + return processCallable(descriptor, data); + } + + @Override + public Boolean visitPropertyDescriptor(PropertyDescriptor descriptor, D data) { + return processCallable(descriptor, data) + && doProcess(descriptor.getGetter(), data) + && doProcess(descriptor.getSetter(), data); + } + + @Override + public Boolean visitFunctionDescriptor(FunctionDescriptor descriptor, D data) { + return processCallable(descriptor, data); + } + + @Override + public Boolean visitTypeParameterDescriptor(TypeParameterDescriptor descriptor, D data) { + return true; + } + + @Override + public Boolean visitClassDescriptor(ClassDescriptor descriptor, D data) { + return doProcess(descriptor.getThisAsReceiverParameter(), data) + && doProcess(descriptor.getConstructors(), data) + && doProcess(descriptor.getTypeConstructor().getParameters(), data) + && doProcess(descriptor.getClassObjectDescriptor(), data) + && doProcess(descriptor.getDefaultType().getMemberScope().getObjectDescriptors(), data) + && doProcess(descriptor.getDefaultType().getMemberScope().getAllDescriptors(), data); + } + + @Override + public Boolean visitModuleDeclaration(ModuleDescriptor descriptor, D data) { + return doProcess(descriptor.getNamespace(FqName.ROOT), data); + } + + @Override + public Boolean visitConstructorDescriptor(ConstructorDescriptor constructorDescriptor, D data) { + return visitFunctionDescriptor(constructorDescriptor, data); + } + + @Override + public Boolean visitScriptDescriptor(ScriptDescriptor scriptDescriptor, D data) { + return visitClassDescriptor(scriptDescriptor.getClassDescriptor(), data); + } + + @Override + public Boolean visitValueParameterDescriptor(ValueParameterDescriptor descriptor, D data) { + return visitVariableDescriptor(descriptor, data); + } + + @Override + public Boolean visitPropertyGetterDescriptor(PropertyGetterDescriptor descriptor, D data) { + return visitFunctionDescriptor(descriptor, data); + } + + @Override + public Boolean visitPropertySetterDescriptor(PropertySetterDescriptor descriptor, D data) { + return visitFunctionDescriptor(descriptor, data); + } + + @Override + public Boolean visitReceiverParameterDescriptor(ReceiverParameterDescriptor descriptor, D data) { + return true; + } + } +} From 9d248d5c4a5901be5a265ec226d16569017ef83f Mon Sep 17 00:00:00 2001 From: Andrey Breslav Date: Fri, 7 Jun 2013 16:24:24 +0400 Subject: [PATCH 241/249] equals() fixed for types --- .../src/org/jetbrains/jet/lang/types/DeferredType.java | 8 +++++++- .../src/org/jetbrains/jet/lang/types/JetTypeImpl.java | 6 +++--- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/types/DeferredType.java b/compiler/frontend/src/org/jetbrains/jet/lang/types/DeferredType.java index f43b5a98f96..36562d8dbbb 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/types/DeferredType.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/types/DeferredType.java @@ -96,7 +96,13 @@ public class DeferredType implements JetType { @Override public boolean equals(Object obj) { - return getActualType().equals(obj); + if (this == obj) return true; + JetType actualType = getActualType(); + if (actualType == obj) return true; + + if (!(obj instanceof JetType)) return false; + + return TypeUtils.equalTypes(actualType, (JetType) obj); } @Override diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/types/JetTypeImpl.java b/compiler/frontend/src/org/jetbrains/jet/lang/types/JetTypeImpl.java index e711d3328bf..3670a6424d7 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/types/JetTypeImpl.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/types/JetTypeImpl.java @@ -102,11 +102,11 @@ public final class JetTypeImpl extends AnnotatedImpl implements JetType { @Override public boolean equals(Object o) { if (this == o) return true; - if (o == null || getClass() != o.getClass()) return false; + if (!(o instanceof JetType)) return false; - JetTypeImpl type = (JetTypeImpl) o; + JetType type = (JetType) o; - return nullable == type.nullable && JetTypeChecker.INSTANCE.equalTypes(this, type); + return nullable == type.isNullable() && JetTypeChecker.INSTANCE.equalTypes(this, type); } @Override From aa985242ba2166241b4f94e4c6d7ae86e0bb299c Mon Sep 17 00:00:00 2001 From: Andrey Breslav Date: Fri, 7 Jun 2013 17:12:08 +0400 Subject: [PATCH 242/249] Some Java tests deliberately have error types --- .../jet/jvm/compiler/LoadDescriptorUtil.java | 2 +- .../jet/test/util/DescriptorValidator.java | 45 +++++++++++-------- 2 files changed, 27 insertions(+), 20 deletions(-) diff --git a/compiler/tests/org/jetbrains/jet/jvm/compiler/LoadDescriptorUtil.java b/compiler/tests/org/jetbrains/jet/jvm/compiler/LoadDescriptorUtil.java index 22f22563599..cac81dec73a 100644 --- a/compiler/tests/org/jetbrains/jet/jvm/compiler/LoadDescriptorUtil.java +++ b/compiler/tests/org/jetbrains/jet/jvm/compiler/LoadDescriptorUtil.java @@ -108,7 +108,7 @@ public final class LoadDescriptorUtil { javaDescriptorResolver.resolveNamespace(TEST_PACKAGE_FQNAME, DescriptorSearchRule.ERROR_IF_FOUND_IN_KOTLIN); assert namespaceDescriptor != null; - DescriptorValidator.validate(namespaceDescriptor); + DescriptorValidator.validateIgnoringErrorTypes(namespaceDescriptor); return Pair.create(namespaceDescriptor, injector.getBindingTrace().getBindingContext()); } diff --git a/compiler/tests/org/jetbrains/jet/test/util/DescriptorValidator.java b/compiler/tests/org/jetbrains/jet/test/util/DescriptorValidator.java index afc2079f311..0bce353abbf 100644 --- a/compiler/tests/org/jetbrains/jet/test/util/DescriptorValidator.java +++ b/compiler/tests/org/jetbrains/jet/test/util/DescriptorValidator.java @@ -32,28 +32,33 @@ import java.util.List; public class DescriptorValidator { + public static final ValidationVisitor FORBID_ERROR_TYPES = new ValidationVisitor(false); + public static final ValidationVisitor ALLOW_ERROR_TYPES = new ValidationVisitor(true); + private DescriptorValidator() {} public static void validate(DeclarationDescriptor... descriptors) { - validate(Arrays.asList(descriptors)); + validate(FORBID_ERROR_TYPES, Arrays.asList(descriptors)); } - public static void validate(@NotNull Collection descriptors) { + public static void validateIgnoringErrorTypes(DeclarationDescriptor... descriptors) { + validate(ALLOW_ERROR_TYPES, Arrays.asList(descriptors)); + } + + public static void validate(@NotNull ValidationVisitor validator, @NotNull Collection descriptors) { DiagnosticCollectorForTests collector = new DiagnosticCollectorForTests(); for (DeclarationDescriptor descriptor : descriptors) { - validate(descriptor, collector); + validate(validator, descriptor, collector); } collector.done(); } - public static void validate(@NotNull Collection descriptors, @NotNull DiagnosticCollector collector) { - for (DeclarationDescriptor descriptor : descriptors) { - validate(descriptor, collector); - } - } - - public static void validate(@NotNull DeclarationDescriptor descriptor, @NotNull DiagnosticCollector collector) { - RecursiveDescriptorProcessor.process(descriptor, collector, ValidationVisitor.INSTANCE); + public static void validate( + @NotNull ValidationVisitor validator, + @NotNull DeclarationDescriptor descriptor, + @NotNull DiagnosticCollector collector + ) { + RecursiveDescriptorProcessor.process(descriptor, collector, validator); } public interface DiagnosticCollector { @@ -65,11 +70,13 @@ public class DescriptorValidator { collector.report(new Diagnostic(descriptor, message)); } - private static class ValidationVisitor implements DeclarationDescriptorVisitor { + public static class ValidationVisitor implements DeclarationDescriptorVisitor { - public static final ValidationVisitor INSTANCE = new ValidationVisitor(); + private final boolean allowErrorTypes; - private ValidationVisitor() {} + private ValidationVisitor(boolean allowErrorTypes) { + this.allowErrorTypes = allowErrorTypes; + } private static void validateScope(@NotNull JetScope scope, @NotNull DiagnosticCollector collector) { for (DeclarationDescriptor descriptor : scope.getAllDescriptors()) { @@ -77,7 +84,7 @@ public class DescriptorValidator { } } - private static void validateType( + private void validateType( @NotNull DeclarationDescriptor descriptor, @Nullable JetType type, @NotNull DiagnosticCollector collector @@ -87,7 +94,7 @@ public class DescriptorValidator { return; } - if (ErrorUtils.isErrorType(type)) { + if (!allowErrorTypes && ErrorUtils.isErrorType(type)) { report(collector, descriptor, "Error type: " + type); return; } @@ -95,7 +102,7 @@ public class DescriptorValidator { validateScope(type.getMemberScope(), collector); } - private static void validateReturnType(CallableDescriptor descriptor, DiagnosticCollector collector) { + private void validateReturnType(CallableDescriptor descriptor, DiagnosticCollector collector) { validateType(descriptor, descriptor.getReturnType(), collector); } @@ -117,7 +124,7 @@ public class DescriptorValidator { } } - private static void validateTypes( + private void validateTypes( DeclarationDescriptor descriptor, DiagnosticCollector collector, Collection types @@ -127,7 +134,7 @@ public class DescriptorValidator { } } - private static void validateCallable(CallableDescriptor descriptor, DiagnosticCollector collector) { + private void validateCallable(CallableDescriptor descriptor, DiagnosticCollector collector) { validateReturnType(descriptor, collector); validateTypeParameters(collector, descriptor.getTypeParameters()); validateValueParameters(collector, descriptor.getValueParameters()); From 56f040608ab46bcf0d988b7e70ba5437ce10c02b Mon Sep 17 00:00:00 2001 From: Andrey Breslav Date: Fri, 7 Jun 2013 17:13:46 +0400 Subject: [PATCH 243/249] Minor: Reorder declarations --- .../jetbrains/jet/test/util/DescriptorValidator.java | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/compiler/tests/org/jetbrains/jet/test/util/DescriptorValidator.java b/compiler/tests/org/jetbrains/jet/test/util/DescriptorValidator.java index 0bce353abbf..9a5c2c5bdde 100644 --- a/compiler/tests/org/jetbrains/jet/test/util/DescriptorValidator.java +++ b/compiler/tests/org/jetbrains/jet/test/util/DescriptorValidator.java @@ -35,8 +35,6 @@ public class DescriptorValidator { public static final ValidationVisitor FORBID_ERROR_TYPES = new ValidationVisitor(false); public static final ValidationVisitor ALLOW_ERROR_TYPES = new ValidationVisitor(true); - private DescriptorValidator() {} - public static void validate(DeclarationDescriptor... descriptors) { validate(FORBID_ERROR_TYPES, Arrays.asList(descriptors)); } @@ -61,15 +59,14 @@ public class DescriptorValidator { RecursiveDescriptorProcessor.process(descriptor, collector, validator); } - public interface DiagnosticCollector { - - void report(@NotNull Diagnostic diagnostic); - } - private static void report(@NotNull DiagnosticCollector collector, @NotNull DeclarationDescriptor descriptor, @NotNull String message) { collector.report(new Diagnostic(descriptor, message)); } + public interface DiagnosticCollector { + void report(@NotNull Diagnostic diagnostic); + } + public static class ValidationVisitor implements DeclarationDescriptorVisitor { private final boolean allowErrorTypes; @@ -510,4 +507,5 @@ public class DescriptorValidator { } } + private DescriptorValidator() {} } From 3e8031acbd4ecbde9fa0f804bc724183d3740f5d Mon Sep 17 00:00:00 2001 From: Andrey Breslav Date: Fri, 7 Jun 2013 17:47:40 +0400 Subject: [PATCH 244/249] Properly load objects nested into class objects from Java --- .../resolver/JavaClassObjectResolver.java | 2 +- .../resolve/java/scope/JavaBaseScope.java | 29 +++++++++++++++---- .../resolve/scopes/WritableScopeImpl.java | 19 ++++++++++-- .../diagnostics/tests/objects/Objects.kt | 4 +-- .../tests/objects/ObjectsInheritance.kt | 2 +- .../loadKotlin/class/NamedObjectInClass.kt | 8 +++++ .../loadKotlin/class/NamedObjectInClass.txt | 13 +++++++++ .../LoadCompiledKotlinTestGenerated.java | 5 ++++ ...esolveNamespaceComparingTestGenerated.java | 5 ++++ 9 files changed, 76 insertions(+), 11 deletions(-) create mode 100644 compiler/testData/loadKotlin/class/NamedObjectInClass.kt create mode 100644 compiler/testData/loadKotlin/class/NamedObjectInClass.txt diff --git a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/resolver/JavaClassObjectResolver.java b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/resolver/JavaClassObjectResolver.java index 8bf16a28584..5f59d056aee 100644 --- a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/resolver/JavaClassObjectResolver.java +++ b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/resolver/JavaClassObjectResolver.java @@ -149,7 +149,7 @@ public final class JavaClassObjectResolver { classObjectDescriptor.createTypeConstructor(); JavaClassNonStaticMembersScope classMembersScope = new JavaClassNonStaticMembersScope(classObjectDescriptor, data, semanticServices); WritableScopeImpl writableScope = - new WritableScopeImpl(classMembersScope, classObjectDescriptor, RedeclarationHandler.THROW_EXCEPTION, fqName.toString()); + new WritableScopeImpl(classMembersScope, classObjectDescriptor, RedeclarationHandler.THROW_EXCEPTION, "Member lookup scope"); writableScope.changeLockLevel(WritableScope.LockLevel.BOTH); classObjectDescriptor.setScopeForMemberLookup(writableScope); classObjectDescriptor.setScopeForConstructorResolve(classMembersScope); diff --git a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/scope/JavaBaseScope.java b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/scope/JavaBaseScope.java index 74628e966a8..6f1edf2f678 100644 --- a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/scope/JavaBaseScope.java +++ b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/scope/JavaBaseScope.java @@ -20,7 +20,9 @@ import com.google.common.collect.Lists; import com.google.common.collect.Maps; import com.google.common.collect.Sets; import com.intellij.openapi.progress.ProgressIndicatorProvider; +import com.intellij.openapi.util.Condition; import com.intellij.psi.PsiElement; +import com.intellij.util.containers.ContainerUtil; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.jet.lang.descriptors.*; @@ -33,10 +35,7 @@ import org.jetbrains.jet.lang.resolve.java.provider.PsiDeclarationProvider; import org.jetbrains.jet.lang.resolve.name.Name; import org.jetbrains.jet.lang.resolve.scopes.JetScopeImpl; -import java.util.Collection; -import java.util.Collections; -import java.util.Map; -import java.util.Set; +import java.util.*; public abstract class JavaBaseScope extends JetScopeImpl { @@ -50,6 +49,8 @@ public abstract class JavaBaseScope extends JetScopeImpl { private final Map> propertyDescriptors = Maps.newHashMap(); @Nullable private Collection allDescriptors = null; + @Nullable + private Set objectDescriptors = null; @NotNull protected final ClassOrNamespaceDescriptor descriptor; @@ -130,10 +131,19 @@ public abstract class JavaBaseScope extends JetScopeImpl { protected Collection computeAllDescriptors() { Collection result = Sets.newHashSet(); result.addAll(computeFieldAndFunctionDescriptors()); - result.addAll(getInnerClasses()); + result.addAll(filterObjects(getInnerClasses(), false)); return result; } + @NotNull + @Override + public Set getObjectDescriptors() { + if (objectDescriptors == null) { + objectDescriptors = new HashSet(filterObjects(getInnerClasses(), true)); + } + return objectDescriptors; + } + @NotNull protected abstract Collection computeInnerClasses(); @@ -174,4 +184,13 @@ public abstract class JavaBaseScope extends JetScopeImpl { } return innerClasses; } + + private static Collection filterObjects(Collection classes, final boolean objects) { + return ContainerUtil.filter(classes, new Condition() { + @Override + public boolean value(T classDescriptor) { + return classDescriptor.getKind().isObject() == objects; + } + }); + } } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/scopes/WritableScopeImpl.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/scopes/WritableScopeImpl.java index 7f1c06745b2..8aeb050d97a 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/scopes/WritableScopeImpl.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/scopes/WritableScopeImpl.java @@ -33,6 +33,8 @@ public class WritableScopeImpl extends WritableScopeWithImports { private final Multimap declaredDescriptorsAccessibleBySimpleName = HashMultimap.create(); private boolean allDescriptorsDone = false; + private Set allObjectDescriptors = null; + @NotNull private final DeclarationDescriptor ownerDeclarationDescriptor; @@ -401,13 +403,26 @@ public class WritableScopeImpl extends WritableScopeWithImports { @Override public ClassDescriptor getObjectDescriptor(@NotNull Name name) { - return getObjectDescriptorsMap().get(name); + ClassDescriptor descriptor = getObjectDescriptorsMap().get(name); + if (descriptor != null) return descriptor; + + ClassDescriptor fromWorker = getWorkerScope().getObjectDescriptor(name); + if (fromWorker != null) return fromWorker; + + return super.getObjectDescriptor(name); } @NotNull @Override public Set getObjectDescriptors() { - return Sets.newHashSet(getObjectDescriptorsMap().values()); + if (allObjectDescriptors == null) { + allObjectDescriptors = Sets.newHashSet(getObjectDescriptorsMap().values()); + allObjectDescriptors.addAll(getWorkerScope().getObjectDescriptors()); + for (JetScope imported : getImports()) { + allObjectDescriptors.addAll(imported.getObjectDescriptors()); + } + } + return allObjectDescriptors; } @Override diff --git a/compiler/testData/diagnostics/tests/objects/Objects.kt b/compiler/testData/diagnostics/tests/objects/Objects.kt index 27575534eb1..f9f8fc7a515 100644 --- a/compiler/testData/diagnostics/tests/objects/Objects.kt +++ b/compiler/testData/diagnostics/tests/objects/Objects.kt @@ -14,7 +14,7 @@ package toplevelObjectDeclarations } } - object B : A {} + object B : A {} val x = A.foo() @@ -26,4 +26,4 @@ package toplevelObjectDeclarations override fun foo() : Int = 1 } - val z = y.foo() + val z = y.foo() \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/objects/ObjectsInheritance.kt b/compiler/testData/diagnostics/tests/objects/ObjectsInheritance.kt index 9d7c9ee16ee..441221407cc 100644 --- a/compiler/testData/diagnostics/tests/objects/ObjectsInheritance.kt +++ b/compiler/testData/diagnostics/tests/objects/ObjectsInheritance.kt @@ -3,4 +3,4 @@ package toplevelObjectDeclarations object CObj {} -object DOjb : CObj {} +object DOjb : CObj {} \ No newline at end of file diff --git a/compiler/testData/loadKotlin/class/NamedObjectInClass.kt b/compiler/testData/loadKotlin/class/NamedObjectInClass.kt new file mode 100644 index 00000000000..367c75a314a --- /dev/null +++ b/compiler/testData/loadKotlin/class/NamedObjectInClass.kt @@ -0,0 +1,8 @@ +package test + +public class Outer { + public object Obj { + public val v: String = "val" + public fun f(): String = "fun" + } +} diff --git a/compiler/testData/loadKotlin/class/NamedObjectInClass.txt b/compiler/testData/loadKotlin/class/NamedObjectInClass.txt new file mode 100644 index 00000000000..d34694c31c3 --- /dev/null +++ b/compiler/testData/loadKotlin/class/NamedObjectInClass.txt @@ -0,0 +1,13 @@ +package test + +public final class Outer { + /*primary*/ public constructor Outer() + public final val Obj: test.Outer.Obj + + public object Obj { + /*primary*/ private constructor Obj() + public final val v: jet.String + public final fun (): jet.String + public final fun f(): jet.String + } +} diff --git a/compiler/tests/org/jetbrains/jet/jvm/compiler/LoadCompiledKotlinTestGenerated.java b/compiler/tests/org/jetbrains/jet/jvm/compiler/LoadCompiledKotlinTestGenerated.java index 191e3bb70de..036177825ea 100644 --- a/compiler/tests/org/jetbrains/jet/jvm/compiler/LoadCompiledKotlinTestGenerated.java +++ b/compiler/tests/org/jetbrains/jet/jvm/compiler/LoadCompiledKotlinTestGenerated.java @@ -158,6 +158,11 @@ public class LoadCompiledKotlinTestGenerated extends AbstractLoadCompiledKotlinT doTestWithAccessors("compiler/testData/loadKotlin/class/NamedObject.kt"); } + @TestMetadata("NamedObjectInClass.kt") + public void testNamedObjectInClass() throws Exception { + doTestWithAccessors("compiler/testData/loadKotlin/class/NamedObjectInClass.kt"); + } + @TestMetadata("NamedObjectInClassObject.kt") public void testNamedObjectInClassObject() throws Exception { doTestWithAccessors("compiler/testData/loadKotlin/class/NamedObjectInClassObject.kt"); diff --git a/compiler/tests/org/jetbrains/jet/lang/resolve/lazy/LazyResolveNamespaceComparingTestGenerated.java b/compiler/tests/org/jetbrains/jet/lang/resolve/lazy/LazyResolveNamespaceComparingTestGenerated.java index 4bf970ac668..f6e5a1cdd7f 100644 --- a/compiler/tests/org/jetbrains/jet/lang/resolve/lazy/LazyResolveNamespaceComparingTestGenerated.java +++ b/compiler/tests/org/jetbrains/jet/lang/resolve/lazy/LazyResolveNamespaceComparingTestGenerated.java @@ -160,6 +160,11 @@ public class LazyResolveNamespaceComparingTestGenerated extends AbstractLazyReso doTestCheckingPrimaryConstructorsAndAccessors("compiler/testData/loadKotlin/class/NamedObject.kt"); } + @TestMetadata("NamedObjectInClass.kt") + public void testNamedObjectInClass() throws Exception { + doTestCheckingPrimaryConstructorsAndAccessors("compiler/testData/loadKotlin/class/NamedObjectInClass.kt"); + } + @TestMetadata("NamedObjectInClassObject.kt") public void testNamedObjectInClassObject() throws Exception { doTestCheckingPrimaryConstructorsAndAccessors("compiler/testData/loadKotlin/class/NamedObjectInClassObject.kt"); From 77261a5922d3d1fcde4603d48a38830f4c71fad1 Mon Sep 17 00:00:00 2001 From: Andrey Breslav Date: Fri, 7 Jun 2013 19:13:44 +0400 Subject: [PATCH 245/249] Render properties in builtin-classes.txt --- compiler/testData/builtin-classes.txt | 195 ++++++++++++------ .../lazy/LazyResolveBuiltinClassesTest.java | 4 +- .../jet/test/util/NamespaceComparator.java | 1 + 3 files changed, 139 insertions(+), 61 deletions(-) diff --git a/compiler/testData/builtin-classes.txt b/compiler/testData/builtin-classes.txt index 49213867dbf..1082314e80a 100644 --- a/compiler/testData/builtin-classes.txt +++ b/compiler/testData/builtin-classes.txt @@ -12,20 +12,22 @@ public trait Annotation { } public open class Any { - public constructor Any() + /*primary*/ public constructor Any() } public final class Array { - public constructor Array(/*0*/ size: jet.Int, /*1*/ init: (jet.Int) -> T) + /*primary*/ public constructor Array(/*0*/ size: jet.Int, /*1*/ init: (jet.Int) -> T) public final val indices: jet.IntRange + public final fun (): jet.IntRange public final val size: jet.Int + public final fun (): jet.Int public final fun get(/*0*/ index: jet.Int): T public final fun iterator(): jet.Iterator public final fun set(/*0*/ index: jet.Int, /*1*/ value: T): jet.Unit } public final class Boolean { - public constructor Boolean() + /*primary*/ public constructor Boolean() public final fun and(/*0*/ other: jet.Boolean): jet.Boolean public final fun equals(/*0*/ other: jet.Any?): jet.Boolean public final fun not(): jet.Boolean @@ -34,23 +36,25 @@ public final class Boolean { } public final class BooleanArray { - public constructor BooleanArray(/*0*/ size: jet.Int) + /*primary*/ public constructor BooleanArray(/*0*/ size: jet.Int) public final val indices: jet.IntRange + public final fun (): jet.IntRange public final val size: jet.Int + public final fun (): jet.Int public final fun get(/*0*/ index: jet.Int): jet.Boolean public final fun iterator(): jet.BooleanIterator public final fun set(/*0*/ index: jet.Int, /*1*/ value: jet.Boolean): jet.Unit } public abstract class BooleanIterator : jet.Iterator { - public constructor BooleanIterator() + /*primary*/ public constructor BooleanIterator() public abstract override /*1*/ /*fake_override*/ fun hasNext(): jet.Boolean public open override /*1*/ fun next(): jet.Boolean public abstract fun nextBoolean(): jet.Boolean } public final class Byte : jet.Number, jet.Comparable { - public constructor Byte() + /*primary*/ public constructor Byte() public open override /*1*/ fun compareTo(/*0*/ other: jet.Byte): jet.Int public final fun compareTo(/*0*/ other: jet.Char): jet.Int public final fun compareTo(/*0*/ other: jet.Double): jet.Int @@ -116,45 +120,54 @@ public final class Byte : jet.Number, jet.Comparable { } public final class ByteArray { - public constructor ByteArray(/*0*/ size: jet.Int) + /*primary*/ public constructor ByteArray(/*0*/ size: jet.Int) public final val indices: jet.IntRange + public final fun (): jet.IntRange public final val size: jet.Int + public final fun (): jet.Int public final fun get(/*0*/ index: jet.Int): jet.Byte public final fun iterator(): jet.ByteIterator public final fun set(/*0*/ index: jet.Int, /*1*/ value: jet.Byte): jet.Unit } public abstract class ByteIterator : jet.Iterator { - public constructor ByteIterator() + /*primary*/ public constructor ByteIterator() public abstract override /*1*/ /*fake_override*/ fun hasNext(): jet.Boolean public open override /*1*/ fun next(): jet.Byte public abstract fun nextByte(): jet.Byte } public final class ByteProgression : jet.Progression { - public constructor ByteProgression(/*0*/ start: jet.Byte, /*1*/ end: jet.Byte, /*2*/ increment: jet.Int) + /*primary*/ public constructor ByteProgression(/*0*/ start: jet.Byte, /*1*/ end: jet.Byte, /*2*/ increment: jet.Int) public open override /*1*/ val end: jet.Byte + public open override /*1*/ fun (): jet.Byte public open override /*1*/ val increment: jet.Int + public open override /*1*/ fun (): jet.Int public open override /*1*/ val start: jet.Byte + public open override /*1*/ fun (): jet.Byte public open override /*1*/ fun iterator(): jet.ByteIterator } public final class ByteRange : jet.Range, jet.Progression { - public constructor ByteRange(/*0*/ start: jet.Byte, /*1*/ end: jet.Byte) + /*primary*/ public constructor ByteRange(/*0*/ start: jet.Byte, /*1*/ end: jet.Byte) public open override /*2*/ val end: jet.Byte + public open override /*2*/ fun (): jet.Byte public open override /*1*/ val increment: jet.Int + public open override /*1*/ fun (): jet.Int public open override /*2*/ val start: jet.Byte + public open override /*2*/ fun (): jet.Byte public open override /*1*/ fun contains(/*0*/ item: jet.Byte): jet.Boolean public open override /*1*/ fun iterator(): jet.ByteIterator public class object { - private constructor () + /*primary*/ private constructor () public final val EMPTY: jet.ByteRange + public final fun (): jet.ByteRange } } public final class Char : jet.Number, jet.Comparable { - public constructor Char() + /*primary*/ public constructor Char() public final fun compareTo(/*0*/ other: jet.Byte): jet.Int public open override /*1*/ fun compareTo(/*0*/ other: jet.Char): jet.Int public final fun compareTo(/*0*/ other: jet.Double): jet.Int @@ -210,45 +223,55 @@ public final class Char : jet.Number, jet.Comparable { } public final class CharArray { - public constructor CharArray(/*0*/ size: jet.Int) + /*primary*/ public constructor CharArray(/*0*/ size: jet.Int) public final val indices: jet.IntRange + public final fun (): jet.IntRange public final val size: jet.Int + public final fun (): jet.Int public final fun get(/*0*/ index: jet.Int): jet.Char public final fun iterator(): jet.CharIterator public final fun set(/*0*/ index: jet.Int, /*1*/ value: jet.Char): jet.Unit } public abstract class CharIterator : jet.Iterator { - public constructor CharIterator() + /*primary*/ public constructor CharIterator() public abstract override /*1*/ /*fake_override*/ fun hasNext(): jet.Boolean public open override /*1*/ fun next(): jet.Char public abstract fun nextChar(): jet.Char } public final class CharProgression : jet.Progression { - public constructor CharProgression(/*0*/ start: jet.Char, /*1*/ end: jet.Char, /*2*/ increment: jet.Int) + /*primary*/ public constructor CharProgression(/*0*/ start: jet.Char, /*1*/ end: jet.Char, /*2*/ increment: jet.Int) public open override /*1*/ val end: jet.Char + public open override /*1*/ fun (): jet.Char public open override /*1*/ val increment: jet.Int + public open override /*1*/ fun (): jet.Int public open override /*1*/ val start: jet.Char + public open override /*1*/ fun (): jet.Char public open override /*1*/ fun iterator(): jet.CharIterator } public final class CharRange : jet.Range, jet.Progression { - public constructor CharRange(/*0*/ start: jet.Char, /*1*/ end: jet.Char) + /*primary*/ public constructor CharRange(/*0*/ start: jet.Char, /*1*/ end: jet.Char) public open override /*2*/ val end: jet.Char + public open override /*2*/ fun (): jet.Char public open override /*1*/ val increment: jet.Int + public open override /*1*/ fun (): jet.Int public open override /*2*/ val start: jet.Char + public open override /*2*/ fun (): jet.Char public open override /*1*/ fun contains(/*0*/ item: jet.Char): jet.Boolean public open override /*1*/ fun iterator(): jet.CharIterator public class object { - private constructor () + /*primary*/ private constructor () public final val EMPTY: jet.CharRange + public final fun (): jet.CharRange } } public trait CharSequence { public abstract val length: jet.Int + public abstract fun (): jet.Int public abstract fun get(/*0*/ index: jet.Int): jet.Char public abstract fun toString(): jet.String } @@ -270,7 +293,7 @@ public trait Comparable { } public final class Double : jet.Number, jet.Comparable { - public constructor Double() + /*primary*/ public constructor Double() public final fun compareTo(/*0*/ other: jet.Byte): jet.Int public final fun compareTo(/*0*/ other: jet.Char): jet.Int public open override /*1*/ fun compareTo(/*0*/ other: jet.Double): jet.Int @@ -335,45 +358,54 @@ public final class Double : jet.Number, jet.Comparable { } public final class DoubleArray { - public constructor DoubleArray(/*0*/ size: jet.Int) + /*primary*/ public constructor DoubleArray(/*0*/ size: jet.Int) public final val indices: jet.IntRange + public final fun (): jet.IntRange public final val size: jet.Int + public final fun (): jet.Int public final fun get(/*0*/ index: jet.Int): jet.Double public final fun iterator(): jet.DoubleIterator public final fun set(/*0*/ index: jet.Int, /*1*/ value: jet.Double): jet.Unit } public abstract class DoubleIterator : jet.Iterator { - public constructor DoubleIterator() + /*primary*/ public constructor DoubleIterator() public abstract override /*1*/ /*fake_override*/ fun hasNext(): jet.Boolean public open override /*1*/ fun next(): jet.Double public abstract fun nextDouble(): jet.Double } public final class DoubleProgression : jet.Progression { - public constructor DoubleProgression(/*0*/ start: jet.Double, /*1*/ end: jet.Double, /*2*/ increment: jet.Double) + /*primary*/ public constructor DoubleProgression(/*0*/ start: jet.Double, /*1*/ end: jet.Double, /*2*/ increment: jet.Double) public open override /*1*/ val end: jet.Double + public open override /*1*/ fun (): jet.Double public open override /*1*/ val increment: jet.Double + public open override /*1*/ fun (): jet.Double public open override /*1*/ val start: jet.Double + public open override /*1*/ fun (): jet.Double public open override /*1*/ fun iterator(): jet.DoubleIterator } public final class DoubleRange : jet.Range, jet.Progression { - public constructor DoubleRange(/*0*/ start: jet.Double, /*1*/ end: jet.Double) + /*primary*/ public constructor DoubleRange(/*0*/ start: jet.Double, /*1*/ end: jet.Double) public open override /*2*/ val end: jet.Double + public open override /*2*/ fun (): jet.Double public open override /*1*/ val increment: jet.Double + public open override /*1*/ fun (): jet.Double public open override /*2*/ val start: jet.Double + public open override /*2*/ fun (): jet.Double public open override /*1*/ fun contains(/*0*/ item: jet.Double): jet.Boolean public open override /*1*/ fun iterator(): jet.DoubleIterator public class object { - private constructor () + /*primary*/ private constructor () public final val EMPTY: jet.DoubleRange + public final fun (): jet.DoubleRange } } public abstract class Enum> { - public constructor Enum>(/*0*/ name: jet.String, /*1*/ ordinal: jet.Int) + /*primary*/ public constructor Enum>(/*0*/ name: jet.String, /*1*/ ordinal: jet.Int) public final fun name(): jet.String public final fun ordinal(): jet.Int } @@ -471,7 +503,7 @@ public trait ExtensionFunction9 { - public constructor Float() + /*primary*/ public constructor Float() public final fun compareTo(/*0*/ other: jet.Byte): jet.Int public final fun compareTo(/*0*/ other: jet.Char): jet.Int public final fun compareTo(/*0*/ other: jet.Double): jet.Int @@ -537,40 +569,49 @@ public final class Float : jet.Number, jet.Comparable { } public final class FloatArray { - public constructor FloatArray(/*0*/ size: jet.Int) + /*primary*/ public constructor FloatArray(/*0*/ size: jet.Int) public final val indices: jet.IntRange + public final fun (): jet.IntRange public final val size: jet.Int + public final fun (): jet.Int public final fun get(/*0*/ index: jet.Int): jet.Float public final fun iterator(): jet.FloatIterator public final fun set(/*0*/ index: jet.Int, /*1*/ value: jet.Float): jet.Unit } public abstract class FloatIterator : jet.Iterator { - public constructor FloatIterator() + /*primary*/ public constructor FloatIterator() public abstract override /*1*/ /*fake_override*/ fun hasNext(): jet.Boolean public open override /*1*/ fun next(): jet.Float public abstract fun nextFloat(): jet.Float } public final class FloatProgression : jet.Progression { - public constructor FloatProgression(/*0*/ start: jet.Float, /*1*/ end: jet.Float, /*2*/ increment: jet.Float) + /*primary*/ public constructor FloatProgression(/*0*/ start: jet.Float, /*1*/ end: jet.Float, /*2*/ increment: jet.Float) public open override /*1*/ val end: jet.Float + public open override /*1*/ fun (): jet.Float public open override /*1*/ val increment: jet.Float + public open override /*1*/ fun (): jet.Float public open override /*1*/ val start: jet.Float + public open override /*1*/ fun (): jet.Float public open override /*1*/ fun iterator(): jet.FloatIterator } public final class FloatRange : jet.Range, jet.Progression { - public constructor FloatRange(/*0*/ start: jet.Float, /*1*/ end: jet.Float) + /*primary*/ public constructor FloatRange(/*0*/ start: jet.Float, /*1*/ end: jet.Float) public open override /*2*/ val end: jet.Float + public open override /*2*/ fun (): jet.Float public open override /*1*/ val increment: jet.Float + public open override /*1*/ fun (): jet.Float public open override /*2*/ val start: jet.Float + public open override /*2*/ fun (): jet.Float public open override /*1*/ fun contains(/*0*/ item: jet.Float): jet.Boolean public open override /*1*/ fun iterator(): jet.FloatIterator public class object { - private constructor () + /*primary*/ private constructor () public final val EMPTY: jet.FloatRange + public final fun (): jet.FloatRange } } @@ -672,7 +713,7 @@ public trait Hashable { } public final class Int : jet.Number, jet.Comparable { - public constructor Int() + /*primary*/ public constructor Int() public final fun and(/*0*/ other: jet.Int): jet.Int public final fun compareTo(/*0*/ other: jet.Byte): jet.Int public final fun compareTo(/*0*/ other: jet.Char): jet.Int @@ -745,40 +786,49 @@ public final class Int : jet.Number, jet.Comparable { } public final class IntArray { - public constructor IntArray(/*0*/ size: jet.Int) + /*primary*/ public constructor IntArray(/*0*/ size: jet.Int) public final val indices: jet.IntRange + public final fun (): jet.IntRange public final val size: jet.Int + public final fun (): jet.Int public final fun get(/*0*/ index: jet.Int): jet.Int public final fun iterator(): jet.IntIterator public final fun set(/*0*/ index: jet.Int, /*1*/ value: jet.Int): jet.Unit } public abstract class IntIterator : jet.Iterator { - public constructor IntIterator() + /*primary*/ public constructor IntIterator() public abstract override /*1*/ /*fake_override*/ fun hasNext(): jet.Boolean public open override /*1*/ fun next(): jet.Int public abstract fun nextInt(): jet.Int } public final class IntProgression : jet.Progression { - public constructor IntProgression(/*0*/ start: jet.Int, /*1*/ end: jet.Int, /*2*/ increment: jet.Int) + /*primary*/ public constructor IntProgression(/*0*/ start: jet.Int, /*1*/ end: jet.Int, /*2*/ increment: jet.Int) public open override /*1*/ val end: jet.Int + public open override /*1*/ fun (): jet.Int public open override /*1*/ val increment: jet.Int + public open override /*1*/ fun (): jet.Int public open override /*1*/ val start: jet.Int + public open override /*1*/ fun (): jet.Int public open override /*1*/ fun iterator(): jet.IntIterator } public final class IntRange : jet.Range, jet.Progression { - public constructor IntRange(/*0*/ start: jet.Int, /*1*/ end: jet.Int) + /*primary*/ public constructor IntRange(/*0*/ start: jet.Int, /*1*/ end: jet.Int) public open override /*2*/ val end: jet.Int + public open override /*2*/ fun (): jet.Int public open override /*1*/ val increment: jet.Int + public open override /*1*/ fun (): jet.Int public open override /*2*/ val start: jet.Int + public open override /*2*/ fun (): jet.Int public open override /*1*/ fun contains(/*0*/ item: jet.Int): jet.Boolean public open override /*1*/ fun iterator(): jet.IntIterator public class object { - private constructor () + /*primary*/ private constructor () public final val EMPTY: jet.IntRange + public final fun (): jet.IntRange } } @@ -1095,7 +1145,7 @@ public trait ListIterator : jet.Iterator { } public final class Long : jet.Number, jet.Comparable { - public constructor Long() + /*primary*/ public constructor Long() public final fun and(/*0*/ other: jet.Long): jet.Long public final fun compareTo(/*0*/ other: jet.Byte): jet.Int public final fun compareTo(/*0*/ other: jet.Char): jet.Int @@ -1168,40 +1218,49 @@ public final class Long : jet.Number, jet.Comparable { } public final class LongArray { - public constructor LongArray(/*0*/ size: jet.Int) + /*primary*/ public constructor LongArray(/*0*/ size: jet.Int) public final val indices: jet.IntRange + public final fun (): jet.IntRange public final val size: jet.Int + public final fun (): jet.Int public final fun get(/*0*/ index: jet.Int): jet.Long public final fun iterator(): jet.LongIterator public final fun set(/*0*/ index: jet.Int, /*1*/ value: jet.Long): jet.Unit } public abstract class LongIterator : jet.Iterator { - public constructor LongIterator() + /*primary*/ public constructor LongIterator() public abstract override /*1*/ /*fake_override*/ fun hasNext(): jet.Boolean public open override /*1*/ fun next(): jet.Long public abstract fun nextLong(): jet.Long } public final class LongProgression : jet.Progression { - public constructor LongProgression(/*0*/ start: jet.Long, /*1*/ end: jet.Long, /*2*/ increment: jet.Long) + /*primary*/ public constructor LongProgression(/*0*/ start: jet.Long, /*1*/ end: jet.Long, /*2*/ increment: jet.Long) public open override /*1*/ val end: jet.Long + public open override /*1*/ fun (): jet.Long public open override /*1*/ val increment: jet.Long + public open override /*1*/ fun (): jet.Long public open override /*1*/ val start: jet.Long + public open override /*1*/ fun (): jet.Long public open override /*1*/ fun iterator(): jet.LongIterator } public final class LongRange : jet.Range, jet.Progression { - public constructor LongRange(/*0*/ start: jet.Long, /*1*/ end: jet.Long) + /*primary*/ public constructor LongRange(/*0*/ start: jet.Long, /*1*/ end: jet.Long) public open override /*2*/ val end: jet.Long + public open override /*2*/ fun (): jet.Long public open override /*1*/ val increment: jet.Long + public open override /*1*/ fun (): jet.Long public open override /*2*/ val start: jet.Long + public open override /*2*/ fun (): jet.Long public open override /*1*/ fun contains(/*0*/ item: jet.Long): jet.Boolean public open override /*1*/ fun iterator(): jet.LongIterator public class object { - private constructor () + /*primary*/ private constructor () public final val EMPTY: jet.LongRange + public final fun (): jet.LongRange } } @@ -1333,11 +1392,11 @@ public trait MutableSet : jet.Set, jet.MutableCollection { } public final class Nothing { - private constructor Nothing() + /*primary*/ private constructor Nothing() } public abstract class Number : jet.Hashable { - public constructor Number() + /*primary*/ public constructor Number() public abstract override /*1*/ /*fake_override*/ fun equals(/*0*/ other: jet.Any?): jet.Boolean public abstract override /*1*/ /*fake_override*/ fun hashCode(): jet.Int public abstract fun toByte(): jet.Byte @@ -1351,23 +1410,30 @@ public abstract class Number : jet.Hashable { public trait Progression : jet.Iterable { public abstract val end: N + public abstract fun (): N public abstract val increment: jet.Number + public abstract fun (): jet.Number public abstract val start: N + public abstract fun (): N public abstract override /*1*/ /*fake_override*/ fun iterator(): jet.Iterator } public trait PropertyMetadata { public abstract val name: jet.String + public abstract fun (): jet.String } public final class PropertyMetadataImpl : jet.PropertyMetadata { - public constructor PropertyMetadataImpl(/*0*/ name: jet.String) + /*primary*/ public constructor PropertyMetadataImpl(/*0*/ name: jet.String) public open override /*1*/ val name: jet.String + public open override /*1*/ fun (): jet.String } public trait Range> { public abstract val end: T + public abstract fun (): T public abstract val start: T + public abstract fun (): T public abstract fun contains(/*0*/ item: T): jet.Boolean } @@ -1384,7 +1450,7 @@ public trait Set : jet.Collection { } public final class Short : jet.Number, jet.Comparable { - public constructor Short() + /*primary*/ public constructor Short() public final fun compareTo(/*0*/ other: jet.Byte): jet.Int public final fun compareTo(/*0*/ other: jet.Char): jet.Int public final fun compareTo(/*0*/ other: jet.Double): jet.Int @@ -1450,46 +1516,56 @@ public final class Short : jet.Number, jet.Comparable { } public final class ShortArray { - public constructor ShortArray(/*0*/ size: jet.Int) + /*primary*/ public constructor ShortArray(/*0*/ size: jet.Int) public final val indices: jet.IntRange + public final fun (): jet.IntRange public final val size: jet.Int + public final fun (): jet.Int public final fun get(/*0*/ index: jet.Int): jet.Short public final fun iterator(): jet.ShortIterator public final fun set(/*0*/ index: jet.Int, /*1*/ value: jet.Short): jet.Unit } public abstract class ShortIterator : jet.Iterator { - public constructor ShortIterator() + /*primary*/ public constructor ShortIterator() public abstract override /*1*/ /*fake_override*/ fun hasNext(): jet.Boolean public open override /*1*/ fun next(): jet.Short public abstract fun nextShort(): jet.Short } public final class ShortProgression : jet.Progression { - public constructor ShortProgression(/*0*/ start: jet.Short, /*1*/ end: jet.Short, /*2*/ increment: jet.Int) + /*primary*/ public constructor ShortProgression(/*0*/ start: jet.Short, /*1*/ end: jet.Short, /*2*/ increment: jet.Int) public open override /*1*/ val end: jet.Short + public open override /*1*/ fun (): jet.Short public open override /*1*/ val increment: jet.Int + public open override /*1*/ fun (): jet.Int public open override /*1*/ val start: jet.Short + public open override /*1*/ fun (): jet.Short public open override /*1*/ fun iterator(): jet.ShortIterator } public final class ShortRange : jet.Range, jet.Progression { - public constructor ShortRange(/*0*/ start: jet.Short, /*1*/ end: jet.Short) + /*primary*/ public constructor ShortRange(/*0*/ start: jet.Short, /*1*/ end: jet.Short) public open override /*2*/ val end: jet.Short + public open override /*2*/ fun (): jet.Short public open override /*1*/ val increment: jet.Int + public open override /*1*/ fun (): jet.Int public open override /*2*/ val start: jet.Short + public open override /*2*/ fun (): jet.Short public open override /*1*/ fun contains(/*0*/ item: jet.Short): jet.Boolean public open override /*1*/ fun iterator(): jet.ShortIterator public class object { - private constructor () + /*primary*/ private constructor () public final val EMPTY: jet.ShortRange + public final fun (): jet.ShortRange } } public final class String : jet.Comparable, jet.CharSequence { - public constructor String() + /*primary*/ public constructor String() public open override /*1*/ val length: jet.Int + public open override /*1*/ fun (): jet.Int public open override /*1*/ fun compareTo(/*0*/ that: jet.String): jet.Int public final fun equals(/*0*/ other: jet.Any?): jet.Boolean public open override /*1*/ fun get(/*0*/ index: jet.Int): jet.Char @@ -1498,33 +1574,34 @@ public final class String : jet.Comparable, jet.CharSequence { } public open class Throwable { - public constructor Throwable(/*0*/ message: jet.String? = ..., /*1*/ cause: jet.Throwable? = ...) + /*primary*/ public constructor Throwable(/*0*/ message: jet.String? = ..., /*1*/ cause: jet.Throwable? = ...) public final fun getCause(): jet.Throwable? public final fun getMessage(): jet.String? public final fun printStackTrace(): jet.Unit } public final class Unit { - private constructor Unit() + /*primary*/ private constructor Unit() public class object { - private constructor () + /*primary*/ private constructor () public final val VALUE: jet.Unit + public final fun (): jet.Unit } } public final annotation class atomic : jet.Annotation { - public constructor atomic() + /*primary*/ public constructor atomic() } public final annotation class data : jet.Annotation { - public constructor data() + /*primary*/ public constructor data() } public final annotation class deprecated : jet.Annotation { - public constructor deprecated(/*0*/ value: jet.String) + /*primary*/ public constructor deprecated(/*0*/ value: jet.String) } public final annotation class volatile : jet.Annotation { - public constructor volatile() + /*primary*/ public constructor volatile() } diff --git a/compiler/tests/org/jetbrains/jet/lang/resolve/lazy/LazyResolveBuiltinClassesTest.java b/compiler/tests/org/jetbrains/jet/lang/resolve/lazy/LazyResolveBuiltinClassesTest.java index ba8e3e12dbe..2ae15fe6753 100644 --- a/compiler/tests/org/jetbrains/jet/lang/resolve/lazy/LazyResolveBuiltinClassesTest.java +++ b/compiler/tests/org/jetbrains/jet/lang/resolve/lazy/LazyResolveBuiltinClassesTest.java @@ -25,7 +25,7 @@ import org.junit.Test; import java.io.File; -import static org.jetbrains.jet.test.util.NamespaceComparator.RECURSIVE; +import static org.jetbrains.jet.test.util.NamespaceComparator.RECURSIVE_ALL; import static org.jetbrains.jet.test.util.NamespaceComparator.compareNamespaceWithFile; public class LazyResolveBuiltinClassesTest extends KotlinTestWithEnvironment { @@ -38,6 +38,6 @@ public class LazyResolveBuiltinClassesTest extends KotlinTestWithEnvironment { public void testBuiltIns() throws Exception { NamespaceDescriptor builtInsPackage = KotlinBuiltIns.getInstance().getBuiltInsPackage(); DescriptorValidator.validate(builtInsPackage); - compareNamespaceWithFile(builtInsPackage, RECURSIVE, new File("compiler/testData/builtin-classes.txt")); + compareNamespaceWithFile(builtInsPackage, RECURSIVE_ALL, new File("compiler/testData/builtin-classes.txt")); } } diff --git a/compiler/tests/org/jetbrains/jet/test/util/NamespaceComparator.java b/compiler/tests/org/jetbrains/jet/test/util/NamespaceComparator.java index ad16bcc839f..d50c518533a 100644 --- a/compiler/tests/org/jetbrains/jet/test/util/NamespaceComparator.java +++ b/compiler/tests/org/jetbrains/jet/test/util/NamespaceComparator.java @@ -47,6 +47,7 @@ import java.util.List; public class NamespaceComparator { public static final Configuration DONT_INCLUDE_METHODS_OF_OBJECT = new Configuration(false, false, false, Predicates.alwaysTrue()); public static final Configuration RECURSIVE = new Configuration(false, false, true, Predicates.alwaysTrue()); + public static final Configuration RECURSIVE_ALL = new Configuration(true, true, true, Predicates.alwaysTrue()); private static final DescriptorRenderer RENDERER = new DescriptorRendererBuilder() .setWithDefinedIn(false) From 0d0d1ed3007edbb6236bcd7b9193ec89cbd6aea4 Mon Sep 17 00:00:00 2001 From: Andrey Breslav Date: Fri, 7 Jun 2013 19:45:50 +0400 Subject: [PATCH 246/249] Allow error types in some cases for lazy resolve tests --- ...bstractLazyResolveNamespaceComparingTest.java | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/compiler/tests/org/jetbrains/jet/lang/resolve/lazy/AbstractLazyResolveNamespaceComparingTest.java b/compiler/tests/org/jetbrains/jet/lang/resolve/lazy/AbstractLazyResolveNamespaceComparingTest.java index 9b8368f3500..3aee75d6546 100644 --- a/compiler/tests/org/jetbrains/jet/lang/resolve/lazy/AbstractLazyResolveNamespaceComparingTest.java +++ b/compiler/tests/org/jetbrains/jet/lang/resolve/lazy/AbstractLazyResolveNamespaceComparingTest.java @@ -44,18 +44,18 @@ public abstract class AbstractLazyResolveNamespaceComparingTest extends KotlinTe } protected void doTestCheckingPrimaryConstructors(String testFileName) throws IOException { - doTest(testFileName, true, false); + doTest(testFileName, true, false, true); } protected void doTestCheckingPrimaryConstructorsAndAccessors(String testFileName) throws IOException { - doTest(testFileName, true, true); + doTest(testFileName, true, true, false); } protected void doTestNotCheckingPrimaryConstructors(String testFileName) throws IOException { - doTest(testFileName, false, false); + doTest(testFileName, false, false, false); } - private void doTest(String testFileName, boolean checkPrimaryConstructors, boolean checkPropertyAccessors) throws IOException { + private void doTest(String testFileName, boolean checkPrimaryConstructors, boolean checkPropertyAccessors, boolean allowErrorTypes) throws IOException { List files = JetTestUtils .createTestFiles(testFileName, FileUtil.loadFile(new File(testFileName), true), new JetTestUtils.TestFileFactory() { @@ -78,7 +78,13 @@ public abstract class AbstractLazyResolveNamespaceComparingTest extends KotlinTe File serializeResultsTo = new File(FileUtil.getNameWithoutExtension(testFileName) + ".txt"); - DescriptorValidator.validate(expected, actual); + if (allowErrorTypes) { + DescriptorValidator.validateIgnoringErrorTypes(expected, actual); + } + else { + DescriptorValidator.validate(expected, actual); + } + NamespaceComparator.compareNamespaces( expected, actual, NamespaceComparator.DONT_INCLUDE_METHODS_OF_OBJECT.filterRecursion( From d494f4917350bd86eb03cf68deac7e70f9eba07d Mon Sep 17 00:00:00 2001 From: Andrey Breslav Date: Fri, 7 Jun 2013 20:47:02 +0400 Subject: [PATCH 247/249] Removing unneeded flag --- .../src/org/jetbrains/jet/lang/resolve/BindingContext.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/BindingContext.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/BindingContext.java index 9e51ebd58c2..cb7af3786d2 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/BindingContext.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/BindingContext.java @@ -168,10 +168,10 @@ public interface BindingContext { else if (propertyDescriptor.isVar() && setter == null) { return true; } - else if (setter != null && !setter.hasBody() && setter.getModality() != Modality.ABSTRACT) { + else if (setter != null && !setter.isDefault() && setter.getModality() != Modality.ABSTRACT) { return true; } - else if (!getter.hasBody() && getter.getModality() != Modality.ABSTRACT) { + else if (!getter.isDefault() && getter.getModality() != Modality.ABSTRACT) { return true; } return backingFieldRequired; From 7171cd4cc5d7e14b49f6e03593b05d9016579c52 Mon Sep 17 00:00:00 2001 From: Andrey Breslav Date: Mon, 10 Jun 2013 14:45:11 +0400 Subject: [PATCH 248/249] Path separator must be constant TeamCity agents have different OS'es, but build parameters are fixed --- .../jet/jps/build/KotlinBuilderModuleScriptGenerator.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/jps-plugin/src/org/jetbrains/jet/jps/build/KotlinBuilderModuleScriptGenerator.java b/jps-plugin/src/org/jetbrains/jet/jps/build/KotlinBuilderModuleScriptGenerator.java index 593cf2407c6..33b523dab54 100644 --- a/jps-plugin/src/org/jetbrains/jet/jps/build/KotlinBuilderModuleScriptGenerator.java +++ b/jps-plugin/src/org/jetbrains/jet/jps/build/KotlinBuilderModuleScriptGenerator.java @@ -134,7 +134,7 @@ public class KotlinBuilderModuleScriptGenerator { // is not available on TeamCity. When running on TeamCity, one has to provide extra path to JDK annotations String extraAnnotationsPaths = System.getProperty("jps.kotlin.extra.annotation.paths"); if (extraAnnotationsPaths != null) { - String[] paths = extraAnnotationsPaths.split(File.pathSeparator); + String[] paths = extraAnnotationsPaths.split(";"); for (String path : paths) { annotationRootFiles.add(new File(path)); } From 26a6af2765bcb5e728b0e3b0387eab002dd0dbee Mon Sep 17 00:00:00 2001 From: Andrey Breslav Date: Mon, 10 Jun 2013 16:49:41 +0400 Subject: [PATCH 249/249] Revert d494f49 Removing unneeded flag --- .../src/org/jetbrains/jet/lang/resolve/BindingContext.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/BindingContext.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/BindingContext.java index cb7af3786d2..9e51ebd58c2 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/BindingContext.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/BindingContext.java @@ -168,10 +168,10 @@ public interface BindingContext { else if (propertyDescriptor.isVar() && setter == null) { return true; } - else if (setter != null && !setter.isDefault() && setter.getModality() != Modality.ABSTRACT) { + else if (setter != null && !setter.hasBody() && setter.getModality() != Modality.ABSTRACT) { return true; } - else if (!getter.isDefault() && getter.getModality() != Modality.ABSTRACT) { + else if (!getter.hasBody() && getter.getModality() != Modality.ABSTRACT) { return true; } return backingFieldRequired;