From 1f7466b7ab88524fadd9f5c360bf45fd48a0506d Mon Sep 17 00:00:00 2001 From: Jack Zhou Date: Fri, 15 Mar 2013 20:13:12 -0400 Subject: [PATCH 001/291] Create from usage: WIP --- .../jetbrains/jet/plugin/JetBundle.properties | 4 +- .../CreateClassObjectFromUsageFix.java | 56 ++ .../quickfix/CreateFromUsageFixBase.java | 40 + .../quickfix/CreateMethodFromUsageFix.java | 724 ++++++++++++++++++ .../jet/plugin/quickfix/QuickFixes.java | 12 + .../plugin/refactoring/JetNameSuggester.java | 12 + 6 files changed, 847 insertions(+), 1 deletion(-) create mode 100644 idea/src/org/jetbrains/jet/plugin/quickfix/CreateClassObjectFromUsageFix.java create mode 100644 idea/src/org/jetbrains/jet/plugin/quickfix/CreateFromUsageFixBase.java create mode 100644 idea/src/org/jetbrains/jet/plugin/quickfix/CreateMethodFromUsageFix.java diff --git a/idea/src/org/jetbrains/jet/plugin/JetBundle.properties b/idea/src/org/jetbrains/jet/plugin/JetBundle.properties index 4447e0f40c9..21d05ae90c7 100644 --- a/idea/src/org/jetbrains/jet/plugin/JetBundle.properties +++ b/idea/src/org/jetbrains/jet/plugin/JetBundle.properties @@ -143,7 +143,9 @@ map.platform.class.to.kotlin=Change all usages of ''{0}'' in this file to ''{1}' map.platform.class.to.kotlin.multiple=Change all usages of ''{0}'' in this file to a Kotlin class map.platform.class.to.kotlin.advertisement=Choose an appropriate Kotlin class map.platform.class.to.kotlin.family=Change to Kotlin class - +create.from.usage.family=Create from usage +create.method.from.usage=Create method ''{0}'' from usage +create.class.object.from.usage=Create class object from usage surround.with=Surround with surround.with.string.template="${expr}" surround.with.when.template=when (expr) {} diff --git a/idea/src/org/jetbrains/jet/plugin/quickfix/CreateClassObjectFromUsageFix.java b/idea/src/org/jetbrains/jet/plugin/quickfix/CreateClassObjectFromUsageFix.java new file mode 100644 index 00000000000..6a4621dff97 --- /dev/null +++ b/idea/src/org/jetbrains/jet/plugin/quickfix/CreateClassObjectFromUsageFix.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.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.util.IncorrectOperationException; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import org.jetbrains.jet.lang.diagnostics.Diagnostic; +import org.jetbrains.jet.plugin.JetBundle; + +public class CreateClassObjectFromUsageFix extends CreateFromUsageFixBase { + public CreateClassObjectFromUsageFix(@NotNull PsiElement element) { + super(element); + } + + @NotNull + @Override + public String getText() { + return JetBundle.message("create.class.object.from.usage"); + } + + @Override + public void invoke(@NotNull Project project, Editor editor, PsiFile file) throws IncorrectOperationException { + // TODO + } + + @NotNull + public static JetIntentionActionFactory createCreateClassObjectFromUsageFactory() { + return new JetIntentionActionFactory() { + @Nullable + @Override + public IntentionAction createAction(Diagnostic diagnostic) { + return null; // TODO + } + }; + } +} diff --git a/idea/src/org/jetbrains/jet/plugin/quickfix/CreateFromUsageFixBase.java b/idea/src/org/jetbrains/jet/plugin/quickfix/CreateFromUsageFixBase.java new file mode 100644 index 00000000000..407ccd4efaf --- /dev/null +++ b/idea/src/org/jetbrains/jet/plugin/quickfix/CreateFromUsageFixBase.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.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; +import org.jetbrains.jet.lang.psi.JetClass; +import org.jetbrains.jet.lang.psi.JetFile; +import org.jetbrains.jet.lang.psi.JetPsiFactory; +import org.jetbrains.jet.plugin.JetBundle; + +public abstract class CreateFromUsageFixBase extends JetIntentionAction { + public CreateFromUsageFixBase(@NotNull PsiElement element) { + super(element); + } + + @NotNull + @Override + public String getFamilyName() { + return JetBundle.message("create.from.usage.family"); + } +} diff --git a/idea/src/org/jetbrains/jet/plugin/quickfix/CreateMethodFromUsageFix.java b/idea/src/org/jetbrains/jet/plugin/quickfix/CreateMethodFromUsageFix.java new file mode 100644 index 00000000000..3bc5a4a0357 --- /dev/null +++ b/idea/src/org/jetbrains/jet/plugin/quickfix/CreateMethodFromUsageFix.java @@ -0,0 +1,724 @@ +/* + * 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.codeInsight.lookup.LookupElement; +import com.intellij.codeInsight.lookup.LookupElementBuilder; +import com.intellij.codeInsight.template.*; +import com.intellij.codeInsight.template.impl.TemplateImpl; +import com.intellij.codeInsight.template.impl.Variable; +import com.intellij.openapi.editor.CaretModel; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.TextRange; +import com.intellij.openapi.util.text.StringUtil; +import com.intellij.psi.PsiDocumentManager; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiFile; +import com.intellij.psi.util.PsiTreeUtil; +import com.intellij.util.ArrayUtil; +import com.intellij.util.IncorrectOperationException; +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.*; +import org.jetbrains.jet.lang.resolve.BindingContext; +import org.jetbrains.jet.lang.resolve.scopes.JetScope; +import org.jetbrains.jet.lang.types.JetType; +import org.jetbrains.jet.lang.types.TypeProjection; +import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns; +import org.jetbrains.jet.plugin.JetBundle; +import org.jetbrains.jet.plugin.codeInsight.DescriptorToDeclarationUtil; +import org.jetbrains.jet.plugin.project.AnalyzerFacadeWithCache; +import org.jetbrains.jet.plugin.refactoring.JetNameSuggester; +import org.jetbrains.jet.plugin.refactoring.JetNameValidator; +import org.jetbrains.jet.renderer.DescriptorRenderer; + +import java.util.*; + +public class CreateMethodFromUsageFix extends CreateFromUsageFixBase { + private static final String TYPE_PARAMETER_LIST_VARIABLE_NAME = "typeParameterList"; + + /** + * Represents a concrete type or a set of types yet to be inferred from an expression. + */ + private static class TypeOrExpressionThereof { + private final JetExpression expressionOfType; + private final JetType type; + private JetType[] cachedTypeCandidates; + private String[] cachedNameCandidatesFromExpression; + + public TypeOrExpressionThereof(@NotNull JetExpression expressionOfType) { + this.expressionOfType = expressionOfType; + this.type = null; + } + + public TypeOrExpressionThereof(@NotNull JetType type) { + this.expressionOfType = null; + this.type = type; + } + + public boolean isType() { + return this.type != null; + } + + @Nullable + public JetType getType() { + return this.type; + } + + @Nullable + public JetExpression getExpressionOfType() { + return expressionOfType; + } + + /** + * Returns a collection containing the possible types represented by this instance. Infers the type from an expression if necessary. + * @return A collection containing the possible types represented by this instance. + */ + @NotNull + public JetType[] getPossibleTypes(@Nullable("used cached, don't recompute") BindingContext context) { + if (context == null) { + assert cachedTypeCandidates != null; + return cachedTypeCandidates; + } + return cachedTypeCandidates = isType() ? new JetType[] {type} : guessTypeForExpression(expressionOfType, context); + // TODO: supertypes/subtypes of all possible types? + } + + @NotNull + public JetType[] getPossibleTypes() { + return getPossibleTypes(null); + } + + @NotNull + public String[] getPossibleNamesFromExpression() { + if (cachedNameCandidatesFromExpression != null) return cachedNameCandidatesFromExpression; + cachedNameCandidatesFromExpression = isType() + ? ArrayUtil.EMPTY_STRING_ARRAY + : JetNameSuggester.suggestNamesForExpression( + expressionOfType, + JetNameValidator.getEmptyValidator(expressionOfType.getProject())); + return cachedNameCandidatesFromExpression; + } + } + + /** + * Encapsulates information about a method parameter that is going to be created. + */ + private static class Parameter { + private final String preferredName; + private final TypeOrExpressionThereof type; + + public Parameter(@Nullable("no preferred name") String preferredName, TypeOrExpressionThereof type) { + this.preferredName = preferredName; + this.type = type; + } + + public String getPreferredName() { + return preferredName; + } + + public TypeOrExpressionThereof getType() { + return type; + } + } + + /** + * Special Expression for parameter names based on its type. + */ + private static class ParameterNameExpression extends Expression { + private final TypeExpression typeExpression; + private final String[] names; + + public ParameterNameExpression(@NotNull String[] names, @NotNull TypeExpression typeExpression) { + for (String name : names) + assert name != null && !name.isEmpty(); + this.names = names; + this.typeExpression = typeExpression; + } + + @Nullable + @Override + public Result calculateResult(ExpressionContext context) { + LookupElement[] lookupItems = calculateLookupItems(context); + if (lookupItems.length == 0) return new TextResult(""); + + return new TextResult(lookupItems[0].getLookupString()); + } + + @Nullable + @Override + public Result calculateQuickResult(ExpressionContext context) { + return null; + } + + @NotNull + @Override + public LookupElement[] calculateLookupItems(ExpressionContext context) { + Set names = new LinkedHashSet(); + Collections.addAll(names, this.names); + + // find the parameter list + Project project = context.getProject(); + int offset = context.getStartOffset(); + PsiDocumentManager.getInstance(project).commitAllDocuments(); + Editor editor = context.getEditor(); + assert editor != null; + PsiFile file = PsiDocumentManager.getInstance(project).getPsiFile(editor.getDocument()); + assert file != null && file instanceof JetFile; + JetFile jetFile = (JetFile) file; + PsiElement elementAt = file.findElementAt(offset); + JetFunction func = PsiTreeUtil.getParentOfType(elementAt, JetFunction.class); + assert func != null; + JetParameterList parameterList = func.getValueParameterList(); + assert parameterList != null; + + // add names based on selected type + JetParameter parameter = PsiTreeUtil.getParentOfType(elementAt, JetParameter.class); + if (parameter != null) { + JetTypeReference parameterTypeRef = parameter.getTypeReference(); + assert parameterTypeRef != null; + JetType selectedType = typeExpression.getTypeFromSelection(parameterTypeRef.getText()); + if (selectedType != null) { // user selected a type we suggested + Collections.addAll(names, JetNameSuggester.suggestNamesForType(selectedType, JetNameValidator.getEmptyValidator(project))); + } else { // user entered their own type + BindingContext bindingContext = AnalyzerFacadeWithCache.analyzeFileWithCache(jetFile).getBindingContext(); + JetType enteredType = bindingContext.get(BindingContext.TYPE, parameterTypeRef); + if (enteredType != null) { + Collections.addAll(names, JetNameSuggester.suggestNamesForType(enteredType, JetNameValidator.getEmptyValidator(project))); + } + } + } + + // remember other parameter names for later use + Set parameterNames = new HashSet(); + for (JetParameter jetParameter : parameterList.getParameters()) { + if (jetParameter == parameter) continue; + parameterNames.add(jetParameter.getName()); + } + + // add fallback parameter name + if (names.isEmpty()) { + names.add("arg"); + } + + // ensure there are no conflicts + List lookupElements = new ArrayList(); + for (String name : names) { + name = getNextAvailableName(name, parameterNames); + lookupElements.add(LookupElementBuilder.create(name)); + } + + // create and return + return lookupElements.toArray(new LookupElement[lookupElements.size()]); + } + } + + /** + * An Expression for type references. + */ + private static class TypeExpression extends Expression { + private final Project project; + private final JetType[] types; + private LookupElement[] lastCachedLookupElements; + + public TypeExpression(@NotNull Project project, @NotNull JetType[] types) { + this.project = project; + this.types = types; + } + + @Nullable + @Override + public Result calculateResult(ExpressionContext context) { + LookupElement[] lookupItems = calculateLookupItems(context); + if (lookupItems.length == 0) return new TextResult(""); + + return new TextResult(lookupItems[0].getLookupString()); + } + + @Nullable + @Override + public Result calculateQuickResult(ExpressionContext context) { + return null; + } + + @NotNull + @Override + public LookupElement[] calculateLookupItems(ExpressionContext context) { + LookupElement[] lookupElements = new LookupElement[types.length]; + for (int i = 0; i < types.length; i++) { + lookupElements[i] = LookupElementBuilder.create(DescriptorRenderer.TEXT.renderType(types[i])); + // TODO: take into account imports and stuff; how to refer to a type with the simplest name with imports (currently uses fully qualified name)? + } + return lastCachedLookupElements = lookupElements; + } + + @Nullable("can't be found") + public JetType getTypeFromSelection(String selection) { + for (int i = 0; i < lastCachedLookupElements.length; i++) { + if (lastCachedLookupElements[i].getLookupString().equals(selection)) { + return types[i]; + } + } + return null; + } + } + + /** + * A sort-of dummy Expression for parameter lists, to allow us to update the parameter list as the user makes selections. + */ + private static class TypeParameterListExpression extends Expression { + private final String[] ownerTypeParameterNames; + private final Map typeParameterMap; + private final List parameterTypeExpressions; + + public TypeParameterListExpression(@NotNull String[] ownerTypeParameterNames, @NotNull Map typeParameterMap, + @NotNull List parameterTypeExpressions) { + this.ownerTypeParameterNames = ownerTypeParameterNames; + this.typeParameterMap = typeParameterMap; + this.parameterTypeExpressions = parameterTypeExpressions; + } + + @NotNull + @Override + public Result calculateResult(ExpressionContext context) { + Project project = context.getProject(); + int offset = context.getStartOffset(); + PsiDocumentManager.getInstance(project).commitAllDocuments(); + Editor editor = context.getEditor(); + assert editor != null; + PsiFile file = PsiDocumentManager.getInstance(project).getPsiFile(editor.getDocument()); + assert file != null && file instanceof JetFile; + PsiElement elementAt = file.findElementAt(offset); + JetFunction func = PsiTreeUtil.getParentOfType(elementAt, JetFunction.class); + assert func != null; + JetParameterList parameterList = func.getValueParameterList(); + assert parameterList != null; + List parameters = parameterList.getParameters(); + assert parameters.size() == parameterTypeExpressions.size(); + + List typeParameterNames = new ArrayList(); + Collections.addAll(typeParameterNames, ownerTypeParameterNames); + int i = 0; + for (JetParameter parameter : parameters) { + TypeExpression parameterTypeExpression = parameterTypeExpressions.get(i); + JetTypeReference parameterTypeRef = parameter.getTypeReference(); + assert parameterTypeRef != null; + JetType parameterType = parameterTypeExpression.getTypeFromSelection(parameterTypeRef.getText()); + if (parameterType != null) { // the user chose a given type + String[] names = typeParameterMap.get(parameterType); + Collections.addAll(typeParameterNames, names); + } + + i++; + } + + return typeParameterNames.isEmpty() + ? new TextResult("") + : new TextResult(" <" + StringUtil.join(typeParameterNames, ", ") + ">"); + } + + @Nullable + @Override + public Result calculateQuickResult(ExpressionContext context) { + return null; + } + + @NotNull + @Override + public LookupElement[] calculateLookupItems(ExpressionContext context) { + return new LookupElement[0]; // do not offer the user any choices + } + } + + private final String methodName; + private final TypeOrExpressionThereof ownerType; + private final TypeOrExpressionThereof returnType; + private final List parameters; + + public CreateMethodFromUsageFix(@NotNull PsiElement element, @NotNull TypeOrExpressionThereof ownerType, @NotNull String methodName, + @NotNull TypeOrExpressionThereof returnType, @NotNull List parameters) { + super(element); + this.methodName = methodName; + this.ownerType = ownerType; + this.returnType = returnType; + this.parameters = parameters; + } + + @NotNull + @Override + public String getText() { + return JetBundle.message("create.method.from.usage", methodName); + } + + @Override + public void invoke(@NotNull Project project, Editor editor, PsiFile file) throws IncorrectOperationException { + assert file instanceof JetFile; + JetFile jetFile = (JetFile) file; + BindingContext context = AnalyzerFacadeWithCache.analyzeFileWithCache(jetFile).getBindingContext(); + + JetType[] possibleOwnerTypes = ownerType.getPossibleTypes(context); + assert possibleOwnerTypes.length > 0; + + JetType ownerType; + if (possibleOwnerTypes.length == 1) { + ownerType = possibleOwnerTypes[0]; + } else { + // TODO: class selection + ownerType = possibleOwnerTypes[0]; + } + + ClassifierDescriptor ownerTypeDescriptor = ownerType.getConstructor().getDeclarationDescriptor(); + PsiElement typeDeclaration = DescriptorToDeclarationUtil.getDeclaration(jetFile, ownerTypeDescriptor, context); + JetClass klass = (JetClass) typeDeclaration; + + // create method with placeholder types and parameter names + String[] parameterStrings = new String[parameters.size()]; + for (int i = 0; i < parameterStrings.length; i++) { + parameterStrings[i] = "p" + i + ": Any"; + } + String parametersString = StringUtil.join(parameterStrings,", "); + + boolean isUnit = returnType.isType() && isUnit(returnType.getType()); + String returnTypeString = isUnit ? "" : ": Any"; + + String methodText; + JetNamedFunction func; + PsiElement owner; + boolean isExtension = !klass.isWritable(); + if (isExtension) { // create as extension function + methodText = String.format("fun %s.%s(%s)%s { }", DescriptorRenderer.TEXT.renderType(ownerType), + methodName, parametersString, returnTypeString); + func = JetPsiFactory.createFunction(project, methodText); + owner = file; + func = (JetNamedFunction) file.add(func); + } else { // create as method + methodText = String.format("fun %s(%s)%s { }", methodName, parametersString, returnTypeString); + func = JetPsiFactory.createFunction(project, methodText); + owner = klass; + JetClassBody classBody = klass.getBody(); + assert classBody != null; + PsiElement rBrace = classBody.getRBrace(); + func = (JetNamedFunction) classBody.addBefore(func, rBrace); + } + + // TODO: add newlines + + JetParameterList parameterList = func.getValueParameterList(); + assert parameterList != null; + + // build templates + PsiDocumentManager.getInstance(project).commitAllDocuments(); + PsiDocumentManager.getInstance(project).doPostponedOperationsAndUnblockDocument(editor.getDocument()); + + final CaretModel caretModel = editor.getCaretModel(); + final int oldOffset = caretModel.getOffset(); + caretModel.moveToOffset(file.getNode().getStartOffset()); + + TemplateBuilderImpl builder = new TemplateBuilderImpl(file); + + // add return type to the template (if it's not a unit function) + if (!isUnit) { + JetTypeReference returnTypeRef = func.getReturnTypeRef(); + assert returnTypeRef != null; + Expression returnTypeExpression = new TypeExpression(project, returnType.getPossibleTypes()); + builder.replaceElement(returnTypeRef, returnTypeExpression); + } + + // add parameters to the template + List jetParameters = parameterList.getParameters(); + List parameterTypeExpressions = new ArrayList(); + assert jetParameters.size() == parameters.size(); + for (int i = 0; i < parameters.size(); i++) { + Parameter parameter = parameters.get(i); + JetParameter jetParameter = jetParameters.get(i); + + // add parameter type to the template + TypeExpression parameterTypeExpression = new TypeExpression(project, parameter.getType().getPossibleTypes()); + parameterTypeExpressions.add(parameterTypeExpression); + JetTypeReference parameterTypeRef = jetParameter.getTypeReference(); + assert parameterTypeRef != null; + builder.replaceElement(parameterTypeRef, parameterTypeExpression); + + // add parameter name to the template + String[] possibleNamesFromExpression = parameter.getType().getPossibleNamesFromExpression(); + String preferredName = parameter.getPreferredName(); + String[] possibleNames; + if (preferredName != null) { + possibleNames = new String[possibleNamesFromExpression.length + 1]; + possibleNames[0] = preferredName; + System.arraycopy(possibleNamesFromExpression, 0, possibleNames, 1, possibleNamesFromExpression.length); + } else { + possibleNames = possibleNamesFromExpression; + } + Expression parameterNameExpression = new ParameterNameExpression(possibleNames, parameterTypeExpression); + PsiElement parameterNameIdentifier = jetParameter.getNameIdentifier(); + assert parameterNameIdentifier != null; + builder.replaceElement(parameterNameIdentifier, parameterNameExpression); + } + + // add a segment for the parameter list + // Note: because TemplateBuilderImpl does not have a replaceElement overload that takes in both a TextRange and alwaysStopAt, we + // need to create the segment first and then hack the Expression into the template later. We use this template to update the type + // parameter list as the user makes selections in the parameter types, and we need alwaysStopAt to be false so the user can't tab to + // it. + Map typeParameterMap = new HashMap(); + DeclarationDescriptor ownerDescriptor = context.get(BindingContext.DECLARATION_TO_DESCRIPTOR, owner); + JetScope scope; + if (ownerDescriptor instanceof NamespaceDescriptor) { + NamespaceDescriptor namespaceDescriptor = (NamespaceDescriptor) ownerDescriptor; + scope = namespaceDescriptor.getMemberScope(); + } else { + ClassDescriptor classDescriptor = (ClassDescriptor) ownerDescriptor; + scope = classDescriptor.getMemberScope(classDescriptor.getDefaultType().getArguments()); + } + + String[] ownerTypeParameterNames = ArrayUtil.EMPTY_STRING_ARRAY; + if (isExtension) { + Set typeParameters = getTypeParametersInType(ownerType); + typeParameterMap.put(ownerType, ownerTypeParameterNames = getTypeParameterNamesNotInScope(typeParameters, scope)); + } + for (Parameter parameter : parameters) { + for (JetType type : parameter.getType().getPossibleTypes()) { + // get a list of type parameter candidates + Set typeParameters = getTypeParametersInType(type); + typeParameterMap.put(type, getTypeParameterNamesNotInScope(typeParameters, scope)); + } + } + + Expression expression = new TypeParameterListExpression(ownerTypeParameterNames, typeParameterMap, parameterTypeExpressions); + builder.replaceElement(func, TextRange.create(3, 3), TYPE_PARAMETER_LIST_VARIABLE_NAME, null, false); // ((3, 3) is after "fun") + + // the template built by TemplateBuilderImpl is ordered by element position, but we want types to be first, so hack it + TemplateImpl template = (TemplateImpl) builder.buildInlineTemplate(); + ArrayList variables = template.getVariables(); + for (int i = 0; i < parameters.size(); i++) { + Collections.swap(variables, i * 2, i * 2 + 1); + } + + // fix up the template to include the expression for the type parameter list + variables.add(new Variable(TYPE_PARAMETER_LIST_VARIABLE_NAME, expression, expression, false, true)); + + // run the template + TemplateManager.getInstance(project).startTemplate(editor, template, new TemplateEditingAdapter() { // TODO: too slow, speed it up + @Override + public void templateFinished(Template template, boolean brokenOff) { + // TODO: file templates + + caretModel.moveToOffset(oldOffset); + } + }); + } + + @Override + public boolean isAvailable(@NotNull Project project, Editor editor, PsiFile file) { + assert file instanceof JetFile; + JetFile jetFile = (JetFile) file; + BindingContext context = AnalyzerFacadeWithCache.analyzeFileWithCache(jetFile).getBindingContext(); + + JetType[] possibleOwnerTypes = ownerType.getPossibleTypes(context); + if (possibleOwnerTypes.length == 0) return false; + assertNoUnitTypes(possibleOwnerTypes); + JetType[] possibleReturnTypes = returnType.getPossibleTypes(context); + if (!returnType.isType()) { // allow return type to be unit (but not when it's among several options) + assertNoUnitTypes(possibleReturnTypes); + } + if (possibleReturnTypes.length == 0) return false; + for (Parameter parameter : parameters) { + JetType[] possibleTypes = parameter.getType().getPossibleTypes(context); + if (possibleTypes.length == 0) return false; + assertNoUnitTypes(possibleTypes); + } + + return true; + } + + @NotNull + private static String[] getTypeParameterNamesNotInScope(Collection typeParameters, JetScope scope) { + List typeParameterNames = new ArrayList(); + for (TypeParameterDescriptor typeParameter : typeParameters) { + ClassifierDescriptor classifier = scope.getClassifier(typeParameter.getName()); + if (classifier == null || !classifier.equals(typeParameter)) { + typeParameterNames.add(typeParameter.getName().getIdentifier()); + } + } + return ArrayUtil.toStringArray(typeParameterNames); + } + + @NotNull + private static Set getTypeParametersInType(@NotNull JetType type) { + Set typeParameters = new LinkedHashSet(); + List arguments = type.getArguments(); + if (arguments.isEmpty()) { + ClassifierDescriptor descriptor = type.getConstructor().getDeclarationDescriptor(); + if (descriptor instanceof TypeParameterDescriptor) { + typeParameters.add((TypeParameterDescriptor) descriptor); + } + } else { + for (TypeProjection projection : arguments) { + typeParameters.addAll(getTypeParametersInType(projection.getType())); + } + } + return typeParameters; + } + + @NotNull + private static String getNextAvailableName(@NotNull String name, @NotNull Set existingNames) { + if (existingNames.contains(name)) { + int j = 1; + while (existingNames.contains(name + j)) j++; + name += j; + } + return name; + } + + @NotNull + private static JetType[] guessTypeForExpression(@NotNull JetExpression expr, @NotNull BindingContext context) { + JetType actualType = context.get(BindingContext.EXPRESSION_TYPE, expr); + if (actualType != null) { // if we know the actual type of the expression + return new JetType[] {actualType}; + } + + // if we need to guess, there are four cases: + if (expr.getParent() instanceof JetVariableDeclaration) { + JetVariableDeclaration variable = (JetVariableDeclaration) expr.getParent(); + JetTypeReference variableTypeRef = variable.getTypeRef(); + if (variableTypeRef != null) { + // case 1: the expression is the RHS of a variable assignment with a specified type + return new JetType[] {context.get(BindingContext.TYPE, variableTypeRef)}; + } else { + // case 2: the expression is the RHS of a variable assignment without a specified type + // TODO + } + } + + // TODO: other cases + return new JetType[0]; //TODO + } + + private static boolean isUnit(@NotNull JetType type) { + return KotlinBuiltIns.getInstance().isUnit(type); + } + + private static void assertNoUnitTypes(@NotNull JetType[] types) { + for (JetType type : types) { + assert !isUnit(type) : "no support for unit functions"; + } + } + + @NotNull + public static JetIntentionActionFactory createCreateGetMethodFromUsageFactory() { + return new JetIntentionActionFactory() { + @Nullable + @Override + public IntentionAction createAction(Diagnostic diagnostic) { + JetArrayAccessExpression accessExpr = QuickFixUtil.getParentElementOfType(diagnostic, JetArrayAccessExpression.class); + if (accessExpr == null) return null; + JetExpression arrayExpr = accessExpr.getArrayExpression(); + TypeOrExpressionThereof arrayType = new TypeOrExpressionThereof(arrayExpr); + + List parameters = new ArrayList(); + for (JetExpression indexExpr : accessExpr.getIndexExpressions()) { + if (indexExpr == null) return null; + TypeOrExpressionThereof indexType = new TypeOrExpressionThereof(indexExpr); + parameters.add(new Parameter(null, indexType)); + } + + TypeOrExpressionThereof returnType = new TypeOrExpressionThereof(accessExpr); + return new CreateMethodFromUsageFix(accessExpr, arrayType, "get", returnType, parameters); + } + }; + } + + @NotNull + public static JetIntentionActionFactory createCreateSetMethodFromUsageFactory() { + return new JetIntentionActionFactory() { + @Nullable + @Override + public IntentionAction createAction(Diagnostic diagnostic) { + JetArrayAccessExpression accessExpr = QuickFixUtil.getParentElementOfType(diagnostic, JetArrayAccessExpression.class); + if (accessExpr == null) return null; + JetExpression arrayExpr = accessExpr.getArrayExpression(); + TypeOrExpressionThereof arrayType = new TypeOrExpressionThereof(arrayExpr); + + List parameters = new ArrayList(); + for (JetExpression indexExpr : accessExpr.getIndexExpressions()) { + if (indexExpr == null) return null; + TypeOrExpressionThereof indexType = new TypeOrExpressionThereof(indexExpr); + parameters.add(new Parameter(null, indexType)); + } + + JetBinaryExpression assignmentExpr = QuickFixUtil.getParentElementOfType(diagnostic, JetBinaryExpression.class); + if (assignmentExpr == null) return null; + JetExpression rhs = assignmentExpr.getRight(); + if (rhs == null) return null; + TypeOrExpressionThereof valType = new TypeOrExpressionThereof(rhs); + parameters.add(new Parameter("value", valType)); + + TypeOrExpressionThereof returnType = new TypeOrExpressionThereof(KotlinBuiltIns.getInstance().getUnitType()); + return new CreateMethodFromUsageFix(accessExpr, arrayType, "set", returnType, parameters); + } + }; + } + + @NotNull + public static JetIntentionActionFactory createCreateHasNextMethodFromUsageFactory() { + return new JetIntentionActionFactory() { + @Nullable + @Override + public IntentionAction createAction(Diagnostic diagnostic) { + return null; // TODO + } + }; + } + + @NotNull + public static JetIntentionActionFactory createCreateNextMethodFromUsageFactory() { + return new JetIntentionActionFactory() { + @Nullable + @Override + public IntentionAction createAction(Diagnostic diagnostic) { + return null; // TODO + } + }; + } + + @NotNull + public static JetIntentionActionFactory createCreateIteratorMethodFromUsageFactory() { + return new JetIntentionActionFactory() { + @Nullable + @Override + public IntentionAction createAction(Diagnostic diagnostic) { + return null; // TODO + } + }; + } + + @NotNull + public static JetIntentionActionFactory createCreateComponentMethodFromUsageFactory() { + return new JetIntentionActionFactory() { + @Nullable + @Override + public IntentionAction createAction(Diagnostic diagnostic) { + return null; // TODO + } + }; + } +} diff --git a/idea/src/org/jetbrains/jet/plugin/quickfix/QuickFixes.java b/idea/src/org/jetbrains/jet/plugin/quickfix/QuickFixes.java index 756b883bfee..5aa2fd81821 100644 --- a/idea/src/org/jetbrains/jet/plugin/quickfix/QuickFixes.java +++ b/idea/src/org/jetbrains/jet/plugin/quickfix/QuickFixes.java @@ -239,5 +239,17 @@ public class QuickFixes { factories.put(PLATFORM_CLASS_MAPPED_TO_KOTLIN, MapPlatformClassToKotlinFix.createFactory()); factories.put(MANY_CLASSES_IN_SUPERTYPE_LIST, RemoveSupertypeFix.createFactory()); + + factories.put(NO_GET_METHOD, CreateMethodFromUsageFix.createCreateGetMethodFromUsageFactory()); + factories.put(NO_SET_METHOD, CreateMethodFromUsageFix.createCreateSetMethodFromUsageFactory()); + JetIntentionActionFactory createHasNextFromUsageFactory = CreateMethodFromUsageFix.createCreateHasNextMethodFromUsageFactory(); + factories.put(HAS_NEXT_MISSING, createHasNextFromUsageFactory); + factories.put(HAS_NEXT_FUNCTION_NONE_APPLICABLE, createHasNextFromUsageFactory); + JetIntentionActionFactory createNextFromUsageFactory = CreateMethodFromUsageFix.createCreateNextMethodFromUsageFactory(); + factories.put(NEXT_MISSING, createNextFromUsageFactory); + factories.put(NEXT_NONE_APPLICABLE, createNextFromUsageFactory); + factories.put(ITERATOR_MISSING, CreateMethodFromUsageFix.createCreateIteratorMethodFromUsageFactory()); + factories.put(COMPONENT_FUNCTION_MISSING, CreateMethodFromUsageFix.createCreateComponentMethodFromUsageFactory()); + factories.put(NO_CLASS_OBJECT, CreateClassObjectFromUsageFix.createCreateClassObjectFromUsageFactory()); } } diff --git a/idea/src/org/jetbrains/jet/plugin/refactoring/JetNameSuggester.java b/idea/src/org/jetbrains/jet/plugin/refactoring/JetNameSuggester.java index 13e05abc668..1fe8adf3340 100644 --- a/idea/src/org/jetbrains/jet/plugin/refactoring/JetNameSuggester.java +++ b/idea/src/org/jetbrains/jet/plugin/refactoring/JetNameSuggester.java @@ -86,6 +86,18 @@ public class JetNameSuggester { return ArrayUtil.toStringArray(result); } + public static String[] suggestNamesForType(JetType jetType, JetNameValidator validator) { + ArrayList result = new ArrayList(); + addNamesForType(result, jetType, validator); + return ArrayUtil.toStringArray(result); + } + + public static String[] suggestNamesForExpression(JetExpression expression, JetNameValidator validator) { + ArrayList result = new ArrayList(); + addNamesForExpression(result, expression, validator); + return ArrayUtil.toStringArray(result); + } + private static void addNamesForType(ArrayList result, JetType jetType, JetNameValidator validator) { KotlinBuiltIns builtIns = KotlinBuiltIns.getInstance(); JetTypeChecker typeChecker = JetTypeChecker.INSTANCE; From 90f474a85a7492097d3c358b888ed93635f46814 Mon Sep 17 00:00:00 2001 From: Jack Zhou Date: Mon, 8 Apr 2013 11:27:26 -0400 Subject: [PATCH 002/291] Create from usage: Improved template performance by not re-analyzing file in expressions. --- .../quickfix/CreateMethodFromUsageFix.java | 142 +++++++++--------- 1 file changed, 75 insertions(+), 67 deletions(-) diff --git a/idea/src/org/jetbrains/jet/plugin/quickfix/CreateMethodFromUsageFix.java b/idea/src/org/jetbrains/jet/plugin/quickfix/CreateMethodFromUsageFix.java index 3bc5a4a0357..f11f6550c23 100644 --- a/idea/src/org/jetbrains/jet/plugin/quickfix/CreateMethodFromUsageFix.java +++ b/idea/src/org/jetbrains/jet/plugin/quickfix/CreateMethodFromUsageFix.java @@ -144,14 +144,14 @@ public class CreateMethodFromUsageFix extends CreateFromUsageFixBase { * Special Expression for parameter names based on its type. */ private static class ParameterNameExpression extends Expression { - private final TypeExpression typeExpression; private final String[] names; + private final Map parameterTypeToNamesMap; - public ParameterNameExpression(@NotNull String[] names, @NotNull TypeExpression typeExpression) { + public ParameterNameExpression(@NotNull String[] names, @NotNull Map parameterTypeToNamesMap) { for (String name : names) assert name != null && !name.isEmpty(); this.names = names; - this.typeExpression = typeExpression; + this.parameterTypeToNamesMap = parameterTypeToNamesMap; } @Nullable @@ -195,15 +195,9 @@ public class CreateMethodFromUsageFix extends CreateFromUsageFixBase { if (parameter != null) { JetTypeReference parameterTypeRef = parameter.getTypeReference(); assert parameterTypeRef != null; - JetType selectedType = typeExpression.getTypeFromSelection(parameterTypeRef.getText()); - if (selectedType != null) { // user selected a type we suggested - Collections.addAll(names, JetNameSuggester.suggestNamesForType(selectedType, JetNameValidator.getEmptyValidator(project))); - } else { // user entered their own type - BindingContext bindingContext = AnalyzerFacadeWithCache.analyzeFileWithCache(jetFile).getBindingContext(); - JetType enteredType = bindingContext.get(BindingContext.TYPE, parameterTypeRef); - if (enteredType != null) { - Collections.addAll(names, JetNameSuggester.suggestNamesForType(enteredType, JetNameValidator.getEmptyValidator(project))); - } + String[] suggestedNamesBasedOnType = parameterTypeToNamesMap.get(parameterTypeRef.getText()); + if (suggestedNamesBasedOnType != null) { + Collections.addAll(names, suggestedNamesBasedOnType); } } @@ -235,13 +229,13 @@ public class CreateMethodFromUsageFix extends CreateFromUsageFixBase { * An Expression for type references. */ private static class TypeExpression extends Expression { - private final Project project; - private final JetType[] types; - private LookupElement[] lastCachedLookupElements; + private final JetType[] options; + private final String[] optionStrings; - public TypeExpression(@NotNull Project project, @NotNull JetType[] types) { - this.project = project; - this.types = types; + public TypeExpression(@NotNull JetType[] options) { + //To change body of created methods use File | Settings | File Templates. + this.options = options; + optionStrings = renderTypes(options); } @Nullable @@ -262,22 +256,21 @@ public class CreateMethodFromUsageFix extends CreateFromUsageFixBase { @NotNull @Override public LookupElement[] calculateLookupItems(ExpressionContext context) { - LookupElement[] lookupElements = new LookupElement[types.length]; - for (int i = 0; i < types.length; i++) { - lookupElements[i] = LookupElementBuilder.create(DescriptorRenderer.TEXT.renderType(types[i])); - // TODO: take into account imports and stuff; how to refer to a type with the simplest name with imports (currently uses fully qualified name)? + LookupElement[] lookupElements = new LookupElement[options.length]; + for (int i = 0; i < options.length; i++) { + lookupElements[i] = LookupElementBuilder.create(optionStrings[i]); } - return lastCachedLookupElements = lookupElements; + return lookupElements; } - @Nullable("can't be found") - public JetType getTypeFromSelection(String selection) { - for (int i = 0; i < lastCachedLookupElements.length; i++) { - if (lastCachedLookupElements[i].getLookupString().equals(selection)) { - return types[i]; - } - } - return null; + @NotNull + public JetType[] getOptions() { + return options; + } + + @NotNull + public String[] getOptionStrings() { + return optionStrings; } } @@ -286,14 +279,11 @@ public class CreateMethodFromUsageFix extends CreateFromUsageFixBase { */ private static class TypeParameterListExpression extends Expression { private final String[] ownerTypeParameterNames; - private final Map typeParameterMap; - private final List parameterTypeExpressions; + private final Map typeParameterMap; - public TypeParameterListExpression(@NotNull String[] ownerTypeParameterNames, @NotNull Map typeParameterMap, - @NotNull List parameterTypeExpressions) { + public TypeParameterListExpression(@NotNull String[] ownerTypeParameterNames, @NotNull Map typeParameterMap) { this.ownerTypeParameterNames = ownerTypeParameterNames; this.typeParameterMap = typeParameterMap; - this.parameterTypeExpressions = parameterTypeExpressions; } @NotNull @@ -309,25 +299,17 @@ public class CreateMethodFromUsageFix extends CreateFromUsageFixBase { PsiElement elementAt = file.findElementAt(offset); JetFunction func = PsiTreeUtil.getParentOfType(elementAt, JetFunction.class); assert func != null; - JetParameterList parameterList = func.getValueParameterList(); - assert parameterList != null; - List parameters = parameterList.getParameters(); - assert parameters.size() == parameterTypeExpressions.size(); + List parameters = func.getValueParameters(); List typeParameterNames = new ArrayList(); Collections.addAll(typeParameterNames, ownerTypeParameterNames); - int i = 0; for (JetParameter parameter : parameters) { - TypeExpression parameterTypeExpression = parameterTypeExpressions.get(i); JetTypeReference parameterTypeRef = parameter.getTypeReference(); assert parameterTypeRef != null; - JetType parameterType = parameterTypeExpression.getTypeFromSelection(parameterTypeRef.getText()); - if (parameterType != null) { // the user chose a given type - String[] names = typeParameterMap.get(parameterType); + String[] names = typeParameterMap.get(parameterTypeRef.getText()); + if (names != null) { Collections.addAll(typeParameterNames, names); } - - i++; } return typeParameterNames.isEmpty() @@ -399,13 +381,14 @@ public class CreateMethodFromUsageFix extends CreateFromUsageFixBase { boolean isUnit = returnType.isType() && isUnit(returnType.getType()); String returnTypeString = isUnit ? "" : ": Any"; + String ownerTypeString; String methodText; JetNamedFunction func; PsiElement owner; boolean isExtension = !klass.isWritable(); if (isExtension) { // create as extension function - methodText = String.format("fun %s.%s(%s)%s { }", DescriptorRenderer.TEXT.renderType(ownerType), - methodName, parametersString, returnTypeString); + ownerTypeString = renderType(ownerType); + methodText = String.format("fun %s.%s(%s)%s { }", ownerTypeString, methodName, parametersString, returnTypeString); func = JetPsiFactory.createFunction(project, methodText); owner = file; func = (JetNamedFunction) file.add(func); @@ -438,24 +421,24 @@ public class CreateMethodFromUsageFix extends CreateFromUsageFixBase { if (!isUnit) { JetTypeReference returnTypeRef = func.getReturnTypeRef(); assert returnTypeRef != null; - Expression returnTypeExpression = new TypeExpression(project, returnType.getPossibleTypes()); + Expression returnTypeExpression = new TypeExpression(returnType.getPossibleTypes()); builder.replaceElement(returnTypeRef, returnTypeExpression); } // add parameters to the template List jetParameters = parameterList.getParameters(); - List parameterTypeExpressions = new ArrayList(); assert jetParameters.size() == parameters.size(); + TypeExpression[] parameterTypeExpressions = new TypeExpression[parameters.size()]; for (int i = 0; i < parameters.size(); i++) { Parameter parameter = parameters.get(i); JetParameter jetParameter = jetParameters.get(i); // add parameter type to the template - TypeExpression parameterTypeExpression = new TypeExpression(project, parameter.getType().getPossibleTypes()); - parameterTypeExpressions.add(parameterTypeExpression); + JetType[] typeOptions = parameter.getType().getPossibleTypes(); + parameterTypeExpressions[i] = new TypeExpression(typeOptions); JetTypeReference parameterTypeRef = jetParameter.getTypeReference(); assert parameterTypeRef != null; - builder.replaceElement(parameterTypeRef, parameterTypeExpression); + builder.replaceElement(parameterTypeRef, parameterTypeExpressions[i]); // add parameter name to the template String[] possibleNamesFromExpression = parameter.getType().getPossibleNamesFromExpression(); @@ -468,7 +451,18 @@ public class CreateMethodFromUsageFix extends CreateFromUsageFixBase { } else { possibleNames = possibleNamesFromExpression; } - Expression parameterNameExpression = new ParameterNameExpression(possibleNames, parameterTypeExpression); + + // figure out suggested names for each type option + Map parameterTypeToNamesMap = new HashMap(); + String[] typeOptionStrings = parameterTypeExpressions[i].getOptionStrings(); + assert typeOptions.length == typeOptionStrings.length; + for (int j = 0; j < typeOptions.length; j++) { + String[] suggestedNames = JetNameSuggester.suggestNamesForType(typeOptions[j], JetNameValidator.getEmptyValidator(project)); + parameterTypeToNamesMap.put(typeOptionStrings[j], suggestedNames); + } + + // add expression to builder + Expression parameterNameExpression = new ParameterNameExpression(possibleNames, parameterTypeToNamesMap); PsiElement parameterNameIdentifier = jetParameter.getNameIdentifier(); assert parameterNameIdentifier != null; builder.replaceElement(parameterNameIdentifier, parameterNameExpression); @@ -479,7 +473,7 @@ public class CreateMethodFromUsageFix extends CreateFromUsageFixBase { // need to create the segment first and then hack the Expression into the template later. We use this template to update the type // parameter list as the user makes selections in the parameter types, and we need alwaysStopAt to be false so the user can't tab to // it. - Map typeParameterMap = new HashMap(); + Map typeParameterMap = new HashMap(); DeclarationDescriptor ownerDescriptor = context.get(BindingContext.DECLARATION_TO_DESCRIPTOR, owner); JetScope scope; if (ownerDescriptor instanceof NamespaceDescriptor) { @@ -490,20 +484,19 @@ public class CreateMethodFromUsageFix extends CreateFromUsageFixBase { scope = classDescriptor.getMemberScope(classDescriptor.getDefaultType().getArguments()); } - String[] ownerTypeParameterNames = ArrayUtil.EMPTY_STRING_ARRAY; - if (isExtension) { - Set typeParameters = getTypeParametersInType(ownerType); - typeParameterMap.put(ownerType, ownerTypeParameterNames = getTypeParameterNamesNotInScope(typeParameters, scope)); - } - for (Parameter parameter : parameters) { - for (JetType type : parameter.getType().getPossibleTypes()) { - // get a list of type parameter candidates - Set typeParameters = getTypeParametersInType(type); - typeParameterMap.put(type, getTypeParameterNamesNotInScope(typeParameters, scope)); + Set ownerTypeParameters = getTypeParametersInType(ownerType); + String[] ownerTypeParameterNames = getTypeParameterNamesNotInScope(ownerTypeParameters, scope); + for (TypeExpression parameterTypeExpression : parameterTypeExpressions) { + JetType[] parameterTypeOptions = parameterTypeExpression.getOptions(); + String[] parameterTypeOptionStrings = parameterTypeExpression.getOptionStrings(); + assert parameterTypeOptions.length == parameterTypeOptionStrings.length; + for (int i = 0; i < parameterTypeOptions.length; i++) { + Set typeParameters = getTypeParametersInType(parameterTypeOptions[i]); + typeParameterMap.put(parameterTypeOptionStrings[i], getTypeParameterNamesNotInScope(typeParameters, scope)); } } - Expression expression = new TypeParameterListExpression(ownerTypeParameterNames, typeParameterMap, parameterTypeExpressions); + Expression expression = new TypeParameterListExpression(ownerTypeParameterNames, typeParameterMap); builder.replaceElement(func, TextRange.create(3, 3), TYPE_PARAMETER_LIST_VARIABLE_NAME, null, false); // ((3, 3) is after "fun") // the template built by TemplateBuilderImpl is ordered by element position, but we want types to be first, so hack it @@ -550,6 +543,21 @@ public class CreateMethodFromUsageFix extends CreateFromUsageFixBase { return true; } + @NotNull + private static String renderType(JetType type) { + return DescriptorRenderer.TEXT.renderType(type); + // TODO: take into account imports and stuff; how to refer to a type with the simplest name with imports (currently uses fully qualified name)? + } + + @NotNull + private static String[] renderTypes(JetType[] types) { + String[] typeStrings = new String[types.length]; + for (int i = 0; i < types.length; i++) { + typeStrings[i] = renderType(types[i]); + } + return typeStrings; + } + @NotNull private static String[] getTypeParameterNamesNotInScope(Collection typeParameters, JetScope scope) { List typeParameterNames = new ArrayList(); From 9b31195732d0ea95ae7cc202a6c65089e8144c27 Mon Sep 17 00:00:00 2001 From: Jack Zhou Date: Mon, 8 Apr 2013 12:53:06 -0400 Subject: [PATCH 003/291] Create from usage: Added supertype enumeration. --- .../quickfix/CreateMethodFromUsageFix.java | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/idea/src/org/jetbrains/jet/plugin/quickfix/CreateMethodFromUsageFix.java b/idea/src/org/jetbrains/jet/plugin/quickfix/CreateMethodFromUsageFix.java index f11f6550c23..f16ea3c8894 100644 --- a/idea/src/org/jetbrains/jet/plugin/quickfix/CreateMethodFromUsageFix.java +++ b/idea/src/org/jetbrains/jet/plugin/quickfix/CreateMethodFromUsageFix.java @@ -42,6 +42,7 @@ import org.jetbrains.jet.lang.resolve.BindingContext; import org.jetbrains.jet.lang.resolve.scopes.JetScope; 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.lang.KotlinBuiltIns; import org.jetbrains.jet.plugin.JetBundle; import org.jetbrains.jet.plugin.codeInsight.DescriptorToDeclarationUtil; @@ -98,8 +99,17 @@ public class CreateMethodFromUsageFix extends CreateFromUsageFixBase { assert cachedTypeCandidates != null; return cachedTypeCandidates; } - return cachedTypeCandidates = isType() ? new JetType[] {type} : guessTypeForExpression(expressionOfType, context); - // TODO: supertypes/subtypes of all possible types? + List types = new ArrayList(); + if (isType()) { + types.add(type); + types.addAll(TypeUtils.getAllSupertypes(type)); + } else { + for (JetType type : guessTypeForExpression(expressionOfType, context)) { + types.add(type); + types.addAll(TypeUtils.getAllSupertypes(type)); + } + } + return cachedTypeCandidates = types.toArray(new JetType[types.size()]); } @NotNull @@ -510,7 +520,7 @@ public class CreateMethodFromUsageFix extends CreateFromUsageFixBase { variables.add(new Variable(TYPE_PARAMETER_LIST_VARIABLE_NAME, expression, expression, false, true)); // run the template - TemplateManager.getInstance(project).startTemplate(editor, template, new TemplateEditingAdapter() { // TODO: too slow, speed it up + TemplateManager.getInstance(project).startTemplate(editor, template, new TemplateEditingAdapter() { @Override public void templateFinished(Template template, boolean brokenOff) { // TODO: file templates From 28ac582fde8e2b6b4fb9c85dea40d46e66a61ebc Mon Sep 17 00:00:00 2001 From: Jack Zhou Date: Mon, 8 Apr 2013 13:19:04 -0400 Subject: [PATCH 004/291] Create from usage: Refactored invoke(). --- .../quickfix/CreateMethodFromUsageFix.java | 141 ++++++++++-------- 1 file changed, 82 insertions(+), 59 deletions(-) diff --git a/idea/src/org/jetbrains/jet/plugin/quickfix/CreateMethodFromUsageFix.java b/idea/src/org/jetbrains/jet/plugin/quickfix/CreateMethodFromUsageFix.java index f16ea3c8894..0182e96d73a 100644 --- a/idea/src/org/jetbrains/jet/plugin/quickfix/CreateMethodFromUsageFix.java +++ b/idea/src/org/jetbrains/jet/plugin/quickfix/CreateMethodFromUsageFix.java @@ -193,7 +193,6 @@ public class CreateMethodFromUsageFix extends CreateFromUsageFixBase { assert editor != null; PsiFile file = PsiDocumentManager.getInstance(project).getPsiFile(editor.getDocument()); assert file != null && file instanceof JetFile; - JetFile jetFile = (JetFile) file; PsiElement elementAt = file.findElementAt(offset); JetFunction func = PsiTreeUtil.getParentOfType(elementAt, JetFunction.class); assert func != null; @@ -426,16 +425,90 @@ public class CreateMethodFromUsageFix extends CreateFromUsageFixBase { caretModel.moveToOffset(file.getNode().getStartOffset()); TemplateBuilderImpl builder = new TemplateBuilderImpl(file); - - // add return type to the template (if it's not a unit function) if (!isUnit) { - JetTypeReference returnTypeRef = func.getReturnTypeRef(); - assert returnTypeRef != null; - Expression returnTypeExpression = new TypeExpression(returnType.getPossibleTypes()); - builder.replaceElement(returnTypeRef, returnTypeExpression); + setupReturnTypeTemplate(builder, func, returnType); + } + TypeExpression[] parameterTypeExpressions = setupParameterTypeTemplates(project, builder, parameters, parameterList); + + // add a segment for the parameter list + // Note: because TemplateBuilderImpl does not have a replaceElement overload that takes in both a TextRange and alwaysStopAt, we + // need to create the segment first and then hack the Expression into the template later. We use this template to update the type + // parameter list as the user makes selections in the parameter types, and we need alwaysStopAt to be false so the user can't tab to + // it. + JetScope scope = getScope(owner, context); + TypeParameterListExpression expression = setupTypeParameterListTemplate(builder, func, ownerType, parameterTypeExpressions, scope); + + // the template built by TemplateBuilderImpl is ordered by element position, but we want types to be first, so hack it + TemplateImpl template = (TemplateImpl) builder.buildInlineTemplate(); + ArrayList variables = template.getVariables(); + for (int i = 0; i < parameters.size(); i++) { + Collections.swap(variables, i * 2, i * 2 + 1); } - // add parameters to the template + // fix up the template to include the expression for the type parameter list + variables.add(new Variable(TYPE_PARAMETER_LIST_VARIABLE_NAME, expression, expression, false, true)); + + // run the template + TemplateManager.getInstance(project).startTemplate(editor, template, new TemplateEditingAdapter() { + @Override + public void templateFinished(Template template, boolean brokenOff) { + // TODO: file templates + + caretModel.moveToOffset(oldOffset); + } + }); + } + + @NotNull + private static TypeExpression setupReturnTypeTemplate(@NotNull TemplateBuilder builder, @NotNull JetNamedFunction func, + @NotNull TypeOrExpressionThereof returnType) { + JetTypeReference returnTypeRef = func.getReturnTypeRef(); + assert returnTypeRef != null; + TypeExpression returnTypeExpression = new TypeExpression(returnType.getPossibleTypes()); + builder.replaceElement(returnTypeRef, returnTypeExpression); + return returnTypeExpression; + } + + @NotNull + private static TypeParameterListExpression setupTypeParameterListTemplate( + @NotNull TemplateBuilderImpl builder, + @NotNull JetNamedFunction func, + @NotNull JetType ownerType, + @NotNull TypeExpression[] parameterTypeExpressions, + @NotNull JetScope scope + ) { + Map typeParameterMap = new HashMap(); + Set ownerTypeParameters = getTypeParametersInType(ownerType); + String[] ownerTypeParameterNames = getTypeParameterNamesNotInScope(ownerTypeParameters, scope); + for (TypeExpression parameterTypeExpression : parameterTypeExpressions) { + JetType[] parameterTypeOptions = parameterTypeExpression.getOptions(); + String[] parameterTypeOptionStrings = parameterTypeExpression.getOptionStrings(); + assert parameterTypeOptions.length == parameterTypeOptionStrings.length; + for (int i = 0; i < parameterTypeOptions.length; i++) { + Set typeParameters = getTypeParametersInType(parameterTypeOptions[i]); + typeParameterMap.put(parameterTypeOptionStrings[i], getTypeParameterNamesNotInScope(typeParameters, scope)); + } + } + + builder.replaceElement(func, TextRange.create(3, 3), TYPE_PARAMETER_LIST_VARIABLE_NAME, null, false); // ((3, 3) is after "fun") + return new TypeParameterListExpression(ownerTypeParameterNames, typeParameterMap); + } + + @NotNull + private static JetScope getScope(@NotNull PsiElement owner, @NotNull BindingContext context) { + DeclarationDescriptor ownerDescriptor = context.get(BindingContext.DECLARATION_TO_DESCRIPTOR, owner); + assert ownerDescriptor != null; + if (ownerDescriptor instanceof NamespaceDescriptor) { + NamespaceDescriptor namespaceDescriptor = (NamespaceDescriptor) ownerDescriptor; + return namespaceDescriptor.getMemberScope(); + } else { + ClassDescriptor classDescriptor = (ClassDescriptor) ownerDescriptor; + return classDescriptor.getMemberScope(classDescriptor.getDefaultType().getArguments()); + } + } + + private static TypeExpression[] setupParameterTypeTemplates(@NotNull Project project, @NotNull TemplateBuilder builder, + @NotNull List parameters, @NotNull JetParameterList parameterList) { List jetParameters = parameterList.getParameters(); assert jetParameters.size() == parameters.size(); TypeExpression[] parameterTypeExpressions = new TypeExpression[parameters.size()]; @@ -477,57 +550,7 @@ public class CreateMethodFromUsageFix extends CreateFromUsageFixBase { assert parameterNameIdentifier != null; builder.replaceElement(parameterNameIdentifier, parameterNameExpression); } - - // add a segment for the parameter list - // Note: because TemplateBuilderImpl does not have a replaceElement overload that takes in both a TextRange and alwaysStopAt, we - // need to create the segment first and then hack the Expression into the template later. We use this template to update the type - // parameter list as the user makes selections in the parameter types, and we need alwaysStopAt to be false so the user can't tab to - // it. - Map typeParameterMap = new HashMap(); - DeclarationDescriptor ownerDescriptor = context.get(BindingContext.DECLARATION_TO_DESCRIPTOR, owner); - JetScope scope; - if (ownerDescriptor instanceof NamespaceDescriptor) { - NamespaceDescriptor namespaceDescriptor = (NamespaceDescriptor) ownerDescriptor; - scope = namespaceDescriptor.getMemberScope(); - } else { - ClassDescriptor classDescriptor = (ClassDescriptor) ownerDescriptor; - scope = classDescriptor.getMemberScope(classDescriptor.getDefaultType().getArguments()); - } - - Set ownerTypeParameters = getTypeParametersInType(ownerType); - String[] ownerTypeParameterNames = getTypeParameterNamesNotInScope(ownerTypeParameters, scope); - for (TypeExpression parameterTypeExpression : parameterTypeExpressions) { - JetType[] parameterTypeOptions = parameterTypeExpression.getOptions(); - String[] parameterTypeOptionStrings = parameterTypeExpression.getOptionStrings(); - assert parameterTypeOptions.length == parameterTypeOptionStrings.length; - for (int i = 0; i < parameterTypeOptions.length; i++) { - Set typeParameters = getTypeParametersInType(parameterTypeOptions[i]); - typeParameterMap.put(parameterTypeOptionStrings[i], getTypeParameterNamesNotInScope(typeParameters, scope)); - } - } - - Expression expression = new TypeParameterListExpression(ownerTypeParameterNames, typeParameterMap); - builder.replaceElement(func, TextRange.create(3, 3), TYPE_PARAMETER_LIST_VARIABLE_NAME, null, false); // ((3, 3) is after "fun") - - // the template built by TemplateBuilderImpl is ordered by element position, but we want types to be first, so hack it - TemplateImpl template = (TemplateImpl) builder.buildInlineTemplate(); - ArrayList variables = template.getVariables(); - for (int i = 0; i < parameters.size(); i++) { - Collections.swap(variables, i * 2, i * 2 + 1); - } - - // fix up the template to include the expression for the type parameter list - variables.add(new Variable(TYPE_PARAMETER_LIST_VARIABLE_NAME, expression, expression, false, true)); - - // run the template - TemplateManager.getInstance(project).startTemplate(editor, template, new TemplateEditingAdapter() { - @Override - public void templateFinished(Template template, boolean brokenOff) { - // TODO: file templates - - caretModel.moveToOffset(oldOffset); - } - }); + return parameterTypeExpressions; } @Override From 1e573235e8b242a8048b5ebcd6db3aaef1299ff7 Mon Sep 17 00:00:00 2001 From: Jack Zhou Date: Mon, 8 Apr 2013 20:19:14 -0400 Subject: [PATCH 005/291] Create from usage: Added file templates. --- .../jetbrains/jet/lang/psi/JetPsiFactory.java | 5 ++ .../code/New Kotlin Method Body.kt.ft | 1 + .../code/New Kotlin Method Body.kt.html | 38 ++++++++++++ .../quickfix/CreateMethodFromUsageFix.java | 58 ++++++++++++++++--- 4 files changed, 95 insertions(+), 7 deletions(-) create mode 100644 idea/resources/fileTemplates/code/New Kotlin Method Body.kt.ft create mode 100644 idea/resources/fileTemplates/code/New Kotlin Method Body.kt.html 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..fa9c5aadc94 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,9 @@ public class JetPsiFactory { public static JetExpressionCodeFragment createExpressionCodeFragment(Project project, String text, PsiElement context) { return new JetExpressionCodeFragmentImpl(project, "fragment.kt", text, context); } + + public static JetExpression createFunctionBody(Project project, @NotNull String bodyText) { + JetFunction func = createFunction(project, "fun foo() {\n" + bodyText + "\n}"); + return func.getBodyExpression(); + } } diff --git a/idea/resources/fileTemplates/code/New Kotlin Method Body.kt.ft b/idea/resources/fileTemplates/code/New Kotlin Method Body.kt.ft new file mode 100644 index 00000000000..623da6c89fa --- /dev/null +++ b/idea/resources/fileTemplates/code/New Kotlin Method Body.kt.ft @@ -0,0 +1 @@ +//To change body of created methods use File | Settings | File Templates. \ No newline at end of file diff --git a/idea/resources/fileTemplates/code/New Kotlin Method Body.kt.html b/idea/resources/fileTemplates/code/New Kotlin Method Body.kt.html new file mode 100644 index 00000000000..c3526f30920 --- /dev/null +++ b/idea/resources/fileTemplates/code/New Kotlin Method Body.kt.html @@ -0,0 +1,38 @@ + + + + + + +
This is a built-in template used for filling the body of a Kotlin method + each time it is generated by the program, e.g. when using the Create Method from Usage intention action.
+ The template is editable. Along with Kotlin expressions and comments, you can also use the predefined variables + that will be then expanded into the corresponding values.
+
+ + + + + + + + + + + + + + + + + + + + + + + + +
Predefined variables will take the following values:
${RETURN_TYPE} a return type of a created method
${METHOD_NAME} name of the created method
${CLASS_NAME} qualified name of the class where method is created
${SIMPLE_CLASS_NAME} non-qualified name of the class where method is implemented
+ + \ No newline at end of file diff --git a/idea/src/org/jetbrains/jet/plugin/quickfix/CreateMethodFromUsageFix.java b/idea/src/org/jetbrains/jet/plugin/quickfix/CreateMethodFromUsageFix.java index 0182e96d73a..55d7a444144 100644 --- a/idea/src/org/jetbrains/jet/plugin/quickfix/CreateMethodFromUsageFix.java +++ b/idea/src/org/jetbrains/jet/plugin/quickfix/CreateMethodFromUsageFix.java @@ -22,8 +22,11 @@ import com.intellij.codeInsight.lookup.LookupElementBuilder; import com.intellij.codeInsight.template.*; import com.intellij.codeInsight.template.impl.TemplateImpl; import com.intellij.codeInsight.template.impl.Variable; +import com.intellij.ide.fileTemplates.FileTemplate; +import com.intellij.ide.fileTemplates.FileTemplateManager; import com.intellij.openapi.editor.CaretModel; import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.progress.ProcessCanceledException; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.TextRange; import com.intellij.openapi.util.text.StringUtil; @@ -33,12 +36,14 @@ import com.intellij.psi.PsiFile; import com.intellij.psi.util.PsiTreeUtil; import com.intellij.util.ArrayUtil; import com.intellij.util.IncorrectOperationException; +import org.jetbrains.annotations.NonNls; 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.*; import org.jetbrains.jet.lang.resolve.BindingContext; +import org.jetbrains.jet.lang.resolve.DescriptorUtils; import org.jetbrains.jet.lang.resolve.scopes.JetScope; import org.jetbrains.jet.lang.types.JetType; import org.jetbrains.jet.lang.types.TypeProjection; @@ -55,6 +60,7 @@ import java.util.*; public class CreateMethodFromUsageFix extends CreateFromUsageFixBase { private static final String TYPE_PARAMETER_LIST_VARIABLE_NAME = "typeParameterList"; + private static final String TEMPLATE_FROM_USAGE_METHOD_BODY = "New Kotlin Method Body.kt"; /** * Represents a concrete type or a set of types yet to be inferred from an expression. @@ -360,7 +366,7 @@ public class CreateMethodFromUsageFix extends CreateFromUsageFixBase { } @Override - public void invoke(@NotNull Project project, Editor editor, PsiFile file) throws IncorrectOperationException { + public void invoke(@NotNull final Project project, Editor editor, PsiFile file) throws IncorrectOperationException { assert file instanceof JetFile; JetFile jetFile = (JetFile) file; BindingContext context = AnalyzerFacadeWithCache.analyzeFileWithCache(jetFile).getBindingContext(); @@ -376,7 +382,8 @@ public class CreateMethodFromUsageFix extends CreateFromUsageFixBase { ownerType = possibleOwnerTypes[0]; } - ClassifierDescriptor ownerTypeDescriptor = ownerType.getConstructor().getDeclarationDescriptor(); + final ClassifierDescriptor ownerTypeDescriptor = ownerType.getConstructor().getDeclarationDescriptor(); + assert ownerTypeDescriptor != null; PsiElement typeDeclaration = DescriptorToDeclarationUtil.getDeclaration(jetFile, ownerTypeDescriptor, context); JetClass klass = (JetClass) typeDeclaration; @@ -387,24 +394,28 @@ public class CreateMethodFromUsageFix extends CreateFromUsageFixBase { } String parametersString = StringUtil.join(parameterStrings,", "); - boolean isUnit = returnType.isType() && isUnit(returnType.getType()); + final boolean isUnit = returnType.isType() && isUnit(returnType.getType()); String returnTypeString = isUnit ? "" : ": Any"; String ownerTypeString; String methodText; JetNamedFunction func; PsiElement owner; + final JetFile containingFile; boolean isExtension = !klass.isWritable(); if (isExtension) { // create as extension function ownerTypeString = renderType(ownerType); methodText = String.format("fun %s.%s(%s)%s { }", ownerTypeString, methodName, parametersString, returnTypeString); func = JetPsiFactory.createFunction(project, methodText); - owner = file; + owner = containingFile = jetFile; func = (JetNamedFunction) file.add(func); } else { // create as method methodText = String.format("fun %s(%s)%s { }", methodName, parametersString, returnTypeString); func = JetPsiFactory.createFunction(project, methodText); owner = klass; + PsiFile classContainingFile = klass.getContainingFile(); + assert classContainingFile instanceof JetFile; + containingFile = (JetFile) classContainingFile; JetClassBody classBody = klass.getBody(); assert classBody != null; PsiElement rBrace = classBody.getRBrace(); @@ -439,7 +450,7 @@ public class CreateMethodFromUsageFix extends CreateFromUsageFixBase { TypeParameterListExpression expression = setupTypeParameterListTemplate(builder, func, ownerType, parameterTypeExpressions, scope); // the template built by TemplateBuilderImpl is ordered by element position, but we want types to be first, so hack it - TemplateImpl template = (TemplateImpl) builder.buildInlineTemplate(); + final TemplateImpl template = (TemplateImpl) builder.buildInlineTemplate(); ArrayList variables = template.getVariables(); for (int i = 0; i < parameters.size(); i++) { Collections.swap(variables, i * 2, i * 2 + 1); @@ -451,14 +462,47 @@ public class CreateMethodFromUsageFix extends CreateFromUsageFixBase { // run the template TemplateManager.getInstance(project).startTemplate(editor, template, new TemplateEditingAdapter() { @Override - public void templateFinished(Template template, boolean brokenOff) { - // TODO: file templates + public void templateFinished(Template _, boolean brokenOff) { + int offset = template.getSegmentOffset(0); + JetNamedFunction func = PsiTreeUtil.findElementOfClassAtOffset(containingFile, offset, JetNamedFunction.class, false); + assert func != null; + setupFunctionBody(project, func, isUnit, ownerTypeDescriptor); caretModel.moveToOffset(oldOffset); } }); } + private void setupFunctionBody(@NotNull Project project, @NotNull JetNamedFunction func, boolean isUnit, + @NotNull ClassifierDescriptor ownerTypeDescriptor + ) { + FileTemplate fileTemplate = FileTemplateManager.getInstance().getCodeTemplate(TEMPLATE_FROM_USAGE_METHOD_BODY); + Properties properties = new Properties(); + if (isUnit) { + properties.setProperty(FileTemplate.ATTRIBUTE_RETURN_TYPE, "Unit"); + } else { + JetTypeReference returnTypeRef = func.getReturnTypeRef(); + assert returnTypeRef != null; + properties.setProperty(FileTemplate.ATTRIBUTE_RETURN_TYPE, returnTypeRef.getText()); + } + properties.setProperty(FileTemplate.ATTRIBUTE_CLASS_NAME, DescriptorUtils.getFQName(ownerTypeDescriptor).getFqName()); + properties.setProperty(FileTemplate.ATTRIBUTE_SIMPLE_CLASS_NAME, ownerTypeDescriptor.getName().getName()); + properties.setProperty(FileTemplate.ATTRIBUTE_METHOD_NAME, methodName); + + @NonNls String bodyText; + try { + bodyText = fileTemplate.getText(properties); + } catch (ProcessCanceledException e) { + throw e; + } catch (Exception e) { + throw new IncorrectOperationException("Failed to parse file template", e); + } + JetExpression newBodyExpression = JetPsiFactory.createFunctionBody(project, bodyText); + JetExpression oldBodyExpression = func.getBodyExpression(); + assert oldBodyExpression != null; + oldBodyExpression.replace(newBodyExpression); + } + @NotNull private static TypeExpression setupReturnTypeTemplate(@NotNull TemplateBuilder builder, @NotNull JetNamedFunction func, @NotNull TypeOrExpressionThereof returnType) { From 3caad4b199aeacac36af4405149a82a9d408fb63 Mon Sep 17 00:00:00 2001 From: Jack Zhou Date: Mon, 8 Apr 2013 21:25:39 -0400 Subject: [PATCH 006/291] Create from usage: Fixed a runWriteAction. --- .../jet/plugin/quickfix/CreateMethodFromUsageFix.java | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/idea/src/org/jetbrains/jet/plugin/quickfix/CreateMethodFromUsageFix.java b/idea/src/org/jetbrains/jet/plugin/quickfix/CreateMethodFromUsageFix.java index 55d7a444144..a7f2c42e04f 100644 --- a/idea/src/org/jetbrains/jet/plugin/quickfix/CreateMethodFromUsageFix.java +++ b/idea/src/org/jetbrains/jet/plugin/quickfix/CreateMethodFromUsageFix.java @@ -24,6 +24,7 @@ import com.intellij.codeInsight.template.impl.TemplateImpl; import com.intellij.codeInsight.template.impl.Variable; import com.intellij.ide.fileTemplates.FileTemplate; import com.intellij.ide.fileTemplates.FileTemplateManager; +import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.editor.CaretModel; import com.intellij.openapi.editor.Editor; import com.intellij.openapi.progress.ProcessCanceledException; @@ -464,9 +465,14 @@ public class CreateMethodFromUsageFix extends CreateFromUsageFixBase { @Override public void templateFinished(Template _, boolean brokenOff) { int offset = template.getSegmentOffset(0); - JetNamedFunction func = PsiTreeUtil.findElementOfClassAtOffset(containingFile, offset, JetNamedFunction.class, false); + final JetNamedFunction func = PsiTreeUtil.findElementOfClassAtOffset(containingFile, offset, JetNamedFunction.class, false); assert func != null; - setupFunctionBody(project, func, isUnit, ownerTypeDescriptor); + ApplicationManager.getApplication().runWriteAction(new Runnable() { + @Override + public void run() { + setupFunctionBody(project, func, isUnit, ownerTypeDescriptor); + } + }); caretModel.moveToOffset(oldOffset); } From 197000b8cea295b3409c4e5979a26496947f5e8c Mon Sep 17 00:00:00 2001 From: Jack Zhou Date: Mon, 8 Apr 2013 21:33:34 -0400 Subject: [PATCH 007/291] Create from usage: Fixed not resolving type parameter correctly. --- .../jet/plugin/quickfix/CreateMethodFromUsageFix.java | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/idea/src/org/jetbrains/jet/plugin/quickfix/CreateMethodFromUsageFix.java b/idea/src/org/jetbrains/jet/plugin/quickfix/CreateMethodFromUsageFix.java index a7f2c42e04f..938992435c3 100644 --- a/idea/src/org/jetbrains/jet/plugin/quickfix/CreateMethodFromUsageFix.java +++ b/idea/src/org/jetbrains/jet/plugin/quickfix/CreateMethodFromUsageFix.java @@ -41,6 +41,7 @@ import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.jet.lang.descriptors.*; +import org.jetbrains.jet.lang.descriptors.impl.MutableClassDescriptor; import org.jetbrains.jet.lang.diagnostics.Diagnostic; import org.jetbrains.jet.lang.psi.*; import org.jetbrains.jet.lang.resolve.BindingContext; @@ -552,8 +553,9 @@ public class CreateMethodFromUsageFix extends CreateFromUsageFixBase { NamespaceDescriptor namespaceDescriptor = (NamespaceDescriptor) ownerDescriptor; return namespaceDescriptor.getMemberScope(); } else { - ClassDescriptor classDescriptor = (ClassDescriptor) ownerDescriptor; - return classDescriptor.getMemberScope(classDescriptor.getDefaultType().getArguments()); + assert ownerDescriptor instanceof MutableClassDescriptor; + MutableClassDescriptor classDescriptor = (MutableClassDescriptor) ownerDescriptor; + return classDescriptor.getScopeForMemberResolution(); } } From 0d36ae7f0114c629b8186fda75caf4a102436643 Mon Sep 17 00:00:00 2001 From: Jack Zhou Date: Mon, 8 Apr 2013 21:49:57 -0400 Subject: [PATCH 008/291] Create from usage: Fixed return type's type parameters not being taken into account. --- .../quickfix/CreateMethodFromUsageFix.java | 25 ++++++++++++++++--- 1 file changed, 21 insertions(+), 4 deletions(-) diff --git a/idea/src/org/jetbrains/jet/plugin/quickfix/CreateMethodFromUsageFix.java b/idea/src/org/jetbrains/jet/plugin/quickfix/CreateMethodFromUsageFix.java index 938992435c3..a5933c5c3c2 100644 --- a/idea/src/org/jetbrains/jet/plugin/quickfix/CreateMethodFromUsageFix.java +++ b/idea/src/org/jetbrains/jet/plugin/quickfix/CreateMethodFromUsageFix.java @@ -328,6 +328,13 @@ public class CreateMethodFromUsageFix extends CreateFromUsageFixBase { Collections.addAll(typeParameterNames, names); } } + JetTypeReference returnTypeRef = func.getReturnTypeRef(); + if (returnTypeRef != null) { + String[] names = typeParameterMap.get(returnTypeRef.getText()); + if (names != null) { + Collections.addAll(typeParameterNames, names); + } + } return typeParameterNames.isEmpty() ? new TextResult("") @@ -438,9 +445,7 @@ public class CreateMethodFromUsageFix extends CreateFromUsageFixBase { caretModel.moveToOffset(file.getNode().getStartOffset()); TemplateBuilderImpl builder = new TemplateBuilderImpl(file); - if (!isUnit) { - setupReturnTypeTemplate(builder, func, returnType); - } + TypeExpression returnTypeExpression = isUnit ? null : setupReturnTypeTemplate(builder, func, returnType); TypeExpression[] parameterTypeExpressions = setupParameterTypeTemplates(project, builder, parameters, parameterList); // add a segment for the parameter list @@ -449,7 +454,7 @@ public class CreateMethodFromUsageFix extends CreateFromUsageFixBase { // parameter list as the user makes selections in the parameter types, and we need alwaysStopAt to be false so the user can't tab to // it. JetScope scope = getScope(owner, context); - TypeParameterListExpression expression = setupTypeParameterListTemplate(builder, func, ownerType, parameterTypeExpressions, scope); + TypeParameterListExpression expression = setupTypeParameterListTemplate(builder, func, ownerType, parameterTypeExpressions, returnTypeExpression, scope); // the template built by TemplateBuilderImpl is ordered by element position, but we want types to be first, so hack it final TemplateImpl template = (TemplateImpl) builder.buildInlineTemplate(); @@ -526,6 +531,7 @@ public class CreateMethodFromUsageFix extends CreateFromUsageFixBase { @NotNull JetNamedFunction func, @NotNull JetType ownerType, @NotNull TypeExpression[] parameterTypeExpressions, + @Nullable TypeExpression returnTypeExpression, @NotNull JetScope scope ) { Map typeParameterMap = new HashMap(); @@ -541,6 +547,17 @@ public class CreateMethodFromUsageFix extends CreateFromUsageFixBase { } } + JetTypeReference returnTypeRef = func.getReturnTypeRef(); + if (returnTypeRef != null) { + JetType[] returnTypeOptions = returnTypeExpression.getOptions(); + String[] returnTypeOptionStrings = returnTypeExpression.getOptionStrings(); + assert returnTypeOptions.length == returnTypeOptionStrings.length; + for (int i = 0; i < returnTypeOptions.length; i++) { + Set typeParameters = getTypeParametersInType(returnTypeOptions[i]); + typeParameterMap.put(returnTypeOptionStrings[i], getTypeParameterNamesNotInScope(typeParameters, scope)); + } + } + builder.replaceElement(func, TextRange.create(3, 3), TYPE_PARAMETER_LIST_VARIABLE_NAME, null, false); // ((3, 3) is after "fun") return new TypeParameterListExpression(ownerTypeParameterNames, typeParameterMap); } From 870dbd7e86d76312001145531a8fba846fc39895 Mon Sep 17 00:00:00 2001 From: Jack Zhou Date: Mon, 8 Apr 2013 21:52:42 -0400 Subject: [PATCH 009/291] Create from usage: Changed new method template to raise exception like in ReSharper. --- idea/resources/fileTemplates/code/New Kotlin Method Body.kt.ft | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/idea/resources/fileTemplates/code/New Kotlin Method Body.kt.ft b/idea/resources/fileTemplates/code/New Kotlin Method Body.kt.ft index 623da6c89fa..69d16fa46b5 100644 --- a/idea/resources/fileTemplates/code/New Kotlin Method Body.kt.ft +++ b/idea/resources/fileTemplates/code/New Kotlin Method Body.kt.ft @@ -1 +1 @@ -//To change body of created methods use File | Settings | File Templates. \ No newline at end of file +throw Exception("not implemented") //To change body of created methods use File | Settings | File Templates. \ No newline at end of file From f17b93c949739a756b04d61f410a79dfa5602be9 Mon Sep 17 00:00:00 2001 From: Jack Zhou Date: Mon, 8 Apr 2013 22:33:18 -0400 Subject: [PATCH 010/291] Create from usage: Fixed a warning. --- .../jetbrains/jet/plugin/quickfix/CreateMethodFromUsageFix.java | 1 + 1 file changed, 1 insertion(+) diff --git a/idea/src/org/jetbrains/jet/plugin/quickfix/CreateMethodFromUsageFix.java b/idea/src/org/jetbrains/jet/plugin/quickfix/CreateMethodFromUsageFix.java index a5933c5c3c2..724634fc054 100644 --- a/idea/src/org/jetbrains/jet/plugin/quickfix/CreateMethodFromUsageFix.java +++ b/idea/src/org/jetbrains/jet/plugin/quickfix/CreateMethodFromUsageFix.java @@ -549,6 +549,7 @@ public class CreateMethodFromUsageFix extends CreateFromUsageFixBase { JetTypeReference returnTypeRef = func.getReturnTypeRef(); if (returnTypeRef != null) { + assert returnTypeExpression != null; JetType[] returnTypeOptions = returnTypeExpression.getOptions(); String[] returnTypeOptionStrings = returnTypeExpression.getOptionStrings(); assert returnTypeOptions.length == returnTypeOptionStrings.length; From bded310f3eef4718ac642c35bf758ee88843ccc0 Mon Sep 17 00:00:00 2001 From: Jack Zhou Date: Tue, 9 Apr 2013 22:23:43 -0400 Subject: [PATCH 011/291] Create from usage: Changed setupFunctionBody to static. --- .../jet/plugin/quickfix/CreateMethodFromUsageFix.java | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/idea/src/org/jetbrains/jet/plugin/quickfix/CreateMethodFromUsageFix.java b/idea/src/org/jetbrains/jet/plugin/quickfix/CreateMethodFromUsageFix.java index 724634fc054..2b08d9b7c72 100644 --- a/idea/src/org/jetbrains/jet/plugin/quickfix/CreateMethodFromUsageFix.java +++ b/idea/src/org/jetbrains/jet/plugin/quickfix/CreateMethodFromUsageFix.java @@ -476,7 +476,7 @@ public class CreateMethodFromUsageFix extends CreateFromUsageFixBase { ApplicationManager.getApplication().runWriteAction(new Runnable() { @Override public void run() { - setupFunctionBody(project, func, isUnit, ownerTypeDescriptor); + setupFunctionBody(project, func, methodName, isUnit, ownerTypeDescriptor); } }); @@ -485,7 +485,11 @@ public class CreateMethodFromUsageFix extends CreateFromUsageFixBase { }); } - private void setupFunctionBody(@NotNull Project project, @NotNull JetNamedFunction func, boolean isUnit, + private static void setupFunctionBody( + @NotNull Project project, + @NotNull JetNamedFunction func, + @NotNull String funcName, + boolean isUnit, @NotNull ClassifierDescriptor ownerTypeDescriptor ) { FileTemplate fileTemplate = FileTemplateManager.getInstance().getCodeTemplate(TEMPLATE_FROM_USAGE_METHOD_BODY); @@ -499,7 +503,7 @@ public class CreateMethodFromUsageFix extends CreateFromUsageFixBase { } properties.setProperty(FileTemplate.ATTRIBUTE_CLASS_NAME, DescriptorUtils.getFQName(ownerTypeDescriptor).getFqName()); properties.setProperty(FileTemplate.ATTRIBUTE_SIMPLE_CLASS_NAME, ownerTypeDescriptor.getName().getName()); - properties.setProperty(FileTemplate.ATTRIBUTE_METHOD_NAME, methodName); + properties.setProperty(FileTemplate.ATTRIBUTE_METHOD_NAME, funcName); @NonNls String bodyText; try { From 73acc2e99b7c9d6189f31980e9252b1fd62f6e4d Mon Sep 17 00:00:00 2001 From: Jack Zhou Date: Tue, 9 Apr 2013 23:33:08 -0400 Subject: [PATCH 012/291] Create from usage: Fixed type parameters for more complicated cases. --- .../quickfix/CreateMethodFromUsageFix.java | 94 +++++++++++++++++-- 1 file changed, 86 insertions(+), 8 deletions(-) diff --git a/idea/src/org/jetbrains/jet/plugin/quickfix/CreateMethodFromUsageFix.java b/idea/src/org/jetbrains/jet/plugin/quickfix/CreateMethodFromUsageFix.java index 2b08d9b7c72..064d1ef4da0 100644 --- a/idea/src/org/jetbrains/jet/plugin/quickfix/CreateMethodFromUsageFix.java +++ b/idea/src/org/jetbrains/jet/plugin/quickfix/CreateMethodFromUsageFix.java @@ -47,9 +47,7 @@ import org.jetbrains.jet.lang.psi.*; import org.jetbrains.jet.lang.resolve.BindingContext; import org.jetbrains.jet.lang.resolve.DescriptorUtils; import org.jetbrains.jet.lang.resolve.scopes.JetScope; -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.*; import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns; import org.jetbrains.jet.plugin.JetBundle; import org.jetbrains.jet.plugin.codeInsight.DescriptorToDeclarationUtil; @@ -69,7 +67,7 @@ public class CreateMethodFromUsageFix extends CreateFromUsageFixBase { */ private static class TypeOrExpressionThereof { private final JetExpression expressionOfType; - private final JetType type; + private JetType type; private JetType[] cachedTypeCandidates; private String[] cachedNameCandidatesFromExpression; @@ -135,6 +133,15 @@ public class CreateMethodFromUsageFix extends CreateFromUsageFixBase { JetNameValidator.getEmptyValidator(expressionOfType.getProject())); return cachedNameCandidatesFromExpression; } + + public void substitute(TypeSubstitution[] substitutions) { + if (type != null) { + for (TypeSubstitution substitution : substitutions) { + type = substituteType(type, substitution); + } + } + cachedTypeCandidates = substituteTypes(cachedTypeCandidates, substitutions); + } } /** @@ -336,6 +343,13 @@ public class CreateMethodFromUsageFix extends CreateFromUsageFixBase { } } + // make sure there are no name conflicts + for (int i = 0; i < typeParameterNames.size(); i++) { + String name = typeParameterNames.get(i); + name = getNextAvailableName(name, typeParameterNames.subList(0, i)); + typeParameterNames.set(i, name); + } + return typeParameterNames.isEmpty() ? new TextResult("") : new TextResult(" <" + StringUtil.join(typeParameterNames, ", ") + ">"); @@ -354,6 +368,27 @@ public class CreateMethodFromUsageFix extends CreateFromUsageFixBase { } } + /** + * Encapsulates a single type substitution of a JetType by another JetType. + */ + private static class TypeSubstitution { + private final JetType forType; + private final JetType byType; + + private TypeSubstitution(JetType forType, JetType byType) { + this.forType = forType; + this.byType = byType; + } + + private JetType getForType() { + return forType; + } + + private JetType getByType() { + return byType; + } + } + private final String methodName; private final TypeOrExpressionThereof ownerType; private final TypeOrExpressionThereof returnType; @@ -392,10 +427,24 @@ public class CreateMethodFromUsageFix extends CreateFromUsageFixBase { } final ClassifierDescriptor ownerTypeDescriptor = ownerType.getConstructor().getDeclarationDescriptor(); - assert ownerTypeDescriptor != null; + assert ownerTypeDescriptor != null && ownerTypeDescriptor instanceof ClassDescriptor; + ClassDescriptor ownerClassDescriptor = (ClassDescriptor) ownerTypeDescriptor; PsiElement typeDeclaration = DescriptorToDeclarationUtil.getDeclaration(jetFile, ownerTypeDescriptor, context); JetClass klass = (JetClass) typeDeclaration; + // figure out type substitutions for type parameters + List classTypeParameters = ownerClassDescriptor.getDefaultType().getArguments(); + List ownerTypeArguments = ownerType.getArguments(); + assert ownerTypeArguments.size() == classTypeParameters.size(); + TypeSubstitution[] substitutions = new TypeSubstitution[classTypeParameters.size()]; + for (int i = 0; i < substitutions.length; i++) { + substitutions[i] = new TypeSubstitution(ownerTypeArguments.get(i).getType(), classTypeParameters.get(i).getType()); + } + returnType.substitute(substitutions); + for (Parameter parameter : parameters) { + parameter.getType().substitute(substitutions); + } + // create method with placeholder types and parameter names String[] parameterStrings = new String[parameters.size()]; for (int i = 0; i < parameterStrings.length; i++) { @@ -413,7 +462,7 @@ public class CreateMethodFromUsageFix extends CreateFromUsageFixBase { final JetFile containingFile; boolean isExtension = !klass.isWritable(); if (isExtension) { // create as extension function - ownerTypeString = renderType(ownerType); + ownerTypeString = renderType(ownerClassDescriptor.getDefaultType()); methodText = String.format("fun %s.%s(%s)%s { }", ownerTypeString, methodName, parametersString, returnTypeString); func = JetPsiFactory.createFunction(project, methodText); owner = containingFile = jetFile; @@ -454,7 +503,8 @@ public class CreateMethodFromUsageFix extends CreateFromUsageFixBase { // parameter list as the user makes selections in the parameter types, and we need alwaysStopAt to be false so the user can't tab to // it. JetScope scope = getScope(owner, context); - TypeParameterListExpression expression = setupTypeParameterListTemplate(builder, func, ownerType, parameterTypeExpressions, returnTypeExpression, scope); + TypeParameterListExpression expression = setupTypeParameterListTemplate(builder, func, ownerClassDescriptor.getDefaultType(), + parameterTypeExpressions, returnTypeExpression, scope); // the template built by TemplateBuilderImpl is ordered by element position, but we want types to be first, so hack it final TemplateImpl template = (TemplateImpl) builder.buildInlineTemplate(); @@ -485,6 +535,34 @@ public class CreateMethodFromUsageFix extends CreateFromUsageFixBase { }); } + @NotNull + private static JetType substituteType(@NotNull JetType type, @NotNull TypeSubstitution substitution) { + if (type.equals(substitution.getForType())) { + return substitution.getByType(); + } + + List newArguments = new ArrayList(); + for (TypeProjection projection : type.getArguments()) { + JetType newArgument = substituteType(projection.getType(), substitution); + newArguments.add(new TypeProjection(Variance.INVARIANT, newArgument)); + } + return new JetTypeImpl(type.getAnnotations(), type.getConstructor(), + type.isNullable(), newArguments, type.getMemberScope()); + } + + @NotNull + private static JetType[] substituteTypes(@NotNull JetType[] types, @NotNull TypeSubstitution[] substitutions) { + JetType[] newTypes = new JetType[types.length]; + for (int i = 0; i < types.length; i++) { + JetType newType = types[i]; + for (TypeSubstitution substitution : substitutions) { + newType = substituteType(newType, substitution); + } + newTypes[i] = newType; + } + return newTypes; + } + private static void setupFunctionBody( @NotNull Project project, @NotNull JetNamedFunction func, @@ -695,7 +773,7 @@ public class CreateMethodFromUsageFix extends CreateFromUsageFixBase { } @NotNull - private static String getNextAvailableName(@NotNull String name, @NotNull Set existingNames) { + private static String getNextAvailableName(@NotNull String name, @NotNull Collection existingNames) { if (existingNames.contains(name)) { int j = 1; while (existingNames.contains(name + j)) j++; From 8f21a7d97a15b140dc337ad040dc1b9e7090cb5c Mon Sep 17 00:00:00 2001 From: Jack Zhou Date: Wed, 10 Apr 2013 01:29:19 -0400 Subject: [PATCH 013/291] Create from usage: Added type name shortening. --- .../quickfix/CreateMethodFromUsageFix.java | 130 ++++++++++++++---- 1 file changed, 104 insertions(+), 26 deletions(-) diff --git a/idea/src/org/jetbrains/jet/plugin/quickfix/CreateMethodFromUsageFix.java b/idea/src/org/jetbrains/jet/plugin/quickfix/CreateMethodFromUsageFix.java index 064d1ef4da0..b19706cfb47 100644 --- a/idea/src/org/jetbrains/jet/plugin/quickfix/CreateMethodFromUsageFix.java +++ b/idea/src/org/jetbrains/jet/plugin/quickfix/CreateMethodFromUsageFix.java @@ -51,6 +51,7 @@ import org.jetbrains.jet.lang.types.*; import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns; import org.jetbrains.jet.plugin.JetBundle; import org.jetbrains.jet.plugin.codeInsight.DescriptorToDeclarationUtil; +import org.jetbrains.jet.plugin.codeInsight.ReferenceToClassesShortening; import org.jetbrains.jet.plugin.project.AnalyzerFacadeWithCache; import org.jetbrains.jet.plugin.refactoring.JetNameSuggester; import org.jetbrains.jet.plugin.refactoring.JetNameValidator; @@ -191,7 +192,7 @@ public class CreateMethodFromUsageFix extends CreateFromUsageFixBase { @Nullable @Override public Result calculateQuickResult(ExpressionContext context) { - return null; + return calculateResult(context); } @NotNull @@ -255,11 +256,16 @@ public class CreateMethodFromUsageFix extends CreateFromUsageFixBase { private static class TypeExpression extends Expression { private final JetType[] options; private final String[] optionStrings; + private final LookupElement[] cachedLookupElements; public TypeExpression(@NotNull JetType[] options) { - //To change body of created methods use File | Settings | File Templates. this.options = options; - optionStrings = renderTypes(options); + optionStrings = new String[options.length]; + cachedLookupElements = new LookupElement[options.length]; + for (int i = 0; i < options.length; i++) { + optionStrings[i] = renderTypeShort(options[i]); + cachedLookupElements[i] = LookupElementBuilder.create(options[i], optionStrings[i]); + } } @Nullable @@ -274,17 +280,13 @@ public class CreateMethodFromUsageFix extends CreateFromUsageFixBase { @Nullable @Override public Result calculateQuickResult(ExpressionContext context) { - return null; + return calculateResult(context); } @NotNull @Override public LookupElement[] calculateLookupItems(ExpressionContext context) { - LookupElement[] lookupElements = new LookupElement[options.length]; - for (int i = 0; i < options.length; i++) { - lookupElements[i] = LookupElementBuilder.create(optionStrings[i]); - } - return lookupElements; + return cachedLookupElements; } @NotNull @@ -296,6 +298,16 @@ public class CreateMethodFromUsageFix extends CreateFromUsageFixBase { public String[] getOptionStrings() { return optionStrings; } + + @Nullable("can't be found") + public JetType getTypeFromSelection(@NotNull String selection) { + for (int i = 0; i < options.length; i++) { + if (optionStrings[i].equals(selection)) { + return options[i]; + } + } + return null; + } } /** @@ -358,7 +370,7 @@ public class CreateMethodFromUsageFix extends CreateFromUsageFixBase { @Nullable @Override public Result calculateQuickResult(ExpressionContext context) { - return null; + return calculateResult(context); } @NotNull @@ -411,6 +423,8 @@ public class CreateMethodFromUsageFix extends CreateFromUsageFixBase { @Override public void invoke(@NotNull final Project project, Editor editor, PsiFile file) throws IncorrectOperationException { + // TODO: editing across files + assert file instanceof JetFile; JetFile jetFile = (JetFile) file; BindingContext context = AnalyzerFacadeWithCache.analyzeFileWithCache(jetFile).getBindingContext(); @@ -429,11 +443,12 @@ public class CreateMethodFromUsageFix extends CreateFromUsageFixBase { final ClassifierDescriptor ownerTypeDescriptor = ownerType.getConstructor().getDeclarationDescriptor(); assert ownerTypeDescriptor != null && ownerTypeDescriptor instanceof ClassDescriptor; ClassDescriptor ownerClassDescriptor = (ClassDescriptor) ownerTypeDescriptor; + final JetType receiverType = ownerClassDescriptor.getDefaultType(); PsiElement typeDeclaration = DescriptorToDeclarationUtil.getDeclaration(jetFile, ownerTypeDescriptor, context); JetClass klass = (JetClass) typeDeclaration; // figure out type substitutions for type parameters - List classTypeParameters = ownerClassDescriptor.getDefaultType().getArguments(); + List classTypeParameters = receiverType.getArguments(); List ownerTypeArguments = ownerType.getArguments(); assert ownerTypeArguments.size() == classTypeParameters.size(); TypeSubstitution[] substitutions = new TypeSubstitution[classTypeParameters.size()]; @@ -460,9 +475,9 @@ public class CreateMethodFromUsageFix extends CreateFromUsageFixBase { JetNamedFunction func; PsiElement owner; final JetFile containingFile; - boolean isExtension = !klass.isWritable(); + final boolean isExtension = !klass.isWritable(); if (isExtension) { // create as extension function - ownerTypeString = renderType(ownerClassDescriptor.getDefaultType()); + ownerTypeString = renderTypeShort(receiverType); methodText = String.format("fun %s.%s(%s)%s { }", ownerTypeString, methodName, parametersString, returnTypeString); func = JetPsiFactory.createFunction(project, methodText); owner = containingFile = jetFile; @@ -494,8 +509,8 @@ public class CreateMethodFromUsageFix extends CreateFromUsageFixBase { caretModel.moveToOffset(file.getNode().getStartOffset()); TemplateBuilderImpl builder = new TemplateBuilderImpl(file); - TypeExpression returnTypeExpression = isUnit ? null : setupReturnTypeTemplate(builder, func, returnType); - TypeExpression[] parameterTypeExpressions = setupParameterTypeTemplates(project, builder, parameters, parameterList); + final TypeExpression returnTypeExpression = isUnit ? null : setupReturnTypeTemplate(builder, func, returnType); + final TypeExpression[] parameterTypeExpressions = setupParameterTypeTemplates(project, builder, parameters, parameterList); // add a segment for the parameter list // Note: because TemplateBuilderImpl does not have a replaceElement overload that takes in both a TextRange and alwaysStopAt, we @@ -503,8 +518,8 @@ public class CreateMethodFromUsageFix extends CreateFromUsageFixBase { // parameter list as the user makes selections in the parameter types, and we need alwaysStopAt to be false so the user can't tab to // it. JetScope scope = getScope(owner, context); - TypeParameterListExpression expression = setupTypeParameterListTemplate(builder, func, ownerClassDescriptor.getDefaultType(), - parameterTypeExpressions, returnTypeExpression, scope); + TypeParameterListExpression expression = setupTypeParameterListTemplate(builder, func, receiverType, parameterTypeExpressions, + returnTypeExpression, scope); // the template built by TemplateBuilderImpl is ordered by element position, but we want types to be first, so hack it final TemplateImpl template = (TemplateImpl) builder.buildInlineTemplate(); @@ -520,21 +535,89 @@ public class CreateMethodFromUsageFix extends CreateFromUsageFixBase { TemplateManager.getInstance(project).startTemplate(editor, template, new TemplateEditingAdapter() { @Override public void templateFinished(Template _, boolean brokenOff) { + // file templates int offset = template.getSegmentOffset(0); final JetNamedFunction func = PsiTreeUtil.findElementOfClassAtOffset(containingFile, offset, JetNamedFunction.class, false); assert func != null; + final List typeRefsToShorten = new ArrayList(); + ApplicationManager.getApplication().runWriteAction(new Runnable() { @Override public void run() { + // file templates setupFunctionBody(project, func, methodName, isUnit, ownerTypeDescriptor); + + // change short type names to fully qualified ones (to be shortened below) + setupTypeReferencesForShortening(project, func, isExtension, isUnit, typeRefsToShorten, receiverType, + parameterTypeExpressions, returnTypeExpression); } }); + ReferenceToClassesShortening.compactReferenceToClasses(typeRefsToShorten); + caretModel.moveToOffset(oldOffset); } }); } + private static void setupTypeReferencesForShortening( + @NotNull Project project, + @NotNull JetNamedFunction func, + boolean isExtension, + boolean isUnit, + @NotNull List typeRefsToShorten, + @NotNull JetType receiverType, + @NotNull TypeExpression[] parameterTypeExpressions, + @Nullable TypeExpression returnTypeExpression + ) { + if (isExtension) { + JetTypeReference receiverTypeRef = JetPsiFactory.createType(project, renderTypeLong(receiverType)); + replaceWithLongerName(project, receiverTypeRef, receiverType); + + receiverTypeRef = func.getReceiverTypeRef(); + assert receiverTypeRef != null; + typeRefsToShorten.add(receiverTypeRef); + } + + if (!isUnit) { + assert returnTypeExpression != null; + JetTypeReference returnTypeRef = func.getReturnTypeRef(); + assert returnTypeRef != null; + JetType returnType = returnTypeExpression.getTypeFromSelection(returnTypeRef.getText()); + if (returnType != null) { // user selected a given type + replaceWithLongerName(project, returnTypeRef, returnType); + returnTypeRef = func.getReturnTypeRef(); + assert returnTypeRef != null; + typeRefsToShorten.add(returnTypeRef); + } + } + + List valueParameters = func.getValueParameters(); + List parameterIndicesToShorten = new ArrayList(); + assert valueParameters.size() == parameterTypeExpressions.length; + for (int i = 0; i < valueParameters.size(); i++) { + JetParameter parameter = valueParameters.get(i); + JetTypeReference parameterTypeRef = parameter.getTypeReference(); + assert parameterTypeRef != null; + JetType parameterType = parameterTypeExpressions[i].getTypeFromSelection(parameterTypeRef.getText()); + if (parameterType != null) { + replaceWithLongerName(project, parameterTypeRef, parameterType); + parameterIndicesToShorten.add(i); + } + } + valueParameters = func.getValueParameters(); + for (int i : parameterIndicesToShorten) { + JetTypeReference parameterTypeRef = valueParameters.get(i).getTypeReference(); + assert parameterTypeRef != null; + typeRefsToShorten.add(parameterTypeRef); + } + } + + private static void replaceWithLongerName(@NotNull Project project, @NotNull JetTypeReference typeRef, @NotNull JetType type) { + JetTypeReference fullyQualifiedReceiverTypeRef = JetPsiFactory.createType(project, renderTypeLong(type)); + typeRef.replace(fullyQualifiedReceiverTypeRef); + } + @NotNull private static JetType substituteType(@NotNull JetType type, @NotNull TypeSubstitution substitution) { if (type.equals(substitution.getForType())) { @@ -729,18 +812,13 @@ public class CreateMethodFromUsageFix extends CreateFromUsageFixBase { } @NotNull - private static String renderType(JetType type) { - return DescriptorRenderer.TEXT.renderType(type); - // TODO: take into account imports and stuff; how to refer to a type with the simplest name with imports (currently uses fully qualified name)? + private static String renderTypeShort(JetType type) { + return DescriptorRenderer.SHORT_NAMES_IN_TYPES.renderType(type); } @NotNull - private static String[] renderTypes(JetType[] types) { - String[] typeStrings = new String[types.length]; - for (int i = 0; i < types.length; i++) { - typeStrings[i] = renderType(types[i]); - } - return typeStrings; + private static String renderTypeLong(JetType type) { + return DescriptorRenderer.TEXT.renderType(type); } @NotNull From 879a60e40b3a43fd7365de90541b32954ac45c36 Mon Sep 17 00:00:00 2001 From: Jack Zhou Date: Wed, 10 Apr 2013 21:09:40 -0400 Subject: [PATCH 014/291] Create from usage: Refactoring. --- .../quickfix/CreateMethodFromUsageFix.java | 226 +++++++++--------- 1 file changed, 113 insertions(+), 113 deletions(-) diff --git a/idea/src/org/jetbrains/jet/plugin/quickfix/CreateMethodFromUsageFix.java b/idea/src/org/jetbrains/jet/plugin/quickfix/CreateMethodFromUsageFix.java index b19706cfb47..9aa6f78a7c5 100644 --- a/idea/src/org/jetbrains/jet/plugin/quickfix/CreateMethodFromUsageFix.java +++ b/idea/src/org/jetbrains/jet/plugin/quickfix/CreateMethodFromUsageFix.java @@ -45,12 +45,12 @@ import org.jetbrains.jet.lang.descriptors.impl.MutableClassDescriptor; 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.DescriptorUtils; import org.jetbrains.jet.lang.resolve.scopes.JetScope; import org.jetbrains.jet.lang.types.*; import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns; import org.jetbrains.jet.plugin.JetBundle; -import org.jetbrains.jet.plugin.codeInsight.DescriptorToDeclarationUtil; import org.jetbrains.jet.plugin.codeInsight.ReferenceToClassesShortening; import org.jetbrains.jet.plugin.project.AnalyzerFacadeWithCache; import org.jetbrains.jet.plugin.refactoring.JetNameSuggester; @@ -406,6 +406,15 @@ public class CreateMethodFromUsageFix extends CreateFromUsageFixBase { private final TypeOrExpressionThereof returnType; private final List parameters; + private boolean isUnit; + private boolean isExtension; + private JetFile currentFile; + private JetFile containingFile; + private BindingContext currentFileContext; + private JetClass ownerClass; + private ClassDescriptor ownerClassDescriptor; + private JetType receiverType; + public CreateMethodFromUsageFix(@NotNull PsiElement element, @NotNull TypeOrExpressionThereof ownerType, @NotNull String methodName, @NotNull TypeOrExpressionThereof returnType, @NotNull List parameters) { super(element); @@ -422,16 +431,14 @@ public class CreateMethodFromUsageFix extends CreateFromUsageFixBase { } @Override - public void invoke(@NotNull final Project project, Editor editor, PsiFile file) throws IncorrectOperationException { + public void invoke(@NotNull Project project, Editor editor, PsiFile file) throws IncorrectOperationException { // TODO: editing across files assert file instanceof JetFile; - JetFile jetFile = (JetFile) file; - BindingContext context = AnalyzerFacadeWithCache.analyzeFileWithCache(jetFile).getBindingContext(); + currentFile = (JetFile) file; - JetType[] possibleOwnerTypes = ownerType.getPossibleTypes(context); + JetType[] possibleOwnerTypes = ownerType.getPossibleTypes(currentFileContext); assert possibleOwnerTypes.length > 0; - JetType ownerType; if (possibleOwnerTypes.length == 1) { ownerType = possibleOwnerTypes[0]; @@ -440,12 +447,16 @@ public class CreateMethodFromUsageFix extends CreateFromUsageFixBase { ownerType = possibleOwnerTypes[0]; } - final ClassifierDescriptor ownerTypeDescriptor = ownerType.getConstructor().getDeclarationDescriptor(); + // gather relevant information + ClassifierDescriptor ownerTypeDescriptor = ownerType.getConstructor().getDeclarationDescriptor(); assert ownerTypeDescriptor != null && ownerTypeDescriptor instanceof ClassDescriptor; - ClassDescriptor ownerClassDescriptor = (ClassDescriptor) ownerTypeDescriptor; - final JetType receiverType = ownerClassDescriptor.getDefaultType(); - PsiElement typeDeclaration = DescriptorToDeclarationUtil.getDeclaration(jetFile, ownerTypeDescriptor, context); - JetClass klass = (JetClass) typeDeclaration; + ownerClassDescriptor = (ClassDescriptor) ownerTypeDescriptor; + receiverType = ownerClassDescriptor.getDefaultType(); + PsiElement typeDeclaration = BindingContextUtils.classDescriptorToDeclaration(currentFileContext, ownerClassDescriptor); + assert typeDeclaration != null; + ownerClass = (JetClass) typeDeclaration; + isExtension = !ownerClass.isWritable(); + isUnit = returnType.isType() && isUnit(returnType.getType()); // figure out type substitutions for type parameters List classTypeParameters = receiverType.getArguments(); @@ -460,66 +471,67 @@ public class CreateMethodFromUsageFix extends CreateFromUsageFixBase { parameter.getType().substitute(substitutions); } - // create method with placeholder types and parameter names + JetNamedFunction func = createFunctionSkeleton(project); + buildAndRunTemplate(project, editor, func); + } + + private JetNamedFunction createFunctionSkeleton(@NotNull Project project) { + JetNamedFunction func; String[] parameterStrings = new String[parameters.size()]; for (int i = 0; i < parameterStrings.length; i++) { parameterStrings[i] = "p" + i + ": Any"; } String parametersString = StringUtil.join(parameterStrings,", "); - - final boolean isUnit = returnType.isType() && isUnit(returnType.getType()); String returnTypeString = isUnit ? "" : ": Any"; - - String ownerTypeString; - String methodText; - JetNamedFunction func; - PsiElement owner; - final JetFile containingFile; - final boolean isExtension = !klass.isWritable(); if (isExtension) { // create as extension function - ownerTypeString = renderTypeShort(receiverType); - methodText = String.format("fun %s.%s(%s)%s { }", ownerTypeString, methodName, parametersString, returnTypeString); + String ownerTypeString = renderTypeShort(receiverType); + String methodText = String.format("fun %s.%s(%s)%s { }", ownerTypeString, methodName, parametersString, returnTypeString); func = JetPsiFactory.createFunction(project, methodText); - owner = containingFile = jetFile; - func = (JetNamedFunction) file.add(func); + containingFile = currentFile; + func = (JetNamedFunction) currentFile.add(func); } else { // create as method - methodText = String.format("fun %s(%s)%s { }", methodName, parametersString, returnTypeString); + String methodText = String.format("fun %s(%s)%s { }", methodName, parametersString, returnTypeString); func = JetPsiFactory.createFunction(project, methodText); - owner = klass; - PsiFile classContainingFile = klass.getContainingFile(); + PsiFile classContainingFile = ownerClass.getContainingFile(); assert classContainingFile instanceof JetFile; containingFile = (JetFile) classContainingFile; - JetClassBody classBody = klass.getBody(); + JetClassBody classBody = ownerClass.getBody(); assert classBody != null; PsiElement rBrace = classBody.getRBrace(); func = (JetNamedFunction) classBody.addBefore(func, rBrace); } - // TODO: add newlines + return func; + } + private void buildAndRunTemplate(@NotNull final Project project, @NotNull Editor editor, @NotNull JetNamedFunction func) { JetParameterList parameterList = func.getValueParameterList(); assert parameterList != null; + BindingContext containingFileContext = currentFile.equals(containingFile) + ? currentFileContext + : AnalyzerFacadeWithCache.analyzeFileWithCache(containingFile).getBindingContext(); + JetScope scope = getScope(isExtension ? containingFile : ownerClass, containingFileContext); + // build templates PsiDocumentManager.getInstance(project).commitAllDocuments(); PsiDocumentManager.getInstance(project).doPostponedOperationsAndUnblockDocument(editor.getDocument()); final CaretModel caretModel = editor.getCaretModel(); final int oldOffset = caretModel.getOffset(); - caretModel.moveToOffset(file.getNode().getStartOffset()); + caretModel.moveToOffset(currentFile.getNode().getStartOffset()); - TemplateBuilderImpl builder = new TemplateBuilderImpl(file); - final TypeExpression returnTypeExpression = isUnit ? null : setupReturnTypeTemplate(builder, func, returnType); - final TypeExpression[] parameterTypeExpressions = setupParameterTypeTemplates(project, builder, parameters, parameterList); + TemplateBuilderImpl builder = new TemplateBuilderImpl(currentFile); + final TypeExpression returnTypeExpression = isUnit ? null : setupReturnTypeTemplate(builder, func); + final TypeExpression[] parameterTypeExpressions = setupParameterTypeTemplates(project, builder, parameterList); // add a segment for the parameter list // Note: because TemplateBuilderImpl does not have a replaceElement overload that takes in both a TextRange and alwaysStopAt, we // need to create the segment first and then hack the Expression into the template later. We use this template to update the type // parameter list as the user makes selections in the parameter types, and we need alwaysStopAt to be false so the user can't tab to // it. - JetScope scope = getScope(owner, context); - TypeParameterListExpression expression = setupTypeParameterListTemplate(builder, func, receiverType, parameterTypeExpressions, - returnTypeExpression, scope); + TypeParameterListExpression expression = + setupTypeParameterListTemplate(builder, func, parameterTypeExpressions, returnTypeExpression, scope); // the template built by TemplateBuilderImpl is ordered by element position, but we want types to be first, so hack it final TemplateImpl template = (TemplateImpl) builder.buildInlineTemplate(); @@ -545,11 +557,10 @@ public class CreateMethodFromUsageFix extends CreateFromUsageFixBase { @Override public void run() { // file templates - setupFunctionBody(project, func, methodName, isUnit, ownerTypeDescriptor); + setupFunctionBody(project, func); // change short type names to fully qualified ones (to be shortened below) - setupTypeReferencesForShortening(project, func, isExtension, isUnit, typeRefsToShorten, receiverType, - parameterTypeExpressions, returnTypeExpression); + setupTypeReferencesForShortening(project, func, typeRefsToShorten, parameterTypeExpressions, returnTypeExpression); } }); @@ -560,13 +571,10 @@ public class CreateMethodFromUsageFix extends CreateFromUsageFixBase { }); } - private static void setupTypeReferencesForShortening( + private void setupTypeReferencesForShortening( @NotNull Project project, @NotNull JetNamedFunction func, - boolean isExtension, - boolean isUnit, @NotNull List typeRefsToShorten, - @NotNull JetType receiverType, @NotNull TypeExpression[] parameterTypeExpressions, @Nullable TypeExpression returnTypeExpression ) { @@ -613,46 +621,7 @@ public class CreateMethodFromUsageFix extends CreateFromUsageFixBase { } } - private static void replaceWithLongerName(@NotNull Project project, @NotNull JetTypeReference typeRef, @NotNull JetType type) { - JetTypeReference fullyQualifiedReceiverTypeRef = JetPsiFactory.createType(project, renderTypeLong(type)); - typeRef.replace(fullyQualifiedReceiverTypeRef); - } - - @NotNull - private static JetType substituteType(@NotNull JetType type, @NotNull TypeSubstitution substitution) { - if (type.equals(substitution.getForType())) { - return substitution.getByType(); - } - - List newArguments = new ArrayList(); - for (TypeProjection projection : type.getArguments()) { - JetType newArgument = substituteType(projection.getType(), substitution); - newArguments.add(new TypeProjection(Variance.INVARIANT, newArgument)); - } - return new JetTypeImpl(type.getAnnotations(), type.getConstructor(), - type.isNullable(), newArguments, type.getMemberScope()); - } - - @NotNull - private static JetType[] substituteTypes(@NotNull JetType[] types, @NotNull TypeSubstitution[] substitutions) { - JetType[] newTypes = new JetType[types.length]; - for (int i = 0; i < types.length; i++) { - JetType newType = types[i]; - for (TypeSubstitution substitution : substitutions) { - newType = substituteType(newType, substitution); - } - newTypes[i] = newType; - } - return newTypes; - } - - private static void setupFunctionBody( - @NotNull Project project, - @NotNull JetNamedFunction func, - @NotNull String funcName, - boolean isUnit, - @NotNull ClassifierDescriptor ownerTypeDescriptor - ) { + private void setupFunctionBody(@NotNull Project project, @NotNull JetNamedFunction func) { FileTemplate fileTemplate = FileTemplateManager.getInstance().getCodeTemplate(TEMPLATE_FROM_USAGE_METHOD_BODY); Properties properties = new Properties(); if (isUnit) { @@ -662,9 +631,9 @@ public class CreateMethodFromUsageFix extends CreateFromUsageFixBase { assert returnTypeRef != null; properties.setProperty(FileTemplate.ATTRIBUTE_RETURN_TYPE, returnTypeRef.getText()); } - properties.setProperty(FileTemplate.ATTRIBUTE_CLASS_NAME, DescriptorUtils.getFQName(ownerTypeDescriptor).getFqName()); - properties.setProperty(FileTemplate.ATTRIBUTE_SIMPLE_CLASS_NAME, ownerTypeDescriptor.getName().getName()); - properties.setProperty(FileTemplate.ATTRIBUTE_METHOD_NAME, funcName); + properties.setProperty(FileTemplate.ATTRIBUTE_CLASS_NAME, DescriptorUtils.getFQName(ownerClassDescriptor).getFqName()); + properties.setProperty(FileTemplate.ATTRIBUTE_SIMPLE_CLASS_NAME, ownerClassDescriptor.getName().getName()); + properties.setProperty(FileTemplate.ATTRIBUTE_METHOD_NAME, methodName); @NonNls String bodyText; try { @@ -681,8 +650,7 @@ public class CreateMethodFromUsageFix extends CreateFromUsageFixBase { } @NotNull - private static TypeExpression setupReturnTypeTemplate(@NotNull TemplateBuilder builder, @NotNull JetNamedFunction func, - @NotNull TypeOrExpressionThereof returnType) { + private TypeExpression setupReturnTypeTemplate(@NotNull TemplateBuilder builder, @NotNull JetNamedFunction func) { JetTypeReference returnTypeRef = func.getReturnTypeRef(); assert returnTypeRef != null; TypeExpression returnTypeExpression = new TypeExpression(returnType.getPossibleTypes()); @@ -691,17 +659,16 @@ public class CreateMethodFromUsageFix extends CreateFromUsageFixBase { } @NotNull - private static TypeParameterListExpression setupTypeParameterListTemplate( + private TypeParameterListExpression setupTypeParameterListTemplate( @NotNull TemplateBuilderImpl builder, @NotNull JetNamedFunction func, - @NotNull JetType ownerType, @NotNull TypeExpression[] parameterTypeExpressions, @Nullable TypeExpression returnTypeExpression, @NotNull JetScope scope ) { Map typeParameterMap = new HashMap(); - Set ownerTypeParameters = getTypeParametersInType(ownerType); - String[] ownerTypeParameterNames = getTypeParameterNamesNotInScope(ownerTypeParameters, scope); + Set receiverTypeParameters = getTypeParametersInType(receiverType); + String[] ownerTypeParameterNames = getTypeParameterNamesNotInScope(receiverTypeParameters, scope); for (TypeExpression parameterTypeExpression : parameterTypeExpressions) { JetType[] parameterTypeOptions = parameterTypeExpression.getOptions(); String[] parameterTypeOptionStrings = parameterTypeExpression.getOptionStrings(); @@ -728,22 +695,8 @@ public class CreateMethodFromUsageFix extends CreateFromUsageFixBase { return new TypeParameterListExpression(ownerTypeParameterNames, typeParameterMap); } - @NotNull - private static JetScope getScope(@NotNull PsiElement owner, @NotNull BindingContext context) { - DeclarationDescriptor ownerDescriptor = context.get(BindingContext.DECLARATION_TO_DESCRIPTOR, owner); - assert ownerDescriptor != null; - if (ownerDescriptor instanceof NamespaceDescriptor) { - NamespaceDescriptor namespaceDescriptor = (NamespaceDescriptor) ownerDescriptor; - return namespaceDescriptor.getMemberScope(); - } else { - assert ownerDescriptor instanceof MutableClassDescriptor; - MutableClassDescriptor classDescriptor = (MutableClassDescriptor) ownerDescriptor; - return classDescriptor.getScopeForMemberResolution(); - } - } - - private static TypeExpression[] setupParameterTypeTemplates(@NotNull Project project, @NotNull TemplateBuilder builder, - @NotNull List parameters, @NotNull JetParameterList parameterList) { + private TypeExpression[] setupParameterTypeTemplates(@NotNull Project project, @NotNull TemplateBuilder builder, + @NotNull JetParameterList parameterList) { List jetParameters = parameterList.getParameters(); assert jetParameters.size() == parameters.size(); TypeExpression[] parameterTypeExpressions = new TypeExpression[parameters.size()]; @@ -792,18 +745,18 @@ public class CreateMethodFromUsageFix extends CreateFromUsageFixBase { public boolean isAvailable(@NotNull Project project, Editor editor, PsiFile file) { assert file instanceof JetFile; JetFile jetFile = (JetFile) file; - BindingContext context = AnalyzerFacadeWithCache.analyzeFileWithCache(jetFile).getBindingContext(); + currentFileContext = AnalyzerFacadeWithCache.analyzeFileWithCache(jetFile).getBindingContext(); - JetType[] possibleOwnerTypes = ownerType.getPossibleTypes(context); + JetType[] possibleOwnerTypes = ownerType.getPossibleTypes(currentFileContext); if (possibleOwnerTypes.length == 0) return false; assertNoUnitTypes(possibleOwnerTypes); - JetType[] possibleReturnTypes = returnType.getPossibleTypes(context); + JetType[] possibleReturnTypes = returnType.getPossibleTypes(currentFileContext); if (!returnType.isType()) { // allow return type to be unit (but not when it's among several options) assertNoUnitTypes(possibleReturnTypes); } if (possibleReturnTypes.length == 0) return false; for (Parameter parameter : parameters) { - JetType[] possibleTypes = parameter.getType().getPossibleTypes(context); + JetType[] possibleTypes = parameter.getType().getPossibleTypes(currentFileContext); if (possibleTypes.length == 0) return false; assertNoUnitTypes(possibleTypes); } @@ -811,6 +764,53 @@ public class CreateMethodFromUsageFix extends CreateFromUsageFixBase { return true; } + private static void replaceWithLongerName(@NotNull Project project, @NotNull JetTypeReference typeRef, @NotNull JetType type) { + JetTypeReference fullyQualifiedReceiverTypeRef = JetPsiFactory.createType(project, renderTypeLong(type)); + typeRef.replace(fullyQualifiedReceiverTypeRef); + } + + @NotNull + private static JetType substituteType(@NotNull JetType type, @NotNull TypeSubstitution substitution) { + if (type.equals(substitution.getForType())) { + return substitution.getByType(); + } + + List newArguments = new ArrayList(); + for (TypeProjection projection : type.getArguments()) { + JetType newArgument = substituteType(projection.getType(), substitution); + newArguments.add(new TypeProjection(Variance.INVARIANT, newArgument)); + } + return new JetTypeImpl(type.getAnnotations(), type.getConstructor(), + type.isNullable(), newArguments, type.getMemberScope()); + } + + @NotNull + private static JetType[] substituteTypes(@NotNull JetType[] types, @NotNull TypeSubstitution[] substitutions) { + JetType[] newTypes = new JetType[types.length]; + for (int i = 0; i < types.length; i++) { + JetType newType = types[i]; + for (TypeSubstitution substitution : substitutions) { + newType = substituteType(newType, substitution); + } + newTypes[i] = newType; + } + return newTypes; + } + + @NotNull + private static JetScope getScope(@NotNull PsiElement owner, @NotNull BindingContext context) { + DeclarationDescriptor ownerDescriptor = context.get(BindingContext.DECLARATION_TO_DESCRIPTOR, owner); + assert ownerDescriptor != null; + if (ownerDescriptor instanceof NamespaceDescriptor) { + NamespaceDescriptor namespaceDescriptor = (NamespaceDescriptor) ownerDescriptor; + return namespaceDescriptor.getMemberScope(); + } else { + assert ownerDescriptor instanceof MutableClassDescriptor; + MutableClassDescriptor classDescriptor = (MutableClassDescriptor) ownerDescriptor; + return classDescriptor.getScopeForMemberResolution(); + } + } + @NotNull private static String renderTypeShort(JetType type) { return DescriptorRenderer.SHORT_NAMES_IN_TYPES.renderType(type); From dfced1ef74f32d2296290a40ee84940f23ad5dea Mon Sep 17 00:00:00 2001 From: Jack Zhou Date: Thu, 11 Apr 2013 01:25:09 -0400 Subject: [PATCH 015/291] Create from usage: Added class selection. --- .../jetbrains/jet/plugin/JetBundle.properties | 1 + .../quickfix/CreateMethodFromUsageFix.java | 70 ++++++++++++++++--- 2 files changed, 63 insertions(+), 8 deletions(-) diff --git a/idea/src/org/jetbrains/jet/plugin/JetBundle.properties b/idea/src/org/jetbrains/jet/plugin/JetBundle.properties index 21d05ae90c7..84a70b3cbed 100644 --- a/idea/src/org/jetbrains/jet/plugin/JetBundle.properties +++ b/idea/src/org/jetbrains/jet/plugin/JetBundle.properties @@ -146,6 +146,7 @@ map.platform.class.to.kotlin.family=Change to Kotlin class create.from.usage.family=Create from usage create.method.from.usage=Create method ''{0}'' from usage create.class.object.from.usage=Create class object from usage +choose.target.class.or.trait.title=Choose target class or trait surround.with=Surround with surround.with.string.template="${expr}" surround.with.when.template=when (expr) {} diff --git a/idea/src/org/jetbrains/jet/plugin/quickfix/CreateMethodFromUsageFix.java b/idea/src/org/jetbrains/jet/plugin/quickfix/CreateMethodFromUsageFix.java index 9aa6f78a7c5..6c1b36d4276 100644 --- a/idea/src/org/jetbrains/jet/plugin/quickfix/CreateMethodFromUsageFix.java +++ b/idea/src/org/jetbrains/jet/plugin/quickfix/CreateMethodFromUsageFix.java @@ -24,17 +24,21 @@ import com.intellij.codeInsight.template.impl.TemplateImpl; import com.intellij.codeInsight.template.impl.Variable; import com.intellij.ide.fileTemplates.FileTemplate; import com.intellij.ide.fileTemplates.FileTemplateManager; +import com.intellij.ide.util.PsiElementListCellRenderer; import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.command.CommandProcessor; import com.intellij.openapi.editor.CaretModel; import com.intellij.openapi.editor.Editor; import com.intellij.openapi.progress.ProcessCanceledException; import com.intellij.openapi.project.Project; +import com.intellij.openapi.ui.popup.PopupChooserBuilder; import com.intellij.openapi.util.TextRange; import com.intellij.openapi.util.text.StringUtil; import com.intellij.psi.PsiDocumentManager; import com.intellij.psi.PsiElement; import com.intellij.psi.PsiFile; import com.intellij.psi.util.PsiTreeUtil; +import com.intellij.ui.components.JBList; import com.intellij.util.ArrayUtil; import com.intellij.util.IncorrectOperationException; import org.jetbrains.annotations.NonNls; @@ -52,11 +56,13 @@ import org.jetbrains.jet.lang.types.*; import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns; import org.jetbrains.jet.plugin.JetBundle; import org.jetbrains.jet.plugin.codeInsight.ReferenceToClassesShortening; +import org.jetbrains.jet.plugin.presentation.JetLightClassListCellRenderer; import org.jetbrains.jet.plugin.project.AnalyzerFacadeWithCache; import org.jetbrains.jet.plugin.refactoring.JetNameSuggester; import org.jetbrains.jet.plugin.refactoring.JetNameValidator; import org.jetbrains.jet.renderer.DescriptorRenderer; +import javax.swing.*; import java.util.*; public class CreateMethodFromUsageFix extends CreateFromUsageFixBase { @@ -431,7 +437,7 @@ public class CreateMethodFromUsageFix extends CreateFromUsageFixBase { } @Override - public void invoke(@NotNull Project project, Editor editor, PsiFile file) throws IncorrectOperationException { + public void invoke(@NotNull final Project project, final Editor editor, PsiFile file) throws IncorrectOperationException { // TODO: editing across files assert file instanceof JetFile; @@ -439,14 +445,57 @@ public class CreateMethodFromUsageFix extends CreateFromUsageFixBase { JetType[] possibleOwnerTypes = ownerType.getPossibleTypes(currentFileContext); assert possibleOwnerTypes.length > 0; - JetType ownerType; if (possibleOwnerTypes.length == 1) { - ownerType = possibleOwnerTypes[0]; + JetType ownerType = possibleOwnerTypes[0]; + doInvoke(project, editor, ownerType); } else { - // TODO: class selection - ownerType = possibleOwnerTypes[0]; - } + // class selection + List options = new ArrayList(); + final Map optionToTypeMap = new HashMap(); + for (JetType possibleOwnerType : possibleOwnerTypes) { + ClassifierDescriptor possibleClassDescriptor = possibleOwnerType.getConstructor().getDeclarationDescriptor(); + if (possibleClassDescriptor != null) { + String className = DescriptorRenderer.SHORT_NAMES_IN_TYPES.renderType(possibleClassDescriptor.getDefaultType()); + DeclarationDescriptor namespaceDescriptor = possibleClassDescriptor.getContainingDeclaration(); + assert namespaceDescriptor instanceof NamespaceDescriptor; + String namespace = ((NamespaceDescriptor) namespaceDescriptor).getFqName().getFqName(); + String option = className + " (" + namespace + ")"; + options.add(option); + optionToTypeMap.put(option, possibleOwnerType); + } + } + final JList list = new JBList(options); + PsiElementListCellRenderer renderer = new JetLightClassListCellRenderer(); + list.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); + list.setCellRenderer(renderer); + PopupChooserBuilder builder = new PopupChooserBuilder(list); + renderer.installSpeedSearch(builder); + + Runnable runnable = new Runnable() { + @Override + public void run() { + int index = list.getSelectedIndex(); + if (index < 0) return; + String option = (String) list.getSelectedValue(); + final JetType ownerType = optionToTypeMap.get(option); + CommandProcessor.getInstance().executeCommand(project, new Runnable() { + @Override + public void run() { + doInvoke(project, editor, ownerType); + } + }, getText(), null); + } + }; + + builder.setTitle(JetBundle.message("choose.target.class.or.trait.title")) + .setItemChoosenCallback(runnable) + .createPopup() + .showInBestPositionFor(editor); + } + } + + private void doInvoke(@NotNull final Project project, @NotNull final Editor editor, @NotNull JetType ownerType) { // gather relevant information ClassifierDescriptor ownerTypeDescriptor = ownerType.getConstructor().getDeclarationDescriptor(); assert ownerTypeDescriptor != null && ownerTypeDescriptor instanceof ClassDescriptor; @@ -471,8 +520,13 @@ public class CreateMethodFromUsageFix extends CreateFromUsageFixBase { parameter.getType().substitute(substitutions); } - JetNamedFunction func = createFunctionSkeleton(project); - buildAndRunTemplate(project, editor, func); + ApplicationManager.getApplication().runWriteAction(new Runnable() { + @Override + public void run() { + JetNamedFunction func = createFunctionSkeleton(project); + buildAndRunTemplate(project, editor, func); + } + }); } private JetNamedFunction createFunctionSkeleton(@NotNull Project project) { From c0bbb7b2ccd1302c53dadcb9de4a758d37dec1ff Mon Sep 17 00:00:00 2001 From: Jack Zhou Date: Thu, 11 Apr 2013 02:18:36 -0400 Subject: [PATCH 016/291] Create from usage: Fixed a bug where extension methods could not be added properly. --- .../quickfix/CreateMethodFromUsageFix.java | 33 +++++++++---------- 1 file changed, 15 insertions(+), 18 deletions(-) diff --git a/idea/src/org/jetbrains/jet/plugin/quickfix/CreateMethodFromUsageFix.java b/idea/src/org/jetbrains/jet/plugin/quickfix/CreateMethodFromUsageFix.java index 6c1b36d4276..84dbf01c659 100644 --- a/idea/src/org/jetbrains/jet/plugin/quickfix/CreateMethodFromUsageFix.java +++ b/idea/src/org/jetbrains/jet/plugin/quickfix/CreateMethodFromUsageFix.java @@ -502,9 +502,12 @@ public class CreateMethodFromUsageFix extends CreateFromUsageFixBase { ownerClassDescriptor = (ClassDescriptor) ownerTypeDescriptor; receiverType = ownerClassDescriptor.getDefaultType(); PsiElement typeDeclaration = BindingContextUtils.classDescriptorToDeclaration(currentFileContext, ownerClassDescriptor); - assert typeDeclaration != null; - ownerClass = (JetClass) typeDeclaration; - isExtension = !ownerClass.isWritable(); + if (typeDeclaration != null && typeDeclaration instanceof JetClass) { + ownerClass = (JetClass) typeDeclaration; + isExtension = !ownerClass.isWritable(); + } else { + isExtension = true; + } isUnit = returnType.isType() && isUnit(returnType.getType()); // figure out type substitutions for type parameters @@ -565,7 +568,15 @@ public class CreateMethodFromUsageFix extends CreateFromUsageFixBase { BindingContext containingFileContext = currentFile.equals(containingFile) ? currentFileContext : AnalyzerFacadeWithCache.analyzeFileWithCache(containingFile).getBindingContext(); - JetScope scope = getScope(isExtension ? containingFile : ownerClass, containingFileContext); + JetScope scope; + if (isExtension) { + NamespaceDescriptor namespaceDescriptor = currentFileContext.get(BindingContext.FILE_TO_NAMESPACE, containingFile); + assert namespaceDescriptor != null; + scope = namespaceDescriptor.getMemberScope(); + } else { + assert ownerClassDescriptor instanceof MutableClassDescriptor; + scope = ((MutableClassDescriptor) ownerClassDescriptor).getScopeForMemberResolution(); + } // build templates PsiDocumentManager.getInstance(project).commitAllDocuments(); @@ -851,20 +862,6 @@ public class CreateMethodFromUsageFix extends CreateFromUsageFixBase { return newTypes; } - @NotNull - private static JetScope getScope(@NotNull PsiElement owner, @NotNull BindingContext context) { - DeclarationDescriptor ownerDescriptor = context.get(BindingContext.DECLARATION_TO_DESCRIPTOR, owner); - assert ownerDescriptor != null; - if (ownerDescriptor instanceof NamespaceDescriptor) { - NamespaceDescriptor namespaceDescriptor = (NamespaceDescriptor) ownerDescriptor; - return namespaceDescriptor.getMemberScope(); - } else { - assert ownerDescriptor instanceof MutableClassDescriptor; - MutableClassDescriptor classDescriptor = (MutableClassDescriptor) ownerDescriptor; - return classDescriptor.getScopeForMemberResolution(); - } - } - @NotNull private static String renderTypeShort(JetType type) { return DescriptorRenderer.SHORT_NAMES_IN_TYPES.renderType(type); From b07548184a1e9aee8c88a4a73fb5d23afc95974b Mon Sep 17 00:00:00 2001 From: Jack Zhou Date: Thu, 11 Apr 2013 10:00:40 -0400 Subject: [PATCH 017/291] Create from usage: Fixed duplication of type parameters. --- .../quickfix/CreateMethodFromUsageFix.java | 56 ++++++++++--------- 1 file changed, 31 insertions(+), 25 deletions(-) diff --git a/idea/src/org/jetbrains/jet/plugin/quickfix/CreateMethodFromUsageFix.java b/idea/src/org/jetbrains/jet/plugin/quickfix/CreateMethodFromUsageFix.java index 84dbf01c659..150c07639f8 100644 --- a/idea/src/org/jetbrains/jet/plugin/quickfix/CreateMethodFromUsageFix.java +++ b/idea/src/org/jetbrains/jet/plugin/quickfix/CreateMethodFromUsageFix.java @@ -320,12 +320,13 @@ public class CreateMethodFromUsageFix extends CreateFromUsageFixBase { * A sort-of dummy Expression for parameter lists, to allow us to update the parameter list as the user makes selections. */ private static class TypeParameterListExpression extends Expression { - private final String[] ownerTypeParameterNames; - private final Map typeParameterMap; + private final TypeParameterDescriptor[] typeParametersFromReceiverType; + private final Map typeParameterMap; - public TypeParameterListExpression(@NotNull String[] ownerTypeParameterNames, @NotNull Map typeParameterMap) { - this.ownerTypeParameterNames = ownerTypeParameterNames; - this.typeParameterMap = typeParameterMap; + public TypeParameterListExpression(@NotNull TypeParameterDescriptor[] typeParametersFromReceiverType, + @NotNull Map typeParametersMap) { + this.typeParametersFromReceiverType = typeParametersFromReceiverType; + this.typeParameterMap = typeParametersMap; } @NotNull @@ -343,24 +344,29 @@ public class CreateMethodFromUsageFix extends CreateFromUsageFixBase { assert func != null; List parameters = func.getValueParameters(); - List typeParameterNames = new ArrayList(); - Collections.addAll(typeParameterNames, ownerTypeParameterNames); + Set typeParameters = new LinkedHashSet(); + Collections.addAll(typeParameters, typeParametersFromReceiverType); for (JetParameter parameter : parameters) { JetTypeReference parameterTypeRef = parameter.getTypeReference(); assert parameterTypeRef != null; - String[] names = typeParameterMap.get(parameterTypeRef.getText()); - if (names != null) { - Collections.addAll(typeParameterNames, names); + TypeParameterDescriptor[] typeParametersFromParameter = typeParameterMap.get(parameterTypeRef.getText()); + if (typeParametersFromParameter != null) { + Collections.addAll(typeParameters, typeParametersFromParameter); } } JetTypeReference returnTypeRef = func.getReturnTypeRef(); if (returnTypeRef != null) { - String[] names = typeParameterMap.get(returnTypeRef.getText()); - if (names != null) { - Collections.addAll(typeParameterNames, names); + TypeParameterDescriptor[] typeParametersFromReturnType = typeParameterMap.get(returnTypeRef.getText()); + if (typeParametersFromReturnType != null) { + Collections.addAll(typeParameters, typeParametersFromReturnType); } } + List typeParameterNames = new ArrayList(); + for (TypeParameterDescriptor typeParameter : typeParameters) { + typeParameterNames.add(typeParameter.getName().getIdentifier()); + } + // make sure there are no name conflicts for (int i = 0; i < typeParameterNames.size(); i++) { String name = typeParameterNames.get(i); @@ -565,9 +571,6 @@ public class CreateMethodFromUsageFix extends CreateFromUsageFixBase { JetParameterList parameterList = func.getValueParameterList(); assert parameterList != null; - BindingContext containingFileContext = currentFile.equals(containingFile) - ? currentFileContext - : AnalyzerFacadeWithCache.analyzeFileWithCache(containingFile).getBindingContext(); JetScope scope; if (isExtension) { NamespaceDescriptor namespaceDescriptor = currentFileContext.get(BindingContext.FILE_TO_NAMESPACE, containingFile); @@ -731,9 +734,9 @@ public class CreateMethodFromUsageFix extends CreateFromUsageFixBase { @Nullable TypeExpression returnTypeExpression, @NotNull JetScope scope ) { - Map typeParameterMap = new HashMap(); + Map typeParameterMap = new HashMap(); Set receiverTypeParameters = getTypeParametersInType(receiverType); - String[] ownerTypeParameterNames = getTypeParameterNamesNotInScope(receiverTypeParameters, scope); + TypeParameterDescriptor[] receiverTypeParametersNotInScope = getTypeParameterNamesNotInScope(receiverTypeParameters, scope); for (TypeExpression parameterTypeExpression : parameterTypeExpressions) { JetType[] parameterTypeOptions = parameterTypeExpression.getOptions(); String[] parameterTypeOptionStrings = parameterTypeExpression.getOptionStrings(); @@ -757,7 +760,7 @@ public class CreateMethodFromUsageFix extends CreateFromUsageFixBase { } builder.replaceElement(func, TextRange.create(3, 3), TYPE_PARAMETER_LIST_VARIABLE_NAME, null, false); // ((3, 3) is after "fun") - return new TypeParameterListExpression(ownerTypeParameterNames, typeParameterMap); + return new TypeParameterListExpression(receiverTypeParametersNotInScope, typeParameterMap); } private TypeExpression[] setupParameterTypeTemplates(@NotNull Project project, @NotNull TemplateBuilder builder, @@ -863,25 +866,28 @@ public class CreateMethodFromUsageFix extends CreateFromUsageFixBase { } @NotNull - private static String renderTypeShort(JetType type) { + private static String renderTypeShort(@NotNull JetType type) { return DescriptorRenderer.SHORT_NAMES_IN_TYPES.renderType(type); } @NotNull - private static String renderTypeLong(JetType type) { + private static String renderTypeLong(@NotNull JetType type) { return DescriptorRenderer.TEXT.renderType(type); } @NotNull - private static String[] getTypeParameterNamesNotInScope(Collection typeParameters, JetScope scope) { - List typeParameterNames = new ArrayList(); + private static TypeParameterDescriptor[] getTypeParameterNamesNotInScope( + @NotNull Collection typeParameters, + @NotNull JetScope scope + ) { + List typeParameterNames = new ArrayList(); for (TypeParameterDescriptor typeParameter : typeParameters) { ClassifierDescriptor classifier = scope.getClassifier(typeParameter.getName()); if (classifier == null || !classifier.equals(typeParameter)) { - typeParameterNames.add(typeParameter.getName().getIdentifier()); + typeParameterNames.add(typeParameter); } } - return ArrayUtil.toStringArray(typeParameterNames); + return typeParameterNames.toArray(new TypeParameterDescriptor[typeParameterNames.size()]); } @NotNull From cfce75b788cea6836b7314ba00da415b88684d01 Mon Sep 17 00:00:00 2001 From: Jack Zhou Date: Thu, 11 Apr 2013 10:01:21 -0400 Subject: [PATCH 018/291] Create from usage: Fixed warnings. --- .../jet/plugin/quickfix/CreateMethodFromUsageFix.java | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/idea/src/org/jetbrains/jet/plugin/quickfix/CreateMethodFromUsageFix.java b/idea/src/org/jetbrains/jet/plugin/quickfix/CreateMethodFromUsageFix.java index 150c07639f8..dd445f42c71 100644 --- a/idea/src/org/jetbrains/jet/plugin/quickfix/CreateMethodFromUsageFix.java +++ b/idea/src/org/jetbrains/jet/plugin/quickfix/CreateMethodFromUsageFix.java @@ -97,11 +97,6 @@ public class CreateMethodFromUsageFix extends CreateFromUsageFixBase { return this.type; } - @Nullable - public JetExpression getExpressionOfType() { - return expressionOfType; - } - /** * Returns a collection containing the possible types represented by this instance. Infers the type from an expression if necessary. * @return A collection containing the possible types represented by this instance. @@ -933,7 +928,7 @@ public class CreateMethodFromUsageFix extends CreateFromUsageFixBase { return new JetType[] {context.get(BindingContext.TYPE, variableTypeRef)}; } else { // case 2: the expression is the RHS of a variable assignment without a specified type - // TODO + return new JetType[0]; // TODO } } From 7b994388d56a6a477b7bba82247efde7cbd8e7fd Mon Sep 17 00:00:00 2001 From: Jack Zhou Date: Thu, 11 Apr 2013 13:55:38 -0400 Subject: [PATCH 019/291] Create from usage: Implemented all create method from usage fixes. --- .../quickfix/CreateMethodFromUsageFix.java | 97 ++++++++++++++++--- 1 file changed, 86 insertions(+), 11 deletions(-) diff --git a/idea/src/org/jetbrains/jet/plugin/quickfix/CreateMethodFromUsageFix.java b/idea/src/org/jetbrains/jet/plugin/quickfix/CreateMethodFromUsageFix.java index dd445f42c71..a0553c28a54 100644 --- a/idea/src/org/jetbrains/jet/plugin/quickfix/CreateMethodFromUsageFix.java +++ b/idea/src/org/jetbrains/jet/plugin/quickfix/CreateMethodFromUsageFix.java @@ -47,10 +47,13 @@ import org.jetbrains.annotations.Nullable; import org.jetbrains.jet.lang.descriptors.*; import org.jetbrains.jet.lang.descriptors.impl.MutableClassDescriptor; 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.*; import org.jetbrains.jet.lang.resolve.BindingContext; import org.jetbrains.jet.lang.resolve.BindingContextUtils; import org.jetbrains.jet.lang.resolve.DescriptorUtils; +import org.jetbrains.jet.lang.resolve.name.Name; import org.jetbrains.jet.lang.resolve.scopes.JetScope; import org.jetbrains.jet.lang.types.*; import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns; @@ -64,10 +67,12 @@ import org.jetbrains.jet.renderer.DescriptorRenderer; import javax.swing.*; import java.util.*; +import java.util.regex.Pattern; public class CreateMethodFromUsageFix extends CreateFromUsageFixBase { private static final String TYPE_PARAMETER_LIST_VARIABLE_NAME = "typeParameterList"; private static final String TEMPLATE_FROM_USAGE_METHOD_BODY = "New Kotlin Method Body.kt"; + private static final Pattern COMPONENT_FUNCTION_PATTERN = Pattern.compile("^component(\\d+)$"); /** * Represents a concrete type or a set of types yet to be inferred from an expression. @@ -808,7 +813,7 @@ public class CreateMethodFromUsageFix extends CreateFromUsageFixBase { public boolean isAvailable(@NotNull Project project, Editor editor, PsiFile file) { assert file instanceof JetFile; JetFile jetFile = (JetFile) file; - currentFileContext = AnalyzerFacadeWithCache.analyzeFileWithCache(jetFile).getBindingContext(); + currentFileContext = AnalyzerFacadeWithCache.analyzeFileWithCache(jetFile).getBindingContext(); // TODO: can't be called from EDT? JetType[] possibleOwnerTypes = ownerType.getPossibleTypes(currentFileContext); if (possibleOwnerTypes.length == 0) return false; @@ -919,7 +924,7 @@ public class CreateMethodFromUsageFix extends CreateFromUsageFixBase { return new JetType[] {actualType}; } - // if we need to guess, there are four cases: + // if we need to guess, there are five cases: if (expr.getParent() instanceof JetVariableDeclaration) { JetVariableDeclaration variable = (JetVariableDeclaration) expr.getParent(); JetTypeReference variableTypeRef = variable.getTypeRef(); @@ -927,13 +932,29 @@ public class CreateMethodFromUsageFix extends CreateFromUsageFixBase { // case 1: the expression is the RHS of a variable assignment with a specified type return new JetType[] {context.get(BindingContext.TYPE, variableTypeRef)}; } else { - // case 2: the expression is the RHS of a variable assignment without a specified type - return new JetType[0]; // TODO + // TODO: case 2: the expression is the RHS of a variable assignment without a specified type + return new JetType[0]; } } - // TODO: other cases - return new JetType[0]; //TODO + // case 3: the expression has a type assertion attached to it + if (expr instanceof JetTypeConstraint) { // case 3a: expression itself is a type assertion + JetTypeConstraint constraint = (JetTypeConstraint) expr; + return new JetType[] {context.get(BindingContext.TYPE, constraint.getBoundTypeReference())}; + } else { + PsiElement parent = expr.getParent(); + if (parent != null && parent instanceof JetTypeConstraint) { // case 3b: expression is on the left side of a type assertion + JetTypeConstraint constraint = (JetTypeConstraint) parent; + return new JetType[] {context.get(BindingContext.TYPE, constraint.getBoundTypeReference())}; + } + } + + // TODO: case 4: usages of variable + + // TODO: case 5: nested in a trivial expression (e.g. parentheses or if-else) + + // TODO: expected type info + return new JetType[0]; } private static boolean isUnit(@NotNull JetType type) { @@ -942,7 +963,7 @@ public class CreateMethodFromUsageFix extends CreateFromUsageFixBase { private static void assertNoUnitTypes(@NotNull JetType[] types) { for (JetType type : types) { - assert !isUnit(type) : "no support for unit functions"; + assert !isUnit(type); } } @@ -1007,7 +1028,13 @@ public class CreateMethodFromUsageFix extends CreateFromUsageFixBase { @Nullable @Override public IntentionAction createAction(Diagnostic diagnostic) { - return null; // TODO + JetForExpression forExpr = QuickFixUtil.getParentElementOfType(diagnostic, JetForExpression.class); + if (forExpr == null) return null; + JetExpression iterableExpr = forExpr.getLoopRange(); + if (iterableExpr == null) return null; + TypeOrExpressionThereof iterableType = new TypeOrExpressionThereof(iterableExpr); + TypeOrExpressionThereof returnType = new TypeOrExpressionThereof(KotlinBuiltIns.getInstance().getBooleanType()); + return new CreateMethodFromUsageFix(forExpr, iterableType, "hasNext", returnType, new ArrayList()); } }; } @@ -1018,7 +1045,15 @@ public class CreateMethodFromUsageFix extends CreateFromUsageFixBase { @Nullable @Override public IntentionAction createAction(Diagnostic diagnostic) { - return null; // TODO + JetForExpression forExpr = QuickFixUtil.getParentElementOfType(diagnostic, JetForExpression.class); + if (forExpr == null) return null; + JetExpression iterableExpr = forExpr.getLoopRange(); + if (iterableExpr == null) return null; + JetExpression variableExpr = forExpr.getLoopParameter(); + if (variableExpr == null) return null; + TypeOrExpressionThereof iterableType = new TypeOrExpressionThereof(iterableExpr); + TypeOrExpressionThereof returnType = new TypeOrExpressionThereof(variableExpr); + return new CreateMethodFromUsageFix(forExpr, iterableType, "next", returnType, new ArrayList()); } }; } @@ -1029,7 +1064,29 @@ public class CreateMethodFromUsageFix extends CreateFromUsageFixBase { @Nullable @Override public IntentionAction createAction(Diagnostic diagnostic) { - return null; // TODO + PsiFile file = diagnostic.getPsiFile(); + if (!(file instanceof JetFile)) return null; + JetFile jetFile = (JetFile) file; + + JetForExpression forExpr = QuickFixUtil.getParentElementOfType(diagnostic, JetForExpression.class); + if (forExpr == null) return null; + JetExpression iterableExpr = forExpr.getLoopRange(); + if (iterableExpr == null) return null; + JetExpression variableExpr = forExpr.getLoopParameter(); + if (variableExpr == null) return null; + TypeOrExpressionThereof iterableType = new TypeOrExpressionThereof(iterableExpr); + JetType returnJetType = KotlinBuiltIns.getInstance().getIterator().getDefaultType(); + + BindingContext context = AnalyzerFacadeWithCache.analyzeFileWithCache(jetFile).getBindingContext(); + JetType[] returnJetTypeParameterTypes = guessTypeForExpression(variableExpr, context); + if (returnJetTypeParameterTypes.length != 1) return null; + + TypeProjection returnJetTypeParameterType = new TypeProjection(returnJetTypeParameterTypes[0]); + List returnJetTypeArguments = Collections.singletonList(returnJetTypeParameterType); + returnJetType = new JetTypeImpl(returnJetType.getAnnotations(), returnJetType.getConstructor(), returnJetType.isNullable(), + returnJetTypeArguments, returnJetType.getMemberScope()); + TypeOrExpressionThereof returnType = new TypeOrExpressionThereof(returnJetType); + return new CreateMethodFromUsageFix(forExpr, iterableType, "next", returnType, new ArrayList()); } }; } @@ -1040,7 +1097,25 @@ public class CreateMethodFromUsageFix extends CreateFromUsageFixBase { @Nullable @Override public IntentionAction createAction(Diagnostic diagnostic) { - return null; // TODO + JetMultiDeclaration multiDeclaration = QuickFixUtil.getParentElementOfType(diagnostic, JetMultiDeclaration.class); + if (multiDeclaration == null) return null; + List entries = multiDeclaration.getEntries(); + + assert diagnostic.getFactory() == Errors.COMPONENT_FUNCTION_MISSING; + @SuppressWarnings("unchecked") + DiagnosticWithParameters1 diagnosticWithParameters = + (DiagnosticWithParameters1) diagnostic; + Name name = diagnosticWithParameters.getA(); + String componentNumberString = COMPONENT_FUNCTION_PATTERN.matcher(name.getIdentifier()).group(1); + int componentNumber = Integer.decode(componentNumberString); + + JetMultiDeclarationEntry entry = entries.get(componentNumber); + TypeOrExpressionThereof returnType = new TypeOrExpressionThereof(entry); + JetExpression rhs = multiDeclaration.getInitializer(); + if (rhs == null) return null; + TypeOrExpressionThereof ownerType = new TypeOrExpressionThereof(rhs); + + return new CreateMethodFromUsageFix(multiDeclaration, ownerType, name.getIdentifier(), returnType, new ArrayList()); } }; } From 4ee5d95dc9d4e304d1a4d3a8920a4fcc67774680 Mon Sep 17 00:00:00 2001 From: Jack Zhou Date: Thu, 11 Apr 2013 14:39:56 -0400 Subject: [PATCH 020/291] Create from usage: Fixed finding the component number. --- .../quickfix/CreateMethodFromUsageFix.java | 76 ++++++++++++------- 1 file changed, 49 insertions(+), 27 deletions(-) diff --git a/idea/src/org/jetbrains/jet/plugin/quickfix/CreateMethodFromUsageFix.java b/idea/src/org/jetbrains/jet/plugin/quickfix/CreateMethodFromUsageFix.java index a0553c28a54..d0cff826b11 100644 --- a/idea/src/org/jetbrains/jet/plugin/quickfix/CreateMethodFromUsageFix.java +++ b/idea/src/org/jetbrains/jet/plugin/quickfix/CreateMethodFromUsageFix.java @@ -67,6 +67,7 @@ import org.jetbrains.jet.renderer.DescriptorRenderer; import javax.swing.*; import java.util.*; +import java.util.regex.Matcher; import java.util.regex.Pattern; public class CreateMethodFromUsageFix extends CreateFromUsageFixBase { @@ -920,40 +921,59 @@ public class CreateMethodFromUsageFix extends CreateFromUsageFixBase { @NotNull private static JetType[] guessTypeForExpression(@NotNull JetExpression expr, @NotNull BindingContext context) { JetType actualType = context.get(BindingContext.EXPRESSION_TYPE, expr); - if (actualType != null) { // if we know the actual type of the expression + + // if we know the actual type of the expression + if (actualType != null) { return new JetType[] {actualType}; } - // if we need to guess, there are five cases: - if (expr.getParent() instanceof JetVariableDeclaration) { - JetVariableDeclaration variable = (JetVariableDeclaration) expr.getParent(); - JetTypeReference variableTypeRef = variable.getTypeRef(); - if (variableTypeRef != null) { - // case 1: the expression is the RHS of a variable assignment with a specified type - return new JetType[] {context.get(BindingContext.TYPE, variableTypeRef)}; - } else { - // TODO: case 2: the expression is the RHS of a variable assignment without a specified type - return new JetType[0]; - } - } - - // case 3: the expression has a type assertion attached to it - if (expr instanceof JetTypeConstraint) { // case 3a: expression itself is a type assertion + // expression itself is a type assertion + else if (expr instanceof JetTypeConstraint) { // expression itself is a type assertion JetTypeConstraint constraint = (JetTypeConstraint) expr; return new JetType[] {context.get(BindingContext.TYPE, constraint.getBoundTypeReference())}; - } else { - PsiElement parent = expr.getParent(); - if (parent != null && parent instanceof JetTypeConstraint) { // case 3b: expression is on the left side of a type assertion - JetTypeConstraint constraint = (JetTypeConstraint) parent; - return new JetType[] {context.get(BindingContext.TYPE, constraint.getBoundTypeReference())}; - } } - // TODO: case 4: usages of variable + // expression is on the left side of a type assertion + else if (expr.getParent() instanceof JetTypeConstraint) { + JetTypeConstraint constraint = (JetTypeConstraint) expr.getParent(); + return new JetType[] {context.get(BindingContext.TYPE, constraint.getBoundTypeReference())}; + } + + // expression is on the lhs of a multi-declaration + else if (expr instanceof JetMultiDeclarationEntry) { + JetMultiDeclarationEntry entry = (JetMultiDeclarationEntry) expr; + JetTypeReference typeRef = entry.getTypeRef(); + if (typeRef != null) { // and has a specified type + return new JetType[] {context.get(BindingContext.TYPE, typeRef)}; + } + // otherwise fall through and guess + } + + // expression is a parameter (e.g. declared in a for-loop) + else if (expr instanceof JetParameter) { + JetParameter parameter = (JetParameter) expr; + JetTypeReference typeRef = parameter.getTypeReference(); + if (typeRef != null) { // and has a specified type + return new JetType[] {context.get(BindingContext.TYPE, typeRef)}; + } + // otherwise fall through and guess + } + + // the expression is the RHS of a variable assignment with a specified type + else if (expr.getParent() instanceof JetVariableDeclaration) { + JetVariableDeclaration variable = (JetVariableDeclaration) expr.getParent(); + JetTypeReference typetypeRefEf = variable.getTypeRef(); + if (typetypeRefEf != null) { // and has a specified type + return new JetType[] {context.get(BindingContext.TYPE, typetypeRefEf)}; + } + // otherwise fall through and guess + } + + // TODO: need to guess based on usages of expression or expected type info + + // TODO: usages of variable // TODO: case 5: nested in a trivial expression (e.g. parentheses or if-else) - - // TODO: expected type info return new JetType[0]; } @@ -1106,8 +1126,10 @@ public class CreateMethodFromUsageFix extends CreateFromUsageFixBase { DiagnosticWithParameters1 diagnosticWithParameters = (DiagnosticWithParameters1) diagnostic; Name name = diagnosticWithParameters.getA(); - String componentNumberString = COMPONENT_FUNCTION_PATTERN.matcher(name.getIdentifier()).group(1); - int componentNumber = Integer.decode(componentNumberString); + Matcher componentNumberMatcher = COMPONENT_FUNCTION_PATTERN.matcher(name.getIdentifier()); + if (!componentNumberMatcher.matches()) return null; + String componentNumberString = componentNumberMatcher.group(1); + int componentNumber = Integer.decode(componentNumberString) - 1; JetMultiDeclarationEntry entry = entries.get(componentNumber); TypeOrExpressionThereof returnType = new TypeOrExpressionThereof(entry); From 2284c7bd48dc3cf31a08cd04c1bd2b7452a5c8fe Mon Sep 17 00:00:00 2001 From: Jack Zhou Date: Thu, 11 Apr 2013 18:42:10 -0400 Subject: [PATCH 021/291] Create from usage: Fixed typo. --- .../jetbrains/jet/plugin/quickfix/CreateMethodFromUsageFix.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/idea/src/org/jetbrains/jet/plugin/quickfix/CreateMethodFromUsageFix.java b/idea/src/org/jetbrains/jet/plugin/quickfix/CreateMethodFromUsageFix.java index d0cff826b11..d25ea8993f2 100644 --- a/idea/src/org/jetbrains/jet/plugin/quickfix/CreateMethodFromUsageFix.java +++ b/idea/src/org/jetbrains/jet/plugin/quickfix/CreateMethodFromUsageFix.java @@ -1106,7 +1106,7 @@ public class CreateMethodFromUsageFix extends CreateFromUsageFixBase { returnJetType = new JetTypeImpl(returnJetType.getAnnotations(), returnJetType.getConstructor(), returnJetType.isNullable(), returnJetTypeArguments, returnJetType.getMemberScope()); TypeOrExpressionThereof returnType = new TypeOrExpressionThereof(returnJetType); - return new CreateMethodFromUsageFix(forExpr, iterableType, "next", returnType, new ArrayList()); + return new CreateMethodFromUsageFix(forExpr, iterableType, "iterator", returnType, new ArrayList()); } }; } From 4ffbd353d93bc66c328ebbcbbcbcbcc726182ec2 Mon Sep 17 00:00:00 2001 From: Jack Zhou Date: Fri, 12 Apr 2013 00:18:25 -0400 Subject: [PATCH 022/291] Create from usage: Fixed adding methods across files. --- .../quickfix/CreateMethodFromUsageFix.java | 48 +++++++++++-------- 1 file changed, 29 insertions(+), 19 deletions(-) diff --git a/idea/src/org/jetbrains/jet/plugin/quickfix/CreateMethodFromUsageFix.java b/idea/src/org/jetbrains/jet/plugin/quickfix/CreateMethodFromUsageFix.java index d25ea8993f2..76250dcaa12 100644 --- a/idea/src/org/jetbrains/jet/plugin/quickfix/CreateMethodFromUsageFix.java +++ b/idea/src/org/jetbrains/jet/plugin/quickfix/CreateMethodFromUsageFix.java @@ -29,11 +29,13 @@ import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.command.CommandProcessor; import com.intellij.openapi.editor.CaretModel; import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.fileEditor.FileEditorManager; import com.intellij.openapi.progress.ProcessCanceledException; import com.intellij.openapi.project.Project; import com.intellij.openapi.ui.popup.PopupChooserBuilder; import com.intellij.openapi.util.TextRange; import com.intellij.openapi.util.text.StringUtil; +import com.intellij.openapi.vfs.VirtualFile; import com.intellij.psi.PsiDocumentManager; import com.intellij.psi.PsiElement; import com.intellij.psi.PsiFile; @@ -423,6 +425,8 @@ public class CreateMethodFromUsageFix extends CreateFromUsageFixBase { private boolean isExtension; private JetFile currentFile; private JetFile containingFile; + private Editor currentFileEditor; + private Editor containingFileEditor; private BindingContext currentFileContext; private JetClass ownerClass; private ClassDescriptor ownerClassDescriptor; @@ -444,17 +448,16 @@ public class CreateMethodFromUsageFix extends CreateFromUsageFixBase { } @Override - public void invoke(@NotNull final Project project, final Editor editor, PsiFile file) throws IncorrectOperationException { - // TODO: editing across files - - assert file instanceof JetFile; + public void invoke(@NotNull final Project project, Editor editor, PsiFile file) throws IncorrectOperationException { + assert file != null && file instanceof JetFile; currentFile = (JetFile) file; + currentFileEditor = editor; JetType[] possibleOwnerTypes = ownerType.getPossibleTypes(currentFileContext); assert possibleOwnerTypes.length > 0; if (possibleOwnerTypes.length == 1) { JetType ownerType = possibleOwnerTypes[0]; - doInvoke(project, editor, ownerType); + doInvoke(project, ownerType); } else { // class selection List options = new ArrayList(); @@ -489,7 +492,7 @@ public class CreateMethodFromUsageFix extends CreateFromUsageFixBase { CommandProcessor.getInstance().executeCommand(project, new Runnable() { @Override public void run() { - doInvoke(project, editor, ownerType); + doInvoke(project, ownerType); } }, getText(), null); } @@ -498,11 +501,11 @@ public class CreateMethodFromUsageFix extends CreateFromUsageFixBase { builder.setTitle(JetBundle.message("choose.target.class.or.trait.title")) .setItemChoosenCallback(runnable) .createPopup() - .showInBestPositionFor(editor); + .showInBestPositionFor(currentFileEditor); } } - private void doInvoke(@NotNull final Project project, @NotNull final Editor editor, @NotNull JetType ownerType) { + private void doInvoke(@NotNull final Project project, @NotNull JetType ownerType) { // gather relevant information ClassifierDescriptor ownerTypeDescriptor = ownerType.getConstructor().getDeclarationDescriptor(); assert ownerTypeDescriptor != null && ownerTypeDescriptor instanceof ClassDescriptor; @@ -534,7 +537,7 @@ public class CreateMethodFromUsageFix extends CreateFromUsageFixBase { @Override public void run() { JetNamedFunction func = createFunctionSkeleton(project); - buildAndRunTemplate(project, editor, func); + buildAndRunTemplate(project, func); } }); } @@ -552,6 +555,7 @@ public class CreateMethodFromUsageFix extends CreateFromUsageFixBase { String methodText = String.format("fun %s.%s(%s)%s { }", ownerTypeString, methodName, parametersString, returnTypeString); func = JetPsiFactory.createFunction(project, methodText); containingFile = currentFile; + containingFileEditor = currentFileEditor; func = (JetNamedFunction) currentFile.add(func); } else { // create as method String methodText = String.format("fun %s(%s)%s { }", methodName, parametersString, returnTypeString); @@ -559,16 +563,25 @@ public class CreateMethodFromUsageFix extends CreateFromUsageFixBase { PsiFile classContainingFile = ownerClass.getContainingFile(); assert classContainingFile instanceof JetFile; containingFile = (JetFile) classContainingFile; + + VirtualFile virtualFile = containingFile.getVirtualFile(); + assert virtualFile != null; + FileEditorManager fileEditorManager = FileEditorManager.getInstance(project); + fileEditorManager.openFile(virtualFile, true); + containingFileEditor = fileEditorManager.getSelectedTextEditor(); + JetClassBody classBody = ownerClass.getBody(); assert classBody != null; PsiElement rBrace = classBody.getRBrace(); + assert rBrace != null; func = (JetNamedFunction) classBody.addBefore(func, rBrace); } + // TODO: add newlines return func; } - private void buildAndRunTemplate(@NotNull final Project project, @NotNull Editor editor, @NotNull JetNamedFunction func) { + private void buildAndRunTemplate(@NotNull final Project project, @NotNull JetNamedFunction func) { JetParameterList parameterList = func.getValueParameterList(); assert parameterList != null; @@ -584,13 +597,12 @@ public class CreateMethodFromUsageFix extends CreateFromUsageFixBase { // build templates PsiDocumentManager.getInstance(project).commitAllDocuments(); - PsiDocumentManager.getInstance(project).doPostponedOperationsAndUnblockDocument(editor.getDocument()); + PsiDocumentManager.getInstance(project).doPostponedOperationsAndUnblockDocument(containingFileEditor.getDocument()); - final CaretModel caretModel = editor.getCaretModel(); - final int oldOffset = caretModel.getOffset(); - caretModel.moveToOffset(currentFile.getNode().getStartOffset()); + CaretModel caretModel = containingFileEditor.getCaretModel(); + caretModel.moveToOffset(containingFile.getNode().getStartOffset()); - TemplateBuilderImpl builder = new TemplateBuilderImpl(currentFile); + TemplateBuilderImpl builder = new TemplateBuilderImpl(containingFile); final TypeExpression returnTypeExpression = isUnit ? null : setupReturnTypeTemplate(builder, func); final TypeExpression[] parameterTypeExpressions = setupParameterTypeTemplates(project, builder, parameterList); @@ -613,7 +625,7 @@ public class CreateMethodFromUsageFix extends CreateFromUsageFixBase { variables.add(new Variable(TYPE_PARAMETER_LIST_VARIABLE_NAME, expression, expression, false, true)); // run the template - TemplateManager.getInstance(project).startTemplate(editor, template, new TemplateEditingAdapter() { + TemplateManager.getInstance(project).startTemplate(containingFileEditor, template, new TemplateEditingAdapter() { @Override public void templateFinished(Template _, boolean brokenOff) { // file templates @@ -634,8 +646,6 @@ public class CreateMethodFromUsageFix extends CreateFromUsageFixBase { }); ReferenceToClassesShortening.compactReferenceToClasses(typeRefsToShorten); - - caretModel.moveToOffset(oldOffset); } }); } @@ -973,7 +983,7 @@ public class CreateMethodFromUsageFix extends CreateFromUsageFixBase { // TODO: usages of variable - // TODO: case 5: nested in a trivial expression (e.g. parentheses or if-else) + // TODO: nested in a trivial expression (e.g. parentheses or if-else) return new JetType[0]; } From d42edc82071a137fad2279be0791d294b6a7e4f4 Mon Sep 17 00:00:00 2001 From: Jack Zhou Date: Fri, 19 Apr 2013 01:08:38 -0400 Subject: [PATCH 023/291] Create from usage: Added EXPECTED_EXPRESSION_TYPE slice in BindingContext. --- .../src/org/jetbrains/jet/lang/resolve/BindingContext.java | 1 + .../jetbrains/jet/lang/types/expressions/DataFlowUtils.java | 4 ++++ 2 files changed, 5 insertions(+) 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..ef3aa97a688 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/BindingContext.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/BindingContext.java @@ -75,6 +75,7 @@ public interface BindingContext { WritableSlice> COMPILE_TIME_VALUE = Slices.createSimpleSlice(); WritableSlice TYPE = Slices.createSimpleSlice(); WritableSlice EXPRESSION_TYPE = new BasicWritableSlice(DO_NOTHING); + WritableSlice EXPECTED_EXPRESSION_TYPE = new BasicWritableSlice(DO_NOTHING); WritableSlice EXPRESSION_DATA_FLOW_INFO = new BasicWritableSlice(DO_NOTHING); WritableSlice DATAFLOW_INFO_AFTER_CONDITION = Slices.createSimpleSlice(); diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/DataFlowUtils.java b/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/DataFlowUtils.java index 8d074571135..30e27ea9f82 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/DataFlowUtils.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/DataFlowUtils.java @@ -137,6 +137,10 @@ public class DataFlowUtils { @Nullable public static JetType checkType(@Nullable JetType expressionType, @NotNull JetExpression expression, @NotNull ResolutionContext context) { + if (context.expectedType != TypeUtils.NO_EXPECTED_TYPE) { + context.trace.record(BindingContext.EXPECTED_EXPRESSION_TYPE, expression, context.expectedType); + } + if (expressionType == null || context.expectedType == null || context.expectedType == TypeUtils.NO_EXPECTED_TYPE || JetTypeChecker.INSTANCE.isSubtypeOf(expressionType, context.expectedType)) { return expressionType; From 48c825df060590078cd5cdf71eb6aa69d0a1ee05 Mon Sep 17 00:00:00 2001 From: Jack Zhou Date: Fri, 19 Apr 2013 01:08:57 -0400 Subject: [PATCH 024/291] Create from usage: Added guessing types for a declaration without an explicit type. --- .../quickfix/CreateMethodFromUsageFix.java | 62 ++++++++++++++----- 1 file changed, 46 insertions(+), 16 deletions(-) diff --git a/idea/src/org/jetbrains/jet/plugin/quickfix/CreateMethodFromUsageFix.java b/idea/src/org/jetbrains/jet/plugin/quickfix/CreateMethodFromUsageFix.java index 76250dcaa12..5b64a243216 100644 --- a/idea/src/org/jetbrains/jet/plugin/quickfix/CreateMethodFromUsageFix.java +++ b/idea/src/org/jetbrains/jet/plugin/quickfix/CreateMethodFromUsageFix.java @@ -39,7 +39,10 @@ import com.intellij.openapi.vfs.VirtualFile; import com.intellij.psi.PsiDocumentManager; import com.intellij.psi.PsiElement; import com.intellij.psi.PsiFile; +import com.intellij.psi.PsiReference; +import com.intellij.psi.search.SearchScope; import com.intellij.psi.util.PsiTreeUtil; +import com.intellij.refactoring.psi.SearchUtils; import com.intellij.ui.components.JBList; import com.intellij.util.ArrayUtil; import com.intellij.util.IncorrectOperationException; @@ -58,6 +61,7 @@ import org.jetbrains.jet.lang.resolve.DescriptorUtils; import org.jetbrains.jet.lang.resolve.name.Name; import org.jetbrains.jet.lang.resolve.scopes.JetScope; import org.jetbrains.jet.lang.types.*; +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.codeInsight.ReferenceToClassesShortening; @@ -65,6 +69,7 @@ import org.jetbrains.jet.plugin.presentation.JetLightClassListCellRenderer; import org.jetbrains.jet.plugin.project.AnalyzerFacadeWithCache; import org.jetbrains.jet.plugin.refactoring.JetNameSuggester; import org.jetbrains.jet.plugin.refactoring.JetNameValidator; +import org.jetbrains.jet.plugin.references.JetSimpleNameReference; import org.jetbrains.jet.renderer.DescriptorRenderer; import javax.swing.*; @@ -449,7 +454,7 @@ public class CreateMethodFromUsageFix extends CreateFromUsageFixBase { @Override public void invoke(@NotNull final Project project, Editor editor, PsiFile file) throws IncorrectOperationException { - assert file != null && file instanceof JetFile; + assert file != null && file instanceof JetFile; // TODO: change some assertions to notifications currentFile = (JetFile) file; currentFileEditor = editor; @@ -824,7 +829,7 @@ public class CreateMethodFromUsageFix extends CreateFromUsageFixBase { public boolean isAvailable(@NotNull Project project, Editor editor, PsiFile file) { assert file instanceof JetFile; JetFile jetFile = (JetFile) file; - currentFileContext = AnalyzerFacadeWithCache.analyzeFileWithCache(jetFile).getBindingContext(); // TODO: can't be called from EDT? + currentFileContext = AnalyzerFacadeWithCache.analyzeFileWithCache(jetFile).getBindingContext(); JetType[] possibleOwnerTypes = ownerType.getPossibleTypes(currentFileContext); if (possibleOwnerTypes.length == 0) return false; @@ -930,11 +935,17 @@ public class CreateMethodFromUsageFix extends CreateFromUsageFixBase { @NotNull private static JetType[] guessTypeForExpression(@NotNull JetExpression expr, @NotNull BindingContext context) { - JetType actualType = context.get(BindingContext.EXPRESSION_TYPE, expr); + JetType type = context.get(BindingContext.EXPRESSION_TYPE, expr); + JetNamedDeclaration declaration = null; // if we know the actual type of the expression - if (actualType != null) { - return new JetType[] {actualType}; + if (type != null) { + return new JetType[] {type}; + } + + // expression has an expected type + else if ((type = context.get(BindingContext.EXPECTED_EXPRESSION_TYPE, expr)) != null) { + return new JetType[] {type}; } // expression itself is a type assertion @@ -956,7 +967,7 @@ public class CreateMethodFromUsageFix extends CreateFromUsageFixBase { if (typeRef != null) { // and has a specified type return new JetType[] {context.get(BindingContext.TYPE, typeRef)}; } - // otherwise fall through and guess + declaration = entry; // otherwise fall through and guess } // expression is a parameter (e.g. declared in a for-loop) @@ -966,25 +977,44 @@ public class CreateMethodFromUsageFix extends CreateFromUsageFixBase { if (typeRef != null) { // and has a specified type return new JetType[] {context.get(BindingContext.TYPE, typeRef)}; } - // otherwise fall through and guess + declaration = parameter; // otherwise fall through and guess } // the expression is the RHS of a variable assignment with a specified type else if (expr.getParent() instanceof JetVariableDeclaration) { JetVariableDeclaration variable = (JetVariableDeclaration) expr.getParent(); - JetTypeReference typetypeRefEf = variable.getTypeRef(); - if (typetypeRefEf != null) { // and has a specified type - return new JetType[] {context.get(BindingContext.TYPE, typetypeRefEf)}; + JetTypeReference typeRef = variable.getTypeRef(); + if (typeRef != null) { // and has a specified type + return new JetType[] {context.get(BindingContext.TYPE, typeRef)}; } - // otherwise fall through and guess + declaration = variable; // otherwise fall through and guess, based on LHS } - // TODO: need to guess based on usages of expression or expected type info - - // TODO: usages of variable - // TODO: nested in a trivial expression (e.g. parentheses or if-else) - return new JetType[0]; + + // guess based on declaration + SearchScope scope = expr.getContainingFile().getUseScope(); + Set expectedTypes = new HashSet(); + if (declaration != null) { + for (PsiReference ref : SearchUtils.findAllReferences(declaration, scope)) { + if (ref instanceof JetSimpleNameReference) { + JetSimpleNameReference simpleNameRef = (JetSimpleNameReference) ref; + JetType expectedType = context.get(BindingContext.EXPECTED_EXPRESSION_TYPE, simpleNameRef.getExpression()); + if (expectedType != null) { + expectedTypes.add(expectedType); + } + } + } + } + if (expectedTypes.isEmpty()) { + return new JetType[0]; + } + type = TypeUtils.intersect(JetTypeChecker.INSTANCE, expectedTypes); + if (type != null) { + return new JetType[] {type}; + } else { // intersection doesn't exist; let user make an imperfect choice + return expectedTypes.toArray(new JetType[expectedTypes.size()]); + } } private static boolean isUnit(@NotNull JetType type) { From e2313978117a382f9e759fa0434eb7c6d3ff1ba0 Mon Sep 17 00:00:00 2001 From: Jack Zhou Date: Fri, 19 Apr 2013 11:29:45 -0400 Subject: [PATCH 025/291] Create from usage: Fixed expected type for if-expression. --- .../lang/types/expressions/ControlStructureTypingVisitor.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) 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..82eb7a4247d 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 @@ -65,7 +65,8 @@ public class ControlStructureTypingVisitor extends ExpressionTypingVisitor { @NotNull private DataFlowInfo checkCondition(@NotNull JetScope scope, @Nullable JetExpression condition, ExpressionTypingContext context) { if (condition != null) { - JetTypeInfo typeInfo = facade.getTypeInfo(condition, context.replaceScope(scope)); + JetTypeInfo typeInfo = facade.getTypeInfo(condition, context.replaceScope(scope) + .replaceExpectedType(KotlinBuiltIns.getInstance().getBooleanType())); JetType conditionType = typeInfo.getType(); if (conditionType != null && !isBoolean(conditionType)) { From f2dc5e39e786b932c31a5ec88a5d3444bd9aea28 Mon Sep 17 00:00:00 2001 From: Jack Zhou Date: Fri, 19 Apr 2013 12:04:51 -0400 Subject: [PATCH 026/291] Create from usage: Removed a TODO. --- .../jetbrains/jet/plugin/quickfix/CreateMethodFromUsageFix.java | 2 -- 1 file changed, 2 deletions(-) diff --git a/idea/src/org/jetbrains/jet/plugin/quickfix/CreateMethodFromUsageFix.java b/idea/src/org/jetbrains/jet/plugin/quickfix/CreateMethodFromUsageFix.java index 5b64a243216..23b6c2745d2 100644 --- a/idea/src/org/jetbrains/jet/plugin/quickfix/CreateMethodFromUsageFix.java +++ b/idea/src/org/jetbrains/jet/plugin/quickfix/CreateMethodFromUsageFix.java @@ -990,8 +990,6 @@ public class CreateMethodFromUsageFix extends CreateFromUsageFixBase { declaration = variable; // otherwise fall through and guess, based on LHS } - // TODO: nested in a trivial expression (e.g. parentheses or if-else) - // guess based on declaration SearchScope scope = expr.getContainingFile().getUseScope(); Set expectedTypes = new HashSet(); From 9a079ae6212a52e471ad910c60b2c2e6b6dd896b Mon Sep 17 00:00:00 2001 From: Jack Zhou Date: Fri, 19 Apr 2013 18:47:03 -0400 Subject: [PATCH 027/291] Create from usage: Removed supertypes from consideration for return types. --- .../quickfix/CreateMethodFromUsageFix.java | 51 ++++++++++++------- 1 file changed, 33 insertions(+), 18 deletions(-) diff --git a/idea/src/org/jetbrains/jet/plugin/quickfix/CreateMethodFromUsageFix.java b/idea/src/org/jetbrains/jet/plugin/quickfix/CreateMethodFromUsageFix.java index 23b6c2745d2..51075cd0a34 100644 --- a/idea/src/org/jetbrains/jet/plugin/quickfix/CreateMethodFromUsageFix.java +++ b/idea/src/org/jetbrains/jet/plugin/quickfix/CreateMethodFromUsageFix.java @@ -88,17 +88,26 @@ public class CreateMethodFromUsageFix extends CreateFromUsageFixBase { private static class TypeOrExpressionThereof { private final JetExpression expressionOfType; private JetType type; + private final boolean enumerateSupertypes; private JetType[] cachedTypeCandidates; private String[] cachedNameCandidatesFromExpression; public TypeOrExpressionThereof(@NotNull JetExpression expressionOfType) { - this.expressionOfType = expressionOfType; - this.type = null; + this(expressionOfType, true); } - public TypeOrExpressionThereof(@NotNull JetType type) { - this.expressionOfType = null; + public TypeOrExpressionThereof(@NotNull JetExpression expressionOfType, boolean enumerateSupertypes) { + this(expressionOfType, null, enumerateSupertypes); + } + + public TypeOrExpressionThereof(@NotNull JetType type, boolean enumerateSupertypes) { + this(null, type, enumerateSupertypes); + } + + private TypeOrExpressionThereof(@Nullable JetExpression expressionOfType, @Nullable JetType type, boolean enumerateSupertypes) { + this.expressionOfType = expressionOfType; this.type = type; + this.enumerateSupertypes = enumerateSupertypes; } public boolean isType() { @@ -115,7 +124,7 @@ public class CreateMethodFromUsageFix extends CreateFromUsageFixBase { * @return A collection containing the possible types represented by this instance. */ @NotNull - public JetType[] getPossibleTypes(@Nullable("used cached, don't recompute") BindingContext context) { + public JetType[] getPossibleTypes(@Nullable("use cached, don't recompute") BindingContext context) { if (context == null) { assert cachedTypeCandidates != null; return cachedTypeCandidates; @@ -125,9 +134,12 @@ public class CreateMethodFromUsageFix extends CreateFromUsageFixBase { types.add(type); types.addAll(TypeUtils.getAllSupertypes(type)); } else { + assert expressionOfType != null : "!isType() means type == null && expressionOfType != null"; for (JetType type : guessTypeForExpression(expressionOfType, context)) { types.add(type); - types.addAll(TypeUtils.getAllSupertypes(type)); + if (enumerateSupertypes) { + types.addAll(TypeUtils.getAllSupertypes(type)); + } } } return cachedTypeCandidates = types.toArray(new JetType[types.size()]); @@ -141,11 +153,13 @@ public class CreateMethodFromUsageFix extends CreateFromUsageFixBase { @NotNull public String[] getPossibleNamesFromExpression() { if (cachedNameCandidatesFromExpression != null) return cachedNameCandidatesFromExpression; - cachedNameCandidatesFromExpression = isType() - ? ArrayUtil.EMPTY_STRING_ARRAY - : JetNameSuggester.suggestNamesForExpression( - expressionOfType, - JetNameValidator.getEmptyValidator(expressionOfType.getProject())); + if (isType()) { + cachedNameCandidatesFromExpression = ArrayUtil.EMPTY_STRING_ARRAY; + } else { + assert expressionOfType != null : "!isType() means type == null && expressionOfType != null"; + JetNameValidator dummyValidator = JetNameValidator.getEmptyValidator(expressionOfType.getProject()); + cachedNameCandidatesFromExpression = JetNameSuggester.suggestNamesForExpression(expressionOfType, dummyValidator); + } return cachedNameCandidatesFromExpression; } @@ -582,7 +596,6 @@ public class CreateMethodFromUsageFix extends CreateFromUsageFixBase { func = (JetNamedFunction) classBody.addBefore(func, rBrace); } - // TODO: add newlines return func; } @@ -1034,6 +1047,7 @@ public class CreateMethodFromUsageFix extends CreateFromUsageFixBase { JetArrayAccessExpression accessExpr = QuickFixUtil.getParentElementOfType(diagnostic, JetArrayAccessExpression.class); if (accessExpr == null) return null; JetExpression arrayExpr = accessExpr.getArrayExpression(); + if (arrayExpr == null) return null; TypeOrExpressionThereof arrayType = new TypeOrExpressionThereof(arrayExpr); List parameters = new ArrayList(); @@ -1043,7 +1057,7 @@ public class CreateMethodFromUsageFix extends CreateFromUsageFixBase { parameters.add(new Parameter(null, indexType)); } - TypeOrExpressionThereof returnType = new TypeOrExpressionThereof(accessExpr); + TypeOrExpressionThereof returnType = new TypeOrExpressionThereof(accessExpr, false); return new CreateMethodFromUsageFix(accessExpr, arrayType, "get", returnType, parameters); } }; @@ -1058,6 +1072,7 @@ public class CreateMethodFromUsageFix extends CreateFromUsageFixBase { JetArrayAccessExpression accessExpr = QuickFixUtil.getParentElementOfType(diagnostic, JetArrayAccessExpression.class); if (accessExpr == null) return null; JetExpression arrayExpr = accessExpr.getArrayExpression(); + if (arrayExpr == null) return null; TypeOrExpressionThereof arrayType = new TypeOrExpressionThereof(arrayExpr); List parameters = new ArrayList(); @@ -1074,7 +1089,7 @@ public class CreateMethodFromUsageFix extends CreateFromUsageFixBase { TypeOrExpressionThereof valType = new TypeOrExpressionThereof(rhs); parameters.add(new Parameter("value", valType)); - TypeOrExpressionThereof returnType = new TypeOrExpressionThereof(KotlinBuiltIns.getInstance().getUnitType()); + TypeOrExpressionThereof returnType = new TypeOrExpressionThereof(KotlinBuiltIns.getInstance().getUnitType(), false); return new CreateMethodFromUsageFix(accessExpr, arrayType, "set", returnType, parameters); } }; @@ -1091,7 +1106,7 @@ public class CreateMethodFromUsageFix extends CreateFromUsageFixBase { JetExpression iterableExpr = forExpr.getLoopRange(); if (iterableExpr == null) return null; TypeOrExpressionThereof iterableType = new TypeOrExpressionThereof(iterableExpr); - TypeOrExpressionThereof returnType = new TypeOrExpressionThereof(KotlinBuiltIns.getInstance().getBooleanType()); + TypeOrExpressionThereof returnType = new TypeOrExpressionThereof(KotlinBuiltIns.getInstance().getBooleanType(), false); return new CreateMethodFromUsageFix(forExpr, iterableType, "hasNext", returnType, new ArrayList()); } }; @@ -1110,7 +1125,7 @@ public class CreateMethodFromUsageFix extends CreateFromUsageFixBase { JetExpression variableExpr = forExpr.getLoopParameter(); if (variableExpr == null) return null; TypeOrExpressionThereof iterableType = new TypeOrExpressionThereof(iterableExpr); - TypeOrExpressionThereof returnType = new TypeOrExpressionThereof(variableExpr); + TypeOrExpressionThereof returnType = new TypeOrExpressionThereof(variableExpr, false); return new CreateMethodFromUsageFix(forExpr, iterableType, "next", returnType, new ArrayList()); } }; @@ -1143,7 +1158,7 @@ public class CreateMethodFromUsageFix extends CreateFromUsageFixBase { List returnJetTypeArguments = Collections.singletonList(returnJetTypeParameterType); returnJetType = new JetTypeImpl(returnJetType.getAnnotations(), returnJetType.getConstructor(), returnJetType.isNullable(), returnJetTypeArguments, returnJetType.getMemberScope()); - TypeOrExpressionThereof returnType = new TypeOrExpressionThereof(returnJetType); + TypeOrExpressionThereof returnType = new TypeOrExpressionThereof(returnJetType, false); return new CreateMethodFromUsageFix(forExpr, iterableType, "iterator", returnType, new ArrayList()); } }; @@ -1170,7 +1185,7 @@ public class CreateMethodFromUsageFix extends CreateFromUsageFixBase { int componentNumber = Integer.decode(componentNumberString) - 1; JetMultiDeclarationEntry entry = entries.get(componentNumber); - TypeOrExpressionThereof returnType = new TypeOrExpressionThereof(entry); + TypeOrExpressionThereof returnType = new TypeOrExpressionThereof(entry, false); JetExpression rhs = multiDeclaration.getInitializer(); if (rhs == null) return null; TypeOrExpressionThereof ownerType = new TypeOrExpressionThereof(rhs); From 6de37f4c854a4c7d538d6347f9ef8fddeb120e55 Mon Sep 17 00:00:00 2001 From: Jack Zhou Date: Fri, 19 Apr 2013 18:58:59 -0400 Subject: [PATCH 028/291] Create from usage: Added Any as fallback to expressions that has no guessable types. --- .../jet/plugin/quickfix/CreateMethodFromUsageFix.java | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/idea/src/org/jetbrains/jet/plugin/quickfix/CreateMethodFromUsageFix.java b/idea/src/org/jetbrains/jet/plugin/quickfix/CreateMethodFromUsageFix.java index 51075cd0a34..e227391deed 100644 --- a/idea/src/org/jetbrains/jet/plugin/quickfix/CreateMethodFromUsageFix.java +++ b/idea/src/org/jetbrains/jet/plugin/quickfix/CreateMethodFromUsageFix.java @@ -142,6 +142,11 @@ public class CreateMethodFromUsageFix extends CreateFromUsageFixBase { } } } + + if (types.isEmpty()) { + types.add(KotlinBuiltIns.getInstance().getAnyType()); + } + return cachedTypeCandidates = types.toArray(new JetType[types.size()]); } From 4044aae489025df7baae914b0d0c98e5cc23fd5c Mon Sep 17 00:00:00 2001 From: Jack Zhou Date: Fri, 19 Apr 2013 21:29:11 -0400 Subject: [PATCH 029/291] Create from usage: Offering more choices for type substitutions. --- .../quickfix/CreateMethodFromUsageFix.java | 110 ++++++++++++------ 1 file changed, 74 insertions(+), 36 deletions(-) diff --git a/idea/src/org/jetbrains/jet/plugin/quickfix/CreateMethodFromUsageFix.java b/idea/src/org/jetbrains/jet/plugin/quickfix/CreateMethodFromUsageFix.java index e227391deed..1d353cb2f01 100644 --- a/idea/src/org/jetbrains/jet/plugin/quickfix/CreateMethodFromUsageFix.java +++ b/idea/src/org/jetbrains/jet/plugin/quickfix/CreateMethodFromUsageFix.java @@ -87,35 +87,36 @@ public class CreateMethodFromUsageFix extends CreateFromUsageFixBase { */ private static class TypeOrExpressionThereof { private final JetExpression expressionOfType; - private JetType type; - private final boolean enumerateSupertypes; + private final JetType type; + private final Variance variance; private JetType[] cachedTypeCandidates; private String[] cachedNameCandidatesFromExpression; public TypeOrExpressionThereof(@NotNull JetExpression expressionOfType) { - this(expressionOfType, true); + this(expressionOfType, Variance.IN_VARIANCE); } - public TypeOrExpressionThereof(@NotNull JetExpression expressionOfType, boolean enumerateSupertypes) { - this(expressionOfType, null, enumerateSupertypes); + public TypeOrExpressionThereof(@NotNull JetExpression expressionOfType, Variance variance) { + this(expressionOfType, null, variance); } - public TypeOrExpressionThereof(@NotNull JetType type, boolean enumerateSupertypes) { - this(null, type, enumerateSupertypes); + public TypeOrExpressionThereof(@NotNull JetType type, Variance variance) { + this(null, type, variance); } - private TypeOrExpressionThereof(@Nullable JetExpression expressionOfType, @Nullable JetType type, boolean enumerateSupertypes) { + private TypeOrExpressionThereof(@Nullable JetExpression expressionOfType, @Nullable JetType type, Variance variance) { this.expressionOfType = expressionOfType; this.type = type; - this.enumerateSupertypes = enumerateSupertypes; + this.variance = variance; } public boolean isType() { return this.type != null; } - @Nullable + @NotNull public JetType getType() { + assert this.type != null; return this.type; } @@ -131,13 +132,14 @@ public class CreateMethodFromUsageFix extends CreateFromUsageFixBase { } List types = new ArrayList(); if (isType()) { + assert type != null : "!isType() means type == null && expressionOfType != null"; types.add(type); types.addAll(TypeUtils.getAllSupertypes(type)); } else { assert expressionOfType != null : "!isType() means type == null && expressionOfType != null"; for (JetType type : guessTypeForExpression(expressionOfType, context)) { types.add(type); - if (enumerateSupertypes) { + if (variance == Variance.IN_VARIANCE) { types.addAll(TypeUtils.getAllSupertypes(type)); } } @@ -169,12 +171,7 @@ public class CreateMethodFromUsageFix extends CreateFromUsageFixBase { } public void substitute(TypeSubstitution[] substitutions) { - if (type != null) { - for (TypeSubstitution substitution : substitutions) { - type = substituteType(type, substitution); - } - } - cachedTypeCandidates = substituteTypes(cachedTypeCandidates, substitutions); + cachedTypeCandidates = substituteTypes(cachedTypeCandidates, substitutions, variance); } } @@ -477,7 +474,7 @@ public class CreateMethodFromUsageFix extends CreateFromUsageFixBase { currentFile = (JetFile) file; currentFileEditor = editor; - JetType[] possibleOwnerTypes = ownerType.getPossibleTypes(currentFileContext); + JetType[] possibleOwnerTypes = ownerType.getPossibleTypes(); assert possibleOwnerTypes.length > 0; if (possibleOwnerTypes.length == 1) { JetType ownerType = possibleOwnerTypes[0]; @@ -872,31 +869,72 @@ public class CreateMethodFromUsageFix extends CreateFromUsageFixBase { } @NotNull - private static JetType substituteType(@NotNull JetType type, @NotNull TypeSubstitution substitution) { - if (type.equals(substitution.getForType())) { - return substitution.getByType(); + private static JetType substituteType(@NotNull JetType type, @NotNull TypeSubstitution substitution, @NotNull Variance variance) { + switch (variance) { + case INVARIANT: + // for invariant, can replace only when they're equal + if (type.equals(substitution.getForType())) { + return substitution.getByType(); + } + break; + case IN_VARIANCE: + // for covariant (e.g. function parameter), can replace type with any of its supertypes + if (JetTypeChecker.INSTANCE.isSubtypeOf(type, substitution.getForType())) { + return substitution.getByType(); + } + break; + case OUT_VARIANCE: + // for contravariant (e.g. function return value), can replace type with any of its subtypes + if (JetTypeChecker.INSTANCE.isSubtypeOf(substitution.getForType(), type)) { + return substitution.getByType(); + } + break; } List newArguments = new ArrayList(); + List typeParameters = type.getConstructor().getParameters(); + int i = 0; for (TypeProjection projection : type.getArguments()) { - JetType newArgument = substituteType(projection.getType(), substitution); + TypeParameterDescriptor typeParameter = typeParameters.get(i); + JetType newArgument = substituteType(projection.getType(), substitution, typeParameter.getVariance()); newArguments.add(new TypeProjection(Variance.INVARIANT, newArgument)); + i++; } return new JetTypeImpl(type.getAnnotations(), type.getConstructor(), type.isNullable(), newArguments, type.getMemberScope()); } @NotNull - private static JetType[] substituteTypes(@NotNull JetType[] types, @NotNull TypeSubstitution[] substitutions) { - JetType[] newTypes = new JetType[types.length]; - for (int i = 0; i < types.length; i++) { - JetType newType = types[i]; - for (TypeSubstitution substitution : substitutions) { - newType = substituteType(newType, substitution); + private static JetType[] substituteTypes(@NotNull JetType[] types, @NotNull TypeSubstitution[] substitutions, @NotNull Variance variance) { + Set newTypes = new LinkedHashSet(Arrays.asList(types)); + for (TypeSubstitution substitution : substitutions) { // each substitution can be applied or not, so we offer all options + List toAdd = new ArrayList(); + List toRemove = new ArrayList(); + for (JetType type : newTypes) { + toAdd.add(substituteType(type, substitution, variance)); + // substitution.byType are type arguments, but they cannot already occur before substitution + if (containsType(type, substitution.getByType())) { + toRemove.add(type); + } } - newTypes[i] = newType; + newTypes.addAll(toAdd); + newTypes.removeAll(toRemove); } - return newTypes; + return newTypes.toArray(new JetType[newTypes.size()]); + } + + private static boolean containsType(JetType outer, JetType inner) { + if (outer.equals(inner)) { + return true; + } + + for (TypeProjection projection : outer.getArguments()) { + if (containsType(projection.getType(), inner)) { + return true; + } + } + + return false; } @NotNull @@ -1062,7 +1100,7 @@ public class CreateMethodFromUsageFix extends CreateFromUsageFixBase { parameters.add(new Parameter(null, indexType)); } - TypeOrExpressionThereof returnType = new TypeOrExpressionThereof(accessExpr, false); + TypeOrExpressionThereof returnType = new TypeOrExpressionThereof(accessExpr, Variance.OUT_VARIANCE); return new CreateMethodFromUsageFix(accessExpr, arrayType, "get", returnType, parameters); } }; @@ -1094,7 +1132,7 @@ public class CreateMethodFromUsageFix extends CreateFromUsageFixBase { TypeOrExpressionThereof valType = new TypeOrExpressionThereof(rhs); parameters.add(new Parameter("value", valType)); - TypeOrExpressionThereof returnType = new TypeOrExpressionThereof(KotlinBuiltIns.getInstance().getUnitType(), false); + TypeOrExpressionThereof returnType = new TypeOrExpressionThereof(KotlinBuiltIns.getInstance().getUnitType(), Variance.OUT_VARIANCE); return new CreateMethodFromUsageFix(accessExpr, arrayType, "set", returnType, parameters); } }; @@ -1111,7 +1149,7 @@ public class CreateMethodFromUsageFix extends CreateFromUsageFixBase { JetExpression iterableExpr = forExpr.getLoopRange(); if (iterableExpr == null) return null; TypeOrExpressionThereof iterableType = new TypeOrExpressionThereof(iterableExpr); - TypeOrExpressionThereof returnType = new TypeOrExpressionThereof(KotlinBuiltIns.getInstance().getBooleanType(), false); + TypeOrExpressionThereof returnType = new TypeOrExpressionThereof(KotlinBuiltIns.getInstance().getBooleanType(), Variance.OUT_VARIANCE); return new CreateMethodFromUsageFix(forExpr, iterableType, "hasNext", returnType, new ArrayList()); } }; @@ -1130,7 +1168,7 @@ public class CreateMethodFromUsageFix extends CreateFromUsageFixBase { JetExpression variableExpr = forExpr.getLoopParameter(); if (variableExpr == null) return null; TypeOrExpressionThereof iterableType = new TypeOrExpressionThereof(iterableExpr); - TypeOrExpressionThereof returnType = new TypeOrExpressionThereof(variableExpr, false); + TypeOrExpressionThereof returnType = new TypeOrExpressionThereof(variableExpr, Variance.OUT_VARIANCE); return new CreateMethodFromUsageFix(forExpr, iterableType, "next", returnType, new ArrayList()); } }; @@ -1163,7 +1201,7 @@ public class CreateMethodFromUsageFix extends CreateFromUsageFixBase { List returnJetTypeArguments = Collections.singletonList(returnJetTypeParameterType); returnJetType = new JetTypeImpl(returnJetType.getAnnotations(), returnJetType.getConstructor(), returnJetType.isNullable(), returnJetTypeArguments, returnJetType.getMemberScope()); - TypeOrExpressionThereof returnType = new TypeOrExpressionThereof(returnJetType, false); + TypeOrExpressionThereof returnType = new TypeOrExpressionThereof(returnJetType, Variance.OUT_VARIANCE); return new CreateMethodFromUsageFix(forExpr, iterableType, "iterator", returnType, new ArrayList()); } }; @@ -1190,7 +1228,7 @@ public class CreateMethodFromUsageFix extends CreateFromUsageFixBase { int componentNumber = Integer.decode(componentNumberString) - 1; JetMultiDeclarationEntry entry = entries.get(componentNumber); - TypeOrExpressionThereof returnType = new TypeOrExpressionThereof(entry, false); + TypeOrExpressionThereof returnType = new TypeOrExpressionThereof(entry, Variance.OUT_VARIANCE); JetExpression rhs = multiDeclaration.getInitializer(); if (rhs == null) return null; TypeOrExpressionThereof ownerType = new TypeOrExpressionThereof(rhs); From fc6c2be73bab9f9534664effd73c887273e83498 Mon Sep 17 00:00:00 2001 From: Jack Zhou Date: Fri, 19 Apr 2013 21:41:37 -0400 Subject: [PATCH 030/291] Create from usage: Refactoring. --- .../quickfix/CreateMethodFromUsageFix.java | 35 ++++++++----------- 1 file changed, 15 insertions(+), 20 deletions(-) diff --git a/idea/src/org/jetbrains/jet/plugin/quickfix/CreateMethodFromUsageFix.java b/idea/src/org/jetbrains/jet/plugin/quickfix/CreateMethodFromUsageFix.java index 1d353cb2f01..101da587ac4 100644 --- a/idea/src/org/jetbrains/jet/plugin/quickfix/CreateMethodFromUsageFix.java +++ b/idea/src/org/jetbrains/jet/plugin/quickfix/CreateMethodFromUsageFix.java @@ -171,7 +171,21 @@ public class CreateMethodFromUsageFix extends CreateFromUsageFixBase { } public void substitute(TypeSubstitution[] substitutions) { - cachedTypeCandidates = substituteTypes(cachedTypeCandidates, substitutions, variance); + Set newTypes = new LinkedHashSet(Arrays.asList(cachedTypeCandidates)); + for (TypeSubstitution substitution : substitutions) { // each substitution can be applied or not, so we offer all options + List toAdd = new ArrayList(); + List toRemove = new ArrayList(); + for (JetType type : newTypes) { + toAdd.add(substituteType(type, substitution, variance)); + // substitution.byType are type arguments, but they cannot already occur in the type before substitution + if (containsType(type, substitution.getByType())) { + toRemove.add(type); + } + } + newTypes.addAll(toAdd); + newTypes.removeAll(toRemove); + } + cachedTypeCandidates = newTypes.toArray(new JetType[newTypes.size()]); } } @@ -904,25 +918,6 @@ public class CreateMethodFromUsageFix extends CreateFromUsageFixBase { type.isNullable(), newArguments, type.getMemberScope()); } - @NotNull - private static JetType[] substituteTypes(@NotNull JetType[] types, @NotNull TypeSubstitution[] substitutions, @NotNull Variance variance) { - Set newTypes = new LinkedHashSet(Arrays.asList(types)); - for (TypeSubstitution substitution : substitutions) { // each substitution can be applied or not, so we offer all options - List toAdd = new ArrayList(); - List toRemove = new ArrayList(); - for (JetType type : newTypes) { - toAdd.add(substituteType(type, substitution, variance)); - // substitution.byType are type arguments, but they cannot already occur before substitution - if (containsType(type, substitution.getByType())) { - toRemove.add(type); - } - } - newTypes.addAll(toAdd); - newTypes.removeAll(toRemove); - } - return newTypes.toArray(new JetType[newTypes.size()]); - } - private static boolean containsType(JetType outer, JetType inner) { if (outer.equals(inner)) { return true; From a80ea6904aa853de1569b484fac84cce52cf1153 Mon Sep 17 00:00:00 2001 From: Jack Zhou Date: Sat, 20 Apr 2013 19:06:14 -0400 Subject: [PATCH 031/291] Create from usage: Added type parameter renaming. --- .../quickfix/CreateMethodFromUsageFix.java | 472 +++++++++++------- 1 file changed, 290 insertions(+), 182 deletions(-) diff --git a/idea/src/org/jetbrains/jet/plugin/quickfix/CreateMethodFromUsageFix.java b/idea/src/org/jetbrains/jet/plugin/quickfix/CreateMethodFromUsageFix.java index 101da587ac4..afbf3c4835c 100644 --- a/idea/src/org/jetbrains/jet/plugin/quickfix/CreateMethodFromUsageFix.java +++ b/idea/src/org/jetbrains/jet/plugin/quickfix/CreateMethodFromUsageFix.java @@ -82,6 +82,59 @@ public class CreateMethodFromUsageFix extends CreateFromUsageFixBase { private static final String TEMPLATE_FROM_USAGE_METHOD_BODY = "New Kotlin Method Body.kt"; private static final Pattern COMPONENT_FUNCTION_PATTERN = Pattern.compile("^component(\\d+)$"); + /** + * Represents a single choice for a type (e.g. parameter type or return type). + */ + private static class TypeCandidate { + private final JetType type; + private final TypeParameterDescriptor[] typeParameters; + private String renderedType; + private String[] typeParameterNames; + + public TypeCandidate(@NotNull JetType type) { + this.type = type; + Set typeParametersInType = getTypeParametersInType(type); + typeParameters = typeParametersInType.toArray(new TypeParameterDescriptor[typeParametersInType.size()]); + render(Collections.emptyMap()); + } + + public TypeCandidate(@NotNull JetType type, @NotNull JetScope scope) { + this.type = type; + typeParameters = getTypeParameterNamesNotInScope(getTypeParametersInType(type), scope); + } + + public void render(@NotNull Map typeParameterNameMap) { + renderedType = renderTypeShort(type, typeParameterNameMap); + typeParameterNames = new String[typeParameters.length]; + int i = 0; + for (TypeParameterDescriptor typeParameter : typeParameters) { + typeParameterNames[i] = typeParameterNameMap.get(typeParameter); + i++; + } + } + + @NotNull JetType getType() { + return type; + } + + @NotNull + public String getRenderedType() { + assert renderedType != null : "call render() first"; + return renderedType; + } + + @NotNull + public String[] getTypeParameterNames() { + assert typeParameterNames != null : "call render() first"; + return typeParameterNames; + } + + @NotNull + public TypeParameterDescriptor[] getTypeParameters() { + return typeParameters; + } + } + /** * Represents a concrete type or a set of types yet to be inferred from an expression. */ @@ -89,7 +142,7 @@ public class CreateMethodFromUsageFix extends CreateFromUsageFixBase { private final JetExpression expressionOfType; private final JetType type; private final Variance variance; - private JetType[] cachedTypeCandidates; + private TypeCandidate[] typeCandidates; private String[] cachedNameCandidatesFromExpression; public TypeOrExpressionThereof(@NotNull JetExpression expressionOfType) { @@ -120,17 +173,9 @@ public class CreateMethodFromUsageFix extends CreateFromUsageFixBase { return this.type; } - /** - * Returns a collection containing the possible types represented by this instance. Infers the type from an expression if necessary. - * @return A collection containing the possible types represented by this instance. - */ @NotNull - public JetType[] getPossibleTypes(@Nullable("use cached, don't recompute") BindingContext context) { - if (context == null) { - assert cachedTypeCandidates != null; - return cachedTypeCandidates; - } - List types = new ArrayList(); + private Collection getPossibleTypes(BindingContext context) { + Collection types = new ArrayList(); if (isType()) { assert type != null : "!isType() means type == null && expressionOfType != null"; types.add(type); @@ -144,34 +189,28 @@ public class CreateMethodFromUsageFix extends CreateFromUsageFixBase { } } } + return types; + } - if (types.isEmpty()) { - types.add(KotlinBuiltIns.getInstance().getAnyType()); + public void computeTypeCandidates(@NotNull BindingContext context) { + Collection types = getPossibleTypes(context); + + typeCandidates = new TypeCandidate[types.size()]; + int i = 0; + for (JetType type : types) { + typeCandidates[i] = new TypeCandidate(type); + i++; } - - return cachedTypeCandidates = types.toArray(new JetType[types.size()]); } - @NotNull - public JetType[] getPossibleTypes() { - return getPossibleTypes(null); - } + public void computeTypeCandidates( + @NotNull BindingContext context, + @NotNull TypeSubstitution[] substitutions, + @NotNull JetScope scope + ) { + Collection types = getPossibleTypes(context); - @NotNull - public String[] getPossibleNamesFromExpression() { - if (cachedNameCandidatesFromExpression != null) return cachedNameCandidatesFromExpression; - if (isType()) { - cachedNameCandidatesFromExpression = ArrayUtil.EMPTY_STRING_ARRAY; - } else { - assert expressionOfType != null : "!isType() means type == null && expressionOfType != null"; - JetNameValidator dummyValidator = JetNameValidator.getEmptyValidator(expressionOfType.getProject()); - cachedNameCandidatesFromExpression = JetNameSuggester.suggestNamesForExpression(expressionOfType, dummyValidator); - } - return cachedNameCandidatesFromExpression; - } - - public void substitute(TypeSubstitution[] substitutions) { - Set newTypes = new LinkedHashSet(Arrays.asList(cachedTypeCandidates)); + Set newTypes = new LinkedHashSet(types); for (TypeSubstitution substitution : substitutions) { // each substitution can be applied or not, so we offer all options List toAdd = new ArrayList(); List toRemove = new ArrayList(); @@ -185,7 +224,44 @@ public class CreateMethodFromUsageFix extends CreateFromUsageFixBase { newTypes.addAll(toAdd); newTypes.removeAll(toRemove); } - cachedTypeCandidates = newTypes.toArray(new JetType[newTypes.size()]); + + if (newTypes.isEmpty()) { + newTypes.add(KotlinBuiltIns.getInstance().getAnyType()); + } + + types = newTypes; + + typeCandidates = new TypeCandidate[types.size()]; + int i = 0; + for (JetType type : types) { + typeCandidates[i] = new TypeCandidate(type, scope); + i++; + } + } + + @NotNull + public TypeCandidate[] getTypeCandidates() { + assert typeCandidates != null : "call computeTypeCandidates() first"; + return typeCandidates; + } + + public void renderTypeCandidates(@NotNull Map typeParameterNameMap) { + for (TypeCandidate candidate : typeCandidates) { + candidate.render(typeParameterNameMap); + } + } + + @NotNull + public String[] getPossibleNamesFromExpression() { + if (cachedNameCandidatesFromExpression != null) return cachedNameCandidatesFromExpression; + if (isType()) { + cachedNameCandidatesFromExpression = ArrayUtil.EMPTY_STRING_ARRAY; + } else { + assert expressionOfType != null : "!isType() means type == null && expressionOfType != null"; + JetNameValidator dummyValidator = JetNameValidator.getEmptyValidator(expressionOfType.getProject()); + cachedNameCandidatesFromExpression = JetNameSuggester.suggestNamesForExpression(expressionOfType, dummyValidator); + } + return cachedNameCandidatesFromExpression; } } @@ -298,17 +374,15 @@ public class CreateMethodFromUsageFix extends CreateFromUsageFixBase { * An Expression for type references. */ private static class TypeExpression extends Expression { - private final JetType[] options; - private final String[] optionStrings; - private final LookupElement[] cachedLookupElements; + private final TypeOrExpressionThereof type; + private @NotNull LookupElement[] cachedLookupElements; - public TypeExpression(@NotNull JetType[] options) { - this.options = options; - optionStrings = new String[options.length]; - cachedLookupElements = new LookupElement[options.length]; - for (int i = 0; i < options.length; i++) { - optionStrings[i] = renderTypeShort(options[i]); - cachedLookupElements[i] = LookupElementBuilder.create(options[i], optionStrings[i]); + public TypeExpression(@NotNull TypeOrExpressionThereof type) { + this.type = type; + TypeCandidate[] candidates = type.getTypeCandidates(); + cachedLookupElements = new LookupElement[candidates.length]; + for (int i = 0; i < candidates.length; i++) { + cachedLookupElements[i] = LookupElementBuilder.create(candidates[i], candidates[i].getRenderedType()); } } @@ -334,20 +408,16 @@ public class CreateMethodFromUsageFix extends CreateFromUsageFixBase { } @NotNull - public JetType[] getOptions() { - return options; - } - - @NotNull - public String[] getOptionStrings() { - return optionStrings; + public TypeOrExpressionThereof getType() { + return type; } @Nullable("can't be found") public JetType getTypeFromSelection(@NotNull String selection) { - for (int i = 0; i < options.length; i++) { - if (optionStrings[i].equals(selection)) { - return options[i]; + TypeCandidate[] options = type.getTypeCandidates(); + for (TypeCandidate option : options) { + if (option.getRenderedType().equals(selection)) { + return option.getType(); } } return null; @@ -358,13 +428,15 @@ public class CreateMethodFromUsageFix extends CreateFromUsageFixBase { * A sort-of dummy Expression for parameter lists, to allow us to update the parameter list as the user makes selections. */ private static class TypeParameterListExpression extends Expression { - private final TypeParameterDescriptor[] typeParametersFromReceiverType; - private final Map typeParameterMap; + private final String[] typeParameterNamesFromReceiverType; + private final Map parameterTypeToTypeParameterNamesMap; - public TypeParameterListExpression(@NotNull TypeParameterDescriptor[] typeParametersFromReceiverType, - @NotNull Map typeParametersMap) { - this.typeParametersFromReceiverType = typeParametersFromReceiverType; - this.typeParameterMap = typeParametersMap; + public TypeParameterListExpression( + @NotNull String[] typeParameterNamesFromReceiverType, + @NotNull Map typeParametersMap + ) { + this.typeParameterNamesFromReceiverType = typeParameterNamesFromReceiverType; + this.parameterTypeToTypeParameterNamesMap = typeParametersMap; } @NotNull @@ -382,36 +454,24 @@ public class CreateMethodFromUsageFix extends CreateFromUsageFixBase { assert func != null; List parameters = func.getValueParameters(); - Set typeParameters = new LinkedHashSet(); - Collections.addAll(typeParameters, typeParametersFromReceiverType); + Set typeParameterNames = new LinkedHashSet(); + Collections.addAll(typeParameterNames, typeParameterNamesFromReceiverType); for (JetParameter parameter : parameters) { JetTypeReference parameterTypeRef = parameter.getTypeReference(); assert parameterTypeRef != null; - TypeParameterDescriptor[] typeParametersFromParameter = typeParameterMap.get(parameterTypeRef.getText()); - if (typeParametersFromParameter != null) { - Collections.addAll(typeParameters, typeParametersFromParameter); + String[] typeParameterNamesFromParameter = parameterTypeToTypeParameterNamesMap.get(parameterTypeRef.getText()); + if (typeParameterNamesFromParameter != null) { + Collections.addAll(typeParameterNames, typeParameterNamesFromParameter); } } JetTypeReference returnTypeRef = func.getReturnTypeRef(); if (returnTypeRef != null) { - TypeParameterDescriptor[] typeParametersFromReturnType = typeParameterMap.get(returnTypeRef.getText()); - if (typeParametersFromReturnType != null) { - Collections.addAll(typeParameters, typeParametersFromReturnType); + String[] typeParameterNamesFromReturnType = parameterTypeToTypeParameterNamesMap.get(returnTypeRef.getText()); + if (typeParameterNamesFromReturnType != null) { + Collections.addAll(typeParameterNames, typeParameterNamesFromReturnType); } } - List typeParameterNames = new ArrayList(); - for (TypeParameterDescriptor typeParameter : typeParameters) { - typeParameterNames.add(typeParameter.getName().getIdentifier()); - } - - // make sure there are no name conflicts - for (int i = 0; i < typeParameterNames.size(); i++) { - String name = typeParameterNames.get(i); - name = getNextAvailableName(name, typeParameterNames.subList(0, i)); - typeParameterNames.set(i, name); - } - return typeParameterNames.isEmpty() ? new TextResult("") : new TextResult(" <" + StringUtil.join(typeParameterNames, ", ") + ">"); @@ -465,7 +525,8 @@ public class CreateMethodFromUsageFix extends CreateFromUsageFixBase { private BindingContext currentFileContext; private JetClass ownerClass; private ClassDescriptor ownerClassDescriptor; - private JetType receiverType; + private TypeCandidate selectedReceiverType; + private Map typeParameterNameMap; public CreateMethodFromUsageFix(@NotNull PsiElement element, @NotNull TypeOrExpressionThereof ownerType, @NotNull String methodName, @NotNull TypeOrExpressionThereof returnType, @NotNull List parameters) { @@ -487,18 +548,20 @@ public class CreateMethodFromUsageFix extends CreateFromUsageFixBase { assert file != null && file instanceof JetFile; // TODO: change some assertions to notifications currentFile = (JetFile) file; currentFileEditor = editor; + currentFileContext = AnalyzerFacadeWithCache.analyzeFileWithCache(currentFile).getBindingContext(); - JetType[] possibleOwnerTypes = ownerType.getPossibleTypes(); - assert possibleOwnerTypes.length > 0; - if (possibleOwnerTypes.length == 1) { - JetType ownerType = possibleOwnerTypes[0]; - doInvoke(project, ownerType); + ownerType.computeTypeCandidates(currentFileContext); + TypeCandidate[] ownerTypeCandidates = ownerType.getTypeCandidates(); + assert ownerTypeCandidates.length > 0; + if (ownerTypeCandidates.length == 1) { + selectedReceiverType = ownerTypeCandidates[0]; + doInvoke(project); } else { // class selection List options = new ArrayList(); - final Map optionToTypeMap = new HashMap(); - for (JetType possibleOwnerType : possibleOwnerTypes) { - ClassifierDescriptor possibleClassDescriptor = possibleOwnerType.getConstructor().getDeclarationDescriptor(); + final Map optionToTypeMap = new HashMap(); + for (TypeCandidate ownerTypeCandidate : ownerTypeCandidates) { + ClassifierDescriptor possibleClassDescriptor = ownerTypeCandidate.getType().getConstructor().getDeclarationDescriptor(); if (possibleClassDescriptor != null) { String className = DescriptorRenderer.SHORT_NAMES_IN_TYPES.renderType(possibleClassDescriptor.getDefaultType()); DeclarationDescriptor namespaceDescriptor = possibleClassDescriptor.getContainingDeclaration(); @@ -506,7 +569,7 @@ public class CreateMethodFromUsageFix extends CreateFromUsageFixBase { String namespace = ((NamespaceDescriptor) namespaceDescriptor).getFqName().getFqName(); String option = className + " (" + namespace + ")"; options.add(option); - optionToTypeMap.put(option, possibleOwnerType); + optionToTypeMap.put(option, ownerTypeCandidate); } } @@ -523,11 +586,11 @@ public class CreateMethodFromUsageFix extends CreateFromUsageFixBase { int index = list.getSelectedIndex(); if (index < 0) return; String option = (String) list.getSelectedValue(); - final JetType ownerType = optionToTypeMap.get(option); + selectedReceiverType = optionToTypeMap.get(option); CommandProcessor.getInstance().executeCommand(project, new Runnable() { @Override public void run() { - doInvoke(project, ownerType); + doInvoke(project); } }, getText(), null); } @@ -540,12 +603,12 @@ public class CreateMethodFromUsageFix extends CreateFromUsageFixBase { } } - private void doInvoke(@NotNull final Project project, @NotNull JetType ownerType) { + private void doInvoke(@NotNull final Project project) { // gather relevant information - ClassifierDescriptor ownerTypeDescriptor = ownerType.getConstructor().getDeclarationDescriptor(); + ClassifierDescriptor ownerTypeDescriptor = selectedReceiverType.getType().getConstructor().getDeclarationDescriptor(); assert ownerTypeDescriptor != null && ownerTypeDescriptor instanceof ClassDescriptor; ownerClassDescriptor = (ClassDescriptor) ownerTypeDescriptor; - receiverType = ownerClassDescriptor.getDefaultType(); + JetType receiverType = ownerClassDescriptor.getDefaultType(); PsiElement typeDeclaration = BindingContextUtils.classDescriptorToDeclaration(currentFileContext, ownerClassDescriptor); if (typeDeclaration != null && typeDeclaration instanceof JetClass) { ownerClass = (JetClass) typeDeclaration; @@ -555,17 +618,41 @@ public class CreateMethodFromUsageFix extends CreateFromUsageFixBase { } isUnit = returnType.isType() && isUnit(returnType.getType()); + JetScope scope; + if (isExtension) { + NamespaceDescriptor namespaceDescriptor = currentFileContext.get(BindingContext.FILE_TO_NAMESPACE, containingFile); + assert namespaceDescriptor != null; + scope = namespaceDescriptor.getMemberScope(); + } else { + assert ownerClassDescriptor instanceof MutableClassDescriptor; + scope = ((MutableClassDescriptor) ownerClassDescriptor).getScopeForMemberResolution(); + } + // figure out type substitutions for type parameters List classTypeParameters = receiverType.getArguments(); - List ownerTypeArguments = ownerType.getArguments(); + List ownerTypeArguments = selectedReceiverType.getType().getArguments(); assert ownerTypeArguments.size() == classTypeParameters.size(); TypeSubstitution[] substitutions = new TypeSubstitution[classTypeParameters.size()]; for (int i = 0; i < substitutions.length; i++) { substitutions[i] = new TypeSubstitution(ownerTypeArguments.get(i).getType(), classTypeParameters.get(i).getType()); } - returnType.substitute(substitutions); for (Parameter parameter : parameters) { - parameter.getType().substitute(substitutions); + parameter.getType().computeTypeCandidates(currentFileContext, substitutions, scope); + } + if (!isUnit) { + returnType.computeTypeCandidates(currentFileContext, substitutions, scope); + } + + // figure out type parameter renames to avoid conflicts + typeParameterNameMap = getTypeParameterRenames(scope); + for (Parameter parameter : parameters) { + parameter.getType().renderTypeCandidates(typeParameterNameMap); + } + if (!isUnit) { + returnType.renderTypeCandidates(typeParameterNameMap); + } + if (isExtension) { + ownerType.renderTypeCandidates(typeParameterNameMap); } ApplicationManager.getApplication().runWriteAction(new Runnable() { @@ -586,7 +673,7 @@ public class CreateMethodFromUsageFix extends CreateFromUsageFixBase { String parametersString = StringUtil.join(parameterStrings,", "); String returnTypeString = isUnit ? "" : ": Any"; if (isExtension) { // create as extension function - String ownerTypeString = renderTypeShort(receiverType); + String ownerTypeString = selectedReceiverType.getRenderedType(); String methodText = String.format("fun %s.%s(%s)%s { }", ownerTypeString, methodName, parametersString, returnTypeString); func = JetPsiFactory.createFunction(project, methodText); containingFile = currentFile; @@ -619,16 +706,6 @@ public class CreateMethodFromUsageFix extends CreateFromUsageFixBase { JetParameterList parameterList = func.getValueParameterList(); assert parameterList != null; - JetScope scope; - if (isExtension) { - NamespaceDescriptor namespaceDescriptor = currentFileContext.get(BindingContext.FILE_TO_NAMESPACE, containingFile); - assert namespaceDescriptor != null; - scope = namespaceDescriptor.getMemberScope(); - } else { - assert ownerClassDescriptor instanceof MutableClassDescriptor; - scope = ((MutableClassDescriptor) ownerClassDescriptor).getScopeForMemberResolution(); - } - // build templates PsiDocumentManager.getInstance(project).commitAllDocuments(); PsiDocumentManager.getInstance(project).doPostponedOperationsAndUnblockDocument(containingFileEditor.getDocument()); @@ -645,8 +722,7 @@ public class CreateMethodFromUsageFix extends CreateFromUsageFixBase { // need to create the segment first and then hack the Expression into the template later. We use this template to update the type // parameter list as the user makes selections in the parameter types, and we need alwaysStopAt to be false so the user can't tab to // it. - TypeParameterListExpression expression = - setupTypeParameterListTemplate(builder, func, parameterTypeExpressions, returnTypeExpression, scope); + TypeParameterListExpression expression = setupTypeParameterListTemplate(builder, func); // the template built by TemplateBuilderImpl is ordered by element position, but we want types to be first, so hack it final TemplateImpl template = (TemplateImpl) builder.buildInlineTemplate(); @@ -684,6 +760,39 @@ public class CreateMethodFromUsageFix extends CreateFromUsageFixBase { }); } + private Map getTypeParameterRenames(JetScope scope) { + TypeParameterDescriptor[] receiverTypeParametersNotInScope = selectedReceiverType.getTypeParameters(); + Set allTypeParametersNotInScope = new LinkedHashSet(); + allTypeParametersNotInScope.addAll(Arrays.asList(receiverTypeParametersNotInScope)); + + for (Parameter parameter : parameters) { + TypeCandidate[] parameterTypeCandidates = parameter.getType().getTypeCandidates(); + for (TypeCandidate parameterTypeCandidate : parameterTypeCandidates) { + allTypeParametersNotInScope.addAll(Arrays.asList(parameterTypeCandidate.getTypeParameters())); + } + } + + if (!isUnit) { + TypeCandidate[] returnTypeCandidates = returnType.getTypeCandidates(); + for (TypeCandidate returnTypeCandidate : returnTypeCandidates) { + allTypeParametersNotInScope.addAll(Arrays.asList(returnTypeCandidate.getTypeParameters())); + } + } + + List typeParameters = new ArrayList(allTypeParametersNotInScope); + List typeParameterNames = new ArrayList(); + for (TypeParameterDescriptor typeParameter : typeParameters) { + typeParameterNames.add(getNextAvailableName(typeParameter.getName().getName(), typeParameterNames, scope)); + } + assert typeParameters.size() == typeParameterNames.size(); + Map typeParameterNameMap = new HashMap(); + for (int i = 0; i < typeParameters.size(); i++) { + typeParameterNameMap.put(typeParameters.get(i), typeParameterNames.get(i)); + } + + return typeParameterNameMap; + } + private void setupTypeReferencesForShortening( @NotNull Project project, @NotNull JetNamedFunction func, @@ -692,8 +801,9 @@ public class CreateMethodFromUsageFix extends CreateFromUsageFixBase { @Nullable TypeExpression returnTypeExpression ) { if (isExtension) { - JetTypeReference receiverTypeRef = JetPsiFactory.createType(project, renderTypeLong(receiverType)); - replaceWithLongerName(project, receiverTypeRef, receiverType); + JetTypeReference receiverTypeRef = + JetPsiFactory.createType(project, renderTypeLong(selectedReceiverType.getType(), typeParameterNameMap)); + replaceWithLongerName(project, receiverTypeRef, selectedReceiverType.getType()); receiverTypeRef = func.getReceiverTypeRef(); assert receiverTypeRef != null; @@ -766,46 +876,33 @@ public class CreateMethodFromUsageFix extends CreateFromUsageFixBase { private TypeExpression setupReturnTypeTemplate(@NotNull TemplateBuilder builder, @NotNull JetNamedFunction func) { JetTypeReference returnTypeRef = func.getReturnTypeRef(); assert returnTypeRef != null; - TypeExpression returnTypeExpression = new TypeExpression(returnType.getPossibleTypes()); + TypeExpression returnTypeExpression = new TypeExpression(returnType); builder.replaceElement(returnTypeRef, returnTypeExpression); return returnTypeExpression; } @NotNull - private TypeParameterListExpression setupTypeParameterListTemplate( - @NotNull TemplateBuilderImpl builder, - @NotNull JetNamedFunction func, - @NotNull TypeExpression[] parameterTypeExpressions, - @Nullable TypeExpression returnTypeExpression, - @NotNull JetScope scope - ) { - Map typeParameterMap = new HashMap(); - Set receiverTypeParameters = getTypeParametersInType(receiverType); - TypeParameterDescriptor[] receiverTypeParametersNotInScope = getTypeParameterNamesNotInScope(receiverTypeParameters, scope); - for (TypeExpression parameterTypeExpression : parameterTypeExpressions) { - JetType[] parameterTypeOptions = parameterTypeExpression.getOptions(); - String[] parameterTypeOptionStrings = parameterTypeExpression.getOptionStrings(); - assert parameterTypeOptions.length == parameterTypeOptionStrings.length; - for (int i = 0; i < parameterTypeOptions.length; i++) { - Set typeParameters = getTypeParametersInType(parameterTypeOptions[i]); - typeParameterMap.put(parameterTypeOptionStrings[i], getTypeParameterNamesNotInScope(typeParameters, scope)); + private TypeParameterListExpression setupTypeParameterListTemplate(@NotNull TemplateBuilderImpl builder, @NotNull JetNamedFunction func) { + Map typeParameterMap = new HashMap(); + String[] receiverTypeParameterNames = selectedReceiverType.getTypeParameterNames(); + + for (Parameter parameter : parameters) { + TypeCandidate[] parameterTypeCandidates = parameter.getType().getTypeCandidates(); + for (TypeCandidate parameterTypeCandidate : parameterTypeCandidates) { + typeParameterMap.put(parameterTypeCandidate.getRenderedType(), parameterTypeCandidate.getTypeParameterNames()); } } JetTypeReference returnTypeRef = func.getReturnTypeRef(); if (returnTypeRef != null) { - assert returnTypeExpression != null; - JetType[] returnTypeOptions = returnTypeExpression.getOptions(); - String[] returnTypeOptionStrings = returnTypeExpression.getOptionStrings(); - assert returnTypeOptions.length == returnTypeOptionStrings.length; - for (int i = 0; i < returnTypeOptions.length; i++) { - Set typeParameters = getTypeParametersInType(returnTypeOptions[i]); - typeParameterMap.put(returnTypeOptionStrings[i], getTypeParameterNamesNotInScope(typeParameters, scope)); + TypeCandidate[] returnTypeCandidates = returnType.getTypeCandidates(); + for (TypeCandidate returnTypeCandidate : returnTypeCandidates) { + typeParameterMap.put(returnTypeCandidate.getRenderedType(), returnTypeCandidate.getTypeParameterNames()); } } builder.replaceElement(func, TextRange.create(3, 3), TYPE_PARAMETER_LIST_VARIABLE_NAME, null, false); // ((3, 3) is after "fun") - return new TypeParameterListExpression(receiverTypeParametersNotInScope, typeParameterMap); + return new TypeParameterListExpression(receiverTypeParameterNames, typeParameterMap); } private TypeExpression[] setupParameterTypeTemplates(@NotNull Project project, @NotNull TemplateBuilder builder, @@ -813,13 +910,13 @@ public class CreateMethodFromUsageFix extends CreateFromUsageFixBase { List jetParameters = parameterList.getParameters(); assert jetParameters.size() == parameters.size(); TypeExpression[] parameterTypeExpressions = new TypeExpression[parameters.size()]; + JetNameValidator dummyValidator = JetNameValidator.getEmptyValidator(project); for (int i = 0; i < parameters.size(); i++) { Parameter parameter = parameters.get(i); JetParameter jetParameter = jetParameters.get(i); // add parameter type to the template - JetType[] typeOptions = parameter.getType().getPossibleTypes(); - parameterTypeExpressions[i] = new TypeExpression(typeOptions); + parameterTypeExpressions[i] = new TypeExpression(parameter.getType()); JetTypeReference parameterTypeRef = jetParameter.getTypeReference(); assert parameterTypeRef != null; builder.replaceElement(parameterTypeRef, parameterTypeExpressions[i]); @@ -838,11 +935,9 @@ public class CreateMethodFromUsageFix extends CreateFromUsageFixBase { // figure out suggested names for each type option Map parameterTypeToNamesMap = new HashMap(); - String[] typeOptionStrings = parameterTypeExpressions[i].getOptionStrings(); - assert typeOptions.length == typeOptionStrings.length; - for (int j = 0; j < typeOptions.length; j++) { - String[] suggestedNames = JetNameSuggester.suggestNamesForType(typeOptions[j], JetNameValidator.getEmptyValidator(project)); - parameterTypeToNamesMap.put(typeOptionStrings[j], suggestedNames); + for (TypeCandidate typeCandidate : parameter.getType().getTypeCandidates()) { + String[] suggestedNames = JetNameSuggester.suggestNamesForType(typeCandidate.getType(), dummyValidator); + parameterTypeToNamesMap.put(typeCandidate.getRenderedType(), suggestedNames); } // add expression to builder @@ -854,31 +949,8 @@ public class CreateMethodFromUsageFix extends CreateFromUsageFixBase { return parameterTypeExpressions; } - @Override - public boolean isAvailable(@NotNull Project project, Editor editor, PsiFile file) { - assert file instanceof JetFile; - JetFile jetFile = (JetFile) file; - currentFileContext = AnalyzerFacadeWithCache.analyzeFileWithCache(jetFile).getBindingContext(); - - JetType[] possibleOwnerTypes = ownerType.getPossibleTypes(currentFileContext); - if (possibleOwnerTypes.length == 0) return false; - assertNoUnitTypes(possibleOwnerTypes); - JetType[] possibleReturnTypes = returnType.getPossibleTypes(currentFileContext); - if (!returnType.isType()) { // allow return type to be unit (but not when it's among several options) - assertNoUnitTypes(possibleReturnTypes); - } - if (possibleReturnTypes.length == 0) return false; - for (Parameter parameter : parameters) { - JetType[] possibleTypes = parameter.getType().getPossibleTypes(currentFileContext); - if (possibleTypes.length == 0) return false; - assertNoUnitTypes(possibleTypes); - } - - return true; - } - - private static void replaceWithLongerName(@NotNull Project project, @NotNull JetTypeReference typeRef, @NotNull JetType type) { - JetTypeReference fullyQualifiedReceiverTypeRef = JetPsiFactory.createType(project, renderTypeLong(type)); + private void replaceWithLongerName(@NotNull Project project, @NotNull JetTypeReference typeRef, @NotNull JetType type) { + JetTypeReference fullyQualifiedReceiverTypeRef = JetPsiFactory.createType(project, renderTypeLong(type, typeParameterNameMap)); typeRef.replace(fullyQualifiedReceiverTypeRef); } @@ -933,13 +1005,45 @@ public class CreateMethodFromUsageFix extends CreateFromUsageFixBase { } @NotNull - private static String renderTypeShort(@NotNull JetType type) { - return DescriptorRenderer.SHORT_NAMES_IN_TYPES.renderType(type); + private static String renderDescriptor( + @NotNull DeclarationDescriptor declarationDescriptor, + @NotNull Map typeParameterNameMap, + boolean fq + ) { + if (declarationDescriptor instanceof TypeParameterDescriptor) { + String replacement = typeParameterNameMap.get(declarationDescriptor); + return replacement == null ? declarationDescriptor.getName().getName() : replacement; + } else if (declarationDescriptor instanceof ClassDescriptor) { + return fq ? DescriptorUtils.getFQName(declarationDescriptor).getFqName() : declarationDescriptor.getName().getName(); + } else { + assert false : "unexpected descriptor in type"; + return null; + } + } + + private static String renderType(@NotNull JetType type, @NotNull Map typeParameterNameMap, boolean fq) { + List projections = type.getArguments(); + DeclarationDescriptor declarationDescriptor = type.getConstructor().getDeclarationDescriptor(); + assert declarationDescriptor != null; + if (projections.isEmpty()) { + return renderDescriptor(declarationDescriptor, typeParameterNameMap, fq); + } + + List arguments = new ArrayList(); + for (TypeProjection projection : projections) { + arguments.add(renderTypeLong(projection.getType(), typeParameterNameMap)); + } + return renderDescriptor(declarationDescriptor, typeParameterNameMap, fq) + "<" + StringUtil.join(arguments, ", ") + ">"; } @NotNull - private static String renderTypeLong(@NotNull JetType type) { - return DescriptorRenderer.TEXT.renderType(type); + private static String renderTypeShort(@NotNull JetType type, @NotNull Map typeParameterNameMap) { + return renderType(type, typeParameterNameMap, false); + } + + @NotNull + private static String renderTypeLong(@NotNull JetType type, @NotNull Map typeParameterNameMap) { + return renderType(type, typeParameterNameMap, true); } @NotNull @@ -984,6 +1088,16 @@ public class CreateMethodFromUsageFix extends CreateFromUsageFixBase { return name; } + @NotNull + private static String getNextAvailableName(@NotNull String name, @NotNull Collection existingNames, @NotNull JetScope scope) { + if (existingNames.contains(name) || scope.getClassifier(Name.identifier(name)) != null) { + int j = 1; + while (existingNames.contains(name + j) || scope.getClassifier(Name.identifier(name + j)) != null) j++; + name += j; + } + return name; + } + @NotNull private static JetType[] guessTypeForExpression(@NotNull JetExpression expr, @NotNull BindingContext context) { JetType type = context.get(BindingContext.EXPRESSION_TYPE, expr); @@ -1070,12 +1184,6 @@ public class CreateMethodFromUsageFix extends CreateFromUsageFixBase { return KotlinBuiltIns.getInstance().isUnit(type); } - private static void assertNoUnitTypes(@NotNull JetType[] types) { - for (JetType type : types) { - assert !isUnit(type); - } - } - @NotNull public static JetIntentionActionFactory createCreateGetMethodFromUsageFactory() { return new JetIntentionActionFactory() { From d20e3413e0b20a7a0000c4512655553b3e9bcf85 Mon Sep 17 00:00:00 2001 From: Jack Zhou Date: Sun, 21 Apr 2013 12:51:33 -0400 Subject: [PATCH 032/291] Create from usage: Fixed up assertions. --- .../quickfix/CreateMethodFromUsageFix.java | 72 +++++++++++-------- 1 file changed, 42 insertions(+), 30 deletions(-) diff --git a/idea/src/org/jetbrains/jet/plugin/quickfix/CreateMethodFromUsageFix.java b/idea/src/org/jetbrains/jet/plugin/quickfix/CreateMethodFromUsageFix.java index afbf3c4835c..9c4f3efe800 100644 --- a/idea/src/org/jetbrains/jet/plugin/quickfix/CreateMethodFromUsageFix.java +++ b/idea/src/org/jetbrains/jet/plugin/quickfix/CreateMethodFromUsageFix.java @@ -294,8 +294,9 @@ public class CreateMethodFromUsageFix extends CreateFromUsageFixBase { private final Map parameterTypeToNamesMap; public ParameterNameExpression(@NotNull String[] names, @NotNull Map parameterTypeToNamesMap) { - for (String name : names) + for (String name : names) { assert name != null && !name.isEmpty(); + } this.names = names; this.parameterTypeToNamesMap = parameterTypeToNamesMap; } @@ -331,7 +332,7 @@ public class CreateMethodFromUsageFix extends CreateFromUsageFixBase { assert file != null && file instanceof JetFile; PsiElement elementAt = file.findElementAt(offset); JetFunction func = PsiTreeUtil.getParentOfType(elementAt, JetFunction.class); - assert func != null; + if (func == null) return new LookupElement[0]; JetParameterList parameterList = func.getValueParameterList(); assert parameterList != null; @@ -339,17 +340,18 @@ public class CreateMethodFromUsageFix extends CreateFromUsageFixBase { JetParameter parameter = PsiTreeUtil.getParentOfType(elementAt, JetParameter.class); if (parameter != null) { JetTypeReference parameterTypeRef = parameter.getTypeReference(); - assert parameterTypeRef != null; - String[] suggestedNamesBasedOnType = parameterTypeToNamesMap.get(parameterTypeRef.getText()); - if (suggestedNamesBasedOnType != null) { - Collections.addAll(names, suggestedNamesBasedOnType); + if (parameterTypeRef != null) { + String[] suggestedNamesBasedOnType = parameterTypeToNamesMap.get(parameterTypeRef.getText()); + if (suggestedNamesBasedOnType != null) { + Collections.addAll(names, suggestedNamesBasedOnType); + } } } // remember other parameter names for later use Set parameterNames = new HashSet(); for (JetParameter jetParameter : parameterList.getParameters()) { - if (jetParameter == parameter) continue; + if (jetParameter == parameter || jetParameter.getName() == null) continue; parameterNames.add(jetParameter.getName()); } @@ -451,17 +453,20 @@ public class CreateMethodFromUsageFix extends CreateFromUsageFixBase { assert file != null && file instanceof JetFile; PsiElement elementAt = file.findElementAt(offset); JetFunction func = PsiTreeUtil.getParentOfType(elementAt, JetFunction.class); - assert func != null; + if (func == null) { + return new TextResult(""); + } List parameters = func.getValueParameters(); Set typeParameterNames = new LinkedHashSet(); Collections.addAll(typeParameterNames, typeParameterNamesFromReceiverType); for (JetParameter parameter : parameters) { JetTypeReference parameterTypeRef = parameter.getTypeReference(); - assert parameterTypeRef != null; - String[] typeParameterNamesFromParameter = parameterTypeToTypeParameterNamesMap.get(parameterTypeRef.getText()); - if (typeParameterNamesFromParameter != null) { - Collections.addAll(typeParameterNames, typeParameterNamesFromParameter); + if (parameterTypeRef != null) { + String[] typeParameterNamesFromParameter = parameterTypeToTypeParameterNamesMap.get(parameterTypeRef.getText()); + if (typeParameterNamesFromParameter != null) { + Collections.addAll(typeParameterNames, typeParameterNamesFromParameter); + } } } JetTypeReference returnTypeRef = func.getReturnTypeRef(); @@ -545,7 +550,7 @@ public class CreateMethodFromUsageFix extends CreateFromUsageFixBase { @Override public void invoke(@NotNull final Project project, Editor editor, PsiFile file) throws IncorrectOperationException { - assert file != null && file instanceof JetFile; // TODO: change some assertions to notifications + assert file != null && file instanceof JetFile; currentFile = (JetFile) file; currentFileEditor = editor; currentFileContext = AnalyzerFacadeWithCache.analyzeFileWithCache(currentFile).getBindingContext(); @@ -693,7 +698,10 @@ public class CreateMethodFromUsageFix extends CreateFromUsageFixBase { containingFileEditor = fileEditorManager.getSelectedTextEditor(); JetClassBody classBody = ownerClass.getBody(); - assert classBody != null; + if (classBody == null) { + classBody = (JetClassBody) ownerClass.add(JetPsiFactory.createEmptyClassBody(project)); + ownerClass.addBefore(JetPsiFactory.createWhiteSpace(project), classBody); + } PsiElement rBrace = classBody.getRBrace(); assert rBrace != null; func = (JetNamedFunction) classBody.addBefore(func, rBrace); @@ -806,20 +814,22 @@ public class CreateMethodFromUsageFix extends CreateFromUsageFixBase { replaceWithLongerName(project, receiverTypeRef, selectedReceiverType.getType()); receiverTypeRef = func.getReceiverTypeRef(); - assert receiverTypeRef != null; - typeRefsToShorten.add(receiverTypeRef); + if (receiverTypeRef != null) { + typeRefsToShorten.add(receiverTypeRef); + } } if (!isUnit) { assert returnTypeExpression != null; JetTypeReference returnTypeRef = func.getReturnTypeRef(); - assert returnTypeRef != null; - JetType returnType = returnTypeExpression.getTypeFromSelection(returnTypeRef.getText()); - if (returnType != null) { // user selected a given type - replaceWithLongerName(project, returnTypeRef, returnType); - returnTypeRef = func.getReturnTypeRef(); - assert returnTypeRef != null; - typeRefsToShorten.add(returnTypeRef); + if (returnTypeRef != null) { + JetType returnType = returnTypeExpression.getTypeFromSelection(returnTypeRef.getText()); + if (returnType != null) { // user selected a given type + replaceWithLongerName(project, returnTypeRef, returnType); + returnTypeRef = func.getReturnTypeRef(); + assert returnTypeRef != null; + typeRefsToShorten.add(returnTypeRef); + } } } @@ -829,18 +839,20 @@ public class CreateMethodFromUsageFix extends CreateFromUsageFixBase { for (int i = 0; i < valueParameters.size(); i++) { JetParameter parameter = valueParameters.get(i); JetTypeReference parameterTypeRef = parameter.getTypeReference(); - assert parameterTypeRef != null; - JetType parameterType = parameterTypeExpressions[i].getTypeFromSelection(parameterTypeRef.getText()); - if (parameterType != null) { - replaceWithLongerName(project, parameterTypeRef, parameterType); - parameterIndicesToShorten.add(i); + if (parameterTypeRef != null) { + JetType parameterType = parameterTypeExpressions[i].getTypeFromSelection(parameterTypeRef.getText()); + if (parameterType != null) { + replaceWithLongerName(project, parameterTypeRef, parameterType); + parameterIndicesToShorten.add(i); + } } } valueParameters = func.getValueParameters(); for (int i : parameterIndicesToShorten) { JetTypeReference parameterTypeRef = valueParameters.get(i).getTypeReference(); - assert parameterTypeRef != null; - typeRefsToShorten.add(parameterTypeRef); + if (parameterTypeRef != null) { + typeRefsToShorten.add(parameterTypeRef); + } } } From 7b072e573acd5050e51606db2e9b3e53f42ca89e Mon Sep 17 00:00:00 2001 From: Jack Zhou Date: Sun, 21 Apr 2013 13:22:43 -0400 Subject: [PATCH 033/291] Create from usage: Implemented CreateClassObjectFromUsageFix. --- .../jetbrains/jet/lang/psi/JetPsiFactory.java | 5 +++ .../CreateClassObjectFromUsageFix.java | 34 +++++++++++++++++-- 2 files changed, 36 insertions(+), 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 fa9c5aadc94..38902dbe308 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetPsiFactory.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetPsiFactory.java @@ -277,4 +277,9 @@ public class JetPsiFactory { JetFunction func = createFunction(project, "fun foo() {\n" + bodyText + "\n}"); return func.getBodyExpression(); } + + public static JetClassObject createEmptyClassObject(Project project) { + JetClass klass = createClass(project, "class foo { class object { } }"); + return klass.getClassObject(); + } } diff --git a/idea/src/org/jetbrains/jet/plugin/quickfix/CreateClassObjectFromUsageFix.java b/idea/src/org/jetbrains/jet/plugin/quickfix/CreateClassObjectFromUsageFix.java index 6a4621dff97..0a52a91ae91 100644 --- a/idea/src/org/jetbrains/jet/plugin/quickfix/CreateClassObjectFromUsageFix.java +++ b/idea/src/org/jetbrains/jet/plugin/quickfix/CreateClassObjectFromUsageFix.java @@ -18,18 +18,25 @@ package org.jetbrains.jet.plugin.quickfix; import com.intellij.codeInsight.intention.IntentionAction; import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.fileEditor.FileEditorManager; import com.intellij.openapi.project.Project; +import com.intellij.openapi.vfs.VirtualFile; import com.intellij.psi.PsiElement; import com.intellij.psi.PsiFile; +import com.intellij.psi.PsiReference; 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.plugin.JetBundle; public class CreateClassObjectFromUsageFix extends CreateFromUsageFixBase { - public CreateClassObjectFromUsageFix(@NotNull PsiElement element) { + private final JetClass klass; + + public CreateClassObjectFromUsageFix(@NotNull PsiElement element, @NotNull JetClass klass) { super(element); + this.klass = klass; } @NotNull @@ -40,7 +47,20 @@ public class CreateClassObjectFromUsageFix extends CreateFromUsageFixBase { @Override public void invoke(@NotNull Project project, Editor editor, PsiFile file) throws IncorrectOperationException { - // TODO + PsiFile containingFile = klass.getContainingFile(); + VirtualFile virtualFile = containingFile.getVirtualFile(); + assert virtualFile != null; + FileEditorManager fileEditorManager = FileEditorManager.getInstance(project); + fileEditorManager.openFile(virtualFile, true); + + JetClassBody classBody = klass.getBody(); + if (classBody == null) { + classBody = (JetClassBody) klass.add(JetPsiFactory.createEmptyClassBody(project)); + klass.addBefore(JetPsiFactory.createWhiteSpace(project), classBody); + } + PsiElement lBrace = classBody.getLBrace(); + JetClassObject classObject = (JetClassObject) classBody.addAfter(JetPsiFactory.createEmptyClassObject(project), lBrace); + classBody.addBefore(JetPsiFactory.createNewLine(project), classObject); } @NotNull @@ -49,7 +69,15 @@ public class CreateClassObjectFromUsageFix extends CreateFromUsageFixBase { @Nullable @Override public IntentionAction createAction(Diagnostic diagnostic) { - return null; // TODO + JetReferenceExpression refExpr = QuickFixUtil.getParentElementOfType(diagnostic, JetReferenceExpression.class); + if (refExpr == null) return null; + PsiReference reference = refExpr.getReference(); + if (reference == null) return null; + PsiElement resolvedReference = reference.resolve(); + if (resolvedReference == null || !(resolvedReference instanceof JetClass)) return null; + JetClass klass = (JetClass) resolvedReference; + if (!klass.isWritable()) return null; + return new CreateClassObjectFromUsageFix(refExpr, (JetClass) resolvedReference); } }; } From 0cd9c2d9a86505114c6b8978fbdd0b5e3fbb139d Mon Sep 17 00:00:00 2001 From: Jack Zhou Date: Sun, 21 Apr 2013 14:20:36 -0400 Subject: [PATCH 034/291] Create from usage: Fixed an overly restrictive assertion. --- .../plugin/quickfix/CreateMethodFromUsageFix.java | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/idea/src/org/jetbrains/jet/plugin/quickfix/CreateMethodFromUsageFix.java b/idea/src/org/jetbrains/jet/plugin/quickfix/CreateMethodFromUsageFix.java index 9c4f3efe800..1c8397aa7b5 100644 --- a/idea/src/org/jetbrains/jet/plugin/quickfix/CreateMethodFromUsageFix.java +++ b/idea/src/org/jetbrains/jet/plugin/quickfix/CreateMethodFromUsageFix.java @@ -570,8 +570,7 @@ public class CreateMethodFromUsageFix extends CreateFromUsageFixBase { if (possibleClassDescriptor != null) { String className = DescriptorRenderer.SHORT_NAMES_IN_TYPES.renderType(possibleClassDescriptor.getDefaultType()); DeclarationDescriptor namespaceDescriptor = possibleClassDescriptor.getContainingDeclaration(); - assert namespaceDescriptor instanceof NamespaceDescriptor; - String namespace = ((NamespaceDescriptor) namespaceDescriptor).getFqName().getFqName(); + String namespace = renderDescriptor(namespaceDescriptor, true); String option = className + " (" + namespace + ")"; options.add(option); optionToTypeMap.put(option, ownerTypeCandidate); @@ -1025,14 +1024,16 @@ public class CreateMethodFromUsageFix extends CreateFromUsageFixBase { if (declarationDescriptor instanceof TypeParameterDescriptor) { String replacement = typeParameterNameMap.get(declarationDescriptor); return replacement == null ? declarationDescriptor.getName().getName() : replacement; - } else if (declarationDescriptor instanceof ClassDescriptor) { - return fq ? DescriptorUtils.getFQName(declarationDescriptor).getFqName() : declarationDescriptor.getName().getName(); } else { - assert false : "unexpected descriptor in type"; - return null; + return fq ? DescriptorUtils.getFQName(declarationDescriptor).getFqName() : declarationDescriptor.getName().getName(); } } + @NotNull + private static String renderDescriptor(@NotNull DeclarationDescriptor declarationDescriptor, boolean fq) { + return renderDescriptor(declarationDescriptor, Collections.emptyMap(), fq); + } + private static String renderType(@NotNull JetType type, @NotNull Map typeParameterNameMap, boolean fq) { List projections = type.getArguments(); DeclarationDescriptor declarationDescriptor = type.getConstructor().getDeclarationDescriptor(); From a9f1ba3063f214e608a58d9bb971970e2121fead Mon Sep 17 00:00:00 2001 From: Jack Zhou Date: Sun, 21 Apr 2013 15:04:18 -0400 Subject: [PATCH 035/291] Create from usage: Fixed a bug where the type parameter list is not rendered correctly when empty. --- .../jet/plugin/quickfix/CreateMethodFromUsageFix.java | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/idea/src/org/jetbrains/jet/plugin/quickfix/CreateMethodFromUsageFix.java b/idea/src/org/jetbrains/jet/plugin/quickfix/CreateMethodFromUsageFix.java index 1c8397aa7b5..3b7d7772d69 100644 --- a/idea/src/org/jetbrains/jet/plugin/quickfix/CreateMethodFromUsageFix.java +++ b/idea/src/org/jetbrains/jet/plugin/quickfix/CreateMethodFromUsageFix.java @@ -95,7 +95,7 @@ public class CreateMethodFromUsageFix extends CreateFromUsageFixBase { this.type = type; Set typeParametersInType = getTypeParametersInType(type); typeParameters = typeParametersInType.toArray(new TypeParameterDescriptor[typeParametersInType.size()]); - render(Collections.emptyMap()); + renderedType = renderTypeShort(type, Collections.emptyMap()); } public TypeCandidate(@NotNull JetType type, @NotNull JetScope scope) { @@ -647,6 +647,9 @@ public class CreateMethodFromUsageFix extends CreateFromUsageFixBase { returnType.computeTypeCandidates(currentFileContext, substitutions, scope); } + // now that we have done substitutions, we can throw it away + selectedReceiverType = new TypeCandidate(receiverType, scope); + // figure out type parameter renames to avoid conflicts typeParameterNameMap = getTypeParameterRenames(scope); for (Parameter parameter : parameters) { @@ -655,9 +658,7 @@ public class CreateMethodFromUsageFix extends CreateFromUsageFixBase { if (!isUnit) { returnType.renderTypeCandidates(typeParameterNameMap); } - if (isExtension) { - ownerType.renderTypeCandidates(typeParameterNameMap); - } + selectedReceiverType.render(typeParameterNameMap); ApplicationManager.getApplication().runWriteAction(new Runnable() { @Override From 0e73e32621a6072289de9a663874a668a6595f26 Mon Sep 17 00:00:00 2001 From: Jack Zhou Date: Sun, 21 Apr 2013 16:29:00 -0400 Subject: [PATCH 036/291] Create from usage: Fixed a bug with extension functions. --- .../jetbrains/jet/plugin/quickfix/CreateMethodFromUsageFix.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/idea/src/org/jetbrains/jet/plugin/quickfix/CreateMethodFromUsageFix.java b/idea/src/org/jetbrains/jet/plugin/quickfix/CreateMethodFromUsageFix.java index 3b7d7772d69..9e05f4fc930 100644 --- a/idea/src/org/jetbrains/jet/plugin/quickfix/CreateMethodFromUsageFix.java +++ b/idea/src/org/jetbrains/jet/plugin/quickfix/CreateMethodFromUsageFix.java @@ -624,7 +624,7 @@ public class CreateMethodFromUsageFix extends CreateFromUsageFixBase { JetScope scope; if (isExtension) { - NamespaceDescriptor namespaceDescriptor = currentFileContext.get(BindingContext.FILE_TO_NAMESPACE, containingFile); + NamespaceDescriptor namespaceDescriptor = currentFileContext.get(BindingContext.FILE_TO_NAMESPACE, currentFile); assert namespaceDescriptor != null; scope = namespaceDescriptor.getMemberScope(); } else { From 7a42ca211d4f441b1e2924c3df67e5ac9e43bab4 Mon Sep 17 00:00:00 2001 From: Jack Zhou Date: Sun, 21 Apr 2013 16:56:11 -0400 Subject: [PATCH 037/291] Create from usage: Changed type order to prefer substituted versions. --- .../quickfix/CreateMethodFromUsageFix.java | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/idea/src/org/jetbrains/jet/plugin/quickfix/CreateMethodFromUsageFix.java b/idea/src/org/jetbrains/jet/plugin/quickfix/CreateMethodFromUsageFix.java index 9e05f4fc930..61083bad78d 100644 --- a/idea/src/org/jetbrains/jet/plugin/quickfix/CreateMethodFromUsageFix.java +++ b/idea/src/org/jetbrains/jet/plugin/quickfix/CreateMethodFromUsageFix.java @@ -174,8 +174,8 @@ public class CreateMethodFromUsageFix extends CreateFromUsageFixBase { } @NotNull - private Collection getPossibleTypes(BindingContext context) { - Collection types = new ArrayList(); + private List getPossibleTypes(BindingContext context) { + List types = new ArrayList(); if (isType()) { assert type != null : "!isType() means type == null && expressionOfType != null"; types.add(type); @@ -208,7 +208,8 @@ public class CreateMethodFromUsageFix extends CreateFromUsageFixBase { @NotNull TypeSubstitution[] substitutions, @NotNull JetScope scope ) { - Collection types = getPossibleTypes(context); + List types = getPossibleTypes(context); + Collections.reverse(types); // reverse and reverse back later, so that things added below are added at the front Set newTypes = new LinkedHashSet(types); for (TypeSubstitution substitution : substitutions) { // each substitution can be applied or not, so we offer all options @@ -229,13 +230,11 @@ public class CreateMethodFromUsageFix extends CreateFromUsageFixBase { newTypes.add(KotlinBuiltIns.getInstance().getAnyType()); } - types = newTypes; - - typeCandidates = new TypeCandidate[types.size()]; - int i = 0; - for (JetType type : types) { + typeCandidates = new TypeCandidate[newTypes.size()]; + int i = typeCandidates.length - 1; // reverse order (see explanation above) + for (JetType type : newTypes) { typeCandidates[i] = new TypeCandidate(type, scope); - i++; + i--; } } From 3d120432c5ecf09128641504d7a07e0757090bdc Mon Sep 17 00:00:00 2001 From: Jack Zhou Date: Sun, 21 Apr 2013 17:44:31 -0400 Subject: [PATCH 038/291] Create from usage: Fixed extra type options. --- .../jet/plugin/quickfix/CreateMethodFromUsageFix.java | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/idea/src/org/jetbrains/jet/plugin/quickfix/CreateMethodFromUsageFix.java b/idea/src/org/jetbrains/jet/plugin/quickfix/CreateMethodFromUsageFix.java index 61083bad78d..b87b18f1905 100644 --- a/idea/src/org/jetbrains/jet/plugin/quickfix/CreateMethodFromUsageFix.java +++ b/idea/src/org/jetbrains/jet/plugin/quickfix/CreateMethodFromUsageFix.java @@ -179,7 +179,9 @@ public class CreateMethodFromUsageFix extends CreateFromUsageFixBase { if (isType()) { assert type != null : "!isType() means type == null && expressionOfType != null"; types.add(type); - types.addAll(TypeUtils.getAllSupertypes(type)); + if (variance == Variance.IN_VARIANCE) { + types.addAll(TypeUtils.getAllSupertypes(type)); + } } else { assert expressionOfType != null : "!isType() means type == null && expressionOfType != null"; for (JetType type : guessTypeForExpression(expressionOfType, context)) { @@ -1044,7 +1046,7 @@ public class CreateMethodFromUsageFix extends CreateFromUsageFixBase { List arguments = new ArrayList(); for (TypeProjection projection : projections) { - arguments.add(renderTypeLong(projection.getType(), typeParameterNameMap)); + arguments.add(renderType(projection.getType(), typeParameterNameMap, fq)); } return renderDescriptor(declarationDescriptor, typeParameterNameMap, fq) + "<" + StringUtil.join(arguments, ", ") + ">"; } From 60fa732042798a119f4d31eb7e5290b4736f5258 Mon Sep 17 00:00:00 2001 From: Jack Zhou Date: Sun, 21 Apr 2013 18:02:57 -0400 Subject: [PATCH 039/291] Create from usage: Fixed a bug with creating methods in the wrong owners for next and hasNext. --- .../quickfix/CreateMethodFromUsageFix.java | 27 +++++++++++++------ 1 file changed, 19 insertions(+), 8 deletions(-) diff --git a/idea/src/org/jetbrains/jet/plugin/quickfix/CreateMethodFromUsageFix.java b/idea/src/org/jetbrains/jet/plugin/quickfix/CreateMethodFromUsageFix.java index b87b18f1905..9e63d56564a 100644 --- a/idea/src/org/jetbrains/jet/plugin/quickfix/CreateMethodFromUsageFix.java +++ b/idea/src/org/jetbrains/jet/plugin/quickfix/CreateMethodFromUsageFix.java @@ -153,6 +153,10 @@ public class CreateMethodFromUsageFix extends CreateFromUsageFixBase { this(expressionOfType, null, variance); } + public TypeOrExpressionThereof(@NotNull JetType type) { + this(type, Variance.IN_VARIANCE); + } + public TypeOrExpressionThereof(@NotNull JetType type, Variance variance) { this(null, type, variance); } @@ -1262,13 +1266,17 @@ public class CreateMethodFromUsageFix extends CreateFromUsageFixBase { @Nullable @Override public IntentionAction createAction(Diagnostic diagnostic) { + assert diagnostic.getFactory() == Errors.HAS_NEXT_MISSING || + diagnostic.getFactory() == Errors.HAS_NEXT_FUNCTION_NONE_APPLICABLE; + @SuppressWarnings("unchecked") + DiagnosticWithParameters1 diagnosticWithParameters = + (DiagnosticWithParameters1) diagnostic; + TypeOrExpressionThereof ownerType = new TypeOrExpressionThereof(diagnosticWithParameters.getA()); + JetForExpression forExpr = QuickFixUtil.getParentElementOfType(diagnostic, JetForExpression.class); if (forExpr == null) return null; - JetExpression iterableExpr = forExpr.getLoopRange(); - if (iterableExpr == null) return null; - TypeOrExpressionThereof iterableType = new TypeOrExpressionThereof(iterableExpr); TypeOrExpressionThereof returnType = new TypeOrExpressionThereof(KotlinBuiltIns.getInstance().getBooleanType(), Variance.OUT_VARIANCE); - return new CreateMethodFromUsageFix(forExpr, iterableType, "hasNext", returnType, new ArrayList()); + return new CreateMethodFromUsageFix(forExpr, ownerType, "hasNext", returnType, new ArrayList()); } }; } @@ -1279,15 +1287,18 @@ public class CreateMethodFromUsageFix extends CreateFromUsageFixBase { @Nullable @Override public IntentionAction createAction(Diagnostic diagnostic) { + assert diagnostic.getFactory() == Errors.NEXT_MISSING || diagnostic.getFactory() == Errors.NEXT_NONE_APPLICABLE; + @SuppressWarnings("unchecked") + DiagnosticWithParameters1 diagnosticWithParameters = + (DiagnosticWithParameters1) diagnostic; + TypeOrExpressionThereof ownerType = new TypeOrExpressionThereof(diagnosticWithParameters.getA()); + JetForExpression forExpr = QuickFixUtil.getParentElementOfType(diagnostic, JetForExpression.class); if (forExpr == null) return null; - JetExpression iterableExpr = forExpr.getLoopRange(); - if (iterableExpr == null) return null; JetExpression variableExpr = forExpr.getLoopParameter(); if (variableExpr == null) return null; - TypeOrExpressionThereof iterableType = new TypeOrExpressionThereof(iterableExpr); TypeOrExpressionThereof returnType = new TypeOrExpressionThereof(variableExpr, Variance.OUT_VARIANCE); - return new CreateMethodFromUsageFix(forExpr, iterableType, "next", returnType, new ArrayList()); + return new CreateMethodFromUsageFix(forExpr, ownerType, "next", returnType, new ArrayList()); } }; } From b7fe134b61c2d536819aa1bcc9af19a05d59a693 Mon Sep 17 00:00:00 2001 From: Jack Zhou Date: Sun, 21 Apr 2013 18:31:06 -0400 Subject: [PATCH 040/291] Create from usage: Added tests. --- .../quickfix/CreateMethodFromUsageFix.java | 2 +- .../classObject/afterCreateClassObject1.kt | 10 + .../classObject/afterCreateClassObject2.kt | 10 + .../classObject/beforeCreateClassObject1.kt | 8 + .../classObject/beforeCreateClassObject2.kt | 6 + .../afterCreateComponentFromUsage1.kt | 11 + .../afterCreateComponentFromUsage2.kt | 11 + .../beforeCreateComponentFromUsage1.kt | 8 + .../beforeCreateComponentFromUsage2.kt | 8 + .../get/afterCreateGetFromUsage1.kt | 9 + .../get/afterCreateGetFromUsage10.kt | 9 + .../get/afterCreateGetFromUsage11.kt | 9 + .../get/afterCreateGetFromUsage12.kt | 9 + .../get/afterCreateGetFromUsage13.kt | 13 ++ .../get/afterCreateGetFromUsage2.kt | 7 + .../get/afterCreateGetFromUsage3.kt | 9 + .../get/afterCreateGetFromUsage4.kt | 9 + .../get/afterCreateGetFromUsage5.kt | 9 + .../get/afterCreateGetFromUsage6.kt | 11 + .../get/afterCreateGetFromUsage7.kt | 11 + .../get/afterCreateGetFromUsage8.kt | 11 + .../get/afterCreateGetFromUsage9.kt | 11 + .../get/beforeCreateGetFromUsage1.kt | 6 + .../get/beforeCreateGetFromUsage10.kt | 6 + .../get/beforeCreateGetFromUsage11.kt | 5 + .../get/beforeCreateGetFromUsage12.kt | 5 + .../get/beforeCreateGetFromUsage13.kt | 10 + .../get/beforeCreateGetFromUsage2.kt | 4 + .../get/beforeCreateGetFromUsage3.kt | 6 + .../get/beforeCreateGetFromUsage4.kt | 6 + .../get/beforeCreateGetFromUsage5.kt | 6 + .../get/beforeCreateGetFromUsage6.kt | 6 + .../get/beforeCreateGetFromUsage7.kt | 8 + .../get/beforeCreateGetFromUsage8.kt | 8 + .../get/beforeCreateGetFromUsage9.kt | 8 + .../hasNext/afterCreateHasNextFromUsage1.kt | 17 ++ .../hasNext/afterCreateHasNextFromUsage2.kt | 17 ++ .../hasNext/beforeCreateHasNextFromUsage1.kt | 14 ++ .../hasNext/beforeCreateHasNextFromUsage2.kt | 14 ++ .../iterator/afterCreateIteratorFromUsage1.kt | 9 + .../iterator/afterCreateIteratorFromUsage2.kt | 12 + .../beforeCreateIteratorFromUsage1.kt | 5 + .../beforeCreateIteratorFromUsage2.kt | 8 + .../next/afterCreateNextFromUsage1.kt | 15 ++ .../next/afterCreateNextFromUsage2.kt | 15 ++ .../next/beforeCreateNextFromUsage1.kt | 12 + .../next/beforeCreateNextFromUsage2.kt | 12 + .../set/afterCreateSetFromUsage1.kt | 9 + .../set/afterCreateSetFromUsage2.kt | 11 + .../set/beforeCreateSetFromUsage1.kt | 6 + .../set/beforeCreateSetFromUsage2.kt | 6 + .../QuickFixMultiFileTestGenerated.java | 17 +- .../quickfix/QuickFixTestGenerated.java | 212 +++++++++++++++++- 53 files changed, 691 insertions(+), 5 deletions(-) create mode 100644 idea/testData/quickfix/createFromUsage/classObject/afterCreateClassObject1.kt create mode 100644 idea/testData/quickfix/createFromUsage/classObject/afterCreateClassObject2.kt create mode 100644 idea/testData/quickfix/createFromUsage/classObject/beforeCreateClassObject1.kt create mode 100644 idea/testData/quickfix/createFromUsage/classObject/beforeCreateClassObject2.kt create mode 100644 idea/testData/quickfix/createFromUsage/component/afterCreateComponentFromUsage1.kt create mode 100644 idea/testData/quickfix/createFromUsage/component/afterCreateComponentFromUsage2.kt create mode 100644 idea/testData/quickfix/createFromUsage/component/beforeCreateComponentFromUsage1.kt create mode 100644 idea/testData/quickfix/createFromUsage/component/beforeCreateComponentFromUsage2.kt create mode 100644 idea/testData/quickfix/createFromUsage/get/afterCreateGetFromUsage1.kt create mode 100644 idea/testData/quickfix/createFromUsage/get/afterCreateGetFromUsage10.kt create mode 100644 idea/testData/quickfix/createFromUsage/get/afterCreateGetFromUsage11.kt create mode 100644 idea/testData/quickfix/createFromUsage/get/afterCreateGetFromUsage12.kt create mode 100644 idea/testData/quickfix/createFromUsage/get/afterCreateGetFromUsage13.kt create mode 100644 idea/testData/quickfix/createFromUsage/get/afterCreateGetFromUsage2.kt create mode 100644 idea/testData/quickfix/createFromUsage/get/afterCreateGetFromUsage3.kt create mode 100644 idea/testData/quickfix/createFromUsage/get/afterCreateGetFromUsage4.kt create mode 100644 idea/testData/quickfix/createFromUsage/get/afterCreateGetFromUsage5.kt create mode 100644 idea/testData/quickfix/createFromUsage/get/afterCreateGetFromUsage6.kt create mode 100644 idea/testData/quickfix/createFromUsage/get/afterCreateGetFromUsage7.kt create mode 100644 idea/testData/quickfix/createFromUsage/get/afterCreateGetFromUsage8.kt create mode 100644 idea/testData/quickfix/createFromUsage/get/afterCreateGetFromUsage9.kt create mode 100644 idea/testData/quickfix/createFromUsage/get/beforeCreateGetFromUsage1.kt create mode 100644 idea/testData/quickfix/createFromUsage/get/beforeCreateGetFromUsage10.kt create mode 100644 idea/testData/quickfix/createFromUsage/get/beforeCreateGetFromUsage11.kt create mode 100644 idea/testData/quickfix/createFromUsage/get/beforeCreateGetFromUsage12.kt create mode 100644 idea/testData/quickfix/createFromUsage/get/beforeCreateGetFromUsage13.kt create mode 100644 idea/testData/quickfix/createFromUsage/get/beforeCreateGetFromUsage2.kt create mode 100644 idea/testData/quickfix/createFromUsage/get/beforeCreateGetFromUsage3.kt create mode 100644 idea/testData/quickfix/createFromUsage/get/beforeCreateGetFromUsage4.kt create mode 100644 idea/testData/quickfix/createFromUsage/get/beforeCreateGetFromUsage5.kt create mode 100644 idea/testData/quickfix/createFromUsage/get/beforeCreateGetFromUsage6.kt create mode 100644 idea/testData/quickfix/createFromUsage/get/beforeCreateGetFromUsage7.kt create mode 100644 idea/testData/quickfix/createFromUsage/get/beforeCreateGetFromUsage8.kt create mode 100644 idea/testData/quickfix/createFromUsage/get/beforeCreateGetFromUsage9.kt create mode 100644 idea/testData/quickfix/createFromUsage/hasNext/afterCreateHasNextFromUsage1.kt create mode 100644 idea/testData/quickfix/createFromUsage/hasNext/afterCreateHasNextFromUsage2.kt create mode 100644 idea/testData/quickfix/createFromUsage/hasNext/beforeCreateHasNextFromUsage1.kt create mode 100644 idea/testData/quickfix/createFromUsage/hasNext/beforeCreateHasNextFromUsage2.kt create mode 100644 idea/testData/quickfix/createFromUsage/iterator/afterCreateIteratorFromUsage1.kt create mode 100644 idea/testData/quickfix/createFromUsage/iterator/afterCreateIteratorFromUsage2.kt create mode 100644 idea/testData/quickfix/createFromUsage/iterator/beforeCreateIteratorFromUsage1.kt create mode 100644 idea/testData/quickfix/createFromUsage/iterator/beforeCreateIteratorFromUsage2.kt create mode 100644 idea/testData/quickfix/createFromUsage/next/afterCreateNextFromUsage1.kt create mode 100644 idea/testData/quickfix/createFromUsage/next/afterCreateNextFromUsage2.kt create mode 100644 idea/testData/quickfix/createFromUsage/next/beforeCreateNextFromUsage1.kt create mode 100644 idea/testData/quickfix/createFromUsage/next/beforeCreateNextFromUsage2.kt create mode 100644 idea/testData/quickfix/createFromUsage/set/afterCreateSetFromUsage1.kt create mode 100644 idea/testData/quickfix/createFromUsage/set/afterCreateSetFromUsage2.kt create mode 100644 idea/testData/quickfix/createFromUsage/set/beforeCreateSetFromUsage1.kt create mode 100644 idea/testData/quickfix/createFromUsage/set/beforeCreateSetFromUsage2.kt diff --git a/idea/src/org/jetbrains/jet/plugin/quickfix/CreateMethodFromUsageFix.java b/idea/src/org/jetbrains/jet/plugin/quickfix/CreateMethodFromUsageFix.java index 9e63d56564a..d4a018fcf64 100644 --- a/idea/src/org/jetbrains/jet/plugin/quickfix/CreateMethodFromUsageFix.java +++ b/idea/src/org/jetbrains/jet/plugin/quickfix/CreateMethodFromUsageFix.java @@ -563,7 +563,7 @@ public class CreateMethodFromUsageFix extends CreateFromUsageFixBase { ownerType.computeTypeCandidates(currentFileContext); TypeCandidate[] ownerTypeCandidates = ownerType.getTypeCandidates(); assert ownerTypeCandidates.length > 0; - if (ownerTypeCandidates.length == 1) { + if (ownerTypeCandidates.length == 1 || ApplicationManager.getApplication().isUnitTestMode()) { selectedReceiverType = ownerTypeCandidates[0]; doInvoke(project); } else { diff --git a/idea/testData/quickfix/createFromUsage/classObject/afterCreateClassObject1.kt b/idea/testData/quickfix/createFromUsage/classObject/afterCreateClassObject1.kt new file mode 100644 index 00000000000..046b2ea50ef --- /dev/null +++ b/idea/testData/quickfix/createFromUsage/classObject/afterCreateClassObject1.kt @@ -0,0 +1,10 @@ +// "Create class object from usage" "true" +// ERROR: Expression 'T' of type '' cannot be invoked as a function +trait T { + class object { + } + +} +fun foo() { + val x = T() +} diff --git a/idea/testData/quickfix/createFromUsage/classObject/afterCreateClassObject2.kt b/idea/testData/quickfix/createFromUsage/classObject/afterCreateClassObject2.kt new file mode 100644 index 00000000000..e43a2d55083 --- /dev/null +++ b/idea/testData/quickfix/createFromUsage/classObject/afterCreateClassObject2.kt @@ -0,0 +1,10 @@ +// "Create class object from usage" "true" +// ERROR: Expression 'T' of type '' cannot be invoked as a function +trait T +{ + class object { + } +} +fun foo() { + val x = T() +} diff --git a/idea/testData/quickfix/createFromUsage/classObject/beforeCreateClassObject1.kt b/idea/testData/quickfix/createFromUsage/classObject/beforeCreateClassObject1.kt new file mode 100644 index 00000000000..146b39ce721 --- /dev/null +++ b/idea/testData/quickfix/createFromUsage/classObject/beforeCreateClassObject1.kt @@ -0,0 +1,8 @@ +// "Create class object from usage" "true" +// ERROR: Expression 'T' of type '' cannot be invoked as a function +trait T { + +} +fun foo() { + val x = T() +} diff --git a/idea/testData/quickfix/createFromUsage/classObject/beforeCreateClassObject2.kt b/idea/testData/quickfix/createFromUsage/classObject/beforeCreateClassObject2.kt new file mode 100644 index 00000000000..48024776e0e --- /dev/null +++ b/idea/testData/quickfix/createFromUsage/classObject/beforeCreateClassObject2.kt @@ -0,0 +1,6 @@ +// "Create class object from usage" "true" +// ERROR: Expression 'T' of type '' cannot be invoked as a function +trait T +fun foo() { + val x = T() +} diff --git a/idea/testData/quickfix/createFromUsage/component/afterCreateComponentFromUsage1.kt b/idea/testData/quickfix/createFromUsage/component/afterCreateComponentFromUsage1.kt new file mode 100644 index 00000000000..4a730095803 --- /dev/null +++ b/idea/testData/quickfix/createFromUsage/component/afterCreateComponentFromUsage1.kt @@ -0,0 +1,11 @@ +// "Create method 'component3' from usage" "true" +class Foo { + fun component1(): Int { return 0 } + fun component2(): Int { return 0 } + fun component3(): Any { + throw Exception("not implemented") //To change body of created methods use File | Settings | File Templates. + } +} +fun foo() { + val (a, b, c) = Foo() +} diff --git a/idea/testData/quickfix/createFromUsage/component/afterCreateComponentFromUsage2.kt b/idea/testData/quickfix/createFromUsage/component/afterCreateComponentFromUsage2.kt new file mode 100644 index 00000000000..4e30704925d --- /dev/null +++ b/idea/testData/quickfix/createFromUsage/component/afterCreateComponentFromUsage2.kt @@ -0,0 +1,11 @@ +// "Create method 'component3' from usage" "true" +class Foo { + fun component1(): Int { return 0 } + fun component2(): Int { return 0 } + fun component3(): String { + throw Exception("not implemented") //To change body of created methods use File | Settings | File Templates. + } +} +fun foo() { + val (a, b, c: String) = Foo() +} diff --git a/idea/testData/quickfix/createFromUsage/component/beforeCreateComponentFromUsage1.kt b/idea/testData/quickfix/createFromUsage/component/beforeCreateComponentFromUsage1.kt new file mode 100644 index 00000000000..8d1bf4515a7 --- /dev/null +++ b/idea/testData/quickfix/createFromUsage/component/beforeCreateComponentFromUsage1.kt @@ -0,0 +1,8 @@ +// "Create method 'component3' from usage" "true" +class Foo { + fun component1(): Int { return 0 } + fun component2(): Int { return 0 } +} +fun foo() { + val (a, b, c) = Foo() +} diff --git a/idea/testData/quickfix/createFromUsage/component/beforeCreateComponentFromUsage2.kt b/idea/testData/quickfix/createFromUsage/component/beforeCreateComponentFromUsage2.kt new file mode 100644 index 00000000000..5ec47c32c3b --- /dev/null +++ b/idea/testData/quickfix/createFromUsage/component/beforeCreateComponentFromUsage2.kt @@ -0,0 +1,8 @@ +// "Create method 'component3' from usage" "true" +class Foo { + fun component1(): Int { return 0 } + fun component2(): Int { return 0 } +} +fun foo() { + val (a, b, c: String) = Foo() +} diff --git a/idea/testData/quickfix/createFromUsage/get/afterCreateGetFromUsage1.kt b/idea/testData/quickfix/createFromUsage/get/afterCreateGetFromUsage1.kt new file mode 100644 index 00000000000..8cf409481af --- /dev/null +++ b/idea/testData/quickfix/createFromUsage/get/afterCreateGetFromUsage1.kt @@ -0,0 +1,9 @@ +// "Create method 'get' from usage" "true" +class Foo { + fun x (y: Foo>) { + val z: Iterable = y[""] + } + fun get(s: String): T { + throw Exception("not implemented") //To change body of created methods use File | Settings | File Templates. + } +} diff --git a/idea/testData/quickfix/createFromUsage/get/afterCreateGetFromUsage10.kt b/idea/testData/quickfix/createFromUsage/get/afterCreateGetFromUsage10.kt new file mode 100644 index 00000000000..f16da937ee3 --- /dev/null +++ b/idea/testData/quickfix/createFromUsage/get/afterCreateGetFromUsage10.kt @@ -0,0 +1,9 @@ +// "Create method 'get' from usage" "true" +class Foo { + fun x (y: Foo>, w: java.util.ArrayList) { + val z: Iterable = y["", w] + } + fun get(s: String, w: T): T { + throw Exception("not implemented") //To change body of created methods use File | Settings | File Templates. + } +} diff --git a/idea/testData/quickfix/createFromUsage/get/afterCreateGetFromUsage11.kt b/idea/testData/quickfix/createFromUsage/get/afterCreateGetFromUsage11.kt new file mode 100644 index 00000000000..8686065e93f --- /dev/null +++ b/idea/testData/quickfix/createFromUsage/get/afterCreateGetFromUsage11.kt @@ -0,0 +1,9 @@ +// "Create method 'get' from usage" "true" +class Foo { + fun get(s: String, w: T): T { + throw Exception("not implemented") //To change body of created methods use File | Settings | File Templates. + } +} +fun x (y: Foo>, w: java.util.ArrayList) { + val z: Iterable = y["", w] +} diff --git a/idea/testData/quickfix/createFromUsage/get/afterCreateGetFromUsage12.kt b/idea/testData/quickfix/createFromUsage/get/afterCreateGetFromUsage12.kt new file mode 100644 index 00000000000..d3d25c27abc --- /dev/null +++ b/idea/testData/quickfix/createFromUsage/get/afterCreateGetFromUsage12.kt @@ -0,0 +1,9 @@ +// "Create method 'get' from usage" "true" +class Foo { + fun get(s: String, w: T): Any { + throw Exception("not implemented") //To change body of created methods use File | Settings | File Templates. + } +} +fun x (y: Foo>, w: java.util.ArrayList) { + val z = y["", w] +} diff --git a/idea/testData/quickfix/createFromUsage/get/afterCreateGetFromUsage13.kt b/idea/testData/quickfix/createFromUsage/get/afterCreateGetFromUsage13.kt new file mode 100644 index 00000000000..f23bb7f2fd2 --- /dev/null +++ b/idea/testData/quickfix/createFromUsage/get/afterCreateGetFromUsage13.kt @@ -0,0 +1,13 @@ +// "Create method 'get' from usage" "true" +import java.util.ArrayList + +class Foo { + fun bar(arg: String) { } + fun x (y: Foo>, w: ArrayList) { + val z = y["", w] + bar(z) + } + fun get(s: String, w: ArrayList): String { + throw Exception("not implemented") //To change body of created methods use File | Settings | File Templates. + } +} diff --git a/idea/testData/quickfix/createFromUsage/get/afterCreateGetFromUsage2.kt b/idea/testData/quickfix/createFromUsage/get/afterCreateGetFromUsage2.kt new file mode 100644 index 00000000000..dffa092c6ed --- /dev/null +++ b/idea/testData/quickfix/createFromUsage/get/afterCreateGetFromUsage2.kt @@ -0,0 +1,7 @@ +// "Create method 'get' from usage" "true" +fun x (y: Any) { + val z: Any = y[""] +} +fun Any.get(s: String): Any { + throw Exception("not implemented") //To change body of created methods use File | Settings | File Templates. +} \ No newline at end of file diff --git a/idea/testData/quickfix/createFromUsage/get/afterCreateGetFromUsage3.kt b/idea/testData/quickfix/createFromUsage/get/afterCreateGetFromUsage3.kt new file mode 100644 index 00000000000..04315facefd --- /dev/null +++ b/idea/testData/quickfix/createFromUsage/get/afterCreateGetFromUsage3.kt @@ -0,0 +1,9 @@ +// "Create method 'get' from usage" "true" +class Foo { + fun x (y: Foo>) { + val z: Iterable = y[""] + } + fun get(s: String): T { + throw Exception("not implemented") //To change body of created methods use File | Settings | File Templates. + } +} diff --git a/idea/testData/quickfix/createFromUsage/get/afterCreateGetFromUsage4.kt b/idea/testData/quickfix/createFromUsage/get/afterCreateGetFromUsage4.kt new file mode 100644 index 00000000000..a95fd697bc5 --- /dev/null +++ b/idea/testData/quickfix/createFromUsage/get/afterCreateGetFromUsage4.kt @@ -0,0 +1,9 @@ +// "Create method 'get' from usage" "true" +class Foo> { + fun x (y: Foo>) { + val z: U = y[""] + } + fun get(s: String): T { + throw Exception("not implemented") //To change body of created methods use File | Settings | File Templates. + } +} diff --git a/idea/testData/quickfix/createFromUsage/get/afterCreateGetFromUsage5.kt b/idea/testData/quickfix/createFromUsage/get/afterCreateGetFromUsage5.kt new file mode 100644 index 00000000000..09289a73dc1 --- /dev/null +++ b/idea/testData/quickfix/createFromUsage/get/afterCreateGetFromUsage5.kt @@ -0,0 +1,9 @@ +// "Create method 'get' from usage" "true" +class Foo { + fun x (y: Foo>, w: Iterable) { + val z: Iterable = y["", w] + } + fun get(s: String, w: Iterable): T { + throw Exception("not implemented") //To change body of created methods use File | Settings | File Templates. + } +} diff --git a/idea/testData/quickfix/createFromUsage/get/afterCreateGetFromUsage6.kt b/idea/testData/quickfix/createFromUsage/get/afterCreateGetFromUsage6.kt new file mode 100644 index 00000000000..dc50306d47b --- /dev/null +++ b/idea/testData/quickfix/createFromUsage/get/afterCreateGetFromUsage6.kt @@ -0,0 +1,11 @@ +// "Create method 'get' from usage" "true" +import java.util.ArrayList + +class Foo { + fun x (y: java.util.ArrayList, w: java.util.ArrayList) { + val z: java.util.ArrayList? = if (y["", w]) null else null + } +} +fun ArrayList.get(s: String, w: ArrayList): Boolean { + throw Exception("not implemented") //To change body of created methods use File | Settings | File Templates. +} \ No newline at end of file diff --git a/idea/testData/quickfix/createFromUsage/get/afterCreateGetFromUsage7.kt b/idea/testData/quickfix/createFromUsage/get/afterCreateGetFromUsage7.kt new file mode 100644 index 00000000000..b32be62c6c1 --- /dev/null +++ b/idea/testData/quickfix/createFromUsage/get/afterCreateGetFromUsage7.kt @@ -0,0 +1,11 @@ +// "Create method 'get' from usage" "true" +import java.util.ArrayList + +class Foo { + fun x (y: Foo>, w: ArrayList) { + val z: Iterable = y["", w] + } + fun get(s: String, w: ArrayList): T { + throw Exception("not implemented") //To change body of created methods use File | Settings | File Templates. + } +} diff --git a/idea/testData/quickfix/createFromUsage/get/afterCreateGetFromUsage8.kt b/idea/testData/quickfix/createFromUsage/get/afterCreateGetFromUsage8.kt new file mode 100644 index 00000000000..caa960c3eae --- /dev/null +++ b/idea/testData/quickfix/createFromUsage/get/afterCreateGetFromUsage8.kt @@ -0,0 +1,11 @@ +// "Create method 'get' from usage" "true" +import java.util.ArrayList + +class Foo { + fun x (y: Foo>, w: ArrayList) { + val z: Iterable = y["", w] + } + fun get(s: String, w: T): T { + throw Exception("not implemented") //To change body of created methods use File | Settings | File Templates. + } +} diff --git a/idea/testData/quickfix/createFromUsage/get/afterCreateGetFromUsage9.kt b/idea/testData/quickfix/createFromUsage/get/afterCreateGetFromUsage9.kt new file mode 100644 index 00000000000..8cf0aea7d04 --- /dev/null +++ b/idea/testData/quickfix/createFromUsage/get/afterCreateGetFromUsage9.kt @@ -0,0 +1,11 @@ +// "Create method 'get' from usage" "true" +import java.util.ArrayList + +class Foo { + fun x (y: Foo>, w: ArrayList) { + val z: Iterable = y["", w] + } + fun get(s: String, w: S): S { + throw Exception("not implemented") //To change body of created methods use File | Settings | File Templates. + } +} diff --git a/idea/testData/quickfix/createFromUsage/get/beforeCreateGetFromUsage1.kt b/idea/testData/quickfix/createFromUsage/get/beforeCreateGetFromUsage1.kt new file mode 100644 index 00000000000..1f3f356d134 --- /dev/null +++ b/idea/testData/quickfix/createFromUsage/get/beforeCreateGetFromUsage1.kt @@ -0,0 +1,6 @@ +// "Create method 'get' from usage" "true" +class Foo { + fun x (y: Foo>) { + val z: Iterable = y[""] + } +} diff --git a/idea/testData/quickfix/createFromUsage/get/beforeCreateGetFromUsage10.kt b/idea/testData/quickfix/createFromUsage/get/beforeCreateGetFromUsage10.kt new file mode 100644 index 00000000000..dfe91efecb6 --- /dev/null +++ b/idea/testData/quickfix/createFromUsage/get/beforeCreateGetFromUsage10.kt @@ -0,0 +1,6 @@ +// "Create method 'get' from usage" "true" +class Foo { + fun x (y: Foo>, w: java.util.ArrayList) { + val z: Iterable = y["", w] + } +} diff --git a/idea/testData/quickfix/createFromUsage/get/beforeCreateGetFromUsage11.kt b/idea/testData/quickfix/createFromUsage/get/beforeCreateGetFromUsage11.kt new file mode 100644 index 00000000000..1962cc4865a --- /dev/null +++ b/idea/testData/quickfix/createFromUsage/get/beforeCreateGetFromUsage11.kt @@ -0,0 +1,5 @@ +// "Create method 'get' from usage" "true" +class Foo +fun x (y: Foo>, w: java.util.ArrayList) { + val z: Iterable = y["", w] +} diff --git a/idea/testData/quickfix/createFromUsage/get/beforeCreateGetFromUsage12.kt b/idea/testData/quickfix/createFromUsage/get/beforeCreateGetFromUsage12.kt new file mode 100644 index 00000000000..9a13b753aca --- /dev/null +++ b/idea/testData/quickfix/createFromUsage/get/beforeCreateGetFromUsage12.kt @@ -0,0 +1,5 @@ +// "Create method 'get' from usage" "true" +class Foo +fun x (y: Foo>, w: java.util.ArrayList) { + val z = y["", w] +} diff --git a/idea/testData/quickfix/createFromUsage/get/beforeCreateGetFromUsage13.kt b/idea/testData/quickfix/createFromUsage/get/beforeCreateGetFromUsage13.kt new file mode 100644 index 00000000000..9986981854f --- /dev/null +++ b/idea/testData/quickfix/createFromUsage/get/beforeCreateGetFromUsage13.kt @@ -0,0 +1,10 @@ +// "Create method 'get' from usage" "true" +import java.util.ArrayList + +class Foo { + fun bar(arg: String) { } + fun x (y: Foo>, w: ArrayList) { + val z = y["", w] + bar(z) + } +} diff --git a/idea/testData/quickfix/createFromUsage/get/beforeCreateGetFromUsage2.kt b/idea/testData/quickfix/createFromUsage/get/beforeCreateGetFromUsage2.kt new file mode 100644 index 00000000000..9d2682fbcc1 --- /dev/null +++ b/idea/testData/quickfix/createFromUsage/get/beforeCreateGetFromUsage2.kt @@ -0,0 +1,4 @@ +// "Create method 'get' from usage" "true" +fun x (y: Any) { + val z: Any = y[""] +} diff --git a/idea/testData/quickfix/createFromUsage/get/beforeCreateGetFromUsage3.kt b/idea/testData/quickfix/createFromUsage/get/beforeCreateGetFromUsage3.kt new file mode 100644 index 00000000000..044c3f30c02 --- /dev/null +++ b/idea/testData/quickfix/createFromUsage/get/beforeCreateGetFromUsage3.kt @@ -0,0 +1,6 @@ +// "Create method 'get' from usage" "true" +class Foo { + fun x (y: Foo>) { + val z: Iterable = y[""] + } +} diff --git a/idea/testData/quickfix/createFromUsage/get/beforeCreateGetFromUsage4.kt b/idea/testData/quickfix/createFromUsage/get/beforeCreateGetFromUsage4.kt new file mode 100644 index 00000000000..06e54a609fb --- /dev/null +++ b/idea/testData/quickfix/createFromUsage/get/beforeCreateGetFromUsage4.kt @@ -0,0 +1,6 @@ +// "Create method 'get' from usage" "true" +class Foo> { + fun x (y: Foo>) { + val z: U = y[""] + } +} diff --git a/idea/testData/quickfix/createFromUsage/get/beforeCreateGetFromUsage5.kt b/idea/testData/quickfix/createFromUsage/get/beforeCreateGetFromUsage5.kt new file mode 100644 index 00000000000..606253ab6dd --- /dev/null +++ b/idea/testData/quickfix/createFromUsage/get/beforeCreateGetFromUsage5.kt @@ -0,0 +1,6 @@ +// "Create method 'get' from usage" "true" +class Foo { + fun x (y: Foo>, w: Iterable) { + val z: Iterable = y["", w] + } +} diff --git a/idea/testData/quickfix/createFromUsage/get/beforeCreateGetFromUsage6.kt b/idea/testData/quickfix/createFromUsage/get/beforeCreateGetFromUsage6.kt new file mode 100644 index 00000000000..6df19aaf1fb --- /dev/null +++ b/idea/testData/quickfix/createFromUsage/get/beforeCreateGetFromUsage6.kt @@ -0,0 +1,6 @@ +// "Create method 'get' from usage" "true" +class Foo { + fun x (y: java.util.ArrayList, w: java.util.ArrayList) { + val z: java.util.ArrayList? = if (y["", w]) null else null + } +} diff --git a/idea/testData/quickfix/createFromUsage/get/beforeCreateGetFromUsage7.kt b/idea/testData/quickfix/createFromUsage/get/beforeCreateGetFromUsage7.kt new file mode 100644 index 00000000000..585766c4eeb --- /dev/null +++ b/idea/testData/quickfix/createFromUsage/get/beforeCreateGetFromUsage7.kt @@ -0,0 +1,8 @@ +// "Create method 'get' from usage" "true" +import java.util.ArrayList + +class Foo { + fun x (y: Foo>, w: ArrayList) { + val z: Iterable = y["", w] + } +} diff --git a/idea/testData/quickfix/createFromUsage/get/beforeCreateGetFromUsage8.kt b/idea/testData/quickfix/createFromUsage/get/beforeCreateGetFromUsage8.kt new file mode 100644 index 00000000000..7daa508dd1d --- /dev/null +++ b/idea/testData/quickfix/createFromUsage/get/beforeCreateGetFromUsage8.kt @@ -0,0 +1,8 @@ +// "Create method 'get' from usage" "true" +import java.util.ArrayList + +class Foo { + fun x (y: Foo>, w: ArrayList) { + val z: Iterable = y["", w] + } +} diff --git a/idea/testData/quickfix/createFromUsage/get/beforeCreateGetFromUsage9.kt b/idea/testData/quickfix/createFromUsage/get/beforeCreateGetFromUsage9.kt new file mode 100644 index 00000000000..e6fb8ae0da4 --- /dev/null +++ b/idea/testData/quickfix/createFromUsage/get/beforeCreateGetFromUsage9.kt @@ -0,0 +1,8 @@ +// "Create method 'get' from usage" "true" +import java.util.ArrayList + +class Foo { + fun x (y: Foo>, w: ArrayList) { + val z: Iterable = y["", w] + } +} diff --git a/idea/testData/quickfix/createFromUsage/hasNext/afterCreateHasNextFromUsage1.kt b/idea/testData/quickfix/createFromUsage/hasNext/afterCreateHasNextFromUsage1.kt new file mode 100644 index 00000000000..32d44370b25 --- /dev/null +++ b/idea/testData/quickfix/createFromUsage/hasNext/afterCreateHasNextFromUsage1.kt @@ -0,0 +1,17 @@ +// "Create method 'hasNext' from usage" "true" +class FooIterator { + fun next(): Int { + throw Exception("not implemented") + } + fun hasNext(): Boolean { + throw Exception("not implemented") //To change body of created methods use File | Settings | File Templates. + } +} +class Foo { + fun iterator(): FooIterator { + throw Exception("not implemented") + } +} +fun foo() { + for (i: Int in Foo()) { } +} diff --git a/idea/testData/quickfix/createFromUsage/hasNext/afterCreateHasNextFromUsage2.kt b/idea/testData/quickfix/createFromUsage/hasNext/afterCreateHasNextFromUsage2.kt new file mode 100644 index 00000000000..4a6fc9ef0d5 --- /dev/null +++ b/idea/testData/quickfix/createFromUsage/hasNext/afterCreateHasNextFromUsage2.kt @@ -0,0 +1,17 @@ +// "Create method 'hasNext' from usage" "true" +class FooIterator { + fun next(): T { + throw Exception("not implemented") + } + fun hasNext(): Boolean { + throw Exception("not implemented") //To change body of created methods use File | Settings | File Templates. + } +} +class Foo { + fun iterator(): FooIterator { + throw Exception("not implemented") + } +} +fun foo() { + for (i in Foo()) { } +} diff --git a/idea/testData/quickfix/createFromUsage/hasNext/beforeCreateHasNextFromUsage1.kt b/idea/testData/quickfix/createFromUsage/hasNext/beforeCreateHasNextFromUsage1.kt new file mode 100644 index 00000000000..33e316a58dc --- /dev/null +++ b/idea/testData/quickfix/createFromUsage/hasNext/beforeCreateHasNextFromUsage1.kt @@ -0,0 +1,14 @@ +// "Create method 'hasNext' from usage" "true" +class FooIterator { + fun next(): Int { + throw Exception("not implemented") + } +} +class Foo { + fun iterator(): FooIterator { + throw Exception("not implemented") + } +} +fun foo() { + for (i: Int in Foo()) { } +} diff --git a/idea/testData/quickfix/createFromUsage/hasNext/beforeCreateHasNextFromUsage2.kt b/idea/testData/quickfix/createFromUsage/hasNext/beforeCreateHasNextFromUsage2.kt new file mode 100644 index 00000000000..e51b24ecefc --- /dev/null +++ b/idea/testData/quickfix/createFromUsage/hasNext/beforeCreateHasNextFromUsage2.kt @@ -0,0 +1,14 @@ +// "Create method 'hasNext' from usage" "true" +class FooIterator { + fun next(): T { + throw Exception("not implemented") + } +} +class Foo { + fun iterator(): FooIterator { + throw Exception("not implemented") + } +} +fun foo() { + for (i in Foo()) { } +} diff --git a/idea/testData/quickfix/createFromUsage/iterator/afterCreateIteratorFromUsage1.kt b/idea/testData/quickfix/createFromUsage/iterator/afterCreateIteratorFromUsage1.kt new file mode 100644 index 00000000000..a405af8df81 --- /dev/null +++ b/idea/testData/quickfix/createFromUsage/iterator/afterCreateIteratorFromUsage1.kt @@ -0,0 +1,9 @@ +// "Create method 'iterator' from usage" "true" +class Foo { + fun iterator(): Iterator { + throw Exception("not implemented") //To change body of created methods use File | Settings | File Templates. + } +} +fun foo() { + for (i: Int in Foo()) { } +} diff --git a/idea/testData/quickfix/createFromUsage/iterator/afterCreateIteratorFromUsage2.kt b/idea/testData/quickfix/createFromUsage/iterator/afterCreateIteratorFromUsage2.kt new file mode 100644 index 00000000000..a5d765d5791 --- /dev/null +++ b/idea/testData/quickfix/createFromUsage/iterator/afterCreateIteratorFromUsage2.kt @@ -0,0 +1,12 @@ +// "Create method 'iterator' from usage" "true" +class Foo { + fun iterator(): Iterator { + throw Exception("not implemented") //To change body of created methods use File | Settings | File Templates. + } +} +fun foo() { + for (i in Foo()) { + bar(i) + } +} +fun bar(i: String) { } diff --git a/idea/testData/quickfix/createFromUsage/iterator/beforeCreateIteratorFromUsage1.kt b/idea/testData/quickfix/createFromUsage/iterator/beforeCreateIteratorFromUsage1.kt new file mode 100644 index 00000000000..e369b20bfd1 --- /dev/null +++ b/idea/testData/quickfix/createFromUsage/iterator/beforeCreateIteratorFromUsage1.kt @@ -0,0 +1,5 @@ +// "Create method 'iterator' from usage" "true" +class Foo +fun foo() { + for (i: Int in Foo()) { } +} diff --git a/idea/testData/quickfix/createFromUsage/iterator/beforeCreateIteratorFromUsage2.kt b/idea/testData/quickfix/createFromUsage/iterator/beforeCreateIteratorFromUsage2.kt new file mode 100644 index 00000000000..dfbec160ce3 --- /dev/null +++ b/idea/testData/quickfix/createFromUsage/iterator/beforeCreateIteratorFromUsage2.kt @@ -0,0 +1,8 @@ +// "Create method 'iterator' from usage" "true" +class Foo +fun foo() { + for (i in Foo()) { + bar(i) + } +} +fun bar(i: String) { } diff --git a/idea/testData/quickfix/createFromUsage/next/afterCreateNextFromUsage1.kt b/idea/testData/quickfix/createFromUsage/next/afterCreateNextFromUsage1.kt new file mode 100644 index 00000000000..91cd86a1e88 --- /dev/null +++ b/idea/testData/quickfix/createFromUsage/next/afterCreateNextFromUsage1.kt @@ -0,0 +1,15 @@ +// "Create method 'next' from usage" "true" +class FooIterator { + fun hasNext(): Boolean { return false } + fun next(): Int { + throw Exception("not implemented") //To change body of created methods use File | Settings | File Templates. + } +} +class Foo { + fun iterator(): FooIterator { + throw Exception("not implemented") + } +} +fun foo() { + for (i: Int in Foo()) { } +} diff --git a/idea/testData/quickfix/createFromUsage/next/afterCreateNextFromUsage2.kt b/idea/testData/quickfix/createFromUsage/next/afterCreateNextFromUsage2.kt new file mode 100644 index 00000000000..f16aa88f96d --- /dev/null +++ b/idea/testData/quickfix/createFromUsage/next/afterCreateNextFromUsage2.kt @@ -0,0 +1,15 @@ +// "Create method 'next' from usage" "true" +class FooIterator { + fun hasNext(): Boolean { return false } + fun next(): T { + throw Exception("not implemented") //To change body of created methods use File | Settings | File Templates. + } +} +class Foo { + fun iterator(): FooIterator { + throw Exception("not implemented") + } +} +fun foo() { + for (i: Int in Foo()) { } +} diff --git a/idea/testData/quickfix/createFromUsage/next/beforeCreateNextFromUsage1.kt b/idea/testData/quickfix/createFromUsage/next/beforeCreateNextFromUsage1.kt new file mode 100644 index 00000000000..c4b57554e31 --- /dev/null +++ b/idea/testData/quickfix/createFromUsage/next/beforeCreateNextFromUsage1.kt @@ -0,0 +1,12 @@ +// "Create method 'next' from usage" "true" +class FooIterator { + fun hasNext(): Boolean { return false } +} +class Foo { + fun iterator(): FooIterator { + throw Exception("not implemented") + } +} +fun foo() { + for (i: Int in Foo()) { } +} diff --git a/idea/testData/quickfix/createFromUsage/next/beforeCreateNextFromUsage2.kt b/idea/testData/quickfix/createFromUsage/next/beforeCreateNextFromUsage2.kt new file mode 100644 index 00000000000..401cdf419c5 --- /dev/null +++ b/idea/testData/quickfix/createFromUsage/next/beforeCreateNextFromUsage2.kt @@ -0,0 +1,12 @@ +// "Create method 'next' from usage" "true" +class FooIterator { + fun hasNext(): Boolean { return false } +} +class Foo { + fun iterator(): FooIterator { + throw Exception("not implemented") + } +} +fun foo() { + for (i: Int in Foo()) { } +} diff --git a/idea/testData/quickfix/createFromUsage/set/afterCreateSetFromUsage1.kt b/idea/testData/quickfix/createFromUsage/set/afterCreateSetFromUsage1.kt new file mode 100644 index 00000000000..234cb8f6c77 --- /dev/null +++ b/idea/testData/quickfix/createFromUsage/set/afterCreateSetFromUsage1.kt @@ -0,0 +1,9 @@ +// "Create method 'set' from usage" "true" +class Foo { + fun x (y: Foo>, w: java.util.ArrayList) { + y["", w] = w + } + fun set(s: String, w: T, value: T) { + throw Exception("not implemented") //To change body of created methods use File | Settings | File Templates. + } +} diff --git a/idea/testData/quickfix/createFromUsage/set/afterCreateSetFromUsage2.kt b/idea/testData/quickfix/createFromUsage/set/afterCreateSetFromUsage2.kt new file mode 100644 index 00000000000..1fe75ddfe34 --- /dev/null +++ b/idea/testData/quickfix/createFromUsage/set/afterCreateSetFromUsage2.kt @@ -0,0 +1,11 @@ +// "Create method 'set' from usage" "true" +import java.util.ArrayList + +class Foo { + fun x (y: Any, w: java.util.ArrayList) { + y["", w] = w + } +} +fun Any.set(s: String, w: ArrayList, value: ArrayList) { + throw Exception("not implemented") //To change body of created methods use File | Settings | File Templates. +} \ No newline at end of file diff --git a/idea/testData/quickfix/createFromUsage/set/beforeCreateSetFromUsage1.kt b/idea/testData/quickfix/createFromUsage/set/beforeCreateSetFromUsage1.kt new file mode 100644 index 00000000000..1cb5ce5e854 --- /dev/null +++ b/idea/testData/quickfix/createFromUsage/set/beforeCreateSetFromUsage1.kt @@ -0,0 +1,6 @@ +// "Create method 'set' from usage" "true" +class Foo { + fun x (y: Foo>, w: java.util.ArrayList) { + y["", w] = w + } +} diff --git a/idea/testData/quickfix/createFromUsage/set/beforeCreateSetFromUsage2.kt b/idea/testData/quickfix/createFromUsage/set/beforeCreateSetFromUsage2.kt new file mode 100644 index 00000000000..528ebc67bb2 --- /dev/null +++ b/idea/testData/quickfix/createFromUsage/set/beforeCreateSetFromUsage2.kt @@ -0,0 +1,6 @@ +// "Create method 'set' from usage" "true" +class Foo { + fun x (y: Any, w: java.util.ArrayList) { + y["", w] = w + } +} diff --git a/idea/tests/org/jetbrains/jet/plugin/quickfix/QuickFixMultiFileTestGenerated.java b/idea/tests/org/jetbrains/jet/plugin/quickfix/QuickFixMultiFileTestGenerated.java index 42777588b35..b585c4a7827 100644 --- a/idea/tests/org/jetbrains/jet/plugin/quickfix/QuickFixMultiFileTestGenerated.java +++ b/idea/tests/org/jetbrains/jet/plugin/quickfix/QuickFixMultiFileTestGenerated.java @@ -31,7 +31,7 @@ import org.jetbrains.jet.plugin.quickfix.AbstractQuickFixMultiFileTest; /** This class is generated by {@link org.jetbrains.jet.generators.tests.GenerateTests}. DO NOT MODIFY MANUALLY */ @SuppressWarnings("all") @TestMetadata("idea/testData/quickfix") -@InnerTestClasses({QuickFixMultiFileTestGenerated.AddStarProjections.class, QuickFixMultiFileTestGenerated.AutoImports.class, QuickFixMultiFileTestGenerated.Modifiers.class, QuickFixMultiFileTestGenerated.Nullables.class, QuickFixMultiFileTestGenerated.Override.class, QuickFixMultiFileTestGenerated.TypeImports.class, QuickFixMultiFileTestGenerated.TypeMismatch.class, QuickFixMultiFileTestGenerated.Variables.class}) +@InnerTestClasses({QuickFixMultiFileTestGenerated.AddStarProjections.class, QuickFixMultiFileTestGenerated.AutoImports.class, QuickFixMultiFileTestGenerated.CreateFromUsage.class, QuickFixMultiFileTestGenerated.Modifiers.class, QuickFixMultiFileTestGenerated.Nullables.class, QuickFixMultiFileTestGenerated.Override.class, QuickFixMultiFileTestGenerated.TypeImports.class, QuickFixMultiFileTestGenerated.TypeMismatch.class, QuickFixMultiFileTestGenerated.Variables.class}) public class QuickFixMultiFileTestGenerated extends AbstractQuickFixMultiFileTest { public void testAllFilesPresentInQuickfix() throws Exception { JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.GenerateTests", new File("idea/testData/quickfix"), Pattern.compile("^(\\w+)\\.before\\.Main\\.kt$"), true); @@ -129,6 +129,20 @@ public class QuickFixMultiFileTestGenerated extends AbstractQuickFixMultiFileTes } + @TestMetadata("idea/testData/quickfix/createFromUsage") + @InnerTestClasses({}) + public static class CreateFromUsage extends AbstractQuickFixMultiFileTest { + public void testAllFilesPresentInCreateFromUsage() throws Exception { + JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.GenerateTests", new File("idea/testData/quickfix/createFromUsage"), Pattern.compile("^(\\w+)\\.before\\.Main\\.kt$"), true); + } + + public static Test innerSuite() { + TestSuite suite = new TestSuite("CreateFromUsage"); + suite.addTestSuite(CreateFromUsage.class); + return suite; + } + } + @TestMetadata("idea/testData/quickfix/modifiers") @InnerTestClasses({Modifiers.AddOpenToClassDeclaration.class}) public static class Modifiers extends AbstractQuickFixMultiFileTest { @@ -281,6 +295,7 @@ public class QuickFixMultiFileTestGenerated extends AbstractQuickFixMultiFileTes suite.addTestSuite(QuickFixMultiFileTestGenerated.class); suite.addTest(AddStarProjections.innerSuite()); suite.addTestSuite(AutoImports.class); + suite.addTest(CreateFromUsage.innerSuite()); suite.addTest(Modifiers.innerSuite()); suite.addTest(Nullables.innerSuite()); suite.addTest(Override.innerSuite()); diff --git a/idea/tests/org/jetbrains/jet/plugin/quickfix/QuickFixTestGenerated.java b/idea/tests/org/jetbrains/jet/plugin/quickfix/QuickFixTestGenerated.java index 9697cd550b8..02da71be244 100644 --- a/idea/tests/org/jetbrains/jet/plugin/quickfix/QuickFixTestGenerated.java +++ b/idea/tests/org/jetbrains/jet/plugin/quickfix/QuickFixTestGenerated.java @@ -16,19 +16,22 @@ 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") @TestMetadata("idea/testData/quickfix") -@InnerTestClasses({QuickFixTestGenerated.Abstract.class, QuickFixTestGenerated.AddStarProjections.class, QuickFixTestGenerated.AutoImports.class, QuickFixTestGenerated.ChangeSignature.class, QuickFixTestGenerated.CheckArguments.class, QuickFixTestGenerated.Expressions.class, QuickFixTestGenerated.Migration.class, QuickFixTestGenerated.Modifiers.class, QuickFixTestGenerated.Nullables.class, QuickFixTestGenerated.Override.class, QuickFixTestGenerated.PlatformClasses.class, QuickFixTestGenerated.Supercalls.class, QuickFixTestGenerated.SupertypeInitialization.class, QuickFixTestGenerated.TypeAddition.class, QuickFixTestGenerated.TypeImports.class, QuickFixTestGenerated.TypeMismatch.class, QuickFixTestGenerated.TypeProjection.class, QuickFixTestGenerated.UselessImports.class, QuickFixTestGenerated.Variables.class, QuickFixTestGenerated.When.class}) +@InnerTestClasses({QuickFixTestGenerated.Abstract.class, QuickFixTestGenerated.AddStarProjections.class, QuickFixTestGenerated.AutoImports.class, QuickFixTestGenerated.ChangeSignature.class, QuickFixTestGenerated.CheckArguments.class, QuickFixTestGenerated.CreateFromUsage.class, QuickFixTestGenerated.Expressions.class, QuickFixTestGenerated.Migration.class, QuickFixTestGenerated.Modifiers.class, QuickFixTestGenerated.Nullables.class, QuickFixTestGenerated.Override.class, QuickFixTestGenerated.PlatformClasses.class, QuickFixTestGenerated.Supercalls.class, QuickFixTestGenerated.SupertypeInitialization.class, QuickFixTestGenerated.TypeAddition.class, QuickFixTestGenerated.TypeImports.class, QuickFixTestGenerated.TypeMismatch.class, QuickFixTestGenerated.TypeProjection.class, QuickFixTestGenerated.UselessImports.class, QuickFixTestGenerated.Variables.class, QuickFixTestGenerated.When.class}) public class QuickFixTestGenerated extends AbstractQuickFixTest { public void testAllFilesPresentInQuickfix() throws Exception { JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.GenerateTests", new File("idea/testData/quickfix"), Pattern.compile("^before(\\w+)\\.kt$"), true); @@ -426,6 +429,208 @@ public class QuickFixTestGenerated extends AbstractQuickFixTest { } + @TestMetadata("idea/testData/quickfix/createFromUsage") + @InnerTestClasses({CreateFromUsage.ClassObject.class, CreateFromUsage.Component.class, CreateFromUsage.Get.class, CreateFromUsage.HasNext.class, CreateFromUsage.Iterator.class, CreateFromUsage.Next.class, CreateFromUsage.Set.class}) + public static class CreateFromUsage extends AbstractQuickFixTest { + public void testAllFilesPresentInCreateFromUsage() throws Exception { + JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.GenerateTests", new File("idea/testData/quickfix/createFromUsage"), Pattern.compile("^before(\\w+)\\.kt$"), true); + } + + @TestMetadata("idea/testData/quickfix/createFromUsage/classObject") + public static class ClassObject extends AbstractQuickFixTest { + public void testAllFilesPresentInClassObject() throws Exception { + JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.GenerateTests", new File("idea/testData/quickfix/createFromUsage/classObject"), Pattern.compile("^before(\\w+)\\.kt$"), true); + } + + @TestMetadata("beforeCreateClassObject1.kt") + public void testCreateClassObject1() throws Exception { + doTest("idea/testData/quickfix/createFromUsage/classObject/beforeCreateClassObject1.kt"); + } + + @TestMetadata("beforeCreateClassObject2.kt") + public void testCreateClassObject2() throws Exception { + doTest("idea/testData/quickfix/createFromUsage/classObject/beforeCreateClassObject2.kt"); + } + + } + + @TestMetadata("idea/testData/quickfix/createFromUsage/component") + public static class Component extends AbstractQuickFixTest { + public void testAllFilesPresentInComponent() throws Exception { + JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.GenerateTests", new File("idea/testData/quickfix/createFromUsage/component"), Pattern.compile("^before(\\w+)\\.kt$"), true); + } + + @TestMetadata("beforeCreateComponentFromUsage1.kt") + public void testCreateComponentFromUsage1() throws Exception { + doTest("idea/testData/quickfix/createFromUsage/component/beforeCreateComponentFromUsage1.kt"); + } + + @TestMetadata("beforeCreateComponentFromUsage2.kt") + public void testCreateComponentFromUsage2() throws Exception { + doTest("idea/testData/quickfix/createFromUsage/component/beforeCreateComponentFromUsage2.kt"); + } + + } + + @TestMetadata("idea/testData/quickfix/createFromUsage/get") + public static class Get extends AbstractQuickFixTest { + public void testAllFilesPresentInGet() throws Exception { + JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.GenerateTests", new File("idea/testData/quickfix/createFromUsage/get"), Pattern.compile("^before(\\w+)\\.kt$"), true); + } + + @TestMetadata("beforeCreateGetFromUsage1.kt") + public void testCreateGetFromUsage1() throws Exception { + doTest("idea/testData/quickfix/createFromUsage/get/beforeCreateGetFromUsage1.kt"); + } + + @TestMetadata("beforeCreateGetFromUsage10.kt") + public void testCreateGetFromUsage10() throws Exception { + doTest("idea/testData/quickfix/createFromUsage/get/beforeCreateGetFromUsage10.kt"); + } + + @TestMetadata("beforeCreateGetFromUsage11.kt") + public void testCreateGetFromUsage11() throws Exception { + doTest("idea/testData/quickfix/createFromUsage/get/beforeCreateGetFromUsage11.kt"); + } + + @TestMetadata("beforeCreateGetFromUsage12.kt") + public void testCreateGetFromUsage12() throws Exception { + doTest("idea/testData/quickfix/createFromUsage/get/beforeCreateGetFromUsage12.kt"); + } + + @TestMetadata("beforeCreateGetFromUsage13.kt") + public void testCreateGetFromUsage13() throws Exception { + doTest("idea/testData/quickfix/createFromUsage/get/beforeCreateGetFromUsage13.kt"); + } + + @TestMetadata("beforeCreateGetFromUsage2.kt") + public void testCreateGetFromUsage2() throws Exception { + doTest("idea/testData/quickfix/createFromUsage/get/beforeCreateGetFromUsage2.kt"); + } + + @TestMetadata("beforeCreateGetFromUsage3.kt") + public void testCreateGetFromUsage3() throws Exception { + doTest("idea/testData/quickfix/createFromUsage/get/beforeCreateGetFromUsage3.kt"); + } + + @TestMetadata("beforeCreateGetFromUsage4.kt") + public void testCreateGetFromUsage4() throws Exception { + doTest("idea/testData/quickfix/createFromUsage/get/beforeCreateGetFromUsage4.kt"); + } + + @TestMetadata("beforeCreateGetFromUsage5.kt") + public void testCreateGetFromUsage5() throws Exception { + doTest("idea/testData/quickfix/createFromUsage/get/beforeCreateGetFromUsage5.kt"); + } + + @TestMetadata("beforeCreateGetFromUsage6.kt") + public void testCreateGetFromUsage6() throws Exception { + doTest("idea/testData/quickfix/createFromUsage/get/beforeCreateGetFromUsage6.kt"); + } + + @TestMetadata("beforeCreateGetFromUsage7.kt") + public void testCreateGetFromUsage7() throws Exception { + doTest("idea/testData/quickfix/createFromUsage/get/beforeCreateGetFromUsage7.kt"); + } + + @TestMetadata("beforeCreateGetFromUsage8.kt") + public void testCreateGetFromUsage8() throws Exception { + doTest("idea/testData/quickfix/createFromUsage/get/beforeCreateGetFromUsage8.kt"); + } + + @TestMetadata("beforeCreateGetFromUsage9.kt") + public void testCreateGetFromUsage9() throws Exception { + doTest("idea/testData/quickfix/createFromUsage/get/beforeCreateGetFromUsage9.kt"); + } + + } + + @TestMetadata("idea/testData/quickfix/createFromUsage/hasNext") + public static class HasNext extends AbstractQuickFixTest { + public void testAllFilesPresentInHasNext() throws Exception { + JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.GenerateTests", new File("idea/testData/quickfix/createFromUsage/hasNext"), Pattern.compile("^before(\\w+)\\.kt$"), true); + } + + @TestMetadata("beforeCreateHasNextFromUsage1.kt") + public void testCreateHasNextFromUsage1() throws Exception { + doTest("idea/testData/quickfix/createFromUsage/hasNext/beforeCreateHasNextFromUsage1.kt"); + } + + @TestMetadata("beforeCreateHasNextFromUsage2.kt") + public void testCreateHasNextFromUsage2() throws Exception { + doTest("idea/testData/quickfix/createFromUsage/hasNext/beforeCreateHasNextFromUsage2.kt"); + } + + } + + @TestMetadata("idea/testData/quickfix/createFromUsage/iterator") + public static class Iterator extends AbstractQuickFixTest { + public void testAllFilesPresentInIterator() throws Exception { + JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.GenerateTests", new File("idea/testData/quickfix/createFromUsage/iterator"), Pattern.compile("^before(\\w+)\\.kt$"), true); + } + + @TestMetadata("beforeCreateIteratorFromUsage1.kt") + public void testCreateIteratorFromUsage1() throws Exception { + doTest("idea/testData/quickfix/createFromUsage/iterator/beforeCreateIteratorFromUsage1.kt"); + } + + @TestMetadata("beforeCreateIteratorFromUsage2.kt") + public void testCreateIteratorFromUsage2() throws Exception { + doTest("idea/testData/quickfix/createFromUsage/iterator/beforeCreateIteratorFromUsage2.kt"); + } + + } + + @TestMetadata("idea/testData/quickfix/createFromUsage/next") + public static class Next extends AbstractQuickFixTest { + public void testAllFilesPresentInNext() throws Exception { + JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.GenerateTests", new File("idea/testData/quickfix/createFromUsage/next"), Pattern.compile("^before(\\w+)\\.kt$"), true); + } + + @TestMetadata("beforeCreateNextFromUsage1.kt") + public void testCreateNextFromUsage1() throws Exception { + doTest("idea/testData/quickfix/createFromUsage/next/beforeCreateNextFromUsage1.kt"); + } + + @TestMetadata("beforeCreateNextFromUsage2.kt") + public void testCreateNextFromUsage2() throws Exception { + doTest("idea/testData/quickfix/createFromUsage/next/beforeCreateNextFromUsage2.kt"); + } + + } + + @TestMetadata("idea/testData/quickfix/createFromUsage/set") + public static class Set extends AbstractQuickFixTest { + public void testAllFilesPresentInSet() throws Exception { + JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.GenerateTests", new File("idea/testData/quickfix/createFromUsage/set"), Pattern.compile("^before(\\w+)\\.kt$"), true); + } + + @TestMetadata("beforeCreateSetFromUsage1.kt") + public void testCreateSetFromUsage1() throws Exception { + doTest("idea/testData/quickfix/createFromUsage/set/beforeCreateSetFromUsage1.kt"); + } + + @TestMetadata("beforeCreateSetFromUsage2.kt") + public void testCreateSetFromUsage2() throws Exception { + doTest("idea/testData/quickfix/createFromUsage/set/beforeCreateSetFromUsage2.kt"); + } + + } + + public static Test innerSuite() { + TestSuite suite = new TestSuite("CreateFromUsage"); + suite.addTestSuite(CreateFromUsage.class); + suite.addTestSuite(ClassObject.class); + suite.addTestSuite(Component.class); + suite.addTestSuite(Get.class); + suite.addTestSuite(HasNext.class); + suite.addTestSuite(Iterator.class); + suite.addTestSuite(Next.class); + suite.addTestSuite(Set.class); + return suite; + } + } + @TestMetadata("idea/testData/quickfix/expressions") public static class Expressions extends AbstractQuickFixTest { public void testAllFilesPresentInExpressions() throws Exception { @@ -1501,6 +1706,7 @@ public class QuickFixTestGenerated extends AbstractQuickFixTest { suite.addTestSuite(AutoImports.class); suite.addTestSuite(ChangeSignature.class); suite.addTestSuite(CheckArguments.class); + suite.addTest(CreateFromUsage.innerSuite()); suite.addTestSuite(Expressions.class); suite.addTestSuite(Migration.class); suite.addTest(Modifiers.innerSuite()); From c7c8c096f782274526ef66a6e12e353a852e2edb Mon Sep 17 00:00:00 2001 From: Jack Zhou Date: Wed, 1 May 2013 17:28:06 -0400 Subject: [PATCH 041/291] Create from usage: Removed quickfix for NO_CLASS_OBJECT. --- .../jetbrains/jet/plugin/JetBundle.properties | 1 - .../CreateClassObjectFromUsageFix.java | 84 ------------------- .../jet/plugin/quickfix/QuickFixes.java | 1 - .../classObject/afterCreateClassObject1.kt | 10 --- .../classObject/afterCreateClassObject2.kt | 10 --- .../classObject/beforeCreateClassObject1.kt | 8 -- .../classObject/beforeCreateClassObject2.kt | 6 -- .../quickfix/QuickFixTestGenerated.java | 21 +---- 8 files changed, 1 insertion(+), 140 deletions(-) delete mode 100644 idea/src/org/jetbrains/jet/plugin/quickfix/CreateClassObjectFromUsageFix.java delete mode 100644 idea/testData/quickfix/createFromUsage/classObject/afterCreateClassObject1.kt delete mode 100644 idea/testData/quickfix/createFromUsage/classObject/afterCreateClassObject2.kt delete mode 100644 idea/testData/quickfix/createFromUsage/classObject/beforeCreateClassObject1.kt delete mode 100644 idea/testData/quickfix/createFromUsage/classObject/beforeCreateClassObject2.kt diff --git a/idea/src/org/jetbrains/jet/plugin/JetBundle.properties b/idea/src/org/jetbrains/jet/plugin/JetBundle.properties index 84a70b3cbed..22535d9d944 100644 --- a/idea/src/org/jetbrains/jet/plugin/JetBundle.properties +++ b/idea/src/org/jetbrains/jet/plugin/JetBundle.properties @@ -145,7 +145,6 @@ map.platform.class.to.kotlin.advertisement=Choose an appropriate Kotlin class map.platform.class.to.kotlin.family=Change to Kotlin class create.from.usage.family=Create from usage create.method.from.usage=Create method ''{0}'' from usage -create.class.object.from.usage=Create class object from usage choose.target.class.or.trait.title=Choose target class or trait surround.with=Surround with surround.with.string.template="${expr}" diff --git a/idea/src/org/jetbrains/jet/plugin/quickfix/CreateClassObjectFromUsageFix.java b/idea/src/org/jetbrains/jet/plugin/quickfix/CreateClassObjectFromUsageFix.java deleted file mode 100644 index 0a52a91ae91..00000000000 --- a/idea/src/org/jetbrains/jet/plugin/quickfix/CreateClassObjectFromUsageFix.java +++ /dev/null @@ -1,84 +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.quickfix; - -import com.intellij.codeInsight.intention.IntentionAction; -import com.intellij.openapi.editor.Editor; -import com.intellij.openapi.fileEditor.FileEditorManager; -import com.intellij.openapi.project.Project; -import com.intellij.openapi.vfs.VirtualFile; -import com.intellij.psi.PsiElement; -import com.intellij.psi.PsiFile; -import com.intellij.psi.PsiReference; -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.plugin.JetBundle; - -public class CreateClassObjectFromUsageFix extends CreateFromUsageFixBase { - private final JetClass klass; - - public CreateClassObjectFromUsageFix(@NotNull PsiElement element, @NotNull JetClass klass) { - super(element); - this.klass = klass; - } - - @NotNull - @Override - public String getText() { - return JetBundle.message("create.class.object.from.usage"); - } - - @Override - public void invoke(@NotNull Project project, Editor editor, PsiFile file) throws IncorrectOperationException { - PsiFile containingFile = klass.getContainingFile(); - VirtualFile virtualFile = containingFile.getVirtualFile(); - assert virtualFile != null; - FileEditorManager fileEditorManager = FileEditorManager.getInstance(project); - fileEditorManager.openFile(virtualFile, true); - - JetClassBody classBody = klass.getBody(); - if (classBody == null) { - classBody = (JetClassBody) klass.add(JetPsiFactory.createEmptyClassBody(project)); - klass.addBefore(JetPsiFactory.createWhiteSpace(project), classBody); - } - PsiElement lBrace = classBody.getLBrace(); - JetClassObject classObject = (JetClassObject) classBody.addAfter(JetPsiFactory.createEmptyClassObject(project), lBrace); - classBody.addBefore(JetPsiFactory.createNewLine(project), classObject); - } - - @NotNull - public static JetIntentionActionFactory createCreateClassObjectFromUsageFactory() { - return new JetIntentionActionFactory() { - @Nullable - @Override - public IntentionAction createAction(Diagnostic diagnostic) { - JetReferenceExpression refExpr = QuickFixUtil.getParentElementOfType(diagnostic, JetReferenceExpression.class); - if (refExpr == null) return null; - PsiReference reference = refExpr.getReference(); - if (reference == null) return null; - PsiElement resolvedReference = reference.resolve(); - if (resolvedReference == null || !(resolvedReference instanceof JetClass)) return null; - JetClass klass = (JetClass) resolvedReference; - if (!klass.isWritable()) return null; - return new CreateClassObjectFromUsageFix(refExpr, (JetClass) resolvedReference); - } - }; - } -} diff --git a/idea/src/org/jetbrains/jet/plugin/quickfix/QuickFixes.java b/idea/src/org/jetbrains/jet/plugin/quickfix/QuickFixes.java index 5aa2fd81821..eeb9d63bde6 100644 --- a/idea/src/org/jetbrains/jet/plugin/quickfix/QuickFixes.java +++ b/idea/src/org/jetbrains/jet/plugin/quickfix/QuickFixes.java @@ -250,6 +250,5 @@ public class QuickFixes { factories.put(NEXT_NONE_APPLICABLE, createNextFromUsageFactory); factories.put(ITERATOR_MISSING, CreateMethodFromUsageFix.createCreateIteratorMethodFromUsageFactory()); factories.put(COMPONENT_FUNCTION_MISSING, CreateMethodFromUsageFix.createCreateComponentMethodFromUsageFactory()); - factories.put(NO_CLASS_OBJECT, CreateClassObjectFromUsageFix.createCreateClassObjectFromUsageFactory()); } } diff --git a/idea/testData/quickfix/createFromUsage/classObject/afterCreateClassObject1.kt b/idea/testData/quickfix/createFromUsage/classObject/afterCreateClassObject1.kt deleted file mode 100644 index 046b2ea50ef..00000000000 --- a/idea/testData/quickfix/createFromUsage/classObject/afterCreateClassObject1.kt +++ /dev/null @@ -1,10 +0,0 @@ -// "Create class object from usage" "true" -// ERROR: Expression 'T' of type '' cannot be invoked as a function -trait T { - class object { - } - -} -fun foo() { - val x = T() -} diff --git a/idea/testData/quickfix/createFromUsage/classObject/afterCreateClassObject2.kt b/idea/testData/quickfix/createFromUsage/classObject/afterCreateClassObject2.kt deleted file mode 100644 index e43a2d55083..00000000000 --- a/idea/testData/quickfix/createFromUsage/classObject/afterCreateClassObject2.kt +++ /dev/null @@ -1,10 +0,0 @@ -// "Create class object from usage" "true" -// ERROR: Expression 'T' of type '' cannot be invoked as a function -trait T -{ - class object { - } -} -fun foo() { - val x = T() -} diff --git a/idea/testData/quickfix/createFromUsage/classObject/beforeCreateClassObject1.kt b/idea/testData/quickfix/createFromUsage/classObject/beforeCreateClassObject1.kt deleted file mode 100644 index 146b39ce721..00000000000 --- a/idea/testData/quickfix/createFromUsage/classObject/beforeCreateClassObject1.kt +++ /dev/null @@ -1,8 +0,0 @@ -// "Create class object from usage" "true" -// ERROR: Expression 'T' of type '' cannot be invoked as a function -trait T { - -} -fun foo() { - val x = T() -} diff --git a/idea/testData/quickfix/createFromUsage/classObject/beforeCreateClassObject2.kt b/idea/testData/quickfix/createFromUsage/classObject/beforeCreateClassObject2.kt deleted file mode 100644 index 48024776e0e..00000000000 --- a/idea/testData/quickfix/createFromUsage/classObject/beforeCreateClassObject2.kt +++ /dev/null @@ -1,6 +0,0 @@ -// "Create class object from usage" "true" -// ERROR: Expression 'T' of type '' cannot be invoked as a function -trait T -fun foo() { - val x = T() -} diff --git a/idea/tests/org/jetbrains/jet/plugin/quickfix/QuickFixTestGenerated.java b/idea/tests/org/jetbrains/jet/plugin/quickfix/QuickFixTestGenerated.java index 02da71be244..bf4b20b7aeb 100644 --- a/idea/tests/org/jetbrains/jet/plugin/quickfix/QuickFixTestGenerated.java +++ b/idea/tests/org/jetbrains/jet/plugin/quickfix/QuickFixTestGenerated.java @@ -430,30 +430,12 @@ public class QuickFixTestGenerated extends AbstractQuickFixTest { } @TestMetadata("idea/testData/quickfix/createFromUsage") - @InnerTestClasses({CreateFromUsage.ClassObject.class, CreateFromUsage.Component.class, CreateFromUsage.Get.class, CreateFromUsage.HasNext.class, CreateFromUsage.Iterator.class, CreateFromUsage.Next.class, CreateFromUsage.Set.class}) + @InnerTestClasses({CreateFromUsage.Component.class, CreateFromUsage.Get.class, CreateFromUsage.HasNext.class, CreateFromUsage.Iterator.class, CreateFromUsage.Next.class, CreateFromUsage.Set.class}) public static class CreateFromUsage extends AbstractQuickFixTest { public void testAllFilesPresentInCreateFromUsage() throws Exception { JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.GenerateTests", new File("idea/testData/quickfix/createFromUsage"), Pattern.compile("^before(\\w+)\\.kt$"), true); } - @TestMetadata("idea/testData/quickfix/createFromUsage/classObject") - public static class ClassObject extends AbstractQuickFixTest { - public void testAllFilesPresentInClassObject() throws Exception { - JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.GenerateTests", new File("idea/testData/quickfix/createFromUsage/classObject"), Pattern.compile("^before(\\w+)\\.kt$"), true); - } - - @TestMetadata("beforeCreateClassObject1.kt") - public void testCreateClassObject1() throws Exception { - doTest("idea/testData/quickfix/createFromUsage/classObject/beforeCreateClassObject1.kt"); - } - - @TestMetadata("beforeCreateClassObject2.kt") - public void testCreateClassObject2() throws Exception { - doTest("idea/testData/quickfix/createFromUsage/classObject/beforeCreateClassObject2.kt"); - } - - } - @TestMetadata("idea/testData/quickfix/createFromUsage/component") public static class Component extends AbstractQuickFixTest { public void testAllFilesPresentInComponent() throws Exception { @@ -620,7 +602,6 @@ public class QuickFixTestGenerated extends AbstractQuickFixTest { public static Test innerSuite() { TestSuite suite = new TestSuite("CreateFromUsage"); suite.addTestSuite(CreateFromUsage.class); - suite.addTestSuite(ClassObject.class); suite.addTestSuite(Component.class); suite.addTestSuite(Get.class); suite.addTestSuite(HasNext.class); From eadb73c9f8a22234e25d73a206371ec50a0c3e15 Mon Sep 17 00:00:00 2001 From: Jack Zhou Date: Wed, 1 May 2013 17:34:20 -0400 Subject: [PATCH 042/291] Create from usage: Using UnsupportedOperationException for the file template instead. --- idea/resources/fileTemplates/code/New Kotlin Method Body.kt.ft | 2 +- .../createFromUsage/component/afterCreateComponentFromUsage1.kt | 2 +- .../createFromUsage/component/afterCreateComponentFromUsage2.kt | 2 +- .../quickfix/createFromUsage/get/afterCreateGetFromUsage1.kt | 2 +- .../quickfix/createFromUsage/get/afterCreateGetFromUsage10.kt | 2 +- .../quickfix/createFromUsage/get/afterCreateGetFromUsage11.kt | 2 +- .../quickfix/createFromUsage/get/afterCreateGetFromUsage12.kt | 2 +- .../quickfix/createFromUsage/get/afterCreateGetFromUsage13.kt | 2 +- .../quickfix/createFromUsage/get/afterCreateGetFromUsage2.kt | 2 +- .../quickfix/createFromUsage/get/afterCreateGetFromUsage3.kt | 2 +- .../quickfix/createFromUsage/get/afterCreateGetFromUsage4.kt | 2 +- .../quickfix/createFromUsage/get/afterCreateGetFromUsage5.kt | 2 +- .../quickfix/createFromUsage/get/afterCreateGetFromUsage6.kt | 2 +- .../quickfix/createFromUsage/get/afterCreateGetFromUsage7.kt | 2 +- .../quickfix/createFromUsage/get/afterCreateGetFromUsage8.kt | 2 +- .../quickfix/createFromUsage/get/afterCreateGetFromUsage9.kt | 2 +- .../createFromUsage/hasNext/afterCreateHasNextFromUsage1.kt | 2 +- .../createFromUsage/hasNext/afterCreateHasNextFromUsage2.kt | 2 +- .../createFromUsage/iterator/afterCreateIteratorFromUsage1.kt | 2 +- .../createFromUsage/iterator/afterCreateIteratorFromUsage2.kt | 2 +- .../quickfix/createFromUsage/next/afterCreateNextFromUsage1.kt | 2 +- .../quickfix/createFromUsage/next/afterCreateNextFromUsage2.kt | 2 +- .../quickfix/createFromUsage/set/afterCreateSetFromUsage1.kt | 2 +- .../quickfix/createFromUsage/set/afterCreateSetFromUsage2.kt | 2 +- 24 files changed, 24 insertions(+), 24 deletions(-) diff --git a/idea/resources/fileTemplates/code/New Kotlin Method Body.kt.ft b/idea/resources/fileTemplates/code/New Kotlin Method Body.kt.ft index 69d16fa46b5..e5364a5698f 100644 --- a/idea/resources/fileTemplates/code/New Kotlin Method Body.kt.ft +++ b/idea/resources/fileTemplates/code/New Kotlin Method Body.kt.ft @@ -1 +1 @@ -throw Exception("not implemented") //To change body of created methods use File | Settings | File Templates. \ No newline at end of file +throw UnsupportedOperationException("not implemented") //To change body of created methods use File | Settings | File Templates. \ No newline at end of file diff --git a/idea/testData/quickfix/createFromUsage/component/afterCreateComponentFromUsage1.kt b/idea/testData/quickfix/createFromUsage/component/afterCreateComponentFromUsage1.kt index 4a730095803..07f9a9c89cc 100644 --- a/idea/testData/quickfix/createFromUsage/component/afterCreateComponentFromUsage1.kt +++ b/idea/testData/quickfix/createFromUsage/component/afterCreateComponentFromUsage1.kt @@ -3,7 +3,7 @@ class Foo { fun component1(): Int { return 0 } fun component2(): Int { return 0 } fun component3(): Any { - throw Exception("not implemented") //To change body of created methods use File | Settings | File Templates. + throw UnsupportedOperationException("not implemented") //To change body of created methods use File | Settings | File Templates. } } fun foo() { diff --git a/idea/testData/quickfix/createFromUsage/component/afterCreateComponentFromUsage2.kt b/idea/testData/quickfix/createFromUsage/component/afterCreateComponentFromUsage2.kt index 4e30704925d..a0b58ed7311 100644 --- a/idea/testData/quickfix/createFromUsage/component/afterCreateComponentFromUsage2.kt +++ b/idea/testData/quickfix/createFromUsage/component/afterCreateComponentFromUsage2.kt @@ -3,7 +3,7 @@ class Foo { fun component1(): Int { return 0 } fun component2(): Int { return 0 } fun component3(): String { - throw Exception("not implemented") //To change body of created methods use File | Settings | File Templates. + throw UnsupportedOperationException("not implemented") //To change body of created methods use File | Settings | File Templates. } } fun foo() { diff --git a/idea/testData/quickfix/createFromUsage/get/afterCreateGetFromUsage1.kt b/idea/testData/quickfix/createFromUsage/get/afterCreateGetFromUsage1.kt index 8cf409481af..2743d727be0 100644 --- a/idea/testData/quickfix/createFromUsage/get/afterCreateGetFromUsage1.kt +++ b/idea/testData/quickfix/createFromUsage/get/afterCreateGetFromUsage1.kt @@ -4,6 +4,6 @@ class Foo { val z: Iterable = y[""] } fun get(s: String): T { - throw Exception("not implemented") //To change body of created methods use File | Settings | File Templates. + throw UnsupportedOperationException("not implemented") //To change body of created methods use File | Settings | File Templates. } } diff --git a/idea/testData/quickfix/createFromUsage/get/afterCreateGetFromUsage10.kt b/idea/testData/quickfix/createFromUsage/get/afterCreateGetFromUsage10.kt index f16da937ee3..dca15cbc5c5 100644 --- a/idea/testData/quickfix/createFromUsage/get/afterCreateGetFromUsage10.kt +++ b/idea/testData/quickfix/createFromUsage/get/afterCreateGetFromUsage10.kt @@ -4,6 +4,6 @@ class Foo { val z: Iterable = y["", w] } fun get(s: String, w: T): T { - throw Exception("not implemented") //To change body of created methods use File | Settings | File Templates. + throw UnsupportedOperationException("not implemented") //To change body of created methods use File | Settings | File Templates. } } diff --git a/idea/testData/quickfix/createFromUsage/get/afterCreateGetFromUsage11.kt b/idea/testData/quickfix/createFromUsage/get/afterCreateGetFromUsage11.kt index 8686065e93f..0427e0f0ff2 100644 --- a/idea/testData/quickfix/createFromUsage/get/afterCreateGetFromUsage11.kt +++ b/idea/testData/quickfix/createFromUsage/get/afterCreateGetFromUsage11.kt @@ -1,7 +1,7 @@ // "Create method 'get' from usage" "true" class Foo { fun get(s: String, w: T): T { - throw Exception("not implemented") //To change body of created methods use File | Settings | File Templates. + throw UnsupportedOperationException("not implemented") //To change body of created methods use File | Settings | File Templates. } } fun x (y: Foo>, w: java.util.ArrayList) { diff --git a/idea/testData/quickfix/createFromUsage/get/afterCreateGetFromUsage12.kt b/idea/testData/quickfix/createFromUsage/get/afterCreateGetFromUsage12.kt index d3d25c27abc..cdcba5fb1ff 100644 --- a/idea/testData/quickfix/createFromUsage/get/afterCreateGetFromUsage12.kt +++ b/idea/testData/quickfix/createFromUsage/get/afterCreateGetFromUsage12.kt @@ -1,7 +1,7 @@ // "Create method 'get' from usage" "true" class Foo { fun get(s: String, w: T): Any { - throw Exception("not implemented") //To change body of created methods use File | Settings | File Templates. + throw UnsupportedOperationException("not implemented") //To change body of created methods use File | Settings | File Templates. } } fun x (y: Foo>, w: java.util.ArrayList) { diff --git a/idea/testData/quickfix/createFromUsage/get/afterCreateGetFromUsage13.kt b/idea/testData/quickfix/createFromUsage/get/afterCreateGetFromUsage13.kt index f23bb7f2fd2..025bce56aa3 100644 --- a/idea/testData/quickfix/createFromUsage/get/afterCreateGetFromUsage13.kt +++ b/idea/testData/quickfix/createFromUsage/get/afterCreateGetFromUsage13.kt @@ -8,6 +8,6 @@ class Foo { bar(z) } fun get(s: String, w: ArrayList): String { - throw Exception("not implemented") //To change body of created methods use File | Settings | File Templates. + throw UnsupportedOperationException("not implemented") //To change body of created methods use File | Settings | File Templates. } } diff --git a/idea/testData/quickfix/createFromUsage/get/afterCreateGetFromUsage2.kt b/idea/testData/quickfix/createFromUsage/get/afterCreateGetFromUsage2.kt index dffa092c6ed..6a383097550 100644 --- a/idea/testData/quickfix/createFromUsage/get/afterCreateGetFromUsage2.kt +++ b/idea/testData/quickfix/createFromUsage/get/afterCreateGetFromUsage2.kt @@ -3,5 +3,5 @@ fun x (y: Any) { val z: Any = y[""] } fun Any.get(s: String): Any { - throw Exception("not implemented") //To change body of created methods use File | Settings | File Templates. + throw UnsupportedOperationException("not implemented") //To change body of created methods use File | Settings | File Templates. } \ No newline at end of file diff --git a/idea/testData/quickfix/createFromUsage/get/afterCreateGetFromUsage3.kt b/idea/testData/quickfix/createFromUsage/get/afterCreateGetFromUsage3.kt index 04315facefd..932974dafdb 100644 --- a/idea/testData/quickfix/createFromUsage/get/afterCreateGetFromUsage3.kt +++ b/idea/testData/quickfix/createFromUsage/get/afterCreateGetFromUsage3.kt @@ -4,6 +4,6 @@ class Foo { val z: Iterable = y[""] } fun get(s: String): T { - throw Exception("not implemented") //To change body of created methods use File | Settings | File Templates. + throw UnsupportedOperationException("not implemented") //To change body of created methods use File | Settings | File Templates. } } diff --git a/idea/testData/quickfix/createFromUsage/get/afterCreateGetFromUsage4.kt b/idea/testData/quickfix/createFromUsage/get/afterCreateGetFromUsage4.kt index a95fd697bc5..896f28e678e 100644 --- a/idea/testData/quickfix/createFromUsage/get/afterCreateGetFromUsage4.kt +++ b/idea/testData/quickfix/createFromUsage/get/afterCreateGetFromUsage4.kt @@ -4,6 +4,6 @@ class Foo> { val z: U = y[""] } fun get(s: String): T { - throw Exception("not implemented") //To change body of created methods use File | Settings | File Templates. + throw UnsupportedOperationException("not implemented") //To change body of created methods use File | Settings | File Templates. } } diff --git a/idea/testData/quickfix/createFromUsage/get/afterCreateGetFromUsage5.kt b/idea/testData/quickfix/createFromUsage/get/afterCreateGetFromUsage5.kt index 09289a73dc1..c3870922212 100644 --- a/idea/testData/quickfix/createFromUsage/get/afterCreateGetFromUsage5.kt +++ b/idea/testData/quickfix/createFromUsage/get/afterCreateGetFromUsage5.kt @@ -4,6 +4,6 @@ class Foo { val z: Iterable = y["", w] } fun get(s: String, w: Iterable): T { - throw Exception("not implemented") //To change body of created methods use File | Settings | File Templates. + throw UnsupportedOperationException("not implemented") //To change body of created methods use File | Settings | File Templates. } } diff --git a/idea/testData/quickfix/createFromUsage/get/afterCreateGetFromUsage6.kt b/idea/testData/quickfix/createFromUsage/get/afterCreateGetFromUsage6.kt index dc50306d47b..5302f028434 100644 --- a/idea/testData/quickfix/createFromUsage/get/afterCreateGetFromUsage6.kt +++ b/idea/testData/quickfix/createFromUsage/get/afterCreateGetFromUsage6.kt @@ -7,5 +7,5 @@ class Foo { } } fun ArrayList.get(s: String, w: ArrayList): Boolean { - throw Exception("not implemented") //To change body of created methods use File | Settings | File Templates. + throw UnsupportedOperationException("not implemented") //To change body of created methods use File | Settings | File Templates. } \ No newline at end of file diff --git a/idea/testData/quickfix/createFromUsage/get/afterCreateGetFromUsage7.kt b/idea/testData/quickfix/createFromUsage/get/afterCreateGetFromUsage7.kt index b32be62c6c1..6f52661137a 100644 --- a/idea/testData/quickfix/createFromUsage/get/afterCreateGetFromUsage7.kt +++ b/idea/testData/quickfix/createFromUsage/get/afterCreateGetFromUsage7.kt @@ -6,6 +6,6 @@ class Foo { val z: Iterable = y["", w] } fun get(s: String, w: ArrayList): T { - throw Exception("not implemented") //To change body of created methods use File | Settings | File Templates. + throw UnsupportedOperationException("not implemented") //To change body of created methods use File | Settings | File Templates. } } diff --git a/idea/testData/quickfix/createFromUsage/get/afterCreateGetFromUsage8.kt b/idea/testData/quickfix/createFromUsage/get/afterCreateGetFromUsage8.kt index caa960c3eae..0c87aa0374d 100644 --- a/idea/testData/quickfix/createFromUsage/get/afterCreateGetFromUsage8.kt +++ b/idea/testData/quickfix/createFromUsage/get/afterCreateGetFromUsage8.kt @@ -6,6 +6,6 @@ class Foo { val z: Iterable = y["", w] } fun get(s: String, w: T): T { - throw Exception("not implemented") //To change body of created methods use File | Settings | File Templates. + throw UnsupportedOperationException("not implemented") //To change body of created methods use File | Settings | File Templates. } } diff --git a/idea/testData/quickfix/createFromUsage/get/afterCreateGetFromUsage9.kt b/idea/testData/quickfix/createFromUsage/get/afterCreateGetFromUsage9.kt index 8cf0aea7d04..ed68a3b30d8 100644 --- a/idea/testData/quickfix/createFromUsage/get/afterCreateGetFromUsage9.kt +++ b/idea/testData/quickfix/createFromUsage/get/afterCreateGetFromUsage9.kt @@ -6,6 +6,6 @@ class Foo { val z: Iterable = y["", w] } fun get(s: String, w: S): S { - throw Exception("not implemented") //To change body of created methods use File | Settings | File Templates. + throw UnsupportedOperationException("not implemented") //To change body of created methods use File | Settings | File Templates. } } diff --git a/idea/testData/quickfix/createFromUsage/hasNext/afterCreateHasNextFromUsage1.kt b/idea/testData/quickfix/createFromUsage/hasNext/afterCreateHasNextFromUsage1.kt index 32d44370b25..f88d808c6e3 100644 --- a/idea/testData/quickfix/createFromUsage/hasNext/afterCreateHasNextFromUsage1.kt +++ b/idea/testData/quickfix/createFromUsage/hasNext/afterCreateHasNextFromUsage1.kt @@ -4,7 +4,7 @@ class FooIterator { throw Exception("not implemented") } fun hasNext(): Boolean { - throw Exception("not implemented") //To change body of created methods use File | Settings | File Templates. + throw UnsupportedOperationException("not implemented") //To change body of created methods use File | Settings | File Templates. } } class Foo { diff --git a/idea/testData/quickfix/createFromUsage/hasNext/afterCreateHasNextFromUsage2.kt b/idea/testData/quickfix/createFromUsage/hasNext/afterCreateHasNextFromUsage2.kt index 4a6fc9ef0d5..d9e4dff154f 100644 --- a/idea/testData/quickfix/createFromUsage/hasNext/afterCreateHasNextFromUsage2.kt +++ b/idea/testData/quickfix/createFromUsage/hasNext/afterCreateHasNextFromUsage2.kt @@ -4,7 +4,7 @@ class FooIterator { throw Exception("not implemented") } fun hasNext(): Boolean { - throw Exception("not implemented") //To change body of created methods use File | Settings | File Templates. + throw UnsupportedOperationException("not implemented") //To change body of created methods use File | Settings | File Templates. } } class Foo { diff --git a/idea/testData/quickfix/createFromUsage/iterator/afterCreateIteratorFromUsage1.kt b/idea/testData/quickfix/createFromUsage/iterator/afterCreateIteratorFromUsage1.kt index a405af8df81..c3392c5e2ef 100644 --- a/idea/testData/quickfix/createFromUsage/iterator/afterCreateIteratorFromUsage1.kt +++ b/idea/testData/quickfix/createFromUsage/iterator/afterCreateIteratorFromUsage1.kt @@ -1,7 +1,7 @@ // "Create method 'iterator' from usage" "true" class Foo { fun iterator(): Iterator { - throw Exception("not implemented") //To change body of created methods use File | Settings | File Templates. + throw UnsupportedOperationException("not implemented") //To change body of created methods use File | Settings | File Templates. } } fun foo() { diff --git a/idea/testData/quickfix/createFromUsage/iterator/afterCreateIteratorFromUsage2.kt b/idea/testData/quickfix/createFromUsage/iterator/afterCreateIteratorFromUsage2.kt index a5d765d5791..48e3b81e83f 100644 --- a/idea/testData/quickfix/createFromUsage/iterator/afterCreateIteratorFromUsage2.kt +++ b/idea/testData/quickfix/createFromUsage/iterator/afterCreateIteratorFromUsage2.kt @@ -1,7 +1,7 @@ // "Create method 'iterator' from usage" "true" class Foo { fun iterator(): Iterator { - throw Exception("not implemented") //To change body of created methods use File | Settings | File Templates. + throw UnsupportedOperationException("not implemented") //To change body of created methods use File | Settings | File Templates. } } fun foo() { diff --git a/idea/testData/quickfix/createFromUsage/next/afterCreateNextFromUsage1.kt b/idea/testData/quickfix/createFromUsage/next/afterCreateNextFromUsage1.kt index 91cd86a1e88..84973737408 100644 --- a/idea/testData/quickfix/createFromUsage/next/afterCreateNextFromUsage1.kt +++ b/idea/testData/quickfix/createFromUsage/next/afterCreateNextFromUsage1.kt @@ -2,7 +2,7 @@ class FooIterator { fun hasNext(): Boolean { return false } fun next(): Int { - throw Exception("not implemented") //To change body of created methods use File | Settings | File Templates. + throw UnsupportedOperationException("not implemented") //To change body of created methods use File | Settings | File Templates. } } class Foo { diff --git a/idea/testData/quickfix/createFromUsage/next/afterCreateNextFromUsage2.kt b/idea/testData/quickfix/createFromUsage/next/afterCreateNextFromUsage2.kt index f16aa88f96d..65fd4e50922 100644 --- a/idea/testData/quickfix/createFromUsage/next/afterCreateNextFromUsage2.kt +++ b/idea/testData/quickfix/createFromUsage/next/afterCreateNextFromUsage2.kt @@ -2,7 +2,7 @@ class FooIterator { fun hasNext(): Boolean { return false } fun next(): T { - throw Exception("not implemented") //To change body of created methods use File | Settings | File Templates. + throw UnsupportedOperationException("not implemented") //To change body of created methods use File | Settings | File Templates. } } class Foo { diff --git a/idea/testData/quickfix/createFromUsage/set/afterCreateSetFromUsage1.kt b/idea/testData/quickfix/createFromUsage/set/afterCreateSetFromUsage1.kt index 234cb8f6c77..24563965899 100644 --- a/idea/testData/quickfix/createFromUsage/set/afterCreateSetFromUsage1.kt +++ b/idea/testData/quickfix/createFromUsage/set/afterCreateSetFromUsage1.kt @@ -4,6 +4,6 @@ class Foo { y["", w] = w } fun set(s: String, w: T, value: T) { - throw Exception("not implemented") //To change body of created methods use File | Settings | File Templates. + throw UnsupportedOperationException("not implemented") //To change body of created methods use File | Settings | File Templates. } } diff --git a/idea/testData/quickfix/createFromUsage/set/afterCreateSetFromUsage2.kt b/idea/testData/quickfix/createFromUsage/set/afterCreateSetFromUsage2.kt index 1fe75ddfe34..9312ab89375 100644 --- a/idea/testData/quickfix/createFromUsage/set/afterCreateSetFromUsage2.kt +++ b/idea/testData/quickfix/createFromUsage/set/afterCreateSetFromUsage2.kt @@ -7,5 +7,5 @@ class Foo { } } fun Any.set(s: String, w: ArrayList, value: ArrayList) { - throw Exception("not implemented") //To change body of created methods use File | Settings | File Templates. + throw UnsupportedOperationException("not implemented") //To change body of created methods use File | Settings | File Templates. } \ No newline at end of file From e53feac26d00af9bd92773614d2e3f9d5da635bb Mon Sep 17 00:00:00 2001 From: Jack Zhou Date: Wed, 1 May 2013 17:35:18 -0400 Subject: [PATCH 043/291] Create from usage: Fixed extraneous imports in CreateFromUsageFixBase. --- .../jet/plugin/quickfix/CreateFromUsageFixBase.java | 7 ------- 1 file changed, 7 deletions(-) diff --git a/idea/src/org/jetbrains/jet/plugin/quickfix/CreateFromUsageFixBase.java b/idea/src/org/jetbrains/jet/plugin/quickfix/CreateFromUsageFixBase.java index 407ccd4efaf..0a9cbfccbe0 100644 --- a/idea/src/org/jetbrains/jet/plugin/quickfix/CreateFromUsageFixBase.java +++ b/idea/src/org/jetbrains/jet/plugin/quickfix/CreateFromUsageFixBase.java @@ -16,15 +16,8 @@ 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; -import org.jetbrains.jet.lang.psi.JetClass; -import org.jetbrains.jet.lang.psi.JetFile; -import org.jetbrains.jet.lang.psi.JetPsiFactory; import org.jetbrains.jet.plugin.JetBundle; public abstract class CreateFromUsageFixBase extends JetIntentionAction { From d2ce58e912043fb6b11a495534036d84aed8f512 Mon Sep 17 00:00:00 2001 From: Jack Zhou Date: Wed, 1 May 2013 17:39:53 -0400 Subject: [PATCH 044/291] Create from usage: Replaced boilerplate code with NavigationUtil.activateFileWithPsiElement. --- .../jet/plugin/quickfix/CreateMethodFromUsageFix.java | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/idea/src/org/jetbrains/jet/plugin/quickfix/CreateMethodFromUsageFix.java b/idea/src/org/jetbrains/jet/plugin/quickfix/CreateMethodFromUsageFix.java index d4a018fcf64..1ce351e8c80 100644 --- a/idea/src/org/jetbrains/jet/plugin/quickfix/CreateMethodFromUsageFix.java +++ b/idea/src/org/jetbrains/jet/plugin/quickfix/CreateMethodFromUsageFix.java @@ -19,6 +19,7 @@ package org.jetbrains.jet.plugin.quickfix; import com.intellij.codeInsight.intention.IntentionAction; import com.intellij.codeInsight.lookup.LookupElement; import com.intellij.codeInsight.lookup.LookupElementBuilder; +import com.intellij.codeInsight.navigation.NavigationUtil; import com.intellij.codeInsight.template.*; import com.intellij.codeInsight.template.impl.TemplateImpl; import com.intellij.codeInsight.template.impl.Variable; @@ -696,11 +697,10 @@ public class CreateMethodFromUsageFix extends CreateFromUsageFixBase { assert classContainingFile instanceof JetFile; containingFile = (JetFile) classContainingFile; - VirtualFile virtualFile = containingFile.getVirtualFile(); - assert virtualFile != null; - FileEditorManager fileEditorManager = FileEditorManager.getInstance(project); - fileEditorManager.openFile(virtualFile, true); - containingFileEditor = fileEditorManager.getSelectedTextEditor(); + if (!ApplicationManager.getApplication().isUnitTestMode()) { + NavigationUtil.activateFileWithPsiElement(containingFile); + } + containingFileEditor = FileEditorManager.getInstance(project).getSelectedTextEditor(); JetClassBody classBody = ownerClass.getBody(); if (classBody == null) { From ec15d5fee43e2067457701412816bd8622356911 Mon Sep 17 00:00:00 2001 From: Jack Zhou Date: Wed, 1 May 2013 17:58:25 -0400 Subject: [PATCH 045/291] Create from usage: Renamed all references of 'method' to 'function'. --- .../code/New Kotlin Function Body.kt.ft | 1 + ....html => New Kotlin Function Body.kt.html} | 14 ++--- .../code/New Kotlin Method Body.kt.ft | 1 - .../jetbrains/jet/plugin/JetBundle.properties | 2 +- ...x.java => CreateFunctionFromUsageFix.java} | 58 ++++++++++--------- .../jet/plugin/quickfix/QuickFixes.java | 12 ++-- .../afterCreateComponentFromUsage1.kt | 4 +- .../afterCreateComponentFromUsage2.kt | 4 +- .../beforeCreateComponentFromUsage1.kt | 2 +- .../beforeCreateComponentFromUsage2.kt | 2 +- .../get/afterCreateGetFromUsage1.kt | 4 +- .../get/afterCreateGetFromUsage10.kt | 4 +- .../get/afterCreateGetFromUsage11.kt | 4 +- .../get/afterCreateGetFromUsage12.kt | 4 +- .../get/afterCreateGetFromUsage13.kt | 4 +- .../get/afterCreateGetFromUsage2.kt | 4 +- .../get/afterCreateGetFromUsage3.kt | 4 +- .../get/afterCreateGetFromUsage4.kt | 4 +- .../get/afterCreateGetFromUsage5.kt | 4 +- .../get/afterCreateGetFromUsage6.kt | 4 +- .../get/afterCreateGetFromUsage7.kt | 4 +- .../get/afterCreateGetFromUsage8.kt | 4 +- .../get/afterCreateGetFromUsage9.kt | 4 +- .../get/beforeCreateGetFromUsage1.kt | 2 +- .../get/beforeCreateGetFromUsage10.kt | 2 +- .../get/beforeCreateGetFromUsage11.kt | 2 +- .../get/beforeCreateGetFromUsage12.kt | 2 +- .../get/beforeCreateGetFromUsage13.kt | 2 +- .../get/beforeCreateGetFromUsage2.kt | 2 +- .../get/beforeCreateGetFromUsage3.kt | 2 +- .../get/beforeCreateGetFromUsage4.kt | 2 +- .../get/beforeCreateGetFromUsage5.kt | 2 +- .../get/beforeCreateGetFromUsage6.kt | 2 +- .../get/beforeCreateGetFromUsage7.kt | 2 +- .../get/beforeCreateGetFromUsage8.kt | 2 +- .../get/beforeCreateGetFromUsage9.kt | 2 +- .../hasNext/afterCreateHasNextFromUsage1.kt | 4 +- .../hasNext/afterCreateHasNextFromUsage2.kt | 4 +- .../hasNext/beforeCreateHasNextFromUsage1.kt | 2 +- .../hasNext/beforeCreateHasNextFromUsage2.kt | 2 +- .../iterator/afterCreateIteratorFromUsage1.kt | 4 +- .../iterator/afterCreateIteratorFromUsage2.kt | 4 +- .../beforeCreateIteratorFromUsage1.kt | 2 +- .../beforeCreateIteratorFromUsage2.kt | 2 +- .../next/afterCreateNextFromUsage1.kt | 4 +- .../next/afterCreateNextFromUsage2.kt | 4 +- .../next/beforeCreateNextFromUsage1.kt | 2 +- .../next/beforeCreateNextFromUsage2.kt | 2 +- .../set/afterCreateSetFromUsage1.kt | 4 +- .../set/afterCreateSetFromUsage2.kt | 4 +- .../set/beforeCreateSetFromUsage1.kt | 2 +- .../set/beforeCreateSetFromUsage2.kt | 2 +- 52 files changed, 114 insertions(+), 112 deletions(-) create mode 100644 idea/resources/fileTemplates/code/New Kotlin Function Body.kt.ft rename idea/resources/fileTemplates/code/{New Kotlin Method Body.kt.html => New Kotlin Function Body.kt.html} (81%) delete mode 100644 idea/resources/fileTemplates/code/New Kotlin Method Body.kt.ft rename idea/src/org/jetbrains/jet/plugin/quickfix/{CreateMethodFromUsageFix.java => CreateFunctionFromUsageFix.java} (96%) diff --git a/idea/resources/fileTemplates/code/New Kotlin Function Body.kt.ft b/idea/resources/fileTemplates/code/New Kotlin Function Body.kt.ft new file mode 100644 index 00000000000..8c5a4e426d1 --- /dev/null +++ b/idea/resources/fileTemplates/code/New Kotlin Function Body.kt.ft @@ -0,0 +1 @@ +throw UnsupportedOperationException("not implemented") //To change body of created functions use File | Settings | File Templates. \ No newline at end of file diff --git a/idea/resources/fileTemplates/code/New Kotlin Method Body.kt.html b/idea/resources/fileTemplates/code/New Kotlin Function Body.kt.html similarity index 81% rename from idea/resources/fileTemplates/code/New Kotlin Method Body.kt.html rename to idea/resources/fileTemplates/code/New Kotlin Function Body.kt.html index c3526f30920..44f331d71f9 100644 --- a/idea/resources/fileTemplates/code/New Kotlin Method Body.kt.html +++ b/idea/resources/fileTemplates/code/New Kotlin Function Body.kt.html @@ -2,8 +2,8 @@ - @@ -16,22 +16,22 @@ - + - + - + - + - +
This is a built-in template used for filling the body of a Kotlin method - each time it is generated by the program, e.g. when using the Create Method from Usage intention action.
+
This is a built-in template used for filling the body of a Kotlin function + each time it is generated by the program, e.g. when using the Create Function from Usage intention action.
The template is editable. Along with Kotlin expressions and comments, you can also use the predefined variables that will be then expanded into the corresponding values.
${RETURN_TYPE}  a return type of a created methoda return type of a created function
${METHOD_NAME}${FUNCTION_NAME}  name of the created methodname of the created function
${CLASS_NAME}  qualified name of the class where method is createdqualified name of the class where function is created
${SIMPLE_CLASS_NAME}  non-qualified name of the class where method is implementednon-qualified name of the class where function is implemented
diff --git a/idea/resources/fileTemplates/code/New Kotlin Method Body.kt.ft b/idea/resources/fileTemplates/code/New Kotlin Method Body.kt.ft deleted file mode 100644 index e5364a5698f..00000000000 --- a/idea/resources/fileTemplates/code/New Kotlin Method Body.kt.ft +++ /dev/null @@ -1 +0,0 @@ -throw UnsupportedOperationException("not implemented") //To change body of created methods use File | Settings | File Templates. \ 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 22535d9d944..bdd50b3a5f4 100644 --- a/idea/src/org/jetbrains/jet/plugin/JetBundle.properties +++ b/idea/src/org/jetbrains/jet/plugin/JetBundle.properties @@ -144,7 +144,7 @@ map.platform.class.to.kotlin.multiple=Change all usages of ''{0}'' in this file map.platform.class.to.kotlin.advertisement=Choose an appropriate Kotlin class map.platform.class.to.kotlin.family=Change to Kotlin class create.from.usage.family=Create from usage -create.method.from.usage=Create method ''{0}'' from usage +create.function.from.usage=Create function ''{0}'' from usage choose.target.class.or.trait.title=Choose target class or trait surround.with=Surround with surround.with.string.template="${expr}" diff --git a/idea/src/org/jetbrains/jet/plugin/quickfix/CreateMethodFromUsageFix.java b/idea/src/org/jetbrains/jet/plugin/quickfix/CreateFunctionFromUsageFix.java similarity index 96% rename from idea/src/org/jetbrains/jet/plugin/quickfix/CreateMethodFromUsageFix.java rename to idea/src/org/jetbrains/jet/plugin/quickfix/CreateFunctionFromUsageFix.java index 1ce351e8c80..3ab5e083522 100644 --- a/idea/src/org/jetbrains/jet/plugin/quickfix/CreateMethodFromUsageFix.java +++ b/idea/src/org/jetbrains/jet/plugin/quickfix/CreateFunctionFromUsageFix.java @@ -36,7 +36,6 @@ import com.intellij.openapi.project.Project; import com.intellij.openapi.ui.popup.PopupChooserBuilder; import com.intellij.openapi.util.TextRange; import com.intellij.openapi.util.text.StringUtil; -import com.intellij.openapi.vfs.VirtualFile; import com.intellij.psi.PsiDocumentManager; import com.intellij.psi.PsiElement; import com.intellij.psi.PsiFile; @@ -78,9 +77,10 @@ import java.util.*; import java.util.regex.Matcher; import java.util.regex.Pattern; -public class CreateMethodFromUsageFix extends CreateFromUsageFixBase { +public class CreateFunctionFromUsageFix extends CreateFromUsageFixBase { private static final String TYPE_PARAMETER_LIST_VARIABLE_NAME = "typeParameterList"; - private static final String TEMPLATE_FROM_USAGE_METHOD_BODY = "New Kotlin Method Body.kt"; + private static final String TEMPLATE_FROM_USAGE_FUNCTION_BODY = "New Kotlin Function Body.kt"; + private static final String ATTRIBUTE_FUNCTION_NAME = "FUNCTION_NAME"; private static final Pattern COMPONENT_FUNCTION_PATTERN = Pattern.compile("^component(\\d+)$"); /** @@ -272,7 +272,7 @@ public class CreateMethodFromUsageFix extends CreateFromUsageFixBase { } /** - * Encapsulates information about a method parameter that is going to be created. + * Encapsulates information about a function parameter that is going to be created. */ private static class Parameter { private final String preferredName; @@ -522,7 +522,7 @@ public class CreateMethodFromUsageFix extends CreateFromUsageFixBase { } } - private final String methodName; + private final String functionName; private final TypeOrExpressionThereof ownerType; private final TypeOrExpressionThereof returnType; private final List parameters; @@ -539,10 +539,12 @@ public class CreateMethodFromUsageFix extends CreateFromUsageFixBase { private TypeCandidate selectedReceiverType; private Map typeParameterNameMap; - public CreateMethodFromUsageFix(@NotNull PsiElement element, @NotNull TypeOrExpressionThereof ownerType, @NotNull String methodName, - @NotNull TypeOrExpressionThereof returnType, @NotNull List parameters) { + public CreateFunctionFromUsageFix( + @NotNull PsiElement element, @NotNull TypeOrExpressionThereof ownerType, @NotNull String functionName, + @NotNull TypeOrExpressionThereof returnType, @NotNull List parameters + ) { super(element); - this.methodName = methodName; + this.functionName = functionName; this.ownerType = ownerType; this.returnType = returnType; this.parameters = parameters; @@ -551,7 +553,7 @@ public class CreateMethodFromUsageFix extends CreateFromUsageFixBase { @NotNull @Override public String getText() { - return JetBundle.message("create.method.from.usage", methodName); + return JetBundle.message("create.function.from.usage", functionName); } @Override @@ -685,14 +687,14 @@ public class CreateMethodFromUsageFix extends CreateFromUsageFixBase { String returnTypeString = isUnit ? "" : ": Any"; if (isExtension) { // create as extension function String ownerTypeString = selectedReceiverType.getRenderedType(); - String methodText = String.format("fun %s.%s(%s)%s { }", ownerTypeString, methodName, parametersString, returnTypeString); - func = JetPsiFactory.createFunction(project, methodText); + String functionText = String.format("fun %s.%s(%s)%s { }", ownerTypeString, functionName, parametersString, returnTypeString); + func = JetPsiFactory.createFunction(project, functionText); containingFile = currentFile; containingFileEditor = currentFileEditor; func = (JetNamedFunction) currentFile.add(func); - } else { // create as method - String methodText = String.format("fun %s(%s)%s { }", methodName, parametersString, returnTypeString); - func = JetPsiFactory.createFunction(project, methodText); + } else { // create as regular function + String functionText = String.format("fun %s(%s)%s { }", functionName, parametersString, returnTypeString); + func = JetPsiFactory.createFunction(project, functionText); PsiFile classContainingFile = ownerClass.getContainingFile(); assert classContainingFile instanceof JetFile; containingFile = (JetFile) classContainingFile; @@ -862,7 +864,7 @@ public class CreateMethodFromUsageFix extends CreateFromUsageFixBase { } private void setupFunctionBody(@NotNull Project project, @NotNull JetNamedFunction func) { - FileTemplate fileTemplate = FileTemplateManager.getInstance().getCodeTemplate(TEMPLATE_FROM_USAGE_METHOD_BODY); + FileTemplate fileTemplate = FileTemplateManager.getInstance().getCodeTemplate(TEMPLATE_FROM_USAGE_FUNCTION_BODY); Properties properties = new Properties(); if (isUnit) { properties.setProperty(FileTemplate.ATTRIBUTE_RETURN_TYPE, "Unit"); @@ -873,7 +875,7 @@ public class CreateMethodFromUsageFix extends CreateFromUsageFixBase { } properties.setProperty(FileTemplate.ATTRIBUTE_CLASS_NAME, DescriptorUtils.getFQName(ownerClassDescriptor).getFqName()); properties.setProperty(FileTemplate.ATTRIBUTE_SIMPLE_CLASS_NAME, ownerClassDescriptor.getName().getName()); - properties.setProperty(FileTemplate.ATTRIBUTE_METHOD_NAME, methodName); + properties.setProperty(ATTRIBUTE_FUNCTION_NAME, functionName); @NonNls String bodyText; try { @@ -1204,7 +1206,7 @@ public class CreateMethodFromUsageFix extends CreateFromUsageFixBase { } @NotNull - public static JetIntentionActionFactory createCreateGetMethodFromUsageFactory() { + public static JetIntentionActionFactory createCreateGetFunctionFromUsageFactory() { return new JetIntentionActionFactory() { @Nullable @Override @@ -1223,13 +1225,13 @@ public class CreateMethodFromUsageFix extends CreateFromUsageFixBase { } TypeOrExpressionThereof returnType = new TypeOrExpressionThereof(accessExpr, Variance.OUT_VARIANCE); - return new CreateMethodFromUsageFix(accessExpr, arrayType, "get", returnType, parameters); + return new CreateFunctionFromUsageFix(accessExpr, arrayType, "get", returnType, parameters); } }; } @NotNull - public static JetIntentionActionFactory createCreateSetMethodFromUsageFactory() { + public static JetIntentionActionFactory createCreateSetFunctionFromUsageFactory() { return new JetIntentionActionFactory() { @Nullable @Override @@ -1255,13 +1257,13 @@ public class CreateMethodFromUsageFix extends CreateFromUsageFixBase { parameters.add(new Parameter("value", valType)); TypeOrExpressionThereof returnType = new TypeOrExpressionThereof(KotlinBuiltIns.getInstance().getUnitType(), Variance.OUT_VARIANCE); - return new CreateMethodFromUsageFix(accessExpr, arrayType, "set", returnType, parameters); + return new CreateFunctionFromUsageFix(accessExpr, arrayType, "set", returnType, parameters); } }; } @NotNull - public static JetIntentionActionFactory createCreateHasNextMethodFromUsageFactory() { + public static JetIntentionActionFactory createCreateHasNextFunctionFromUsageFactory() { return new JetIntentionActionFactory() { @Nullable @Override @@ -1276,13 +1278,13 @@ public class CreateMethodFromUsageFix extends CreateFromUsageFixBase { JetForExpression forExpr = QuickFixUtil.getParentElementOfType(diagnostic, JetForExpression.class); if (forExpr == null) return null; TypeOrExpressionThereof returnType = new TypeOrExpressionThereof(KotlinBuiltIns.getInstance().getBooleanType(), Variance.OUT_VARIANCE); - return new CreateMethodFromUsageFix(forExpr, ownerType, "hasNext", returnType, new ArrayList()); + return new CreateFunctionFromUsageFix(forExpr, ownerType, "hasNext", returnType, new ArrayList()); } }; } @NotNull - public static JetIntentionActionFactory createCreateNextMethodFromUsageFactory() { + public static JetIntentionActionFactory createCreateNextFunctionFromUsageFactory() { return new JetIntentionActionFactory() { @Nullable @Override @@ -1298,13 +1300,13 @@ public class CreateMethodFromUsageFix extends CreateFromUsageFixBase { JetExpression variableExpr = forExpr.getLoopParameter(); if (variableExpr == null) return null; TypeOrExpressionThereof returnType = new TypeOrExpressionThereof(variableExpr, Variance.OUT_VARIANCE); - return new CreateMethodFromUsageFix(forExpr, ownerType, "next", returnType, new ArrayList()); + return new CreateFunctionFromUsageFix(forExpr, ownerType, "next", returnType, new ArrayList()); } }; } @NotNull - public static JetIntentionActionFactory createCreateIteratorMethodFromUsageFactory() { + public static JetIntentionActionFactory createCreateIteratorFunctionFromUsageFactory() { return new JetIntentionActionFactory() { @Nullable @Override @@ -1331,13 +1333,13 @@ public class CreateMethodFromUsageFix extends CreateFromUsageFixBase { returnJetType = new JetTypeImpl(returnJetType.getAnnotations(), returnJetType.getConstructor(), returnJetType.isNullable(), returnJetTypeArguments, returnJetType.getMemberScope()); TypeOrExpressionThereof returnType = new TypeOrExpressionThereof(returnJetType, Variance.OUT_VARIANCE); - return new CreateMethodFromUsageFix(forExpr, iterableType, "iterator", returnType, new ArrayList()); + return new CreateFunctionFromUsageFix(forExpr, iterableType, "iterator", returnType, new ArrayList()); } }; } @NotNull - public static JetIntentionActionFactory createCreateComponentMethodFromUsageFactory() { + public static JetIntentionActionFactory createCreateComponentFunctionFromUsageFactory() { return new JetIntentionActionFactory() { @Nullable @Override @@ -1362,7 +1364,7 @@ public class CreateMethodFromUsageFix extends CreateFromUsageFixBase { if (rhs == null) return null; TypeOrExpressionThereof ownerType = new TypeOrExpressionThereof(rhs); - return new CreateMethodFromUsageFix(multiDeclaration, ownerType, name.getIdentifier(), returnType, new ArrayList()); + return new CreateFunctionFromUsageFix(multiDeclaration, ownerType, name.getIdentifier(), returnType, new ArrayList()); } }; } diff --git a/idea/src/org/jetbrains/jet/plugin/quickfix/QuickFixes.java b/idea/src/org/jetbrains/jet/plugin/quickfix/QuickFixes.java index eeb9d63bde6..8974e83f6da 100644 --- a/idea/src/org/jetbrains/jet/plugin/quickfix/QuickFixes.java +++ b/idea/src/org/jetbrains/jet/plugin/quickfix/QuickFixes.java @@ -240,15 +240,15 @@ public class QuickFixes { factories.put(MANY_CLASSES_IN_SUPERTYPE_LIST, RemoveSupertypeFix.createFactory()); - factories.put(NO_GET_METHOD, CreateMethodFromUsageFix.createCreateGetMethodFromUsageFactory()); - factories.put(NO_SET_METHOD, CreateMethodFromUsageFix.createCreateSetMethodFromUsageFactory()); - JetIntentionActionFactory createHasNextFromUsageFactory = CreateMethodFromUsageFix.createCreateHasNextMethodFromUsageFactory(); + factories.put(NO_GET_METHOD, CreateFunctionFromUsageFix.createCreateGetFunctionFromUsageFactory()); + factories.put(NO_SET_METHOD, CreateFunctionFromUsageFix.createCreateSetFunctionFromUsageFactory()); + JetIntentionActionFactory createHasNextFromUsageFactory = CreateFunctionFromUsageFix.createCreateHasNextFunctionFromUsageFactory(); factories.put(HAS_NEXT_MISSING, createHasNextFromUsageFactory); factories.put(HAS_NEXT_FUNCTION_NONE_APPLICABLE, createHasNextFromUsageFactory); - JetIntentionActionFactory createNextFromUsageFactory = CreateMethodFromUsageFix.createCreateNextMethodFromUsageFactory(); + JetIntentionActionFactory createNextFromUsageFactory = CreateFunctionFromUsageFix.createCreateNextFunctionFromUsageFactory(); factories.put(NEXT_MISSING, createNextFromUsageFactory); factories.put(NEXT_NONE_APPLICABLE, createNextFromUsageFactory); - factories.put(ITERATOR_MISSING, CreateMethodFromUsageFix.createCreateIteratorMethodFromUsageFactory()); - factories.put(COMPONENT_FUNCTION_MISSING, CreateMethodFromUsageFix.createCreateComponentMethodFromUsageFactory()); + factories.put(ITERATOR_MISSING, CreateFunctionFromUsageFix.createCreateIteratorFunctionFromUsageFactory()); + factories.put(COMPONENT_FUNCTION_MISSING, CreateFunctionFromUsageFix.createCreateComponentFunctionFromUsageFactory()); } } diff --git a/idea/testData/quickfix/createFromUsage/component/afterCreateComponentFromUsage1.kt b/idea/testData/quickfix/createFromUsage/component/afterCreateComponentFromUsage1.kt index 07f9a9c89cc..fea659b5f7f 100644 --- a/idea/testData/quickfix/createFromUsage/component/afterCreateComponentFromUsage1.kt +++ b/idea/testData/quickfix/createFromUsage/component/afterCreateComponentFromUsage1.kt @@ -1,9 +1,9 @@ -// "Create method 'component3' from usage" "true" +// "Create function 'component3' from usage" "true" class Foo { fun component1(): Int { return 0 } fun component2(): Int { return 0 } fun component3(): Any { - throw UnsupportedOperationException("not implemented") //To change body of created methods use File | Settings | File Templates. + throw UnsupportedOperationException("not implemented") //To change body of created functions use File | Settings | File Templates. } } fun foo() { diff --git a/idea/testData/quickfix/createFromUsage/component/afterCreateComponentFromUsage2.kt b/idea/testData/quickfix/createFromUsage/component/afterCreateComponentFromUsage2.kt index a0b58ed7311..654b2b0f728 100644 --- a/idea/testData/quickfix/createFromUsage/component/afterCreateComponentFromUsage2.kt +++ b/idea/testData/quickfix/createFromUsage/component/afterCreateComponentFromUsage2.kt @@ -1,9 +1,9 @@ -// "Create method 'component3' from usage" "true" +// "Create function 'component3' from usage" "true" class Foo { fun component1(): Int { return 0 } fun component2(): Int { return 0 } fun component3(): String { - throw UnsupportedOperationException("not implemented") //To change body of created methods use File | Settings | File Templates. + throw UnsupportedOperationException("not implemented") //To change body of created functions use File | Settings | File Templates. } } fun foo() { diff --git a/idea/testData/quickfix/createFromUsage/component/beforeCreateComponentFromUsage1.kt b/idea/testData/quickfix/createFromUsage/component/beforeCreateComponentFromUsage1.kt index 8d1bf4515a7..69d48c6d639 100644 --- a/idea/testData/quickfix/createFromUsage/component/beforeCreateComponentFromUsage1.kt +++ b/idea/testData/quickfix/createFromUsage/component/beforeCreateComponentFromUsage1.kt @@ -1,4 +1,4 @@ -// "Create method 'component3' from usage" "true" +// "Create function 'component3' from usage" "true" class Foo { fun component1(): Int { return 0 } fun component2(): Int { return 0 } diff --git a/idea/testData/quickfix/createFromUsage/component/beforeCreateComponentFromUsage2.kt b/idea/testData/quickfix/createFromUsage/component/beforeCreateComponentFromUsage2.kt index 5ec47c32c3b..f2aa8b37e21 100644 --- a/idea/testData/quickfix/createFromUsage/component/beforeCreateComponentFromUsage2.kt +++ b/idea/testData/quickfix/createFromUsage/component/beforeCreateComponentFromUsage2.kt @@ -1,4 +1,4 @@ -// "Create method 'component3' from usage" "true" +// "Create function 'component3' from usage" "true" class Foo { fun component1(): Int { return 0 } fun component2(): Int { return 0 } diff --git a/idea/testData/quickfix/createFromUsage/get/afterCreateGetFromUsage1.kt b/idea/testData/quickfix/createFromUsage/get/afterCreateGetFromUsage1.kt index 2743d727be0..b9bba27b830 100644 --- a/idea/testData/quickfix/createFromUsage/get/afterCreateGetFromUsage1.kt +++ b/idea/testData/quickfix/createFromUsage/get/afterCreateGetFromUsage1.kt @@ -1,9 +1,9 @@ -// "Create method 'get' from usage" "true" +// "Create function 'get' from usage" "true" class Foo { fun x (y: Foo>) { val z: Iterable = y[""] } fun get(s: String): T { - throw UnsupportedOperationException("not implemented") //To change body of created methods use File | Settings | File Templates. + throw UnsupportedOperationException("not implemented") //To change body of created functions use File | Settings | File Templates. } } diff --git a/idea/testData/quickfix/createFromUsage/get/afterCreateGetFromUsage10.kt b/idea/testData/quickfix/createFromUsage/get/afterCreateGetFromUsage10.kt index dca15cbc5c5..c382e8ea21f 100644 --- a/idea/testData/quickfix/createFromUsage/get/afterCreateGetFromUsage10.kt +++ b/idea/testData/quickfix/createFromUsage/get/afterCreateGetFromUsage10.kt @@ -1,9 +1,9 @@ -// "Create method 'get' from usage" "true" +// "Create function 'get' from usage" "true" class Foo { fun x (y: Foo>, w: java.util.ArrayList) { val z: Iterable = y["", w] } fun get(s: String, w: T): T { - throw UnsupportedOperationException("not implemented") //To change body of created methods use File | Settings | File Templates. + throw UnsupportedOperationException("not implemented") //To change body of created functions use File | Settings | File Templates. } } diff --git a/idea/testData/quickfix/createFromUsage/get/afterCreateGetFromUsage11.kt b/idea/testData/quickfix/createFromUsage/get/afterCreateGetFromUsage11.kt index 0427e0f0ff2..6c30fb1b38e 100644 --- a/idea/testData/quickfix/createFromUsage/get/afterCreateGetFromUsage11.kt +++ b/idea/testData/quickfix/createFromUsage/get/afterCreateGetFromUsage11.kt @@ -1,7 +1,7 @@ -// "Create method 'get' from usage" "true" +// "Create function 'get' from usage" "true" class Foo { fun get(s: String, w: T): T { - throw UnsupportedOperationException("not implemented") //To change body of created methods use File | Settings | File Templates. + throw UnsupportedOperationException("not implemented") //To change body of created functions use File | Settings | File Templates. } } fun x (y: Foo>, w: java.util.ArrayList) { diff --git a/idea/testData/quickfix/createFromUsage/get/afterCreateGetFromUsage12.kt b/idea/testData/quickfix/createFromUsage/get/afterCreateGetFromUsage12.kt index cdcba5fb1ff..7045315ec0a 100644 --- a/idea/testData/quickfix/createFromUsage/get/afterCreateGetFromUsage12.kt +++ b/idea/testData/quickfix/createFromUsage/get/afterCreateGetFromUsage12.kt @@ -1,7 +1,7 @@ -// "Create method 'get' from usage" "true" +// "Create function 'get' from usage" "true" class Foo { fun get(s: String, w: T): Any { - throw UnsupportedOperationException("not implemented") //To change body of created methods use File | Settings | File Templates. + throw UnsupportedOperationException("not implemented") //To change body of created functions use File | Settings | File Templates. } } fun x (y: Foo>, w: java.util.ArrayList) { diff --git a/idea/testData/quickfix/createFromUsage/get/afterCreateGetFromUsage13.kt b/idea/testData/quickfix/createFromUsage/get/afterCreateGetFromUsage13.kt index 025bce56aa3..9326291c2b7 100644 --- a/idea/testData/quickfix/createFromUsage/get/afterCreateGetFromUsage13.kt +++ b/idea/testData/quickfix/createFromUsage/get/afterCreateGetFromUsage13.kt @@ -1,4 +1,4 @@ -// "Create method 'get' from usage" "true" +// "Create function 'get' from usage" "true" import java.util.ArrayList class Foo { @@ -8,6 +8,6 @@ class Foo { bar(z) } fun get(s: String, w: ArrayList): String { - throw UnsupportedOperationException("not implemented") //To change body of created methods use File | Settings | File Templates. + throw UnsupportedOperationException("not implemented") //To change body of created functions use File | Settings | File Templates. } } diff --git a/idea/testData/quickfix/createFromUsage/get/afterCreateGetFromUsage2.kt b/idea/testData/quickfix/createFromUsage/get/afterCreateGetFromUsage2.kt index 6a383097550..bb3346e55ff 100644 --- a/idea/testData/quickfix/createFromUsage/get/afterCreateGetFromUsage2.kt +++ b/idea/testData/quickfix/createFromUsage/get/afterCreateGetFromUsage2.kt @@ -1,7 +1,7 @@ -// "Create method 'get' from usage" "true" +// "Create function 'get' from usage" "true" fun x (y: Any) { val z: Any = y[""] } fun Any.get(s: String): Any { - throw UnsupportedOperationException("not implemented") //To change body of created methods use File | Settings | File Templates. + throw UnsupportedOperationException("not implemented") //To change body of created functions use File | Settings | File Templates. } \ No newline at end of file diff --git a/idea/testData/quickfix/createFromUsage/get/afterCreateGetFromUsage3.kt b/idea/testData/quickfix/createFromUsage/get/afterCreateGetFromUsage3.kt index 932974dafdb..7e2eda1e05a 100644 --- a/idea/testData/quickfix/createFromUsage/get/afterCreateGetFromUsage3.kt +++ b/idea/testData/quickfix/createFromUsage/get/afterCreateGetFromUsage3.kt @@ -1,9 +1,9 @@ -// "Create method 'get' from usage" "true" +// "Create function 'get' from usage" "true" class Foo { fun x (y: Foo>) { val z: Iterable = y[""] } fun get(s: String): T { - throw UnsupportedOperationException("not implemented") //To change body of created methods use File | Settings | File Templates. + throw UnsupportedOperationException("not implemented") //To change body of created functions use File | Settings | File Templates. } } diff --git a/idea/testData/quickfix/createFromUsage/get/afterCreateGetFromUsage4.kt b/idea/testData/quickfix/createFromUsage/get/afterCreateGetFromUsage4.kt index 896f28e678e..1a7a9c74bf6 100644 --- a/idea/testData/quickfix/createFromUsage/get/afterCreateGetFromUsage4.kt +++ b/idea/testData/quickfix/createFromUsage/get/afterCreateGetFromUsage4.kt @@ -1,9 +1,9 @@ -// "Create method 'get' from usage" "true" +// "Create function 'get' from usage" "true" class Foo> { fun x (y: Foo>) { val z: U = y[""] } fun get(s: String): T { - throw UnsupportedOperationException("not implemented") //To change body of created methods use File | Settings | File Templates. + throw UnsupportedOperationException("not implemented") //To change body of created functions use File | Settings | File Templates. } } diff --git a/idea/testData/quickfix/createFromUsage/get/afterCreateGetFromUsage5.kt b/idea/testData/quickfix/createFromUsage/get/afterCreateGetFromUsage5.kt index c3870922212..b04845a5917 100644 --- a/idea/testData/quickfix/createFromUsage/get/afterCreateGetFromUsage5.kt +++ b/idea/testData/quickfix/createFromUsage/get/afterCreateGetFromUsage5.kt @@ -1,9 +1,9 @@ -// "Create method 'get' from usage" "true" +// "Create function 'get' from usage" "true" class Foo { fun x (y: Foo>, w: Iterable) { val z: Iterable = y["", w] } fun get(s: String, w: Iterable): T { - throw UnsupportedOperationException("not implemented") //To change body of created methods use File | Settings | File Templates. + throw UnsupportedOperationException("not implemented") //To change body of created functions use File | Settings | File Templates. } } diff --git a/idea/testData/quickfix/createFromUsage/get/afterCreateGetFromUsage6.kt b/idea/testData/quickfix/createFromUsage/get/afterCreateGetFromUsage6.kt index 5302f028434..0a7c6bd4cae 100644 --- a/idea/testData/quickfix/createFromUsage/get/afterCreateGetFromUsage6.kt +++ b/idea/testData/quickfix/createFromUsage/get/afterCreateGetFromUsage6.kt @@ -1,4 +1,4 @@ -// "Create method 'get' from usage" "true" +// "Create function 'get' from usage" "true" import java.util.ArrayList class Foo { @@ -7,5 +7,5 @@ class Foo { } } fun ArrayList.get(s: String, w: ArrayList): Boolean { - throw UnsupportedOperationException("not implemented") //To change body of created methods use File | Settings | File Templates. + throw UnsupportedOperationException("not implemented") //To change body of created functions use File | Settings | File Templates. } \ No newline at end of file diff --git a/idea/testData/quickfix/createFromUsage/get/afterCreateGetFromUsage7.kt b/idea/testData/quickfix/createFromUsage/get/afterCreateGetFromUsage7.kt index 6f52661137a..1c4b070d6f2 100644 --- a/idea/testData/quickfix/createFromUsage/get/afterCreateGetFromUsage7.kt +++ b/idea/testData/quickfix/createFromUsage/get/afterCreateGetFromUsage7.kt @@ -1,4 +1,4 @@ -// "Create method 'get' from usage" "true" +// "Create function 'get' from usage" "true" import java.util.ArrayList class Foo { @@ -6,6 +6,6 @@ class Foo { val z: Iterable = y["", w] } fun get(s: String, w: ArrayList): T { - throw UnsupportedOperationException("not implemented") //To change body of created methods use File | Settings | File Templates. + throw UnsupportedOperationException("not implemented") //To change body of created functions use File | Settings | File Templates. } } diff --git a/idea/testData/quickfix/createFromUsage/get/afterCreateGetFromUsage8.kt b/idea/testData/quickfix/createFromUsage/get/afterCreateGetFromUsage8.kt index 0c87aa0374d..5697c984d88 100644 --- a/idea/testData/quickfix/createFromUsage/get/afterCreateGetFromUsage8.kt +++ b/idea/testData/quickfix/createFromUsage/get/afterCreateGetFromUsage8.kt @@ -1,4 +1,4 @@ -// "Create method 'get' from usage" "true" +// "Create function 'get' from usage" "true" import java.util.ArrayList class Foo { @@ -6,6 +6,6 @@ class Foo { val z: Iterable = y["", w] } fun get(s: String, w: T): T { - throw UnsupportedOperationException("not implemented") //To change body of created methods use File | Settings | File Templates. + throw UnsupportedOperationException("not implemented") //To change body of created functions use File | Settings | File Templates. } } diff --git a/idea/testData/quickfix/createFromUsage/get/afterCreateGetFromUsage9.kt b/idea/testData/quickfix/createFromUsage/get/afterCreateGetFromUsage9.kt index ed68a3b30d8..595ca53ddba 100644 --- a/idea/testData/quickfix/createFromUsage/get/afterCreateGetFromUsage9.kt +++ b/idea/testData/quickfix/createFromUsage/get/afterCreateGetFromUsage9.kt @@ -1,4 +1,4 @@ -// "Create method 'get' from usage" "true" +// "Create function 'get' from usage" "true" import java.util.ArrayList class Foo { @@ -6,6 +6,6 @@ class Foo { val z: Iterable = y["", w] } fun get(s: String, w: S): S { - throw UnsupportedOperationException("not implemented") //To change body of created methods use File | Settings | File Templates. + throw UnsupportedOperationException("not implemented") //To change body of created functions use File | Settings | File Templates. } } diff --git a/idea/testData/quickfix/createFromUsage/get/beforeCreateGetFromUsage1.kt b/idea/testData/quickfix/createFromUsage/get/beforeCreateGetFromUsage1.kt index 1f3f356d134..45cf33ed64a 100644 --- a/idea/testData/quickfix/createFromUsage/get/beforeCreateGetFromUsage1.kt +++ b/idea/testData/quickfix/createFromUsage/get/beforeCreateGetFromUsage1.kt @@ -1,4 +1,4 @@ -// "Create method 'get' from usage" "true" +// "Create function 'get' from usage" "true" class Foo { fun x (y: Foo>) { val z: Iterable = y[""] diff --git a/idea/testData/quickfix/createFromUsage/get/beforeCreateGetFromUsage10.kt b/idea/testData/quickfix/createFromUsage/get/beforeCreateGetFromUsage10.kt index dfe91efecb6..9827749a27d 100644 --- a/idea/testData/quickfix/createFromUsage/get/beforeCreateGetFromUsage10.kt +++ b/idea/testData/quickfix/createFromUsage/get/beforeCreateGetFromUsage10.kt @@ -1,4 +1,4 @@ -// "Create method 'get' from usage" "true" +// "Create function 'get' from usage" "true" class Foo { fun x (y: Foo>, w: java.util.ArrayList) { val z: Iterable = y["", w] diff --git a/idea/testData/quickfix/createFromUsage/get/beforeCreateGetFromUsage11.kt b/idea/testData/quickfix/createFromUsage/get/beforeCreateGetFromUsage11.kt index 1962cc4865a..76e5a86ca5a 100644 --- a/idea/testData/quickfix/createFromUsage/get/beforeCreateGetFromUsage11.kt +++ b/idea/testData/quickfix/createFromUsage/get/beforeCreateGetFromUsage11.kt @@ -1,4 +1,4 @@ -// "Create method 'get' from usage" "true" +// "Create function 'get' from usage" "true" class Foo fun x (y: Foo>, w: java.util.ArrayList) { val z: Iterable = y["", w] diff --git a/idea/testData/quickfix/createFromUsage/get/beforeCreateGetFromUsage12.kt b/idea/testData/quickfix/createFromUsage/get/beforeCreateGetFromUsage12.kt index 9a13b753aca..878d2a3a8f1 100644 --- a/idea/testData/quickfix/createFromUsage/get/beforeCreateGetFromUsage12.kt +++ b/idea/testData/quickfix/createFromUsage/get/beforeCreateGetFromUsage12.kt @@ -1,4 +1,4 @@ -// "Create method 'get' from usage" "true" +// "Create function 'get' from usage" "true" class Foo fun x (y: Foo>, w: java.util.ArrayList) { val z = y["", w] diff --git a/idea/testData/quickfix/createFromUsage/get/beforeCreateGetFromUsage13.kt b/idea/testData/quickfix/createFromUsage/get/beforeCreateGetFromUsage13.kt index 9986981854f..908af6d8dcb 100644 --- a/idea/testData/quickfix/createFromUsage/get/beforeCreateGetFromUsage13.kt +++ b/idea/testData/quickfix/createFromUsage/get/beforeCreateGetFromUsage13.kt @@ -1,4 +1,4 @@ -// "Create method 'get' from usage" "true" +// "Create function 'get' from usage" "true" import java.util.ArrayList class Foo { diff --git a/idea/testData/quickfix/createFromUsage/get/beforeCreateGetFromUsage2.kt b/idea/testData/quickfix/createFromUsage/get/beforeCreateGetFromUsage2.kt index 9d2682fbcc1..323a9d89ddf 100644 --- a/idea/testData/quickfix/createFromUsage/get/beforeCreateGetFromUsage2.kt +++ b/idea/testData/quickfix/createFromUsage/get/beforeCreateGetFromUsage2.kt @@ -1,4 +1,4 @@ -// "Create method 'get' from usage" "true" +// "Create function 'get' from usage" "true" fun x (y: Any) { val z: Any = y[""] } diff --git a/idea/testData/quickfix/createFromUsage/get/beforeCreateGetFromUsage3.kt b/idea/testData/quickfix/createFromUsage/get/beforeCreateGetFromUsage3.kt index 044c3f30c02..75ddb82a2dd 100644 --- a/idea/testData/quickfix/createFromUsage/get/beforeCreateGetFromUsage3.kt +++ b/idea/testData/quickfix/createFromUsage/get/beforeCreateGetFromUsage3.kt @@ -1,4 +1,4 @@ -// "Create method 'get' from usage" "true" +// "Create function 'get' from usage" "true" class Foo { fun x (y: Foo>) { val z: Iterable = y[""] diff --git a/idea/testData/quickfix/createFromUsage/get/beforeCreateGetFromUsage4.kt b/idea/testData/quickfix/createFromUsage/get/beforeCreateGetFromUsage4.kt index 06e54a609fb..9da2c52f293 100644 --- a/idea/testData/quickfix/createFromUsage/get/beforeCreateGetFromUsage4.kt +++ b/idea/testData/quickfix/createFromUsage/get/beforeCreateGetFromUsage4.kt @@ -1,4 +1,4 @@ -// "Create method 'get' from usage" "true" +// "Create function 'get' from usage" "true" class Foo> { fun x (y: Foo>) { val z: U = y[""] diff --git a/idea/testData/quickfix/createFromUsage/get/beforeCreateGetFromUsage5.kt b/idea/testData/quickfix/createFromUsage/get/beforeCreateGetFromUsage5.kt index 606253ab6dd..bc03671e4b4 100644 --- a/idea/testData/quickfix/createFromUsage/get/beforeCreateGetFromUsage5.kt +++ b/idea/testData/quickfix/createFromUsage/get/beforeCreateGetFromUsage5.kt @@ -1,4 +1,4 @@ -// "Create method 'get' from usage" "true" +// "Create function 'get' from usage" "true" class Foo { fun x (y: Foo>, w: Iterable) { val z: Iterable = y["", w] diff --git a/idea/testData/quickfix/createFromUsage/get/beforeCreateGetFromUsage6.kt b/idea/testData/quickfix/createFromUsage/get/beforeCreateGetFromUsage6.kt index 6df19aaf1fb..5ebce16d067 100644 --- a/idea/testData/quickfix/createFromUsage/get/beforeCreateGetFromUsage6.kt +++ b/idea/testData/quickfix/createFromUsage/get/beforeCreateGetFromUsage6.kt @@ -1,4 +1,4 @@ -// "Create method 'get' from usage" "true" +// "Create function 'get' from usage" "true" class Foo { fun x (y: java.util.ArrayList, w: java.util.ArrayList) { val z: java.util.ArrayList? = if (y["", w]) null else null diff --git a/idea/testData/quickfix/createFromUsage/get/beforeCreateGetFromUsage7.kt b/idea/testData/quickfix/createFromUsage/get/beforeCreateGetFromUsage7.kt index 585766c4eeb..1c06f9503ad 100644 --- a/idea/testData/quickfix/createFromUsage/get/beforeCreateGetFromUsage7.kt +++ b/idea/testData/quickfix/createFromUsage/get/beforeCreateGetFromUsage7.kt @@ -1,4 +1,4 @@ -// "Create method 'get' from usage" "true" +// "Create function 'get' from usage" "true" import java.util.ArrayList class Foo { diff --git a/idea/testData/quickfix/createFromUsage/get/beforeCreateGetFromUsage8.kt b/idea/testData/quickfix/createFromUsage/get/beforeCreateGetFromUsage8.kt index 7daa508dd1d..283b22d0e9d 100644 --- a/idea/testData/quickfix/createFromUsage/get/beforeCreateGetFromUsage8.kt +++ b/idea/testData/quickfix/createFromUsage/get/beforeCreateGetFromUsage8.kt @@ -1,4 +1,4 @@ -// "Create method 'get' from usage" "true" +// "Create function 'get' from usage" "true" import java.util.ArrayList class Foo { diff --git a/idea/testData/quickfix/createFromUsage/get/beforeCreateGetFromUsage9.kt b/idea/testData/quickfix/createFromUsage/get/beforeCreateGetFromUsage9.kt index e6fb8ae0da4..e41c0004c8d 100644 --- a/idea/testData/quickfix/createFromUsage/get/beforeCreateGetFromUsage9.kt +++ b/idea/testData/quickfix/createFromUsage/get/beforeCreateGetFromUsage9.kt @@ -1,4 +1,4 @@ -// "Create method 'get' from usage" "true" +// "Create function 'get' from usage" "true" import java.util.ArrayList class Foo { diff --git a/idea/testData/quickfix/createFromUsage/hasNext/afterCreateHasNextFromUsage1.kt b/idea/testData/quickfix/createFromUsage/hasNext/afterCreateHasNextFromUsage1.kt index f88d808c6e3..61499fd5802 100644 --- a/idea/testData/quickfix/createFromUsage/hasNext/afterCreateHasNextFromUsage1.kt +++ b/idea/testData/quickfix/createFromUsage/hasNext/afterCreateHasNextFromUsage1.kt @@ -1,10 +1,10 @@ -// "Create method 'hasNext' from usage" "true" +// "Create function 'hasNext' from usage" "true" class FooIterator { fun next(): Int { throw Exception("not implemented") } fun hasNext(): Boolean { - throw UnsupportedOperationException("not implemented") //To change body of created methods use File | Settings | File Templates. + throw UnsupportedOperationException("not implemented") //To change body of created functions use File | Settings | File Templates. } } class Foo { diff --git a/idea/testData/quickfix/createFromUsage/hasNext/afterCreateHasNextFromUsage2.kt b/idea/testData/quickfix/createFromUsage/hasNext/afterCreateHasNextFromUsage2.kt index d9e4dff154f..3ae6aac17ee 100644 --- a/idea/testData/quickfix/createFromUsage/hasNext/afterCreateHasNextFromUsage2.kt +++ b/idea/testData/quickfix/createFromUsage/hasNext/afterCreateHasNextFromUsage2.kt @@ -1,10 +1,10 @@ -// "Create method 'hasNext' from usage" "true" +// "Create function 'hasNext' from usage" "true" class FooIterator { fun next(): T { throw Exception("not implemented") } fun hasNext(): Boolean { - throw UnsupportedOperationException("not implemented") //To change body of created methods use File | Settings | File Templates. + throw UnsupportedOperationException("not implemented") //To change body of created functions use File | Settings | File Templates. } } class Foo { diff --git a/idea/testData/quickfix/createFromUsage/hasNext/beforeCreateHasNextFromUsage1.kt b/idea/testData/quickfix/createFromUsage/hasNext/beforeCreateHasNextFromUsage1.kt index 33e316a58dc..7c7a684a3b7 100644 --- a/idea/testData/quickfix/createFromUsage/hasNext/beforeCreateHasNextFromUsage1.kt +++ b/idea/testData/quickfix/createFromUsage/hasNext/beforeCreateHasNextFromUsage1.kt @@ -1,4 +1,4 @@ -// "Create method 'hasNext' from usage" "true" +// "Create function 'hasNext' from usage" "true" class FooIterator { fun next(): Int { throw Exception("not implemented") diff --git a/idea/testData/quickfix/createFromUsage/hasNext/beforeCreateHasNextFromUsage2.kt b/idea/testData/quickfix/createFromUsage/hasNext/beforeCreateHasNextFromUsage2.kt index e51b24ecefc..a0111a9cf93 100644 --- a/idea/testData/quickfix/createFromUsage/hasNext/beforeCreateHasNextFromUsage2.kt +++ b/idea/testData/quickfix/createFromUsage/hasNext/beforeCreateHasNextFromUsage2.kt @@ -1,4 +1,4 @@ -// "Create method 'hasNext' from usage" "true" +// "Create function 'hasNext' from usage" "true" class FooIterator { fun next(): T { throw Exception("not implemented") diff --git a/idea/testData/quickfix/createFromUsage/iterator/afterCreateIteratorFromUsage1.kt b/idea/testData/quickfix/createFromUsage/iterator/afterCreateIteratorFromUsage1.kt index c3392c5e2ef..56368bda717 100644 --- a/idea/testData/quickfix/createFromUsage/iterator/afterCreateIteratorFromUsage1.kt +++ b/idea/testData/quickfix/createFromUsage/iterator/afterCreateIteratorFromUsage1.kt @@ -1,7 +1,7 @@ -// "Create method 'iterator' from usage" "true" +// "Create function 'iterator' from usage" "true" class Foo { fun iterator(): Iterator { - throw UnsupportedOperationException("not implemented") //To change body of created methods use File | Settings | File Templates. + throw UnsupportedOperationException("not implemented") //To change body of created functions use File | Settings | File Templates. } } fun foo() { diff --git a/idea/testData/quickfix/createFromUsage/iterator/afterCreateIteratorFromUsage2.kt b/idea/testData/quickfix/createFromUsage/iterator/afterCreateIteratorFromUsage2.kt index 48e3b81e83f..745e922b240 100644 --- a/idea/testData/quickfix/createFromUsage/iterator/afterCreateIteratorFromUsage2.kt +++ b/idea/testData/quickfix/createFromUsage/iterator/afterCreateIteratorFromUsage2.kt @@ -1,7 +1,7 @@ -// "Create method 'iterator' from usage" "true" +// "Create function 'iterator' from usage" "true" class Foo { fun iterator(): Iterator { - throw UnsupportedOperationException("not implemented") //To change body of created methods use File | Settings | File Templates. + throw UnsupportedOperationException("not implemented") //To change body of created functions use File | Settings | File Templates. } } fun foo() { diff --git a/idea/testData/quickfix/createFromUsage/iterator/beforeCreateIteratorFromUsage1.kt b/idea/testData/quickfix/createFromUsage/iterator/beforeCreateIteratorFromUsage1.kt index e369b20bfd1..9638ae6649c 100644 --- a/idea/testData/quickfix/createFromUsage/iterator/beforeCreateIteratorFromUsage1.kt +++ b/idea/testData/quickfix/createFromUsage/iterator/beforeCreateIteratorFromUsage1.kt @@ -1,4 +1,4 @@ -// "Create method 'iterator' from usage" "true" +// "Create function 'iterator' from usage" "true" class Foo fun foo() { for (i: Int in Foo()) { } diff --git a/idea/testData/quickfix/createFromUsage/iterator/beforeCreateIteratorFromUsage2.kt b/idea/testData/quickfix/createFromUsage/iterator/beforeCreateIteratorFromUsage2.kt index dfbec160ce3..ac6103d86e4 100644 --- a/idea/testData/quickfix/createFromUsage/iterator/beforeCreateIteratorFromUsage2.kt +++ b/idea/testData/quickfix/createFromUsage/iterator/beforeCreateIteratorFromUsage2.kt @@ -1,4 +1,4 @@ -// "Create method 'iterator' from usage" "true" +// "Create function 'iterator' from usage" "true" class Foo fun foo() { for (i in Foo()) { diff --git a/idea/testData/quickfix/createFromUsage/next/afterCreateNextFromUsage1.kt b/idea/testData/quickfix/createFromUsage/next/afterCreateNextFromUsage1.kt index 84973737408..c4af609d658 100644 --- a/idea/testData/quickfix/createFromUsage/next/afterCreateNextFromUsage1.kt +++ b/idea/testData/quickfix/createFromUsage/next/afterCreateNextFromUsage1.kt @@ -1,8 +1,8 @@ -// "Create method 'next' from usage" "true" +// "Create function 'next' from usage" "true" class FooIterator { fun hasNext(): Boolean { return false } fun next(): Int { - throw UnsupportedOperationException("not implemented") //To change body of created methods use File | Settings | File Templates. + throw UnsupportedOperationException("not implemented") //To change body of created functions use File | Settings | File Templates. } } class Foo { diff --git a/idea/testData/quickfix/createFromUsage/next/afterCreateNextFromUsage2.kt b/idea/testData/quickfix/createFromUsage/next/afterCreateNextFromUsage2.kt index 65fd4e50922..f1232096bc7 100644 --- a/idea/testData/quickfix/createFromUsage/next/afterCreateNextFromUsage2.kt +++ b/idea/testData/quickfix/createFromUsage/next/afterCreateNextFromUsage2.kt @@ -1,8 +1,8 @@ -// "Create method 'next' from usage" "true" +// "Create function 'next' from usage" "true" class FooIterator { fun hasNext(): Boolean { return false } fun next(): T { - throw UnsupportedOperationException("not implemented") //To change body of created methods use File | Settings | File Templates. + throw UnsupportedOperationException("not implemented") //To change body of created functions use File | Settings | File Templates. } } class Foo { diff --git a/idea/testData/quickfix/createFromUsage/next/beforeCreateNextFromUsage1.kt b/idea/testData/quickfix/createFromUsage/next/beforeCreateNextFromUsage1.kt index c4b57554e31..687a980b4b0 100644 --- a/idea/testData/quickfix/createFromUsage/next/beforeCreateNextFromUsage1.kt +++ b/idea/testData/quickfix/createFromUsage/next/beforeCreateNextFromUsage1.kt @@ -1,4 +1,4 @@ -// "Create method 'next' from usage" "true" +// "Create function 'next' from usage" "true" class FooIterator { fun hasNext(): Boolean { return false } } diff --git a/idea/testData/quickfix/createFromUsage/next/beforeCreateNextFromUsage2.kt b/idea/testData/quickfix/createFromUsage/next/beforeCreateNextFromUsage2.kt index 401cdf419c5..8470052011f 100644 --- a/idea/testData/quickfix/createFromUsage/next/beforeCreateNextFromUsage2.kt +++ b/idea/testData/quickfix/createFromUsage/next/beforeCreateNextFromUsage2.kt @@ -1,4 +1,4 @@ -// "Create method 'next' from usage" "true" +// "Create function 'next' from usage" "true" class FooIterator { fun hasNext(): Boolean { return false } } diff --git a/idea/testData/quickfix/createFromUsage/set/afterCreateSetFromUsage1.kt b/idea/testData/quickfix/createFromUsage/set/afterCreateSetFromUsage1.kt index 24563965899..89f11450828 100644 --- a/idea/testData/quickfix/createFromUsage/set/afterCreateSetFromUsage1.kt +++ b/idea/testData/quickfix/createFromUsage/set/afterCreateSetFromUsage1.kt @@ -1,9 +1,9 @@ -// "Create method 'set' from usage" "true" +// "Create function 'set' from usage" "true" class Foo { fun x (y: Foo>, w: java.util.ArrayList) { y["", w] = w } fun set(s: String, w: T, value: T) { - throw UnsupportedOperationException("not implemented") //To change body of created methods use File | Settings | File Templates. + throw UnsupportedOperationException("not implemented") //To change body of created functions use File | Settings | File Templates. } } diff --git a/idea/testData/quickfix/createFromUsage/set/afterCreateSetFromUsage2.kt b/idea/testData/quickfix/createFromUsage/set/afterCreateSetFromUsage2.kt index 9312ab89375..f66da360eab 100644 --- a/idea/testData/quickfix/createFromUsage/set/afterCreateSetFromUsage2.kt +++ b/idea/testData/quickfix/createFromUsage/set/afterCreateSetFromUsage2.kt @@ -1,4 +1,4 @@ -// "Create method 'set' from usage" "true" +// "Create function 'set' from usage" "true" import java.util.ArrayList class Foo { @@ -7,5 +7,5 @@ class Foo { } } fun Any.set(s: String, w: ArrayList, value: ArrayList) { - throw UnsupportedOperationException("not implemented") //To change body of created methods use File | Settings | File Templates. + throw UnsupportedOperationException("not implemented") //To change body of created functions use File | Settings | File Templates. } \ No newline at end of file diff --git a/idea/testData/quickfix/createFromUsage/set/beforeCreateSetFromUsage1.kt b/idea/testData/quickfix/createFromUsage/set/beforeCreateSetFromUsage1.kt index 1cb5ce5e854..273dceb72a2 100644 --- a/idea/testData/quickfix/createFromUsage/set/beforeCreateSetFromUsage1.kt +++ b/idea/testData/quickfix/createFromUsage/set/beforeCreateSetFromUsage1.kt @@ -1,4 +1,4 @@ -// "Create method 'set' from usage" "true" +// "Create function 'set' from usage" "true" class Foo { fun x (y: Foo>, w: java.util.ArrayList) { y["", w] = w diff --git a/idea/testData/quickfix/createFromUsage/set/beforeCreateSetFromUsage2.kt b/idea/testData/quickfix/createFromUsage/set/beforeCreateSetFromUsage2.kt index 528ebc67bb2..dfdab89d714 100644 --- a/idea/testData/quickfix/createFromUsage/set/beforeCreateSetFromUsage2.kt +++ b/idea/testData/quickfix/createFromUsage/set/beforeCreateSetFromUsage2.kt @@ -1,4 +1,4 @@ -// "Create method 'set' from usage" "true" +// "Create function 'set' from usage" "true" class Foo { fun x (y: Any, w: java.util.ArrayList) { y["", w] = w From ea14607576e16314f5b0067482bcc9cf0e03c9a2 Mon Sep 17 00:00:00 2001 From: Jack Zhou Date: Wed, 1 May 2013 22:52:07 -0400 Subject: [PATCH 046/291] Create from usage: Made CreateGetFromUsage7 test clearer. --- .../createFromUsage/get/afterCreateGetFromUsage7.kt | 6 +++--- .../createFromUsage/get/beforeCreateGetFromUsage7.kt | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/idea/testData/quickfix/createFromUsage/get/afterCreateGetFromUsage7.kt b/idea/testData/quickfix/createFromUsage/get/afterCreateGetFromUsage7.kt index 1c4b070d6f2..74ab6f31993 100644 --- a/idea/testData/quickfix/createFromUsage/get/afterCreateGetFromUsage7.kt +++ b/idea/testData/quickfix/createFromUsage/get/afterCreateGetFromUsage7.kt @@ -2,10 +2,10 @@ import java.util.ArrayList class Foo { - fun x (y: Foo>, w: ArrayList) { - val z: Iterable = y["", w] + fun x (y: Foo>, w: ArrayList, v: T) { + val z: Iterable = y["", w, v] } - fun get(s: String, w: ArrayList): T { + fun get(s: String, w: ArrayList, v: T1): T { throw UnsupportedOperationException("not implemented") //To change body of created functions use File | Settings | File Templates. } } diff --git a/idea/testData/quickfix/createFromUsage/get/beforeCreateGetFromUsage7.kt b/idea/testData/quickfix/createFromUsage/get/beforeCreateGetFromUsage7.kt index 1c06f9503ad..b8d92eb2e81 100644 --- a/idea/testData/quickfix/createFromUsage/get/beforeCreateGetFromUsage7.kt +++ b/idea/testData/quickfix/createFromUsage/get/beforeCreateGetFromUsage7.kt @@ -2,7 +2,7 @@ import java.util.ArrayList class Foo { - fun x (y: Foo>, w: ArrayList) { - val z: Iterable = y["", w] + fun x (y: Foo>, w: ArrayList, v: T) { + val z: Iterable = y["", w, v] } } From 8535ef9be2b34e097821efe2d6f9aa876ceec49f Mon Sep 17 00:00:00 2001 From: Jack Zhou Date: Wed, 1 May 2013 22:55:36 -0400 Subject: [PATCH 047/291] Create from usage: Removed two constructors from TypeOrExpressionThereof. --- .../quickfix/CreateFunctionFromUsageFix.java | 26 +++++++------------ 1 file changed, 9 insertions(+), 17 deletions(-) diff --git a/idea/src/org/jetbrains/jet/plugin/quickfix/CreateFunctionFromUsageFix.java b/idea/src/org/jetbrains/jet/plugin/quickfix/CreateFunctionFromUsageFix.java index 3ab5e083522..6a7b30f8399 100644 --- a/idea/src/org/jetbrains/jet/plugin/quickfix/CreateFunctionFromUsageFix.java +++ b/idea/src/org/jetbrains/jet/plugin/quickfix/CreateFunctionFromUsageFix.java @@ -146,18 +146,10 @@ public class CreateFunctionFromUsageFix extends CreateFromUsageFixBase { private TypeCandidate[] typeCandidates; private String[] cachedNameCandidatesFromExpression; - public TypeOrExpressionThereof(@NotNull JetExpression expressionOfType) { - this(expressionOfType, Variance.IN_VARIANCE); - } - public TypeOrExpressionThereof(@NotNull JetExpression expressionOfType, Variance variance) { this(expressionOfType, null, variance); } - public TypeOrExpressionThereof(@NotNull JetType type) { - this(type, Variance.IN_VARIANCE); - } - public TypeOrExpressionThereof(@NotNull JetType type, Variance variance) { this(null, type, variance); } @@ -1215,12 +1207,12 @@ public class CreateFunctionFromUsageFix extends CreateFromUsageFixBase { if (accessExpr == null) return null; JetExpression arrayExpr = accessExpr.getArrayExpression(); if (arrayExpr == null) return null; - TypeOrExpressionThereof arrayType = new TypeOrExpressionThereof(arrayExpr); + TypeOrExpressionThereof arrayType = new TypeOrExpressionThereof(arrayExpr, Variance.IN_VARIANCE); List parameters = new ArrayList(); for (JetExpression indexExpr : accessExpr.getIndexExpressions()) { if (indexExpr == null) return null; - TypeOrExpressionThereof indexType = new TypeOrExpressionThereof(indexExpr); + TypeOrExpressionThereof indexType = new TypeOrExpressionThereof(indexExpr, Variance.IN_VARIANCE); parameters.add(new Parameter(null, indexType)); } @@ -1240,12 +1232,12 @@ public class CreateFunctionFromUsageFix extends CreateFromUsageFixBase { if (accessExpr == null) return null; JetExpression arrayExpr = accessExpr.getArrayExpression(); if (arrayExpr == null) return null; - TypeOrExpressionThereof arrayType = new TypeOrExpressionThereof(arrayExpr); + TypeOrExpressionThereof arrayType = new TypeOrExpressionThereof(arrayExpr, Variance.IN_VARIANCE); List parameters = new ArrayList(); for (JetExpression indexExpr : accessExpr.getIndexExpressions()) { if (indexExpr == null) return null; - TypeOrExpressionThereof indexType = new TypeOrExpressionThereof(indexExpr); + TypeOrExpressionThereof indexType = new TypeOrExpressionThereof(indexExpr, Variance.IN_VARIANCE); parameters.add(new Parameter(null, indexType)); } @@ -1253,7 +1245,7 @@ public class CreateFunctionFromUsageFix extends CreateFromUsageFixBase { if (assignmentExpr == null) return null; JetExpression rhs = assignmentExpr.getRight(); if (rhs == null) return null; - TypeOrExpressionThereof valType = new TypeOrExpressionThereof(rhs); + TypeOrExpressionThereof valType = new TypeOrExpressionThereof(rhs, Variance.IN_VARIANCE); parameters.add(new Parameter("value", valType)); TypeOrExpressionThereof returnType = new TypeOrExpressionThereof(KotlinBuiltIns.getInstance().getUnitType(), Variance.OUT_VARIANCE); @@ -1273,7 +1265,7 @@ public class CreateFunctionFromUsageFix extends CreateFromUsageFixBase { @SuppressWarnings("unchecked") DiagnosticWithParameters1 diagnosticWithParameters = (DiagnosticWithParameters1) diagnostic; - TypeOrExpressionThereof ownerType = new TypeOrExpressionThereof(diagnosticWithParameters.getA()); + TypeOrExpressionThereof ownerType = new TypeOrExpressionThereof(diagnosticWithParameters.getA(), Variance.IN_VARIANCE); JetForExpression forExpr = QuickFixUtil.getParentElementOfType(diagnostic, JetForExpression.class); if (forExpr == null) return null; @@ -1293,7 +1285,7 @@ public class CreateFunctionFromUsageFix extends CreateFromUsageFixBase { @SuppressWarnings("unchecked") DiagnosticWithParameters1 diagnosticWithParameters = (DiagnosticWithParameters1) diagnostic; - TypeOrExpressionThereof ownerType = new TypeOrExpressionThereof(diagnosticWithParameters.getA()); + TypeOrExpressionThereof ownerType = new TypeOrExpressionThereof(diagnosticWithParameters.getA(), Variance.IN_VARIANCE); JetForExpression forExpr = QuickFixUtil.getParentElementOfType(diagnostic, JetForExpression.class); if (forExpr == null) return null; @@ -1321,7 +1313,7 @@ public class CreateFunctionFromUsageFix extends CreateFromUsageFixBase { if (iterableExpr == null) return null; JetExpression variableExpr = forExpr.getLoopParameter(); if (variableExpr == null) return null; - TypeOrExpressionThereof iterableType = new TypeOrExpressionThereof(iterableExpr); + TypeOrExpressionThereof iterableType = new TypeOrExpressionThereof(iterableExpr, Variance.IN_VARIANCE); JetType returnJetType = KotlinBuiltIns.getInstance().getIterator().getDefaultType(); BindingContext context = AnalyzerFacadeWithCache.analyzeFileWithCache(jetFile).getBindingContext(); @@ -1362,7 +1354,7 @@ public class CreateFunctionFromUsageFix extends CreateFromUsageFixBase { TypeOrExpressionThereof returnType = new TypeOrExpressionThereof(entry, Variance.OUT_VARIANCE); JetExpression rhs = multiDeclaration.getInitializer(); if (rhs == null) return null; - TypeOrExpressionThereof ownerType = new TypeOrExpressionThereof(rhs); + TypeOrExpressionThereof ownerType = new TypeOrExpressionThereof(rhs, Variance.IN_VARIANCE); return new CreateFunctionFromUsageFix(multiDeclaration, ownerType, name.getIdentifier(), returnType, new ArrayList()); } From 74ae201c3613ba8f71ea592ae0703d6b4a476638 Mon Sep 17 00:00:00 2001 From: Jack Zhou Date: Wed, 1 May 2013 23:06:13 -0400 Subject: [PATCH 048/291] Create from usage: Changed type of TypeOrExpressionThereof.typeCandidates to List instead of array. --- .../quickfix/CreateFunctionFromUsageFix.java | 48 ++++++++----------- 1 file changed, 20 insertions(+), 28 deletions(-) diff --git a/idea/src/org/jetbrains/jet/plugin/quickfix/CreateFunctionFromUsageFix.java b/idea/src/org/jetbrains/jet/plugin/quickfix/CreateFunctionFromUsageFix.java index 6a7b30f8399..8cf1994f9f4 100644 --- a/idea/src/org/jetbrains/jet/plugin/quickfix/CreateFunctionFromUsageFix.java +++ b/idea/src/org/jetbrains/jet/plugin/quickfix/CreateFunctionFromUsageFix.java @@ -143,7 +143,7 @@ public class CreateFunctionFromUsageFix extends CreateFromUsageFixBase { private final JetExpression expressionOfType; private final JetType type; private final Variance variance; - private TypeCandidate[] typeCandidates; + private List typeCandidates; private String[] cachedNameCandidatesFromExpression; public TypeOrExpressionThereof(@NotNull JetExpression expressionOfType, Variance variance) { @@ -194,11 +194,9 @@ public class CreateFunctionFromUsageFix extends CreateFromUsageFixBase { public void computeTypeCandidates(@NotNull BindingContext context) { Collection types = getPossibleTypes(context); - typeCandidates = new TypeCandidate[types.size()]; - int i = 0; + typeCandidates = new ArrayList(); for (JetType type : types) { - typeCandidates[i] = new TypeCandidate(type); - i++; + typeCandidates.add(new TypeCandidate(type)); } } @@ -229,16 +227,15 @@ public class CreateFunctionFromUsageFix extends CreateFromUsageFixBase { newTypes.add(KotlinBuiltIns.getInstance().getAnyType()); } - typeCandidates = new TypeCandidate[newTypes.size()]; - int i = typeCandidates.length - 1; // reverse order (see explanation above) + typeCandidates = new ArrayList(); for (JetType type : newTypes) { - typeCandidates[i] = new TypeCandidate(type, scope); - i--; + typeCandidates.add(new TypeCandidate(type, scope)); } + Collections.reverse(typeCandidates); // reverse order (see explanation above) } @NotNull - public TypeCandidate[] getTypeCandidates() { + public List getTypeCandidates() { assert typeCandidates != null : "call computeTypeCandidates() first"; return typeCandidates; } @@ -379,10 +376,10 @@ public class CreateFunctionFromUsageFix extends CreateFromUsageFixBase { public TypeExpression(@NotNull TypeOrExpressionThereof type) { this.type = type; - TypeCandidate[] candidates = type.getTypeCandidates(); - cachedLookupElements = new LookupElement[candidates.length]; - for (int i = 0; i < candidates.length; i++) { - cachedLookupElements[i] = LookupElementBuilder.create(candidates[i], candidates[i].getRenderedType()); + List candidates = type.getTypeCandidates(); + cachedLookupElements = new LookupElement[candidates.size()]; + for (int i = 0; i < candidates.size(); i++) { + cachedLookupElements[i] = LookupElementBuilder.create(candidates.get(i), candidates.get(i).getRenderedType()); } } @@ -414,8 +411,7 @@ public class CreateFunctionFromUsageFix extends CreateFromUsageFixBase { @Nullable("can't be found") public JetType getTypeFromSelection(@NotNull String selection) { - TypeCandidate[] options = type.getTypeCandidates(); - for (TypeCandidate option : options) { + for (TypeCandidate option : type.getTypeCandidates()) { if (option.getRenderedType().equals(selection)) { return option.getType(); } @@ -556,10 +552,10 @@ public class CreateFunctionFromUsageFix extends CreateFromUsageFixBase { currentFileContext = AnalyzerFacadeWithCache.analyzeFileWithCache(currentFile).getBindingContext(); ownerType.computeTypeCandidates(currentFileContext); - TypeCandidate[] ownerTypeCandidates = ownerType.getTypeCandidates(); - assert ownerTypeCandidates.length > 0; - if (ownerTypeCandidates.length == 1 || ApplicationManager.getApplication().isUnitTestMode()) { - selectedReceiverType = ownerTypeCandidates[0]; + List ownerTypeCandidates = ownerType.getTypeCandidates(); + assert !ownerTypeCandidates.isEmpty(); + if (ownerTypeCandidates.size() == 1 || ApplicationManager.getApplication().isUnitTestMode()) { + selectedReceiverType = ownerTypeCandidates.get(0); doInvoke(project); } else { // class selection @@ -773,15 +769,13 @@ public class CreateFunctionFromUsageFix extends CreateFromUsageFixBase { allTypeParametersNotInScope.addAll(Arrays.asList(receiverTypeParametersNotInScope)); for (Parameter parameter : parameters) { - TypeCandidate[] parameterTypeCandidates = parameter.getType().getTypeCandidates(); - for (TypeCandidate parameterTypeCandidate : parameterTypeCandidates) { + for (TypeCandidate parameterTypeCandidate : parameter.getType().getTypeCandidates()) { allTypeParametersNotInScope.addAll(Arrays.asList(parameterTypeCandidate.getTypeParameters())); } } if (!isUnit) { - TypeCandidate[] returnTypeCandidates = returnType.getTypeCandidates(); - for (TypeCandidate returnTypeCandidate : returnTypeCandidates) { + for (TypeCandidate returnTypeCandidate : returnType.getTypeCandidates()) { allTypeParametersNotInScope.addAll(Arrays.asList(returnTypeCandidate.getTypeParameters())); } } @@ -898,16 +892,14 @@ public class CreateFunctionFromUsageFix extends CreateFromUsageFixBase { String[] receiverTypeParameterNames = selectedReceiverType.getTypeParameterNames(); for (Parameter parameter : parameters) { - TypeCandidate[] parameterTypeCandidates = parameter.getType().getTypeCandidates(); - for (TypeCandidate parameterTypeCandidate : parameterTypeCandidates) { + for (TypeCandidate parameterTypeCandidate : parameter.getType().getTypeCandidates()) { typeParameterMap.put(parameterTypeCandidate.getRenderedType(), parameterTypeCandidate.getTypeParameterNames()); } } JetTypeReference returnTypeRef = func.getReturnTypeRef(); if (returnTypeRef != null) { - TypeCandidate[] returnTypeCandidates = returnType.getTypeCandidates(); - for (TypeCandidate returnTypeCandidate : returnTypeCandidates) { + for (TypeCandidate returnTypeCandidate : returnType.getTypeCandidates()) { typeParameterMap.put(returnTypeCandidate.getRenderedType(), returnTypeCandidate.getTypeParameterNames()); } } From 1c18f9f17161bc0dd3f59f0d259669c28851c7e2 Mon Sep 17 00:00:00 2001 From: Jack Zhou Date: Wed, 1 May 2013 23:08:11 -0400 Subject: [PATCH 049/291] Create from usage: Renamed TypeSubstitution to JetTypeSubstitution. --- .../quickfix/CreateFunctionFromUsageFix.java | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/idea/src/org/jetbrains/jet/plugin/quickfix/CreateFunctionFromUsageFix.java b/idea/src/org/jetbrains/jet/plugin/quickfix/CreateFunctionFromUsageFix.java index 8cf1994f9f4..aa92b61d6b9 100644 --- a/idea/src/org/jetbrains/jet/plugin/quickfix/CreateFunctionFromUsageFix.java +++ b/idea/src/org/jetbrains/jet/plugin/quickfix/CreateFunctionFromUsageFix.java @@ -202,14 +202,14 @@ public class CreateFunctionFromUsageFix extends CreateFromUsageFixBase { public void computeTypeCandidates( @NotNull BindingContext context, - @NotNull TypeSubstitution[] substitutions, + @NotNull JetTypeSubstitution[] substitutions, @NotNull JetScope scope ) { List types = getPossibleTypes(context); Collections.reverse(types); // reverse and reverse back later, so that things added below are added at the front Set newTypes = new LinkedHashSet(types); - for (TypeSubstitution substitution : substitutions) { // each substitution can be applied or not, so we offer all options + for (JetTypeSubstitution substitution : substitutions) { // each substitution can be applied or not, so we offer all options List toAdd = new ArrayList(); List toRemove = new ArrayList(); for (JetType type : newTypes) { @@ -492,11 +492,11 @@ public class CreateFunctionFromUsageFix extends CreateFromUsageFixBase { /** * Encapsulates a single type substitution of a JetType by another JetType. */ - private static class TypeSubstitution { + private static class JetTypeSubstitution { private final JetType forType; private final JetType byType; - private TypeSubstitution(JetType forType, JetType byType) { + private JetTypeSubstitution(JetType forType, JetType byType) { this.forType = forType; this.byType = byType; } @@ -632,9 +632,9 @@ public class CreateFunctionFromUsageFix extends CreateFromUsageFixBase { List classTypeParameters = receiverType.getArguments(); List ownerTypeArguments = selectedReceiverType.getType().getArguments(); assert ownerTypeArguments.size() == classTypeParameters.size(); - TypeSubstitution[] substitutions = new TypeSubstitution[classTypeParameters.size()]; + JetTypeSubstitution[] substitutions = new JetTypeSubstitution[classTypeParameters.size()]; for (int i = 0; i < substitutions.length; i++) { - substitutions[i] = new TypeSubstitution(ownerTypeArguments.get(i).getType(), classTypeParameters.get(i).getType()); + substitutions[i] = new JetTypeSubstitution(ownerTypeArguments.get(i).getType(), classTypeParameters.get(i).getType()); } for (Parameter parameter : parameters) { parameter.getType().computeTypeCandidates(currentFileContext, substitutions, scope); @@ -958,7 +958,7 @@ public class CreateFunctionFromUsageFix extends CreateFromUsageFixBase { } @NotNull - private static JetType substituteType(@NotNull JetType type, @NotNull TypeSubstitution substitution, @NotNull Variance variance) { + private static JetType substituteType(@NotNull JetType type, @NotNull JetTypeSubstitution substitution, @NotNull Variance variance) { switch (variance) { case INVARIANT: // for invariant, can replace only when they're equal From f3e6c70e4088c89916aa8569eef71cd484088f02 Mon Sep 17 00:00:00 2001 From: Jack Zhou Date: Thu, 2 May 2013 10:54:38 -0400 Subject: [PATCH 050/291] Create from usage: Changed class selection to be look like Java. --- .../quickfix/CreateFunctionFromUsageFix.java | 90 ++++++++++++++----- 1 file changed, 66 insertions(+), 24 deletions(-) diff --git a/idea/src/org/jetbrains/jet/plugin/quickfix/CreateFunctionFromUsageFix.java b/idea/src/org/jetbrains/jet/plugin/quickfix/CreateFunctionFromUsageFix.java index aa92b61d6b9..93e9a769f27 100644 --- a/idea/src/org/jetbrains/jet/plugin/quickfix/CreateFunctionFromUsageFix.java +++ b/idea/src/org/jetbrains/jet/plugin/quickfix/CreateFunctionFromUsageFix.java @@ -64,16 +64,18 @@ import org.jetbrains.jet.lang.types.*; 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.codeInsight.DescriptorToDeclarationUtil; import org.jetbrains.jet.plugin.codeInsight.ReferenceToClassesShortening; -import org.jetbrains.jet.plugin.presentation.JetLightClassListCellRenderer; +import org.jetbrains.jet.plugin.presentation.JetClassPresenter; import org.jetbrains.jet.plugin.project.AnalyzerFacadeWithCache; import org.jetbrains.jet.plugin.refactoring.JetNameSuggester; import org.jetbrains.jet.plugin.refactoring.JetNameValidator; import org.jetbrains.jet.plugin.references.JetSimpleNameReference; -import org.jetbrains.jet.renderer.DescriptorRenderer; import javax.swing.*; +import java.awt.*; import java.util.*; +import java.util.List; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -136,6 +138,62 @@ public class CreateFunctionFromUsageFix extends CreateFromUsageFixBase { } } + /** + * Represents an element in the class selection list. + */ + private static class ClassCandidate { + private final TypeCandidate typeCandidate; + private final JetClass klass; + + public ClassCandidate(TypeCandidate typeCandidate, JetFile file, BindingContext context) { + this.typeCandidate = typeCandidate; + ClassDescriptor classDescriptor = DescriptorUtils.getClassDescriptorForType(typeCandidate.getType()); + PsiElement element = DescriptorToDeclarationUtil.getDeclaration(file, classDescriptor, context); + assert element instanceof JetClass; + klass = (JetClass) element; + } + + public TypeCandidate getTypeCandidate() { + return typeCandidate; + } + + public JetClass getJetClass() { + return klass; + } + } + + /** + * Renders a ClassCandidate. + */ + private static class ClassCandidateListCellRenderer extends PsiElementListCellRenderer { + private final JetClassPresenter presenter; + + public ClassCandidateListCellRenderer() { + presenter = new JetClassPresenter(); + } + + @Override + public String getElementText(JetClass element) { + return presenter.getPresentation(element).getPresentableText(); + } + + @Nullable + @Override + protected String getContainerText(JetClass element, String name) { + return presenter.getPresentation(element).getLocationString(); + } + + @Override + protected int getIconFlags() { + return 0; + } + + @Override + public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) { + return super.getListCellRendererComponent(list, ((ClassCandidate) value).getJetClass(), index, isSelected, cellHasFocus); + } + } + /** * Represents a concrete type or a set of types yet to be inferred from an expression. */ @@ -559,22 +617,13 @@ public class CreateFunctionFromUsageFix extends CreateFromUsageFixBase { doInvoke(project); } else { // class selection - List options = new ArrayList(); - final Map optionToTypeMap = new HashMap(); + List options = new ArrayList(); for (TypeCandidate ownerTypeCandidate : ownerTypeCandidates) { - ClassifierDescriptor possibleClassDescriptor = ownerTypeCandidate.getType().getConstructor().getDeclarationDescriptor(); - if (possibleClassDescriptor != null) { - String className = DescriptorRenderer.SHORT_NAMES_IN_TYPES.renderType(possibleClassDescriptor.getDefaultType()); - DeclarationDescriptor namespaceDescriptor = possibleClassDescriptor.getContainingDeclaration(); - String namespace = renderDescriptor(namespaceDescriptor, true); - String option = className + " (" + namespace + ")"; - options.add(option); - optionToTypeMap.put(option, ownerTypeCandidate); - } + options.add(new ClassCandidate(ownerTypeCandidate, currentFile, currentFileContext)); } final JList list = new JBList(options); - PsiElementListCellRenderer renderer = new JetLightClassListCellRenderer(); + PsiElementListCellRenderer renderer = new ClassCandidateListCellRenderer(); list.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); list.setCellRenderer(renderer); PopupChooserBuilder builder = new PopupChooserBuilder(list); @@ -585,8 +634,8 @@ public class CreateFunctionFromUsageFix extends CreateFromUsageFixBase { public void run() { int index = list.getSelectedIndex(); if (index < 0) return; - String option = (String) list.getSelectedValue(); - selectedReceiverType = optionToTypeMap.get(option); + ClassCandidate selectedCandidate = (ClassCandidate) list.getSelectedValue(); + selectedReceiverType = selectedCandidate.getTypeCandidate(); CommandProcessor.getInstance().executeCommand(project, new Runnable() { @Override public void run() { @@ -605,9 +654,7 @@ public class CreateFunctionFromUsageFix extends CreateFromUsageFixBase { private void doInvoke(@NotNull final Project project) { // gather relevant information - ClassifierDescriptor ownerTypeDescriptor = selectedReceiverType.getType().getConstructor().getDeclarationDescriptor(); - assert ownerTypeDescriptor != null && ownerTypeDescriptor instanceof ClassDescriptor; - ownerClassDescriptor = (ClassDescriptor) ownerTypeDescriptor; + ownerClassDescriptor = DescriptorUtils.getClassDescriptorForType(selectedReceiverType.getType()); JetType receiverType = ownerClassDescriptor.getDefaultType(); PsiElement typeDeclaration = BindingContextUtils.classDescriptorToDeclaration(currentFileContext, ownerClassDescriptor); if (typeDeclaration != null && typeDeclaration instanceof JetClass) { @@ -1021,11 +1068,6 @@ public class CreateFunctionFromUsageFix extends CreateFromUsageFixBase { } } - @NotNull - private static String renderDescriptor(@NotNull DeclarationDescriptor declarationDescriptor, boolean fq) { - return renderDescriptor(declarationDescriptor, Collections.emptyMap(), fq); - } - private static String renderType(@NotNull JetType type, @NotNull Map typeParameterNameMap, boolean fq) { List projections = type.getArguments(); DeclarationDescriptor declarationDescriptor = type.getConstructor().getDeclarationDescriptor(); From 7e5c04ad6de37fe602e0c188cdef4c23773eaedc Mon Sep 17 00:00:00 2001 From: Jack Zhou Date: Thu, 2 May 2013 10:57:54 -0400 Subject: [PATCH 051/291] Create from usage: Changed checking list.getSelectedIndex() for < 0 to checking list.getSelectedValue() for null. --- .../jet/plugin/quickfix/CreateFunctionFromUsageFix.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/idea/src/org/jetbrains/jet/plugin/quickfix/CreateFunctionFromUsageFix.java b/idea/src/org/jetbrains/jet/plugin/quickfix/CreateFunctionFromUsageFix.java index 93e9a769f27..ca7f5879c05 100644 --- a/idea/src/org/jetbrains/jet/plugin/quickfix/CreateFunctionFromUsageFix.java +++ b/idea/src/org/jetbrains/jet/plugin/quickfix/CreateFunctionFromUsageFix.java @@ -632,9 +632,8 @@ public class CreateFunctionFromUsageFix extends CreateFromUsageFixBase { Runnable runnable = new Runnable() { @Override public void run() { - int index = list.getSelectedIndex(); - if (index < 0) return; ClassCandidate selectedCandidate = (ClassCandidate) list.getSelectedValue(); + if (selectedCandidate == null) return; selectedReceiverType = selectedCandidate.getTypeCandidate(); CommandProcessor.getInstance().executeCommand(project, new Runnable() { @Override From 6ba66cedeaaf61ca39468d14c66eda85a3167a71 Mon Sep 17 00:00:00 2001 From: Jack Zhou Date: Thu, 2 May 2013 10:59:56 -0400 Subject: [PATCH 052/291] Create from usage: Renamed doInvoke to addFunctionToSelectedOwner. --- .../jet/plugin/quickfix/CreateFunctionFromUsageFix.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/idea/src/org/jetbrains/jet/plugin/quickfix/CreateFunctionFromUsageFix.java b/idea/src/org/jetbrains/jet/plugin/quickfix/CreateFunctionFromUsageFix.java index ca7f5879c05..69b37d8a128 100644 --- a/idea/src/org/jetbrains/jet/plugin/quickfix/CreateFunctionFromUsageFix.java +++ b/idea/src/org/jetbrains/jet/plugin/quickfix/CreateFunctionFromUsageFix.java @@ -614,7 +614,7 @@ public class CreateFunctionFromUsageFix extends CreateFromUsageFixBase { assert !ownerTypeCandidates.isEmpty(); if (ownerTypeCandidates.size() == 1 || ApplicationManager.getApplication().isUnitTestMode()) { selectedReceiverType = ownerTypeCandidates.get(0); - doInvoke(project); + addFunctionToSelectedOwner(project); } else { // class selection List options = new ArrayList(); @@ -638,7 +638,7 @@ public class CreateFunctionFromUsageFix extends CreateFromUsageFixBase { CommandProcessor.getInstance().executeCommand(project, new Runnable() { @Override public void run() { - doInvoke(project); + addFunctionToSelectedOwner(project); } }, getText(), null); } @@ -651,7 +651,7 @@ public class CreateFunctionFromUsageFix extends CreateFromUsageFixBase { } } - private void doInvoke(@NotNull final Project project) { + private void addFunctionToSelectedOwner(@NotNull final Project project) { // gather relevant information ownerClassDescriptor = DescriptorUtils.getClassDescriptorForType(selectedReceiverType.getType()); JetType receiverType = ownerClassDescriptor.getDefaultType(); From bdf73c07b8e10fdbd3c7cf1fbcc406f91da0e4b6 Mon Sep 17 00:00:00 2001 From: Jack Zhou Date: Thu, 2 May 2013 11:00:58 -0400 Subject: [PATCH 053/291] Create from usage: Renamed typeDeclaration to classDeclaration. --- .../jet/plugin/quickfix/CreateFunctionFromUsageFix.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/idea/src/org/jetbrains/jet/plugin/quickfix/CreateFunctionFromUsageFix.java b/idea/src/org/jetbrains/jet/plugin/quickfix/CreateFunctionFromUsageFix.java index 69b37d8a128..d62da8001c9 100644 --- a/idea/src/org/jetbrains/jet/plugin/quickfix/CreateFunctionFromUsageFix.java +++ b/idea/src/org/jetbrains/jet/plugin/quickfix/CreateFunctionFromUsageFix.java @@ -655,9 +655,9 @@ public class CreateFunctionFromUsageFix extends CreateFromUsageFixBase { // gather relevant information ownerClassDescriptor = DescriptorUtils.getClassDescriptorForType(selectedReceiverType.getType()); JetType receiverType = ownerClassDescriptor.getDefaultType(); - PsiElement typeDeclaration = BindingContextUtils.classDescriptorToDeclaration(currentFileContext, ownerClassDescriptor); - if (typeDeclaration != null && typeDeclaration instanceof JetClass) { - ownerClass = (JetClass) typeDeclaration; + PsiElement classDeclaration = BindingContextUtils.classDescriptorToDeclaration(currentFileContext, ownerClassDescriptor); + if (classDeclaration != null && classDeclaration instanceof JetClass) { + ownerClass = (JetClass) classDeclaration; isExtension = !ownerClass.isWritable(); } else { isExtension = true; From 1a34c71763dfe06779e24aafc79f8b7309f8b6dd Mon Sep 17 00:00:00 2001 From: Jack Zhou Date: Thu, 2 May 2013 11:03:42 -0400 Subject: [PATCH 054/291] Create from usage: Removed checking for null before instanceof. --- .../jet/plugin/quickfix/CreateFunctionFromUsageFix.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/idea/src/org/jetbrains/jet/plugin/quickfix/CreateFunctionFromUsageFix.java b/idea/src/org/jetbrains/jet/plugin/quickfix/CreateFunctionFromUsageFix.java index d62da8001c9..4dd107f54cd 100644 --- a/idea/src/org/jetbrains/jet/plugin/quickfix/CreateFunctionFromUsageFix.java +++ b/idea/src/org/jetbrains/jet/plugin/quickfix/CreateFunctionFromUsageFix.java @@ -382,7 +382,7 @@ public class CreateFunctionFromUsageFix extends CreateFromUsageFixBase { Editor editor = context.getEditor(); assert editor != null; PsiFile file = PsiDocumentManager.getInstance(project).getPsiFile(editor.getDocument()); - assert file != null && file instanceof JetFile; + assert file instanceof JetFile; PsiElement elementAt = file.findElementAt(offset); JetFunction func = PsiTreeUtil.getParentOfType(elementAt, JetFunction.class); if (func == null) return new LookupElement[0]; @@ -502,7 +502,7 @@ public class CreateFunctionFromUsageFix extends CreateFromUsageFixBase { Editor editor = context.getEditor(); assert editor != null; PsiFile file = PsiDocumentManager.getInstance(project).getPsiFile(editor.getDocument()); - assert file != null && file instanceof JetFile; + assert file instanceof JetFile; PsiElement elementAt = file.findElementAt(offset); JetFunction func = PsiTreeUtil.getParentOfType(elementAt, JetFunction.class); if (func == null) { @@ -604,7 +604,7 @@ public class CreateFunctionFromUsageFix extends CreateFromUsageFixBase { @Override public void invoke(@NotNull final Project project, Editor editor, PsiFile file) throws IncorrectOperationException { - assert file != null && file instanceof JetFile; + assert file instanceof JetFile; currentFile = (JetFile) file; currentFileEditor = editor; currentFileContext = AnalyzerFacadeWithCache.analyzeFileWithCache(currentFile).getBindingContext(); @@ -656,7 +656,7 @@ public class CreateFunctionFromUsageFix extends CreateFromUsageFixBase { ownerClassDescriptor = DescriptorUtils.getClassDescriptorForType(selectedReceiverType.getType()); JetType receiverType = ownerClassDescriptor.getDefaultType(); PsiElement classDeclaration = BindingContextUtils.classDescriptorToDeclaration(currentFileContext, ownerClassDescriptor); - if (classDeclaration != null && classDeclaration instanceof JetClass) { + if (classDeclaration instanceof JetClass) { ownerClass = (JetClass) classDeclaration; isExtension = !ownerClass.isWritable(); } else { From e0201bf8f36b879b6f7e5e57fc3842f903c19cdc Mon Sep 17 00:00:00 2001 From: Jack Zhou Date: Thu, 2 May 2013 11:17:04 -0400 Subject: [PATCH 055/291] Create from usage: Removed extraneous project parameters. --- .../quickfix/CreateFunctionFromUsageFix.java | 43 ++++++++++--------- 1 file changed, 22 insertions(+), 21 deletions(-) diff --git a/idea/src/org/jetbrains/jet/plugin/quickfix/CreateFunctionFromUsageFix.java b/idea/src/org/jetbrains/jet/plugin/quickfix/CreateFunctionFromUsageFix.java index 4dd107f54cd..83631599102 100644 --- a/idea/src/org/jetbrains/jet/plugin/quickfix/CreateFunctionFromUsageFix.java +++ b/idea/src/org/jetbrains/jet/plugin/quickfix/CreateFunctionFromUsageFix.java @@ -614,7 +614,7 @@ public class CreateFunctionFromUsageFix extends CreateFromUsageFixBase { assert !ownerTypeCandidates.isEmpty(); if (ownerTypeCandidates.size() == 1 || ApplicationManager.getApplication().isUnitTestMode()) { selectedReceiverType = ownerTypeCandidates.get(0); - addFunctionToSelectedOwner(project); + addFunctionToSelectedOwner(); } else { // class selection List options = new ArrayList(); @@ -638,7 +638,7 @@ public class CreateFunctionFromUsageFix extends CreateFromUsageFixBase { CommandProcessor.getInstance().executeCommand(project, new Runnable() { @Override public void run() { - addFunctionToSelectedOwner(project); + addFunctionToSelectedOwner(); } }, getText(), null); } @@ -651,7 +651,7 @@ public class CreateFunctionFromUsageFix extends CreateFromUsageFixBase { } } - private void addFunctionToSelectedOwner(@NotNull final Project project) { + private void addFunctionToSelectedOwner() { // gather relevant information ownerClassDescriptor = DescriptorUtils.getClassDescriptorForType(selectedReceiverType.getType()); JetType receiverType = ownerClassDescriptor.getDefaultType(); @@ -705,13 +705,14 @@ public class CreateFunctionFromUsageFix extends CreateFromUsageFixBase { ApplicationManager.getApplication().runWriteAction(new Runnable() { @Override public void run() { - JetNamedFunction func = createFunctionSkeleton(project); - buildAndRunTemplate(project, func); + JetNamedFunction func = createFunctionSkeleton(); + buildAndRunTemplate(func); } }); } - private JetNamedFunction createFunctionSkeleton(@NotNull Project project) { + private JetNamedFunction createFunctionSkeleton() { + Project project = currentFile.getProject(); JetNamedFunction func; String[] parameterStrings = new String[parameters.size()]; for (int i = 0; i < parameterStrings.length; i++) { @@ -751,7 +752,8 @@ public class CreateFunctionFromUsageFix extends CreateFromUsageFixBase { return func; } - private void buildAndRunTemplate(@NotNull final Project project, @NotNull JetNamedFunction func) { + private void buildAndRunTemplate(@NotNull JetNamedFunction func) { + Project project = func.getProject(); JetParameterList parameterList = func.getValueParameterList(); assert parameterList != null; @@ -764,7 +766,7 @@ public class CreateFunctionFromUsageFix extends CreateFromUsageFixBase { TemplateBuilderImpl builder = new TemplateBuilderImpl(containingFile); final TypeExpression returnTypeExpression = isUnit ? null : setupReturnTypeTemplate(builder, func); - final TypeExpression[] parameterTypeExpressions = setupParameterTypeTemplates(project, builder, parameterList); + final TypeExpression[] parameterTypeExpressions = setupParameterTypeTemplates(builder, parameterList); // add a segment for the parameter list // Note: because TemplateBuilderImpl does not have a replaceElement overload that takes in both a TextRange and alwaysStopAt, we @@ -797,10 +799,10 @@ public class CreateFunctionFromUsageFix extends CreateFromUsageFixBase { @Override public void run() { // file templates - setupFunctionBody(project, func); + setupFunctionBody(func); // change short type names to fully qualified ones (to be shortened below) - setupTypeReferencesForShortening(project, func, typeRefsToShorten, parameterTypeExpressions, returnTypeExpression); + setupTypeReferencesForShortening(func, typeRefsToShorten, parameterTypeExpressions, returnTypeExpression); } }); @@ -841,7 +843,6 @@ public class CreateFunctionFromUsageFix extends CreateFromUsageFixBase { } private void setupTypeReferencesForShortening( - @NotNull Project project, @NotNull JetNamedFunction func, @NotNull List typeRefsToShorten, @NotNull TypeExpression[] parameterTypeExpressions, @@ -849,8 +850,8 @@ public class CreateFunctionFromUsageFix extends CreateFromUsageFixBase { ) { if (isExtension) { JetTypeReference receiverTypeRef = - JetPsiFactory.createType(project, renderTypeLong(selectedReceiverType.getType(), typeParameterNameMap)); - replaceWithLongerName(project, receiverTypeRef, selectedReceiverType.getType()); + JetPsiFactory.createType(func.getProject(), renderTypeLong(selectedReceiverType.getType(), typeParameterNameMap)); + replaceWithLongerName(receiverTypeRef, selectedReceiverType.getType()); receiverTypeRef = func.getReceiverTypeRef(); if (receiverTypeRef != null) { @@ -864,7 +865,7 @@ public class CreateFunctionFromUsageFix extends CreateFromUsageFixBase { if (returnTypeRef != null) { JetType returnType = returnTypeExpression.getTypeFromSelection(returnTypeRef.getText()); if (returnType != null) { // user selected a given type - replaceWithLongerName(project, returnTypeRef, returnType); + replaceWithLongerName(returnTypeRef, returnType); returnTypeRef = func.getReturnTypeRef(); assert returnTypeRef != null; typeRefsToShorten.add(returnTypeRef); @@ -881,7 +882,7 @@ public class CreateFunctionFromUsageFix extends CreateFromUsageFixBase { if (parameterTypeRef != null) { JetType parameterType = parameterTypeExpressions[i].getTypeFromSelection(parameterTypeRef.getText()); if (parameterType != null) { - replaceWithLongerName(project, parameterTypeRef, parameterType); + replaceWithLongerName(parameterTypeRef, parameterType); parameterIndicesToShorten.add(i); } } @@ -895,7 +896,7 @@ public class CreateFunctionFromUsageFix extends CreateFromUsageFixBase { } } - private void setupFunctionBody(@NotNull Project project, @NotNull JetNamedFunction func) { + private void setupFunctionBody(@NotNull JetNamedFunction func) { FileTemplate fileTemplate = FileTemplateManager.getInstance().getCodeTemplate(TEMPLATE_FROM_USAGE_FUNCTION_BODY); Properties properties = new Properties(); if (isUnit) { @@ -917,7 +918,7 @@ public class CreateFunctionFromUsageFix extends CreateFromUsageFixBase { } catch (Exception e) { throw new IncorrectOperationException("Failed to parse file template", e); } - JetExpression newBodyExpression = JetPsiFactory.createFunctionBody(project, bodyText); + JetExpression newBodyExpression = JetPsiFactory.createFunctionBody(func.getProject(), bodyText); JetExpression oldBodyExpression = func.getBodyExpression(); assert oldBodyExpression != null; oldBodyExpression.replace(newBodyExpression); @@ -954,12 +955,11 @@ public class CreateFunctionFromUsageFix extends CreateFromUsageFixBase { return new TypeParameterListExpression(receiverTypeParameterNames, typeParameterMap); } - private TypeExpression[] setupParameterTypeTemplates(@NotNull Project project, @NotNull TemplateBuilder builder, - @NotNull JetParameterList parameterList) { + private TypeExpression[] setupParameterTypeTemplates(@NotNull TemplateBuilder builder, @NotNull JetParameterList parameterList) { List jetParameters = parameterList.getParameters(); assert jetParameters.size() == parameters.size(); TypeExpression[] parameterTypeExpressions = new TypeExpression[parameters.size()]; - JetNameValidator dummyValidator = JetNameValidator.getEmptyValidator(project); + JetNameValidator dummyValidator = JetNameValidator.getEmptyValidator(parameterList.getProject()); for (int i = 0; i < parameters.size(); i++) { Parameter parameter = parameters.get(i); JetParameter jetParameter = jetParameters.get(i); @@ -998,7 +998,8 @@ public class CreateFunctionFromUsageFix extends CreateFromUsageFixBase { return parameterTypeExpressions; } - private void replaceWithLongerName(@NotNull Project project, @NotNull JetTypeReference typeRef, @NotNull JetType type) { + private void replaceWithLongerName(@NotNull JetTypeReference typeRef, @NotNull JetType type) { + Project project = typeRef.getProject(); JetTypeReference fullyQualifiedReceiverTypeRef = JetPsiFactory.createType(project, renderTypeLong(type, typeParameterNameMap)); typeRef.replace(fullyQualifiedReceiverTypeRef); } From 8d3c1cddb4fb896f5dbfa209f03071bca7403a61 Mon Sep 17 00:00:00 2001 From: Jack Zhou Date: Thu, 2 May 2013 11:17:49 -0400 Subject: [PATCH 056/291] Create from usage: Returning immediately to avoid reassignment. --- .../jet/plugin/quickfix/CreateFunctionFromUsageFix.java | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/idea/src/org/jetbrains/jet/plugin/quickfix/CreateFunctionFromUsageFix.java b/idea/src/org/jetbrains/jet/plugin/quickfix/CreateFunctionFromUsageFix.java index 83631599102..d02698e40d4 100644 --- a/idea/src/org/jetbrains/jet/plugin/quickfix/CreateFunctionFromUsageFix.java +++ b/idea/src/org/jetbrains/jet/plugin/quickfix/CreateFunctionFromUsageFix.java @@ -726,7 +726,7 @@ public class CreateFunctionFromUsageFix extends CreateFromUsageFixBase { func = JetPsiFactory.createFunction(project, functionText); containingFile = currentFile; containingFileEditor = currentFileEditor; - func = (JetNamedFunction) currentFile.add(func); + return (JetNamedFunction) currentFile.add(func); } else { // create as regular function String functionText = String.format("fun %s(%s)%s { }", functionName, parametersString, returnTypeString); func = JetPsiFactory.createFunction(project, functionText); @@ -746,10 +746,8 @@ public class CreateFunctionFromUsageFix extends CreateFromUsageFixBase { } PsiElement rBrace = classBody.getRBrace(); assert rBrace != null; - func = (JetNamedFunction) classBody.addBefore(func, rBrace); + return (JetNamedFunction) classBody.addBefore(func, rBrace); } - - return func; } private void buildAndRunTemplate(@NotNull JetNamedFunction func) { From b527ec45a33d88ec8617df50c1c3682eb13892dc Mon Sep 17 00:00:00 2001 From: Jack Zhou Date: Thu, 2 May 2013 11:20:19 -0400 Subject: [PATCH 057/291] Create from usage: Renamed underscore identifier. --- .../plugin/quickfix/CreateFunctionFromUsageFix.java | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/idea/src/org/jetbrains/jet/plugin/quickfix/CreateFunctionFromUsageFix.java b/idea/src/org/jetbrains/jet/plugin/quickfix/CreateFunctionFromUsageFix.java index d02698e40d4..81f67c0be8c 100644 --- a/idea/src/org/jetbrains/jet/plugin/quickfix/CreateFunctionFromUsageFix.java +++ b/idea/src/org/jetbrains/jet/plugin/quickfix/CreateFunctionFromUsageFix.java @@ -774,8 +774,8 @@ public class CreateFunctionFromUsageFix extends CreateFromUsageFixBase { TypeParameterListExpression expression = setupTypeParameterListTemplate(builder, func); // the template built by TemplateBuilderImpl is ordered by element position, but we want types to be first, so hack it - final TemplateImpl template = (TemplateImpl) builder.buildInlineTemplate(); - ArrayList variables = template.getVariables(); + final TemplateImpl templateImpl = (TemplateImpl) builder.buildInlineTemplate(); + ArrayList variables = templateImpl.getVariables(); for (int i = 0; i < parameters.size(); i++) { Collections.swap(variables, i * 2, i * 2 + 1); } @@ -784,11 +784,11 @@ public class CreateFunctionFromUsageFix extends CreateFromUsageFixBase { variables.add(new Variable(TYPE_PARAMETER_LIST_VARIABLE_NAME, expression, expression, false, true)); // run the template - TemplateManager.getInstance(project).startTemplate(containingFileEditor, template, new TemplateEditingAdapter() { + TemplateManager.getInstance(project).startTemplate(containingFileEditor, templateImpl, new TemplateEditingAdapter() { @Override - public void templateFinished(Template _, boolean brokenOff) { + public void templateFinished(Template template, boolean brokenOff) { // file templates - int offset = template.getSegmentOffset(0); + int offset = templateImpl.getSegmentOffset(0); final JetNamedFunction func = PsiTreeUtil.findElementOfClassAtOffset(containingFile, offset, JetNamedFunction.class, false); assert func != null; final List typeRefsToShorten = new ArrayList(); From ab6cc8b8eaf6850b75af4dfc182b0f0f70f39c5d Mon Sep 17 00:00:00 2001 From: Jack Zhou Date: Thu, 2 May 2013 11:42:00 -0400 Subject: [PATCH 058/291] Create from usage: Fixed swapped co-/contravariant comments. --- .../jet/plugin/quickfix/CreateFunctionFromUsageFix.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/idea/src/org/jetbrains/jet/plugin/quickfix/CreateFunctionFromUsageFix.java b/idea/src/org/jetbrains/jet/plugin/quickfix/CreateFunctionFromUsageFix.java index 81f67c0be8c..e5c1248c1c5 100644 --- a/idea/src/org/jetbrains/jet/plugin/quickfix/CreateFunctionFromUsageFix.java +++ b/idea/src/org/jetbrains/jet/plugin/quickfix/CreateFunctionFromUsageFix.java @@ -1012,13 +1012,13 @@ public class CreateFunctionFromUsageFix extends CreateFromUsageFixBase { } break; case IN_VARIANCE: - // for covariant (e.g. function parameter), can replace type with any of its supertypes + // for contravariant (e.g. function parameter), can replace type with any of its supertypes if (JetTypeChecker.INSTANCE.isSubtypeOf(type, substitution.getForType())) { return substitution.getByType(); } break; case OUT_VARIANCE: - // for contravariant (e.g. function return value), can replace type with any of its subtypes + // for covariant (e.g. function return value), can replace type with any of its subtypes if (JetTypeChecker.INSTANCE.isSubtypeOf(substitution.getForType(), type)) { return substitution.getByType(); } From ce5064e9ae76d00d3c8892d63c9be329e221b603 Mon Sep 17 00:00:00 2001 From: Jack Zhou Date: Thu, 2 May 2013 11:48:30 -0400 Subject: [PATCH 059/291] Create from usage: Combined the two overloads of getNextAvailableName. --- .../quickfix/CreateFunctionFromUsageFix.java | 23 ++++++++----------- 1 file changed, 9 insertions(+), 14 deletions(-) diff --git a/idea/src/org/jetbrains/jet/plugin/quickfix/CreateFunctionFromUsageFix.java b/idea/src/org/jetbrains/jet/plugin/quickfix/CreateFunctionFromUsageFix.java index e5c1248c1c5..c9b11ece4da 100644 --- a/idea/src/org/jetbrains/jet/plugin/quickfix/CreateFunctionFromUsageFix.java +++ b/idea/src/org/jetbrains/jet/plugin/quickfix/CreateFunctionFromUsageFix.java @@ -416,7 +416,7 @@ public class CreateFunctionFromUsageFix extends CreateFromUsageFixBase { // ensure there are no conflicts List lookupElements = new ArrayList(); for (String name : names) { - name = getNextAvailableName(name, parameterNames); + name = getNextAvailableName(name, parameterNames, null); lookupElements.add(LookupElementBuilder.create(name)); } @@ -1123,21 +1123,16 @@ public class CreateFunctionFromUsageFix extends CreateFromUsageFixBase { return typeParameters; } + /** + * Returns the given name, appended with a number if it is one of the existingNames or already exists in + * scope. For example, given "foo", returns the next non-conflicting name in the list "foo", + * "foo1", "foo2", etc. + */ @NotNull - private static String getNextAvailableName(@NotNull String name, @NotNull Collection existingNames) { - if (existingNames.contains(name)) { + private static String getNextAvailableName(@NotNull String name, @NotNull Collection existingNames, @Nullable JetScope scope) { + if (existingNames.contains(name) || (scope != null && scope.getClassifier(Name.identifier(name)) != null)) { int j = 1; - while (existingNames.contains(name + j)) j++; - name += j; - } - return name; - } - - @NotNull - private static String getNextAvailableName(@NotNull String name, @NotNull Collection existingNames, @NotNull JetScope scope) { - if (existingNames.contains(name) || scope.getClassifier(Name.identifier(name)) != null) { - int j = 1; - while (existingNames.contains(name + j) || scope.getClassifier(Name.identifier(name + j)) != null) j++; + while (existingNames.contains(name + j) || (scope != null && scope.getClassifier(Name.identifier(name + j)) != null)) j++; name += j; } return name; From 927baec6cbb7155473285a86c5128439e164fee9 Mon Sep 17 00:00:00 2001 From: Jack Zhou Date: Thu, 2 May 2013 12:04:37 -0400 Subject: [PATCH 060/291] Create from usage: Made guessTypeForExpression clearer. --- .../quickfix/CreateFunctionFromUsageFix.java | 32 +++++++++---------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/idea/src/org/jetbrains/jet/plugin/quickfix/CreateFunctionFromUsageFix.java b/idea/src/org/jetbrains/jet/plugin/quickfix/CreateFunctionFromUsageFix.java index c9b11ece4da..066da2a11cf 100644 --- a/idea/src/org/jetbrains/jet/plugin/quickfix/CreateFunctionFromUsageFix.java +++ b/idea/src/org/jetbrains/jet/plugin/quickfix/CreateFunctionFromUsageFix.java @@ -1141,7 +1141,6 @@ public class CreateFunctionFromUsageFix extends CreateFromUsageFixBase { @NotNull private static JetType[] guessTypeForExpression(@NotNull JetExpression expr, @NotNull BindingContext context) { JetType type = context.get(BindingContext.EXPRESSION_TYPE, expr); - JetNamedDeclaration declaration = null; // if we know the actual type of the expression if (type != null) { @@ -1172,7 +1171,7 @@ public class CreateFunctionFromUsageFix extends CreateFromUsageFixBase { if (typeRef != null) { // and has a specified type return new JetType[] {context.get(BindingContext.TYPE, typeRef)}; } - declaration = entry; // otherwise fall through and guess + return guessTypeForDeclaration(entry, context); // otherwise guess } // expression is a parameter (e.g. declared in a for-loop) @@ -1182,7 +1181,7 @@ public class CreateFunctionFromUsageFix extends CreateFromUsageFixBase { if (typeRef != null) { // and has a specified type return new JetType[] {context.get(BindingContext.TYPE, typeRef)}; } - declaration = parameter; // otherwise fall through and guess + return guessTypeForDeclaration(parameter, context); // otherwise guess } // the expression is the RHS of a variable assignment with a specified type @@ -1192,27 +1191,28 @@ public class CreateFunctionFromUsageFix extends CreateFromUsageFixBase { if (typeRef != null) { // and has a specified type return new JetType[] {context.get(BindingContext.TYPE, typeRef)}; } - declaration = variable; // otherwise fall through and guess, based on LHS + return guessTypeForDeclaration(variable, context); // otherwise guess, based on LHS } - // guess based on declaration - SearchScope scope = expr.getContainingFile().getUseScope(); + return new JetType[0]; // can't infer anything + } + + private static JetType[] guessTypeForDeclaration(@NotNull JetNamedDeclaration declaration, @NotNull BindingContext context) { Set expectedTypes = new HashSet(); - if (declaration != null) { - for (PsiReference ref : SearchUtils.findAllReferences(declaration, scope)) { - if (ref instanceof JetSimpleNameReference) { - JetSimpleNameReference simpleNameRef = (JetSimpleNameReference) ref; - JetType expectedType = context.get(BindingContext.EXPECTED_EXPRESSION_TYPE, simpleNameRef.getExpression()); - if (expectedType != null) { - expectedTypes.add(expectedType); - } + SearchScope scope = declaration.getContainingFile().getUseScope(); + for (PsiReference ref : SearchUtils.findAllReferences(declaration, scope)) { + if (ref instanceof JetSimpleNameReference) { + JetSimpleNameReference simpleNameRef = (JetSimpleNameReference) ref; + JetType expectedType = context.get(BindingContext.EXPECTED_EXPRESSION_TYPE, simpleNameRef.getExpression()); + if (expectedType != null) { + expectedTypes.add(expectedType); } } } if (expectedTypes.isEmpty()) { - return new JetType[0]; + return new JetType[0]; // can't guess } - type = TypeUtils.intersect(JetTypeChecker.INSTANCE, expectedTypes); + JetType type = TypeUtils.intersect(JetTypeChecker.INSTANCE, expectedTypes); if (type != null) { return new JetType[] {type}; } else { // intersection doesn't exist; let user make an imperfect choice From e0a7e85e4a5bbfae48581808b3f90005e4999909 Mon Sep 17 00:00:00 2001 From: Jack Zhou Date: Thu, 2 May 2013 12:06:35 -0400 Subject: [PATCH 061/291] Create from usage: Removed isUnit. --- .../jet/plugin/quickfix/CreateFunctionFromUsageFix.java | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/idea/src/org/jetbrains/jet/plugin/quickfix/CreateFunctionFromUsageFix.java b/idea/src/org/jetbrains/jet/plugin/quickfix/CreateFunctionFromUsageFix.java index 066da2a11cf..4baff4383be 100644 --- a/idea/src/org/jetbrains/jet/plugin/quickfix/CreateFunctionFromUsageFix.java +++ b/idea/src/org/jetbrains/jet/plugin/quickfix/CreateFunctionFromUsageFix.java @@ -662,7 +662,7 @@ public class CreateFunctionFromUsageFix extends CreateFromUsageFixBase { } else { isExtension = true; } - isUnit = returnType.isType() && isUnit(returnType.getType()); + isUnit = returnType.isType() && KotlinBuiltIns.getInstance().isUnit(returnType.getType()); JetScope scope; if (isExtension) { @@ -1220,10 +1220,6 @@ public class CreateFunctionFromUsageFix extends CreateFromUsageFixBase { } } - private static boolean isUnit(@NotNull JetType type) { - return KotlinBuiltIns.getInstance().isUnit(type); - } - @NotNull public static JetIntentionActionFactory createCreateGetFunctionFromUsageFactory() { return new JetIntentionActionFactory() { From 5bd144313d966ac7e2179bc1435a0fa06f954c3a Mon Sep 17 00:00:00 2001 From: Jack Zhou Date: Thu, 2 May 2013 13:35:43 -0400 Subject: [PATCH 062/291] Create from usage: Fixed case for multi-declaration in a for-loop. --- .../jet/lang/diagnostics/Errors.java | 2 +- .../rendering/DefaultErrorMessages.java | 2 +- .../expressions/ExpressionTypingUtils.java | 2 +- .../quickfix/CreateFunctionFromUsageFix.java | 40 ++++++++++++------- .../afterCreateComponentFromUsage3.kt | 21 ++++++++++ .../beforeCreateComponentFromUsage3.kt | 18 +++++++++ .../iterator/afterCreateIteratorFromUsage3.kt | 21 ++++++++++ .../beforeCreateIteratorFromUsage3.kt | 18 +++++++++ .../quickfix/QuickFixTestGenerated.java | 10 +++++ 9 files changed, 117 insertions(+), 17 deletions(-) create mode 100644 idea/testData/quickfix/createFromUsage/component/afterCreateComponentFromUsage3.kt create mode 100644 idea/testData/quickfix/createFromUsage/component/beforeCreateComponentFromUsage3.kt create mode 100644 idea/testData/quickfix/createFromUsage/iterator/afterCreateIteratorFromUsage3.kt create mode 100644 idea/testData/quickfix/createFromUsage/iterator/beforeCreateIteratorFromUsage3.kt diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/diagnostics/Errors.java b/compiler/frontend/src/org/jetbrains/jet/lang/diagnostics/Errors.java index aad818c3785..4f59ca5d8ca 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/diagnostics/Errors.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/diagnostics/Errors.java @@ -358,7 +358,7 @@ public interface Errors { // Multi-declarations DiagnosticFactory0 INITIALIZER_REQUIRED_FOR_MULTIDECLARATION = DiagnosticFactory0.create(ERROR, DEFAULT); - DiagnosticFactory1 COMPONENT_FUNCTION_MISSING = DiagnosticFactory1.create(ERROR, DEFAULT); + DiagnosticFactory2 COMPONENT_FUNCTION_MISSING = DiagnosticFactory2.create(ERROR, DEFAULT); DiagnosticFactory2>> COMPONENT_FUNCTION_AMBIGUITY = DiagnosticFactory2.create(ERROR, DEFAULT); DiagnosticFactory3 COMPONENT_FUNCTION_RETURN_TYPE_MISMATCH = DiagnosticFactory3.create(ERROR, DEFAULT); diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/diagnostics/rendering/DefaultErrorMessages.java b/compiler/frontend/src/org/jetbrains/jet/lang/diagnostics/rendering/DefaultErrorMessages.java index 409d7dfdf1b..6cf84bf8dfc 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/diagnostics/rendering/DefaultErrorMessages.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/diagnostics/rendering/DefaultErrorMessages.java @@ -113,7 +113,7 @@ public class DefaultErrorMessages { MAP.put(VARIABLE_WITH_NO_TYPE_NO_INITIALIZER, "This variable must either have a type annotation or be initialized"); MAP.put(INITIALIZER_REQUIRED_FOR_MULTIDECLARATION, "Initializer required for multi-declaration"); - MAP.put(COMPONENT_FUNCTION_MISSING, "Multi-declaration initializer must have a ''{0}()'' function", TO_STRING); + MAP.put(COMPONENT_FUNCTION_MISSING, "Multi-declaration initializer of type {1} must have a ''{0}()'' function", TO_STRING, RENDER_TYPE); MAP.put(COMPONENT_FUNCTION_AMBIGUITY, "Function ''{0}()'' is ambiguous for this expression: {1}", TO_STRING, AMBIGUOUS_CALLS); MAP.put(COMPONENT_FUNCTION_RETURN_TYPE_MISMATCH, "''{0}()'' function returns ''{1}'', but ''{2}'' is expected", TO_STRING, RENDER_TYPE, RENDER_TYPE); 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..04ae58719c1 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 @@ -417,7 +417,7 @@ public class ExpressionTypingUtils { context.trace.report(COMPONENT_FUNCTION_AMBIGUITY.on(reportErrorsOn, componentName, results.getResultingCalls())); } else { - context.trace.report(COMPONENT_FUNCTION_MISSING.on(reportErrorsOn, componentName)); + context.trace.report(COMPONENT_FUNCTION_MISSING.on(reportErrorsOn, componentName, receiver.getType())); } if (componentType == null) { componentType = ErrorUtils.createErrorType(componentName + "() return type"); diff --git a/idea/src/org/jetbrains/jet/plugin/quickfix/CreateFunctionFromUsageFix.java b/idea/src/org/jetbrains/jet/plugin/quickfix/CreateFunctionFromUsageFix.java index 4baff4383be..5bc985a1b3a 100644 --- a/idea/src/org/jetbrains/jet/plugin/quickfix/CreateFunctionFromUsageFix.java +++ b/idea/src/org/jetbrains/jet/plugin/quickfix/CreateFunctionFromUsageFix.java @@ -51,9 +51,7 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.jet.lang.descriptors.*; import org.jetbrains.jet.lang.descriptors.impl.MutableClassDescriptor; -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.diagnostics.*; import org.jetbrains.jet.lang.psi.*; import org.jetbrains.jet.lang.resolve.BindingContext; import org.jetbrains.jet.lang.resolve.BindingContextUtils; @@ -1313,7 +1311,10 @@ public class CreateFunctionFromUsageFix extends CreateFromUsageFixBase { JetForExpression forExpr = QuickFixUtil.getParentElementOfType(diagnostic, JetForExpression.class); if (forExpr == null) return null; JetExpression variableExpr = forExpr.getLoopParameter(); - if (variableExpr == null) return null; + if (variableExpr == null) { + variableExpr = forExpr.getMultiParameter(); + if (variableExpr == null) return null; + } TypeOrExpressionThereof returnType = new TypeOrExpressionThereof(variableExpr, Variance.OUT_VARIANCE); return new CreateFunctionFromUsageFix(forExpr, ownerType, "next", returnType, new ArrayList()); } @@ -1335,7 +1336,10 @@ public class CreateFunctionFromUsageFix extends CreateFromUsageFixBase { JetExpression iterableExpr = forExpr.getLoopRange(); if (iterableExpr == null) return null; JetExpression variableExpr = forExpr.getLoopParameter(); - if (variableExpr == null) return null; + if (variableExpr == null) { + variableExpr = forExpr.getMultiParameter(); + if (variableExpr == null) return null; + } TypeOrExpressionThereof iterableType = new TypeOrExpressionThereof(iterableExpr, Variance.IN_VARIANCE); JetType returnJetType = KotlinBuiltIns.getInstance().getIterator().getDefaultType(); @@ -1359,25 +1363,33 @@ public class CreateFunctionFromUsageFix extends CreateFromUsageFixBase { @Nullable @Override public IntentionAction createAction(Diagnostic diagnostic) { - JetMultiDeclaration multiDeclaration = QuickFixUtil.getParentElementOfType(diagnostic, JetMultiDeclaration.class); - if (multiDeclaration == null) return null; - List entries = multiDeclaration.getEntries(); - assert diagnostic.getFactory() == Errors.COMPONENT_FUNCTION_MISSING; @SuppressWarnings("unchecked") - DiagnosticWithParameters1 diagnosticWithParameters = - (DiagnosticWithParameters1) diagnostic; + DiagnosticWithParameters2 diagnosticWithParameters = + (DiagnosticWithParameters2) diagnostic; Name name = diagnosticWithParameters.getA(); Matcher componentNumberMatcher = COMPONENT_FUNCTION_PATTERN.matcher(name.getIdentifier()); if (!componentNumberMatcher.matches()) return null; String componentNumberString = componentNumberMatcher.group(1); int componentNumber = Integer.decode(componentNumberString) - 1; + JetMultiDeclaration multiDeclaration = QuickFixUtil.getParentElementOfType(diagnostic, JetMultiDeclaration.class); + TypeOrExpressionThereof ownerType; + if (multiDeclaration == null) { // if it's not a multi-declaration, must be a multi parameter in a for-loop + JetForExpression forExpr = QuickFixUtil.getParentElementOfType(diagnostic, JetForExpression.class); + if (forExpr == null) return null; + multiDeclaration = forExpr.getMultiParameter(); + if (multiDeclaration == null) return null; + ownerType = new TypeOrExpressionThereof(diagnosticWithParameters.getB(), Variance.IN_VARIANCE); + } else { + JetExpression rhs = multiDeclaration.getInitializer(); + if (rhs == null) return null; + ownerType = new TypeOrExpressionThereof(rhs, Variance.IN_VARIANCE); + } + List entries = multiDeclaration.getEntries(); + JetMultiDeclarationEntry entry = entries.get(componentNumber); TypeOrExpressionThereof returnType = new TypeOrExpressionThereof(entry, Variance.OUT_VARIANCE); - JetExpression rhs = multiDeclaration.getInitializer(); - if (rhs == null) return null; - TypeOrExpressionThereof ownerType = new TypeOrExpressionThereof(rhs, Variance.IN_VARIANCE); return new CreateFunctionFromUsageFix(multiDeclaration, ownerType, name.getIdentifier(), returnType, new ArrayList()); } diff --git a/idea/testData/quickfix/createFromUsage/component/afterCreateComponentFromUsage3.kt b/idea/testData/quickfix/createFromUsage/component/afterCreateComponentFromUsage3.kt new file mode 100644 index 00000000000..ec065712113 --- /dev/null +++ b/idea/testData/quickfix/createFromUsage/component/afterCreateComponentFromUsage3.kt @@ -0,0 +1,21 @@ +// "Create function 'component2' from usage" "true" +class FooIterator { + fun hasNext(): Boolean { return false } + fun next(): Any { + throw UnsupportedOperationException("not implemented") + } +} +class Foo { + fun iterator(): FooIterator { + throw UnsupportedOperationException("not implemented") + } +} +fun Any.component1(): Int { + return 0 +} +fun foo() { + for ((i: Int, j: Int) in Foo()) { } +} +fun Any.component2(): Int { + throw UnsupportedOperationException("not implemented") //To change body of created functions use File | Settings | File Templates. +} \ No newline at end of file diff --git a/idea/testData/quickfix/createFromUsage/component/beforeCreateComponentFromUsage3.kt b/idea/testData/quickfix/createFromUsage/component/beforeCreateComponentFromUsage3.kt new file mode 100644 index 00000000000..e14353788b6 --- /dev/null +++ b/idea/testData/quickfix/createFromUsage/component/beforeCreateComponentFromUsage3.kt @@ -0,0 +1,18 @@ +// "Create function 'component2' from usage" "true" +class FooIterator { + fun hasNext(): Boolean { return false } + fun next(): Any { + throw UnsupportedOperationException("not implemented") + } +} +class Foo { + fun iterator(): FooIterator { + throw UnsupportedOperationException("not implemented") + } +} +fun Any.component1(): Int { + return 0 +} +fun foo() { + for ((i: Int, j: Int) in Foo()) { } +} \ No newline at end of file diff --git a/idea/testData/quickfix/createFromUsage/iterator/afterCreateIteratorFromUsage3.kt b/idea/testData/quickfix/createFromUsage/iterator/afterCreateIteratorFromUsage3.kt new file mode 100644 index 00000000000..3c7b5edc152 --- /dev/null +++ b/idea/testData/quickfix/createFromUsage/iterator/afterCreateIteratorFromUsage3.kt @@ -0,0 +1,21 @@ +// "Create function 'next' from usage" "true" +class FooIterator { + fun hasNext(): Boolean { return false } + fun next(): Any { + throw UnsupportedOperationException("not implemented") //To change body of created functions use File | Settings | File Templates. + } +} +class Foo { + fun iterator(): FooIterator { + throw UnsupportedOperationException("not implemented") + } +} +fun Any.component1(): Int { + return 0 +} +fun Any.component2(): Int { + return 0 +} +fun foo() { + for ((i: Int, j: Int) in Foo()) { } +} \ No newline at end of file diff --git a/idea/testData/quickfix/createFromUsage/iterator/beforeCreateIteratorFromUsage3.kt b/idea/testData/quickfix/createFromUsage/iterator/beforeCreateIteratorFromUsage3.kt new file mode 100644 index 00000000000..7f57c5cc39b --- /dev/null +++ b/idea/testData/quickfix/createFromUsage/iterator/beforeCreateIteratorFromUsage3.kt @@ -0,0 +1,18 @@ +// "Create function 'next' from usage" "true" +class FooIterator { + fun hasNext(): Boolean { return false } +} +class Foo { + fun iterator(): FooIterator { + throw UnsupportedOperationException("not implemented") + } +} +fun Any.component1(): Int { + return 0 +} +fun Any.component2(): Int { + return 0 +} +fun foo() { + for ((i: Int, j: Int) in 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 bf4b20b7aeb..9675a9607ac 100644 --- a/idea/tests/org/jetbrains/jet/plugin/quickfix/QuickFixTestGenerated.java +++ b/idea/tests/org/jetbrains/jet/plugin/quickfix/QuickFixTestGenerated.java @@ -452,6 +452,11 @@ public class QuickFixTestGenerated extends AbstractQuickFixTest { doTest("idea/testData/quickfix/createFromUsage/component/beforeCreateComponentFromUsage2.kt"); } + @TestMetadata("beforeCreateComponentFromUsage3.kt") + public void testCreateComponentFromUsage3() throws Exception { + doTest("idea/testData/quickfix/createFromUsage/component/beforeCreateComponentFromUsage3.kt"); + } + } @TestMetadata("idea/testData/quickfix/createFromUsage/get") @@ -561,6 +566,11 @@ public class QuickFixTestGenerated extends AbstractQuickFixTest { doTest("idea/testData/quickfix/createFromUsage/iterator/beforeCreateIteratorFromUsage2.kt"); } + @TestMetadata("beforeCreateIteratorFromUsage3.kt") + public void testCreateIteratorFromUsage3() throws Exception { + doTest("idea/testData/quickfix/createFromUsage/iterator/beforeCreateIteratorFromUsage3.kt"); + } + } @TestMetadata("idea/testData/quickfix/createFromUsage/next") From 924e70f3f79ad390a4859f1f9a6df8066f1d79ba Mon Sep 17 00:00:00 2001 From: Jack Zhou Date: Sun, 12 May 2013 21:15:44 -0400 Subject: [PATCH 063/291] Create from usage: Fixed offering error types when guessing type fails. --- .../jet/plugin/quickfix/CreateFunctionFromUsageFix.java | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/idea/src/org/jetbrains/jet/plugin/quickfix/CreateFunctionFromUsageFix.java b/idea/src/org/jetbrains/jet/plugin/quickfix/CreateFunctionFromUsageFix.java index 5bc985a1b3a..44edb4870b9 100644 --- a/idea/src/org/jetbrains/jet/plugin/quickfix/CreateFunctionFromUsageFix.java +++ b/idea/src/org/jetbrains/jet/plugin/quickfix/CreateFunctionFromUsageFix.java @@ -1209,6 +1209,12 @@ public class CreateFunctionFromUsageFix extends CreateFromUsageFixBase { } if (expectedTypes.isEmpty()) { return new JetType[0]; // can't guess + } else { + for (JetType expectedType : expectedTypes) { + if (ErrorUtils.containsErrorType(expectedType)) { + return new JetType[0]; // guessing resulted in an error + } + } } JetType type = TypeUtils.intersect(JetTypeChecker.INSTANCE, expectedTypes); if (type != null) { From 12aa90f564231e447da2b794c64ddfcba52cc513 Mon Sep 17 00:00:00 2001 From: Jack Zhou Date: Sun, 12 May 2013 21:49:05 -0400 Subject: [PATCH 064/291] Create from usage: Renamed guessTypeForExpression to guessTypesForExpression. --- .../jet/plugin/quickfix/CreateFunctionFromUsageFix.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/idea/src/org/jetbrains/jet/plugin/quickfix/CreateFunctionFromUsageFix.java b/idea/src/org/jetbrains/jet/plugin/quickfix/CreateFunctionFromUsageFix.java index 44edb4870b9..9e679f03ccb 100644 --- a/idea/src/org/jetbrains/jet/plugin/quickfix/CreateFunctionFromUsageFix.java +++ b/idea/src/org/jetbrains/jet/plugin/quickfix/CreateFunctionFromUsageFix.java @@ -237,7 +237,7 @@ public class CreateFunctionFromUsageFix extends CreateFromUsageFixBase { } } else { assert expressionOfType != null : "!isType() means type == null && expressionOfType != null"; - for (JetType type : guessTypeForExpression(expressionOfType, context)) { + for (JetType type : guessTypesForExpression(expressionOfType, context)) { types.add(type); if (variance == Variance.IN_VARIANCE) { types.addAll(TypeUtils.getAllSupertypes(type)); @@ -1137,7 +1137,7 @@ public class CreateFunctionFromUsageFix extends CreateFromUsageFixBase { } @NotNull - private static JetType[] guessTypeForExpression(@NotNull JetExpression expr, @NotNull BindingContext context) { + private static JetType[] guessTypesForExpression(@NotNull JetExpression expr, @NotNull BindingContext context) { JetType type = context.get(BindingContext.EXPRESSION_TYPE, expr); // if we know the actual type of the expression @@ -1350,7 +1350,7 @@ public class CreateFunctionFromUsageFix extends CreateFromUsageFixBase { JetType returnJetType = KotlinBuiltIns.getInstance().getIterator().getDefaultType(); BindingContext context = AnalyzerFacadeWithCache.analyzeFileWithCache(jetFile).getBindingContext(); - JetType[] returnJetTypeParameterTypes = guessTypeForExpression(variableExpr, context); + JetType[] returnJetTypeParameterTypes = guessTypesForExpression(variableExpr, context); if (returnJetTypeParameterTypes.length != 1) return null; TypeProjection returnJetTypeParameterType = new TypeProjection(returnJetTypeParameterTypes[0]); From a91a2efc75d34b5018f03ddea0e0bdca035466e7 Mon Sep 17 00:00:00 2001 From: Jack Zhou Date: Tue, 28 May 2013 16:57:26 -0700 Subject: [PATCH 065/291] Create from usage: Extracted method from getNextAvailableName. --- .../jet/plugin/quickfix/CreateFunctionFromUsageFix.java | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/idea/src/org/jetbrains/jet/plugin/quickfix/CreateFunctionFromUsageFix.java b/idea/src/org/jetbrains/jet/plugin/quickfix/CreateFunctionFromUsageFix.java index 9e679f03ccb..61cba252247 100644 --- a/idea/src/org/jetbrains/jet/plugin/quickfix/CreateFunctionFromUsageFix.java +++ b/idea/src/org/jetbrains/jet/plugin/quickfix/CreateFunctionFromUsageFix.java @@ -1128,14 +1128,18 @@ public class CreateFunctionFromUsageFix extends CreateFromUsageFixBase { */ @NotNull private static String getNextAvailableName(@NotNull String name, @NotNull Collection existingNames, @Nullable JetScope scope) { - if (existingNames.contains(name) || (scope != null && scope.getClassifier(Name.identifier(name)) != null)) { + if (isConflictingName(name, existingNames, scope)) { int j = 1; - while (existingNames.contains(name + j) || (scope != null && scope.getClassifier(Name.identifier(name + j)) != null)) j++; + while (isConflictingName(name + j, existingNames, scope)) j++; name += j; } return name; } + private static boolean isConflictingName(@NotNull String name, @NotNull Collection existingNames, @Nullable JetScope scope) { + return existingNames.contains(name) || (scope != null && scope.getClassifier(Name.identifier(name)) != null); + } + @NotNull private static JetType[] guessTypesForExpression(@NotNull JetExpression expr, @NotNull BindingContext context) { JetType type = context.get(BindingContext.EXPRESSION_TYPE, expr); From 5d786f93f90f491fc320a56647909ce7e1f96e86 Mon Sep 17 00:00:00 2001 From: Jack Zhou Date: Tue, 28 May 2013 17:23:43 -0700 Subject: [PATCH 066/291] Create from usage: Changed comment in createCreateComponentFunctionFromUsageFactory to assertion. --- .../jet/plugin/quickfix/CreateFunctionFromUsageFix.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/idea/src/org/jetbrains/jet/plugin/quickfix/CreateFunctionFromUsageFix.java b/idea/src/org/jetbrains/jet/plugin/quickfix/CreateFunctionFromUsageFix.java index 61cba252247..3a1b447dd54 100644 --- a/idea/src/org/jetbrains/jet/plugin/quickfix/CreateFunctionFromUsageFix.java +++ b/idea/src/org/jetbrains/jet/plugin/quickfix/CreateFunctionFromUsageFix.java @@ -1385,11 +1385,11 @@ public class CreateFunctionFromUsageFix extends CreateFromUsageFixBase { JetMultiDeclaration multiDeclaration = QuickFixUtil.getParentElementOfType(diagnostic, JetMultiDeclaration.class); TypeOrExpressionThereof ownerType; - if (multiDeclaration == null) { // if it's not a multi-declaration, must be a multi parameter in a for-loop + if (multiDeclaration == null) { JetForExpression forExpr = QuickFixUtil.getParentElementOfType(diagnostic, JetForExpression.class); - if (forExpr == null) return null; + assert forExpr != null; // if it's not a multi-declaration, must be a multi parameter in a for-loop multiDeclaration = forExpr.getMultiParameter(); - if (multiDeclaration == null) return null; + assert multiDeclaration != null; // for-loop must have a multi-declaration, for same reason as above ownerType = new TypeOrExpressionThereof(diagnosticWithParameters.getB(), Variance.IN_VARIANCE); } else { JetExpression rhs = multiDeclaration.getInitializer(); From f41584c7abd55e62b52eefe449e1d7a28d56061b Mon Sep 17 00:00:00 2001 From: Svetlana Isakova Date: Wed, 5 Jun 2013 15:27:12 +0400 Subject: [PATCH 067/291] 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 068/291] 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 069/291] 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 070/291] 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 071/291] 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 072/291] 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 073/291] 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 074/291] 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 075/291] 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 076/291] 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 077/291] 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 078/291] 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 079/291] 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 080/291] 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 081/291] 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 082/291] 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 083/291] 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 084/291] 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 085/291] 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 086/291] 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 087/291] 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 088/291] 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 089/291] 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 090/291] 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 091/291] 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 092/291] 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 8f24d1e18beb097235c2aa9edcad69137ab6c1d9 Mon Sep 17 00:00:00 2001 From: Jack Zhou Date: Tue, 4 Jun 2013 22:32:16 -0700 Subject: [PATCH 093/291] Create from usage: Removed a redundant check. --- .../jet/plugin/quickfix/CreateFunctionFromUsageFix.java | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/idea/src/org/jetbrains/jet/plugin/quickfix/CreateFunctionFromUsageFix.java b/idea/src/org/jetbrains/jet/plugin/quickfix/CreateFunctionFromUsageFix.java index 3a1b447dd54..571108a69d6 100644 --- a/idea/src/org/jetbrains/jet/plugin/quickfix/CreateFunctionFromUsageFix.java +++ b/idea/src/org/jetbrains/jet/plugin/quickfix/CreateFunctionFromUsageFix.java @@ -732,9 +732,7 @@ public class CreateFunctionFromUsageFix extends CreateFromUsageFixBase { assert classContainingFile instanceof JetFile; containingFile = (JetFile) classContainingFile; - if (!ApplicationManager.getApplication().isUnitTestMode()) { - NavigationUtil.activateFileWithPsiElement(containingFile); - } + NavigationUtil.activateFileWithPsiElement(containingFile); containingFileEditor = FileEditorManager.getInstance(project).getSelectedTextEditor(); JetClassBody classBody = ownerClass.getBody(); From a6edc21c49b25b5225df449f167424256dd73912 Mon Sep 17 00:00:00 2001 From: Andrey Breslav Date: Fri, 7 Jun 2013 14:14:42 +0400 Subject: [PATCH 094/291] 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 095/291] 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 096/291] 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 097/291] 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 098/291] 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 099/291] 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 100/291] 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 101/291] 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 102/291] 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 103/291] 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; From 28244867eed42331c873ed5d19f3ed7a3a90f294 Mon Sep 17 00:00:00 2001 From: Zalim Bashorov Date: Mon, 10 Jun 2013 20:16:02 +0400 Subject: [PATCH 104/291] Fixed Api Docs Deployment. --- libraries/docs/website/pom.xml | 61 ++++++++++++---------------------- libraries/maven-settings.xml | 3 +- 2 files changed, 23 insertions(+), 41 deletions(-) diff --git a/libraries/docs/website/pom.xml b/libraries/docs/website/pom.xml index 2186d0cfd54..fe413639658 100644 --- a/libraries/docs/website/pom.xml +++ b/libraries/docs/website/pom.xml @@ -75,57 +75,40 @@ - maven-assembly-plugin - 2.2.1 + + org.apache.maven.plugins + maven-site-plugin + 3.3 - - src/main/assembly/zip.xml - + true + + + + + com.github.github + site-maven-plugin + 0.8 + + Update Kotlin API Docs (build ${build.number}) + jetbrains-kotlin - make-zip - package - single + site + site - - - org.apache.maven.scm - maven-scm-provider-gitexe - 1.6 - - - org.apache.maven.scm - maven-scm-manager-plexus - 1.6 - - - com.github.stephenc.wagon - wagon-gitsite - 0.4.1 - - - - - - - github-project-site - gitsite:git@github.com/JetBrains/kotlin.git - - diff --git a/libraries/maven-settings.xml b/libraries/maven-settings.xml index 879b3c2e335..6926a8e7e34 100644 --- a/libraries/maven-settings.xml +++ b/libraries/maven-settings.xml @@ -15,8 +15,7 @@ jetbrains-kotlin - tc-kotlin - ${tc-kotlin.password} + ${KOTLIN_GITHUB_OAUTH_TOKEN} From 6e96ff4b111b91d0621800c78b512aae741827da Mon Sep 17 00:00:00 2001 From: Zalim Bashorov Date: Tue, 11 Jun 2013 13:23:54 +0400 Subject: [PATCH 105/291] Fixed Maven Artifacts Deployment. Reverted the server configuration changes and added a new server to work with GitHub. --- libraries/docs/website/pom.xml | 2 +- libraries/maven-settings.xml | 5 +++++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/libraries/docs/website/pom.xml b/libraries/docs/website/pom.xml index fe413639658..ca0f3129010 100644 --- a/libraries/docs/website/pom.xml +++ b/libraries/docs/website/pom.xml @@ -90,7 +90,7 @@ 0.8 Update Kotlin API Docs (build ${build.number}) - jetbrains-kotlin + jetbrains-kotlin-github diff --git a/libraries/maven-settings.xml b/libraries/maven-settings.xml index 6926a8e7e34..833542dc62a 100644 --- a/libraries/maven-settings.xml +++ b/libraries/maven-settings.xml @@ -15,6 +15,11 @@ jetbrains-kotlin + tc-kotlin + ${tc-kotlin.password} + + + jetbrains-kotlin-github ${KOTLIN_GITHUB_OAUTH_TOKEN} From 03b039b302ce95f4bd01c6f999152b29e687e975 Mon Sep 17 00:00:00 2001 From: Zalim Bashorov Date: Tue, 11 Jun 2013 13:49:09 +0400 Subject: [PATCH 106/291] Fixed the default Kotlin CodeStyle. By default add space before colon when it placed between types (inheritance, type constraint, type parameter). Added example of inheritance to the Sample. --- .../jetbrains/jet/plugin/formatter/JetCodeStyleSettings.java | 2 +- .../formatter/JetLanguageCodeStyleSettingsProvider.java | 5 +++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/idea/src/org/jetbrains/jet/plugin/formatter/JetCodeStyleSettings.java b/idea/src/org/jetbrains/jet/plugin/formatter/JetCodeStyleSettings.java index 58758cd4790..b5a2d2d40c6 100644 --- a/idea/src/org/jetbrains/jet/plugin/formatter/JetCodeStyleSettings.java +++ b/idea/src/org/jetbrains/jet/plugin/formatter/JetCodeStyleSettings.java @@ -28,7 +28,7 @@ public class JetCodeStyleSettings extends CustomCodeStyleSettings { public boolean SPACE_BEFORE_TYPE_COLON = false; public boolean SPACE_AFTER_TYPE_COLON = true; - public boolean SPACE_BEFORE_EXTEND_COLON = false; + public boolean SPACE_BEFORE_EXTEND_COLON = true; public boolean SPACE_AFTER_EXTEND_COLON = true; public boolean INSERT_WHITESPACES_IN_SIMPLE_ONE_LINE_METHOD = true; diff --git a/idea/src/org/jetbrains/jet/plugin/formatter/JetLanguageCodeStyleSettingsProvider.java b/idea/src/org/jetbrains/jet/plugin/formatter/JetLanguageCodeStyleSettingsProvider.java index 7a2f6d30066..c57784aab50 100644 --- a/idea/src/org/jetbrains/jet/plugin/formatter/JetLanguageCodeStyleSettingsProvider.java +++ b/idea/src/org/jetbrains/jet/plugin/formatter/JetLanguageCodeStyleSettingsProvider.java @@ -57,7 +57,7 @@ public class JetLanguageCodeStyleSettingsProvider extends LanguageCodeStyleSetti "}"; default: return - "class Some {\n" + + "open class Some {\n" + " private val f = {(a: Int)->a*2}\n" + " fun foo() : Int {\n" + " val test : Int = 12\n" + @@ -66,7 +66,8 @@ public class JetLanguageCodeStyleSettingsProvider extends LanguageCodeStyleSetti " private fun foo2():Int where T : List {\n" + " return 0\n" + " }\n" + - "}"; + "}\n\n" + + "class AnotherClass: Some"; } } From 9e4f01319b2c430984984716be14298d9a4bba9f Mon Sep 17 00:00:00 2001 From: Zalim Bashorov Date: Tue, 11 Jun 2013 13:59:23 +0400 Subject: [PATCH 107/291] Swapped some CodeStyle options because must first be "... before ..." then "... after..." --- .../JetLanguageCodeStyleSettingsProvider.java | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/idea/src/org/jetbrains/jet/plugin/formatter/JetLanguageCodeStyleSettingsProvider.java b/idea/src/org/jetbrains/jet/plugin/formatter/JetLanguageCodeStyleSettingsProvider.java index c57784aab50..596a6d530cb 100644 --- a/idea/src/org/jetbrains/jet/plugin/formatter/JetLanguageCodeStyleSettingsProvider.java +++ b/idea/src/org/jetbrains/jet/plugin/formatter/JetLanguageCodeStyleSettingsProvider.java @@ -95,20 +95,22 @@ public class JetLanguageCodeStyleSettingsProvider extends LanguageCodeStyleSetti consumer.showCustomOption(JetCodeStyleSettings.class, "SPACE_AROUND_RANGE", "Around range (..)", CodeStyleSettingsCustomizable.SPACES_AROUND_OPERATORS); - consumer.showCustomOption(JetCodeStyleSettings.class, "SPACE_AFTER_TYPE_COLON", "Space after colon, before declarations' type", + consumer.showCustomOption(JetCodeStyleSettings.class, "SPACE_BEFORE_TYPE_COLON", + "Space before colon, after declarations' name", CodeStyleSettingsCustomizable.SPACES_OTHER); - consumer.showCustomOption(JetCodeStyleSettings.class, "SPACE_BEFORE_TYPE_COLON", "Space before colon, after declarations' name", - CodeStyleSettingsCustomizable.SPACES_OTHER); - - consumer.showCustomOption(JetCodeStyleSettings.class, "SPACE_AFTER_EXTEND_COLON", - "Space after colon in new type definition", + consumer.showCustomOption(JetCodeStyleSettings.class, "SPACE_AFTER_TYPE_COLON", + "Space after colon, before declarations' type", CodeStyleSettingsCustomizable.SPACES_OTHER); consumer.showCustomOption(JetCodeStyleSettings.class, "SPACE_BEFORE_EXTEND_COLON", "Space before colon in new type definition", CodeStyleSettingsCustomizable.SPACES_OTHER); + consumer.showCustomOption(JetCodeStyleSettings.class, "SPACE_AFTER_EXTEND_COLON", + "Space after colon in new type definition", + CodeStyleSettingsCustomizable.SPACES_OTHER); + consumer.showCustomOption(JetCodeStyleSettings.class, "INSERT_WHITESPACES_IN_SIMPLE_ONE_LINE_METHOD", "Insert whitespaces in simple one line methods", CodeStyleSettingsCustomizable.SPACES_OTHER); From 1e0f926d398ec83efe74a1614b4a6e423e90e5e6 Mon Sep 17 00:00:00 2001 From: Zalim Bashorov Date: Tue, 11 Jun 2013 15:50:16 +0400 Subject: [PATCH 108/291] Fixed the expected test result for OverrideImplementTest#testFunctionWithTypeParameters. --- .../overrideImplement/functionWithTypeParameters.kt.after | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/idea/testData/codeInsight/overrideImplement/functionWithTypeParameters.kt.after b/idea/testData/codeInsight/overrideImplement/functionWithTypeParameters.kt.after index 17cb21ce990..676ed95b529 100644 --- a/idea/testData/codeInsight/overrideImplement/functionWithTypeParameters.kt.after +++ b/idea/testData/codeInsight/overrideImplement/functionWithTypeParameters.kt.after @@ -4,7 +4,7 @@ trait Trait { class TraitImpl : Trait { - override fun > foo() where B: Cloneable, B: Comparable { + override fun > foo() where B : Cloneable, B : Comparable { throw UnsupportedOperationException() } } \ No newline at end of file From 325946154bd3f5b96a747922cadf6cb6c312e473 Mon Sep 17 00:00:00 2001 From: Andrey Breslav Date: Mon, 10 Jun 2013 20:54:13 +0400 Subject: [PATCH 109/291] Fix and test RecursiveDescriptorProcessor --- .../recursiveProcessor/declarations.kt | 41 ++++ .../recursiveProcessor/declarations.txt | 56 ++++++ .../util/RecursiveDescriptorProcessor.java | 71 ++++--- .../RecursiveDescriptorProcessorTest.java | 185 ++++++++++++++++++ 4 files changed, 315 insertions(+), 38 deletions(-) create mode 100644 compiler/testData/recursiveProcessor/declarations.kt create mode 100644 compiler/testData/recursiveProcessor/declarations.txt create mode 100644 compiler/tests/org/jetbrains/jet/test/util/RecursiveDescriptorProcessorTest.java diff --git a/compiler/testData/recursiveProcessor/declarations.kt b/compiler/testData/recursiveProcessor/declarations.kt new file mode 100644 index 00000000000..d50427ed64e --- /dev/null +++ b/compiler/testData/recursiveProcessor/declarations.kt @@ -0,0 +1,41 @@ +package test.innerTest + +fun T1.func(a: T1): T1 = a +val T2.prop: T2? = null +var propVar: Any? = null + +trait Trait { + fun traitFunc(): Unit {} + val traitProp: Any? +} + +abstract class Class : Trait { + fun classFunc(): Unit {} + val classProp: Any? = null + + class object { + fun classObjFunc(): Unit {} + val classObjProp: Any? = null + } +} + +object Object { + fun objFunc(): Unit {} + val objProp: Any? = null +} + +trait Outer { + trait NestedTrait { + fun nestedTraitFun() {} + } + + abstract class NestedClass { + class object { + fun nestedClassObjFunc(): Unit {} + } + } + + object Object { + fun nestedFunc(): Unit {} + } +} \ No newline at end of file diff --git a/compiler/testData/recursiveProcessor/declarations.txt b/compiler/testData/recursiveProcessor/declarations.txt new file mode 100644 index 00000000000..a64a5a01527 --- /dev/null +++ b/compiler/testData/recursiveProcessor/declarations.txt @@ -0,0 +1,56 @@ +.:PropertyGetterDescriptor +.():ConstructorDescriptor +.classObjFunc:SimpleFunctionDescriptor +.classObjProp:PropertyDescriptor +.this:ReceiverParameterDescriptor +:ClassDescriptor +.():ConstructorDescriptor +.nestedClassObjFunc:SimpleFunctionDescriptor +.this:ReceiverParameterDescriptor +:ClassDescriptor +:MutableValueParameterDescriptor +Class.:PropertyGetterDescriptor +Class.():ConstructorDescriptor +Class.classFunc:SimpleFunctionDescriptor +Class.classProp:PropertyDescriptor +Class.this:ReceiverParameterDescriptor +Class:ClassDescriptor +NestedClass.():ConstructorDescriptor +NestedClass.this:ReceiverParameterDescriptor +NestedClass:ClassDescriptor +NestedTrait.nestedTraitFun:SimpleFunctionDescriptor +NestedTrait.this:ReceiverParameterDescriptor +NestedTrait:ClassDescriptor +Object.():ConstructorDescriptor +Object.nestedFunc:SimpleFunctionDescriptor +Object.this:ReceiverParameterDescriptor +Object:ClassDescriptor +Outer.Object:PropertyDescriptor +Outer.this:ReceiverParameterDescriptor +Outer:ClassDescriptor +T1:TypeParameterDescriptor +T2:TypeParameterDescriptor +T3:TypeParameterDescriptor +T4:TypeParameterDescriptor +T4:TypeParameterDescriptor +Trait.:PropertyGetterDescriptor +Trait.this:ReceiverParameterDescriptor +Trait.traitFunc:SimpleFunctionDescriptor +Trait.traitProp:PropertyDescriptor +Trait:ClassDescriptor +a:MutableValueParameterDescriptor +fake Class.:PropertyGetterDescriptor +fake Class.traitFunc:SimpleFunctionDescriptor +fake Class.traitProp:PropertyDescriptor +func.this:ReceiverParameterDescriptor +innerTest.:PropertyGetterDescriptor +innerTest.:PropertyGetterDescriptor +innerTest.:PropertySetterDescriptor +innerTest.Object:PropertyDescriptor +innerTest.func:SimpleFunctionDescriptor +innerTest.prop:PropertyDescriptor +innerTest.propVar:PropertyDescriptor +innerTest:NamespaceDescriptor +prop.this:ReceiverParameterDescriptor +prop.this:ReceiverParameterDescriptor +test:NamespaceDescriptor diff --git a/compiler/tests/org/jetbrains/jet/test/util/RecursiveDescriptorProcessor.java b/compiler/tests/org/jetbrains/jet/test/util/RecursiveDescriptorProcessor.java index 18e524e46bc..db5c5ab5132 100644 --- a/compiler/tests/org/jetbrains/jet/test/util/RecursiveDescriptorProcessor.java +++ b/compiler/tests/org/jetbrains/jet/test/util/RecursiveDescriptorProcessor.java @@ -22,30 +22,15 @@ 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); + return descriptor.accept(new RecursiveVisitor(visitor), data); } private static class RecursiveVisitor implements DeclarationDescriptorVisitor { @@ -56,26 +41,34 @@ public class RecursiveDescriptorProcessor { this.worker = worker; } - private boolean doProcess(Collection descriptors, D data) { - return process(descriptors, data, worker); + private boolean visitChildren(Collection descriptors, D data) { + for (DeclarationDescriptor descriptor : descriptors) { + if (!descriptor.accept(this, data)) return false; + } + return true; } - private boolean doProcess(@Nullable DeclarationDescriptor receiverParameter, D data) { - if (receiverParameter == null) { - return true; - } - return receiverParameter.accept(worker, data); + private boolean visitChildren(@Nullable DeclarationDescriptor descriptor, D data) { + if (descriptor == null) return true; + + return descriptor.accept(this, data); + } + + private boolean applyWorker(@NotNull DeclarationDescriptor descriptor, D data) { + return descriptor.accept(worker, data); } private boolean processCallable(CallableDescriptor descriptor, D data) { - return doProcess(descriptor.getTypeParameters(), data) - && doProcess(descriptor.getReceiverParameter(), data) - && doProcess(descriptor.getValueParameters(), data); + return applyWorker(descriptor, data) + && visitChildren(descriptor.getTypeParameters(), data) + && visitChildren(descriptor.getReceiverParameter(), data) + && visitChildren(descriptor.getValueParameters(), data); } @Override public Boolean visitNamespaceDescriptor(NamespaceDescriptor descriptor, D data) { - return doProcess(descriptor.getMemberScope().getAllDescriptors(), data); + return applyWorker(descriptor, data) + && visitChildren(descriptor.getMemberScope().getAllDescriptors(), data); } @Override @@ -86,8 +79,8 @@ public class RecursiveDescriptorProcessor { @Override public Boolean visitPropertyDescriptor(PropertyDescriptor descriptor, D data) { return processCallable(descriptor, data) - && doProcess(descriptor.getGetter(), data) - && doProcess(descriptor.getSetter(), data); + && visitChildren(descriptor.getGetter(), data) + && visitChildren(descriptor.getSetter(), data); } @Override @@ -97,22 +90,24 @@ public class RecursiveDescriptorProcessor { @Override public Boolean visitTypeParameterDescriptor(TypeParameterDescriptor descriptor, D data) { - return true; + return applyWorker(descriptor, data); } @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); + return applyWorker(descriptor, data) + && visitChildren(descriptor.getThisAsReceiverParameter(), data) + && visitChildren(descriptor.getConstructors(), data) + && visitChildren(descriptor.getTypeConstructor().getParameters(), data) + && visitChildren(descriptor.getClassObjectDescriptor(), data) + && visitChildren(descriptor.getDefaultType().getMemberScope().getObjectDescriptors(), data) + && visitChildren(descriptor.getDefaultType().getMemberScope().getAllDescriptors(), data); } @Override public Boolean visitModuleDeclaration(ModuleDescriptor descriptor, D data) { - return doProcess(descriptor.getNamespace(FqName.ROOT), data); + return applyWorker(descriptor, data) + && visitChildren(descriptor.getNamespace(FqName.ROOT), data); } @Override @@ -142,7 +137,7 @@ public class RecursiveDescriptorProcessor { @Override public Boolean visitReceiverParameterDescriptor(ReceiverParameterDescriptor descriptor, D data) { - return true; + return applyWorker(descriptor, data); } } } diff --git a/compiler/tests/org/jetbrains/jet/test/util/RecursiveDescriptorProcessorTest.java b/compiler/tests/org/jetbrains/jet/test/util/RecursiveDescriptorProcessorTest.java new file mode 100644 index 00000000000..842d68ffb3e --- /dev/null +++ b/compiler/tests/org/jetbrains/jet/test/util/RecursiveDescriptorProcessorTest.java @@ -0,0 +1,185 @@ +/* + * 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 com.intellij.openapi.util.io.FileUtil; +import org.jetbrains.jet.JetTestUtils; +import org.jetbrains.jet.analyzer.AnalyzeExhaust; +import org.jetbrains.jet.cli.jvm.compiler.JetCoreEnvironment; +import org.jetbrains.jet.lang.descriptors.*; +import org.jetbrains.jet.lang.psi.JetFile; +import org.jetbrains.jet.lang.resolve.lazy.KotlinTestWithEnvironment; +import org.jetbrains.jet.lang.resolve.name.FqName; +import org.jetbrains.jet.lang.resolve.name.Name; +import org.jetbrains.jet.utils.Printer; + +import java.io.File; +import java.util.Collections; +import java.util.List; + +public class RecursiveDescriptorProcessorTest extends KotlinTestWithEnvironment { + @Override + protected JetCoreEnvironment createEnvironment() { + return JetTestUtils.createEnvironmentWithMockJdkAndIdeaAnnotations(getTestRootDisposable()); + } + + public void testRecursive() throws Exception { + File ktFile = new File("compiler/testData/recursiveProcessor/declarations.kt"); + File txtFile = new File("compiler/testData/recursiveProcessor/declarations.txt"); + String text = FileUtil.loadFile(ktFile); + JetFile jetFile = JetTestUtils.createFile("declarations.kt", text, getEnvironment().getProject()); + AnalyzeExhaust exhaust = JetTestUtils.analyzeFile(jetFile); + NamespaceDescriptor testPackage = exhaust.getModuleDescriptor().getNamespace(FqName.topLevel(Name.identifier("test"))); + assert testPackage != null; + + List descriptors = recursivelyCollectDescriptors(testPackage); + + StringBuilder builder = new StringBuilder(); + Printer p = new Printer(builder); + for (String descriptor : descriptors) { + p.println(descriptor); + } + String actualText = builder.toString(); + + if (!txtFile.exists()) { + FileUtil.writeToFile(txtFile, actualText); + fail("Test data file did not exist and was created from the results of the test: " + txtFile); + } + + assertEquals(FileUtil.loadFile(txtFile), actualText); + } + + private static Class closestInterface(Class aClass) { + if (aClass == null) return null; + if (aClass.isInterface()) return aClass; + + Class[] interfaces = aClass.getInterfaces(); + if (interfaces.length > 0) return interfaces[0]; + + return closestInterface(aClass.getSuperclass()); + } + + private static List recursivelyCollectDescriptors(NamespaceDescriptor testPackage) { + final List lines = Lists.newArrayList(); + RecursiveDescriptorProcessor.process(testPackage, null, new DeclarationDescriptorVisitor() { + + private void add(DeclarationDescriptor descriptor) { + add(descriptor.getName().asString(), descriptor); + } + + private void add(String name, DeclarationDescriptor descriptor) { + lines.add(name + ":" + closestInterface(descriptor.getClass()).getSimpleName()); + } + + private void addCallable(CallableMemberDescriptor descriptor) { + String prefix = descriptor.getKind() == CallableMemberDescriptor.Kind.FAKE_OVERRIDE ? "fake " : ""; + add(prefix + descriptor.getContainingDeclaration().getName() + "." + descriptor.getName(), descriptor); + } + + @Override + public Boolean visitNamespaceDescriptor(NamespaceDescriptor descriptor, Void data) { + add(descriptor); + return true; + } + + @Override + public Boolean visitVariableDescriptor(VariableDescriptor descriptor, Void data) { + add(descriptor); + return true; + } + + @Override + public Boolean visitFunctionDescriptor(FunctionDescriptor descriptor, Void data) { + addCallable(descriptor); + return true; + } + + @Override + public Boolean visitTypeParameterDescriptor(TypeParameterDescriptor descriptor, Void data) { + add(descriptor); + return true; + } + + @Override + public Boolean visitClassDescriptor(ClassDescriptor descriptor, Void data) { + add(descriptor); + return true; + } + + @Override + public Boolean visitModuleDeclaration(ModuleDescriptor descriptor, Void data) { + add(descriptor); + return true; + } + + @Override + public Boolean visitConstructorDescriptor( + ConstructorDescriptor constructorDescriptor, Void data + ) { + add(constructorDescriptor.getContainingDeclaration().getName() + ".()", constructorDescriptor); + return true; + } + + @Override + public Boolean visitScriptDescriptor(ScriptDescriptor scriptDescriptor, Void data) { + add(scriptDescriptor); + return true; + } + + @Override + public Boolean visitPropertyDescriptor(PropertyDescriptor descriptor, Void data) { + addCallable(descriptor); + return true; + } + + @Override + public Boolean visitValueParameterDescriptor( + ValueParameterDescriptor descriptor, Void data + ) { + add(descriptor); + return true; + } + + @Override + public Boolean visitPropertyGetterDescriptor( + PropertyGetterDescriptor descriptor, Void data + ) { + addCallable(descriptor); + return true; + } + + @Override + public Boolean visitPropertySetterDescriptor( + PropertySetterDescriptor descriptor, Void data + ) { + addCallable(descriptor); + return true; + } + + @Override + public Boolean visitReceiverParameterDescriptor( + ReceiverParameterDescriptor descriptor, Void data + ) { + add(descriptor.getContainingDeclaration().getName() + ".this", descriptor); + return true; + } + }); + Collections.sort(lines); + return lines; + } +} From dd0e919f8e359f4d17539ef15318f71513d99885 Mon Sep 17 00:00:00 2001 From: Andrey Breslav Date: Tue, 11 Jun 2013 12:59:14 +0400 Subject: [PATCH 110/291] Deferred types may delegate equals() to their actual implementatinos --- .../src/org/jetbrains/jet/lang/types/DeferredType.java | 8 +------- 1 file changed, 1 insertion(+), 7 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 36562d8dbbb..f43b5a98f96 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/types/DeferredType.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/types/DeferredType.java @@ -96,13 +96,7 @@ public class DeferredType implements JetType { @Override public boolean equals(Object 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); + return getActualType().equals(obj); } @Override From 994691579bb5e9863f1cf52ceb4c7787a26bc615 Mon Sep 17 00:00:00 2001 From: Andrey Breslav Date: Tue, 11 Jun 2013 13:03:10 +0400 Subject: [PATCH 111/291] Rename --- .../jetbrains/jet/test/util/DescriptorValidator.java | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/compiler/tests/org/jetbrains/jet/test/util/DescriptorValidator.java b/compiler/tests/org/jetbrains/jet/test/util/DescriptorValidator.java index 9a5c2c5bdde..6320d1ffab5 100644 --- a/compiler/tests/org/jetbrains/jet/test/util/DescriptorValidator.java +++ b/compiler/tests/org/jetbrains/jet/test/util/DescriptorValidator.java @@ -60,11 +60,11 @@ public class DescriptorValidator { } private static void report(@NotNull DiagnosticCollector collector, @NotNull DeclarationDescriptor descriptor, @NotNull String message) { - collector.report(new Diagnostic(descriptor, message)); + collector.report(new ValidationDiagnostic(descriptor, message)); } public interface DiagnosticCollector { - void report(@NotNull Diagnostic diagnostic); + void report(@NotNull ValidationDiagnostic diagnostic); } public static class ValidationVisitor implements DeclarationDescriptorVisitor { @@ -452,13 +452,13 @@ public class DescriptorValidator { } } - public static class Diagnostic { + public static class ValidationDiagnostic { private final DeclarationDescriptor descriptor; private final String message; private final Throwable stackTrace; - private Diagnostic(@NotNull DeclarationDescriptor descriptor, @NotNull String message) { + private ValidationDiagnostic(@NotNull DeclarationDescriptor descriptor, @NotNull String message) { this.descriptor = descriptor; this.message = message; this.stackTrace = new Throwable(); @@ -495,7 +495,7 @@ public class DescriptorValidator { private boolean errorsFound = false; @Override - public void report(@NotNull Diagnostic diagnostic) { + public void report(@NotNull ValidationDiagnostic diagnostic) { diagnostic.printStackTrace(System.err); errorsFound = true; } From f4991fac1e33c7b362b432a1a1787cf513883c63 Mon Sep 17 00:00:00 2001 From: Andrey Breslav Date: Tue, 11 Jun 2013 13:03:52 +0400 Subject: [PATCH 112/291] Minor changes: comment & simplify --- .../org/jetbrains/jet/test/util/DescriptorValidator.java | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/compiler/tests/org/jetbrains/jet/test/util/DescriptorValidator.java b/compiler/tests/org/jetbrains/jet/test/util/DescriptorValidator.java index 6320d1ffab5..5544922cae3 100644 --- a/compiler/tests/org/jetbrains/jet/test/util/DescriptorValidator.java +++ b/compiler/tests/org/jetbrains/jet/test/util/DescriptorValidator.java @@ -155,7 +155,7 @@ public class DescriptorValidator { PropertyAccessorDescriptor accessor, String name ) { - // TODO + // TODO: fix the discrepancies in descriptor construction and enable these checks //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()); @@ -278,8 +278,7 @@ public class DescriptorValidator { public Boolean visitValueParameterDescriptor( ValueParameterDescriptor descriptor, DiagnosticCollector collector ) { - visitVariableDescriptor(descriptor, collector); - return true; + return visitVariableDescriptor(descriptor, collector); } @Override From 9d2ea86a784cf07a9638c58f810decec3974f4ed Mon Sep 17 00:00:00 2001 From: Andrey Breslav Date: Tue, 11 Jun 2013 13:04:18 +0400 Subject: [PATCH 113/291] Additional checks in validator --- .../org/jetbrains/jet/test/util/DescriptorValidator.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/compiler/tests/org/jetbrains/jet/test/util/DescriptorValidator.java b/compiler/tests/org/jetbrains/jet/test/util/DescriptorValidator.java index 5544922cae3..68ddc64adf2 100644 --- a/compiler/tests/org/jetbrains/jet/test/util/DescriptorValidator.java +++ b/compiler/tests/org/jetbrains/jet/test/util/DescriptorValidator.java @@ -190,6 +190,9 @@ public class DescriptorValidator { TypeParameterDescriptor descriptor, DiagnosticCollector collector ) { validateTypes(descriptor, collector, descriptor.getUpperBounds()); + + validateType(descriptor, descriptor.getDefaultType(), collector); + return true; } @@ -269,6 +272,7 @@ public class DescriptorValidator { 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()); + assertEquals(setter, collector, "corresponding property", descriptor, setter.getCorrespondingProperty()); } return true; From d4ee6bd78111b5bec7c6ea1f042f9aabff75e9dc Mon Sep 17 00:00:00 2001 From: Andrey Breslav Date: Tue, 11 Jun 2013 14:03:46 +0400 Subject: [PATCH 114/291] Account for error types equality --- .../jet/test/util/DescriptorValidator.java | 21 ++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/compiler/tests/org/jetbrains/jet/test/util/DescriptorValidator.java b/compiler/tests/org/jetbrains/jet/test/util/DescriptorValidator.java index 68ddc64adf2..ed69a2e33fe 100644 --- a/compiler/tests/org/jetbrains/jet/test/util/DescriptorValidator.java +++ b/compiler/tests/org/jetbrains/jet/test/util/DescriptorValidator.java @@ -149,6 +149,21 @@ public class DescriptorValidator { } } + private static void assertEqualTypes( + DeclarationDescriptor descriptor, + DiagnosticCollector collector, + String name, + JetType expected, + JetType actual + ) { + if (ErrorUtils.isErrorType(expected) && ErrorUtils.isErrorType(actual)) { + assertEquals(descriptor, collector, name, expected.toString(), actual.toString()); + } + else if (!expected.equals(actual)) { + report(collector, descriptor, "Wrong " + name + ": " + actual + " must be " + expected); + } + } + private static void validateAccessor( PropertyDescriptor descriptor, DiagnosticCollector collector, @@ -241,7 +256,7 @@ public class DescriptorValidator { ) { visitFunctionDescriptor(constructorDescriptor, collector); - assertEquals(constructorDescriptor, collector, + assertEqualTypes(constructorDescriptor, collector, "return type", constructorDescriptor.getContainingDeclaration().getDefaultType(), constructorDescriptor.getReturnType()); @@ -264,14 +279,14 @@ public class DescriptorValidator { PropertyGetterDescriptor getter = descriptor.getGetter(); if (getter != null) { - assertEquals(getter, collector, "getter return type", descriptor.getType(), getter.getReturnType()); + assertEqualTypes(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()); + assertEqualTypes(setter, collector, "setter parameter type", descriptor.getType(), setter.getValueParameters().get(0).getType()); assertEquals(setter, collector, "corresponding property", descriptor, setter.getCorrespondingProperty()); } From 40b2478d3d7f239d41836981805a6b8f204fb46a Mon Sep 17 00:00:00 2001 From: Andrey Breslav Date: Tue, 11 Jun 2013 14:12:59 +0400 Subject: [PATCH 115/291] Validation integrated into NamespaceComparator --- ...actCompileKotlinAgainstCustomJavaTest.java | 6 +-- .../AbstractLoadCompiledKotlinTest.java | 15 +++---- .../jvm/compiler/AbstractLoadJavaTest.java | 6 +-- .../jet/jvm/compiler/LoadDescriptorUtil.java | 3 -- .../jvm/compiler/LoadKotlinCustomTest.java | 9 ++--- .../AbstractLazyResolveDiagnosticsTest.java | 7 ++-- ...ractLazyResolveNamespaceComparingTest.java | 15 +++---- .../lazy/LazyResolveBuiltinClassesTest.java | 8 +--- .../lazy/LazyResolveStdlibLoadingTest.java | 4 +- .../jet/test/util/DescriptorValidator.java | 11 +++-- .../jet/test/util/NamespaceComparator.java | 40 +++++++++++++++++++ 11 files changed, 69 insertions(+), 55 deletions(-) diff --git a/compiler/tests/org/jetbrains/jet/jvm/compiler/AbstractCompileKotlinAgainstCustomJavaTest.java b/compiler/tests/org/jetbrains/jet/jvm/compiler/AbstractCompileKotlinAgainstCustomJavaTest.java index 8a6f8df3a38..47d8acfe310 100644 --- a/compiler/tests/org/jetbrains/jet/jvm/compiler/AbstractCompileKotlinAgainstCustomJavaTest.java +++ b/compiler/tests/org/jetbrains/jet/jvm/compiler/AbstractCompileKotlinAgainstCustomJavaTest.java @@ -34,7 +34,6 @@ 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; @@ -45,7 +44,7 @@ import java.util.List; import java.util.concurrent.CopyOnWriteArrayList; import java.util.regex.Pattern; -import static org.jetbrains.jet.test.util.NamespaceComparator.compareNamespaceWithFile; +import static org.jetbrains.jet.test.util.NamespaceComparator.validateAndCompareNamespaceWithFile; public abstract class AbstractCompileKotlinAgainstCustomJavaTest extends TestCaseWithTmpdir { protected void doTest(String ktFilePath) throws Exception { @@ -71,8 +70,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); + validateAndCompareNamespaceWithFile(namespaceDescriptor, NamespaceComparator.DONT_INCLUDE_METHODS_OF_OBJECT, expectedFile); } private JetCoreEnvironment getEnvironment(File ktFile) { diff --git a/compiler/tests/org/jetbrains/jet/jvm/compiler/AbstractLoadCompiledKotlinTest.java b/compiler/tests/org/jetbrains/jet/jvm/compiler/AbstractLoadCompiledKotlinTest.java index a32f2ad7a0a..ceabcd5a33d 100644 --- a/compiler/tests/org/jetbrains/jet/jvm/compiler/AbstractLoadCompiledKotlinTest.java +++ b/compiler/tests/org/jetbrains/jet/jvm/compiler/AbstractLoadCompiledKotlinTest.java @@ -23,14 +23,13 @@ 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; import static org.jetbrains.jet.jvm.compiler.LoadDescriptorUtil.TEST_PACKAGE_FQNAME; import static org.jetbrains.jet.jvm.compiler.LoadDescriptorUtil.compileKotlinToDirAndGetAnalyzeExhaust; -import static org.jetbrains.jet.test.util.NamespaceComparator.compareNamespaces; +import static org.jetbrains.jet.test.util.NamespaceComparator.validateAndCompareNamespaces; /** * Compile Kotlin and then parse model from .class files. @@ -57,15 +56,13 @@ public abstract class AbstractLoadCompiledKotlinTest extends TestCaseWithTmpdir 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) - .checkPropertyAccessors(includeAccessors), - txtFile); + validateAndCompareNamespaces(namespaceFromSource, namespaceFromClass, + NamespaceComparator.DONT_INCLUDE_METHODS_OF_OBJECT + .checkPrimaryConstructors(true) + .checkPropertyAccessors(includeAccessors), + txtFile); } } diff --git a/compiler/tests/org/jetbrains/jet/jvm/compiler/AbstractLoadJavaTest.java b/compiler/tests/org/jetbrains/jet/jvm/compiler/AbstractLoadJavaTest.java index f4809446297..4f3f51842ad 100644 --- a/compiler/tests/org/jetbrains/jet/jvm/compiler/AbstractLoadJavaTest.java +++ b/compiler/tests/org/jetbrains/jet/jvm/compiler/AbstractLoadJavaTest.java @@ -42,7 +42,6 @@ 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; @@ -165,7 +164,6 @@ 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); } @@ -205,7 +203,7 @@ public abstract class AbstractLoadJavaTest extends TestCaseWithTmpdir { checkForLoadErrorsAndCompare(javaNamespace, bindingContext, new Runnable() { @Override public void run() { - compareNamespaces(kotlinNamespace, javaNamespace, DONT_INCLUDE_METHODS_OF_OBJECT, txtFile); + validateAndCompareNamespaces(kotlinNamespace, javaNamespace, DONT_INCLUDE_METHODS_OF_OBJECT, txtFile); } }); } @@ -219,7 +217,7 @@ public abstract class AbstractLoadJavaTest extends TestCaseWithTmpdir { checkForLoadErrorsAndCompare(javaNamespace, bindingContext, new Runnable() { @Override public void run() { - compareNamespaceWithFile(javaNamespace, configuration, txtFile); + validateAndCompareNamespaceWithFile(javaNamespace, configuration, txtFile); } }); } diff --git a/compiler/tests/org/jetbrains/jet/jvm/compiler/LoadDescriptorUtil.java b/compiler/tests/org/jetbrains/jet/jvm/compiler/LoadDescriptorUtil.java index cac81dec73a..cc5a56fd4a4 100644 --- a/compiler/tests/org/jetbrains/jet/jvm/compiler/LoadDescriptorUtil.java +++ b/compiler/tests/org/jetbrains/jet/jvm/compiler/LoadDescriptorUtil.java @@ -42,7 +42,6 @@ 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; @@ -108,7 +107,6 @@ public final class LoadDescriptorUtil { javaDescriptorResolver.resolveNamespace(TEST_PACKAGE_FQNAME, DescriptorSearchRule.ERROR_IF_FOUND_IN_KOTLIN); assert namespaceDescriptor != null; - DescriptorValidator.validateIgnoringErrorTypes(namespaceDescriptor); return Pair.create(namespaceDescriptor, injector.getBindingTrace().getBindingContext()); } @@ -141,7 +139,6 @@ 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 7d990d68ca5..54b7a121da3 100644 --- a/compiler/tests/org/jetbrains/jet/jvm/compiler/LoadKotlinCustomTest.java +++ b/compiler/tests/org/jetbrains/jet/jvm/compiler/LoadKotlinCustomTest.java @@ -22,14 +22,12 @@ 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; import static org.jetbrains.jet.jvm.compiler.LoadDescriptorUtil.*; -import static org.jetbrains.jet.test.util.NamespaceComparator.DONT_INCLUDE_METHODS_OF_OBJECT; -import static org.jetbrains.jet.test.util.NamespaceComparator.compareNamespaceWithFile; +import static org.jetbrains.jet.test.util.NamespaceComparator.*; /* * This test should be implemented via AbstractLoadCompiledKotlinTest. @@ -45,7 +43,7 @@ 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); + validateAndCompareNamespaceWithFile(namespaceFromClass, DONT_INCLUDE_METHODS_OF_OBJECT, expectedFile); } private void loadDescriptorsFromSourceAndCompareWithTxt(@NotNull File expectedFile, @NotNull File kotlinFile) @@ -54,8 +52,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), + validateAndCompareNamespaceWithFile(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 6cea9ee3eb0..f0fec8481a2 100644 --- a/compiler/tests/org/jetbrains/jet/lang/resolve/lazy/AbstractLazyResolveDiagnosticsTest.java +++ b/compiler/tests/org/jetbrains/jet/lang/resolve/lazy/AbstractLazyResolveDiagnosticsTest.java @@ -26,13 +26,13 @@ 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; import java.util.Set; -import static org.jetbrains.jet.test.util.NamespaceComparator.*; +import static org.jetbrains.jet.test.util.NamespaceComparator.RECURSIVE; +import static org.jetbrains.jet.test.util.NamespaceComparator.validateAndCompareNamespaces; public abstract class AbstractLazyResolveDiagnosticsTest extends AbstractJetDiagnosticsTest { @@ -47,7 +47,6 @@ 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); @@ -55,7 +54,7 @@ public abstract class AbstractLazyResolveDiagnosticsTest extends AbstractJetDiag // Only recurse into those namespaces mentioned in the files // Otherwise we'll be examining the whole JDK final Set names = LazyResolveTestUtil.getTopLevelPackagesFromFileList(jetFiles); - compareNamespaces( + validateAndCompareNamespaces( expected, actual, RECURSIVE.filterRecursion(new Predicate() { @Override 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 3aee75d6546..1b18c6fcc17 100644 --- a/compiler/tests/org/jetbrains/jet/lang/resolve/lazy/AbstractLazyResolveNamespaceComparingTest.java +++ b/compiler/tests/org/jetbrains/jet/lang/resolve/lazy/AbstractLazyResolveNamespaceComparingTest.java @@ -28,7 +28,6 @@ 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; @@ -36,6 +35,9 @@ import java.io.File; import java.io.IOException; import java.util.List; +import static org.jetbrains.jet.test.util.DescriptorValidator.ValidationVisitor.ALLOW_ERROR_TYPES; +import static org.jetbrains.jet.test.util.DescriptorValidator.ValidationVisitor.FORBID_ERROR_TYPES; + public abstract class AbstractLazyResolveNamespaceComparingTest extends KotlinTestWithEnvironment { @Override @@ -78,15 +80,8 @@ public abstract class AbstractLazyResolveNamespaceComparingTest extends KotlinTe File serializeResultsTo = new File(FileUtil.getNameWithoutExtension(testFileName) + ".txt"); - if (allowErrorTypes) { - DescriptorValidator.validateIgnoringErrorTypes(expected, actual); - } - else { - DescriptorValidator.validate(expected, actual); - } - - - NamespaceComparator.compareNamespaces( + NamespaceComparator.validateAndCompareNamespaces( + allowErrorTypes ? ALLOW_ERROR_TYPES : FORBID_ERROR_TYPES, expected, actual, NamespaceComparator.DONT_INCLUDE_METHODS_OF_OBJECT.filterRecursion( new Predicate() { @Override 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 2ae15fe6753..c28e1a3c742 100644 --- a/compiler/tests/org/jetbrains/jet/lang/resolve/lazy/LazyResolveBuiltinClassesTest.java +++ b/compiler/tests/org/jetbrains/jet/lang/resolve/lazy/LazyResolveBuiltinClassesTest.java @@ -20,13 +20,11 @@ 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; import static org.jetbrains.jet.test.util.NamespaceComparator.RECURSIVE_ALL; -import static org.jetbrains.jet.test.util.NamespaceComparator.compareNamespaceWithFile; +import static org.jetbrains.jet.test.util.NamespaceComparator.validateAndCompareNamespaceWithFile; public class LazyResolveBuiltinClassesTest extends KotlinTestWithEnvironment { @Override @@ -34,10 +32,8 @@ public class LazyResolveBuiltinClassesTest extends KotlinTestWithEnvironment { return createEnvironmentWithMockJdk(ConfigurationKind.JDK_ONLY); } - @Test public void testBuiltIns() throws Exception { NamespaceDescriptor builtInsPackage = KotlinBuiltIns.getInstance().getBuiltInsPackage(); - DescriptorValidator.validate(builtInsPackage); - compareNamespaceWithFile(builtInsPackage, RECURSIVE_ALL, new File("compiler/testData/builtin-classes.txt")); + validateAndCompareNamespaceWithFile(builtInsPackage, RECURSIVE_ALL, 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 f79c704bf2f..189ac4296ea 100644 --- a/compiler/tests/org/jetbrains/jet/lang/resolve/lazy/LazyResolveStdlibLoadingTest.java +++ b/compiler/tests/org/jetbrains/jet/lang/resolve/lazy/LazyResolveStdlibLoadingTest.java @@ -29,7 +29,6 @@ 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; @@ -60,8 +59,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); + NamespaceComparator.validateAndCompareNamespaces(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 index ed69a2e33fe..489b2b00ee9 100644 --- a/compiler/tests/org/jetbrains/jet/test/util/DescriptorValidator.java +++ b/compiler/tests/org/jetbrains/jet/test/util/DescriptorValidator.java @@ -32,15 +32,12 @@ 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); - public static void validate(DeclarationDescriptor... descriptors) { - validate(FORBID_ERROR_TYPES, Arrays.asList(descriptors)); + validate(ValidationVisitor.FORBID_ERROR_TYPES, Arrays.asList(descriptors)); } - public static void validateIgnoringErrorTypes(DeclarationDescriptor... descriptors) { - validate(ALLOW_ERROR_TYPES, Arrays.asList(descriptors)); + public static void validate(@NotNull ValidationVisitor validationStrategy, DeclarationDescriptor... descriptors) { + validate(validationStrategy, Arrays.asList(descriptors)); } public static void validate(@NotNull ValidationVisitor validator, @NotNull Collection descriptors) { @@ -68,6 +65,8 @@ public class DescriptorValidator { } public static class ValidationVisitor implements DeclarationDescriptorVisitor { + public static final ValidationVisitor FORBID_ERROR_TYPES = new ValidationVisitor(false); + public static final ValidationVisitor ALLOW_ERROR_TYPES = new ValidationVisitor(true); private final boolean allowErrorTypes; diff --git a/compiler/tests/org/jetbrains/jet/test/util/NamespaceComparator.java b/compiler/tests/org/jetbrains/jet/test/util/NamespaceComparator.java index d50c518533a..c5acc602a85 100644 --- a/compiler/tests/org/jetbrains/jet/test/util/NamespaceComparator.java +++ b/compiler/tests/org/jetbrains/jet/test/util/NamespaceComparator.java @@ -44,6 +44,8 @@ import java.util.Collection; import java.util.Collections; import java.util.List; +import static org.jetbrains.jet.test.util.DescriptorValidator.ValidationVisitor.FORBID_ERROR_TYPES; + 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()); @@ -179,6 +181,44 @@ public class NamespaceComparator { doCompareNamespaces(expectedNamespace, actualNamespace, configuration, txtFile); } + public static void validateAndCompareNamespaceWithFile( + @NotNull NamespaceDescriptor actualNamespace, + @NotNull Configuration configuration, + @NotNull File txtFile + ) { + validateAndCompareNamespaceWithFile(FORBID_ERROR_TYPES, actualNamespace, configuration, txtFile); + } + + public static void validateAndCompareNamespaceWithFile( + @NotNull DescriptorValidator.ValidationVisitor validationStrategy, + @NotNull NamespaceDescriptor actualNamespace, + @NotNull Configuration configuration, + @NotNull File txtFile + ) { + DescriptorValidator.validate(validationStrategy, actualNamespace); + compareNamespaceWithFile(actualNamespace, configuration, txtFile); + } + + public static void validateAndCompareNamespaces( + @NotNull NamespaceDescriptor expectedNamespace, + @NotNull NamespaceDescriptor actualNamespace, + @NotNull Configuration configuration, + @Nullable File txtFile + ) { + validateAndCompareNamespaces(FORBID_ERROR_TYPES, expectedNamespace, actualNamespace, configuration, txtFile); + } + + public static void validateAndCompareNamespaces( + @NotNull DescriptorValidator.ValidationVisitor validationStrategy, + @NotNull NamespaceDescriptor expectedNamespace, + @NotNull NamespaceDescriptor actualNamespace, + @NotNull Configuration configuration, + @Nullable File txtFile + ) { + DescriptorValidator.validate(validationStrategy, expectedNamespace, actualNamespace); + compareNamespaces(expectedNamespace, actualNamespace, configuration, txtFile); + } + private static void doCompareNamespaces( @Nullable NamespaceDescriptor expectedNamespace, @NotNull NamespaceDescriptor actualNamespace, From 23f91e49780c1fdb04f6e1621a927a64012d4394 Mon Sep 17 00:00:00 2001 From: Andrey Breslav Date: Tue, 11 Jun 2013 15:48:52 +0400 Subject: [PATCH 116/291] Do not dispose the project before results of its analysis are used --- .../AbstractLoadCompiledKotlinTest.java | 38 +++++++++++-------- .../jvm/compiler/AbstractLoadJavaTest.java | 16 ++++++-- 2 files changed, 35 insertions(+), 19 deletions(-) diff --git a/compiler/tests/org/jetbrains/jet/jvm/compiler/AbstractLoadCompiledKotlinTest.java b/compiler/tests/org/jetbrains/jet/jvm/compiler/AbstractLoadCompiledKotlinTest.java index ceabcd5a33d..f50084a18db 100644 --- a/compiler/tests/org/jetbrains/jet/jvm/compiler/AbstractLoadCompiledKotlinTest.java +++ b/compiler/tests/org/jetbrains/jet/jvm/compiler/AbstractLoadCompiledKotlinTest.java @@ -16,6 +16,8 @@ package org.jetbrains.jet.jvm.compiler; +import com.intellij.openapi.Disposable; +import com.intellij.openapi.util.Disposer; import junit.framework.Assert; import org.jetbrains.annotations.NotNull; import org.jetbrains.jet.ConfigurationKind; @@ -46,23 +48,29 @@ public abstract class AbstractLoadCompiledKotlinTest extends TestCaseWithTmpdir } private void doTest(@NotNull String ktFileName, boolean includeAccessors) throws Exception { - File ktFile = new File(ktFileName); - File txtFile = new File(ktFileName.replaceFirst("\\.kt$", ".txt")); - AnalyzeExhaust exhaust = compileKotlinToDirAndGetAnalyzeExhaust(ktFile, tmpdir, getTestRootDisposable(), - ConfigurationKind.JDK_ONLY); + Disposable tmpDisposable = Disposer.newDisposable(); + try { + File ktFile = new File(ktFileName); + File txtFile = new File(ktFileName.replaceFirst("\\.kt$", ".txt")); + AnalyzeExhaust exhaust = compileKotlinToDirAndGetAnalyzeExhaust(ktFile, tmpdir, tmpDisposable, + ConfigurationKind.JDK_ONLY); - NamespaceDescriptor namespaceFromSource = exhaust.getBindingContext().get(BindingContext.FQNAME_TO_NAMESPACE_DESCRIPTOR, - TEST_PACKAGE_FQNAME); - assert namespaceFromSource != null; - Assert.assertEquals("test", namespaceFromSource.getName().asString()); + NamespaceDescriptor namespaceFromSource = exhaust.getBindingContext().get(BindingContext.FQNAME_TO_NAMESPACE_DESCRIPTOR, + TEST_PACKAGE_FQNAME); + assert namespaceFromSource != null; + Assert.assertEquals("test", namespaceFromSource.getName().asString()); - NamespaceDescriptor namespaceFromClass = LoadDescriptorUtil.loadTestNamespaceAndBindingContextFromJavaRoot( - tmpdir, getTestRootDisposable(), ConfigurationKind.JDK_ONLY).first; + NamespaceDescriptor namespaceFromClass = LoadDescriptorUtil.loadTestNamespaceAndBindingContextFromJavaRoot( + tmpdir, getTestRootDisposable(), ConfigurationKind.JDK_ONLY).first; - validateAndCompareNamespaces(namespaceFromSource, namespaceFromClass, - NamespaceComparator.DONT_INCLUDE_METHODS_OF_OBJECT - .checkPrimaryConstructors(true) - .checkPropertyAccessors(includeAccessors), - txtFile); + validateAndCompareNamespaces(namespaceFromSource, namespaceFromClass, + NamespaceComparator.DONT_INCLUDE_METHODS_OF_OBJECT + .checkPrimaryConstructors(true) + .checkPropertyAccessors(includeAccessors), + txtFile); + } + finally { + Disposer.dispose(tmpDisposable); + } } } diff --git a/compiler/tests/org/jetbrains/jet/jvm/compiler/AbstractLoadJavaTest.java b/compiler/tests/org/jetbrains/jet/jvm/compiler/AbstractLoadJavaTest.java index 4f3f51842ad..e77e36788f4 100644 --- a/compiler/tests/org/jetbrains/jet/jvm/compiler/AbstractLoadJavaTest.java +++ b/compiler/tests/org/jetbrains/jet/jvm/compiler/AbstractLoadJavaTest.java @@ -17,6 +17,8 @@ package org.jetbrains.jet.jvm.compiler; import com.google.common.base.Predicates; +import com.intellij.openapi.Disposable; +import com.intellij.openapi.util.Disposer; import com.intellij.openapi.util.Pair; import com.intellij.openapi.util.io.FileUtil; import com.intellij.psi.PsiFile; @@ -64,10 +66,16 @@ public abstract class AbstractLoadJavaTest extends TestCaseWithTmpdir { File javaFile = new File(javaFileName); File ktFile = new File(javaFile.getPath().replaceFirst("\\.java$", ".kt")); File txtFile = new File(javaFile.getPath().replaceFirst("\\.java$", ".txt")); - NamespaceDescriptor kotlinNamespace = analyzeKotlinAndLoadTestNamespace(ktFile, myTestRootDisposable, ConfigurationKind.JDK_AND_ANNOTATIONS); - Pair javaNamespaceAndContext = compileJavaAndLoadTestNamespaceAndBindingContextFromBinary( - Arrays.asList(javaFile), tmpdir, myTestRootDisposable, ConfigurationKind.JDK_AND_ANNOTATIONS); - checkLoadedNamespaces(txtFile, kotlinNamespace, javaNamespaceAndContext.first, javaNamespaceAndContext.second); + Disposable tmpDisposable = Disposer.newDisposable(); + try { + NamespaceDescriptor kotlinNamespace = analyzeKotlinAndLoadTestNamespace(ktFile, tmpDisposable, ConfigurationKind.JDK_AND_ANNOTATIONS); + Pair javaNamespaceAndContext = compileJavaAndLoadTestNamespaceAndBindingContextFromBinary( + Arrays.asList(javaFile), tmpdir, myTestRootDisposable, ConfigurationKind.JDK_AND_ANNOTATIONS); + checkLoadedNamespaces(txtFile, kotlinNamespace, javaNamespaceAndContext.first, javaNamespaceAndContext.second); + } + finally { + Disposer.dispose(tmpDisposable); + } } protected void doTestCompiledJava(@NotNull String javaFileName) throws Exception { From 4756e9fde323a0320292c09ae161ff9bbd70eb30 Mon Sep 17 00:00:00 2001 From: Andrey Breslav Date: Tue, 11 Jun 2013 16:02:36 +0400 Subject: [PATCH 117/291] Extract method --- .../jet/jvm/compiler/AbstractLoadJavaTest.java | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/compiler/tests/org/jetbrains/jet/jvm/compiler/AbstractLoadJavaTest.java b/compiler/tests/org/jetbrains/jet/jvm/compiler/AbstractLoadJavaTest.java index e77e36788f4..6a3f80bdd61 100644 --- a/compiler/tests/org/jetbrains/jet/jvm/compiler/AbstractLoadJavaTest.java +++ b/compiler/tests/org/jetbrains/jet/jvm/compiler/AbstractLoadJavaTest.java @@ -65,7 +65,7 @@ public abstract class AbstractLoadJavaTest extends TestCaseWithTmpdir { Assert.assertTrue("A java file expected: " + javaFileName, javaFileName.endsWith(".java")); File javaFile = new File(javaFileName); File ktFile = new File(javaFile.getPath().replaceFirst("\\.java$", ".kt")); - File txtFile = new File(javaFile.getPath().replaceFirst("\\.java$", ".txt")); + File txtFile = getTxtFile(javaFile.getPath()); Disposable tmpDisposable = Disposer.newDisposable(); try { NamespaceDescriptor kotlinNamespace = analyzeKotlinAndLoadTestNamespace(ktFile, tmpDisposable, ConfigurationKind.JDK_AND_ANNOTATIONS); @@ -114,12 +114,12 @@ public abstract class AbstractLoadJavaTest extends TestCaseWithTmpdir { Pair javaNamespaceAndContext = compileJavaAndLoadTestNamespaceAndBindingContextFromBinary( srcFiles, compiledDir, getTestRootDisposable(), ConfigurationKind.JDK_ONLY); - checkJavaNamespace(new File(javaFileName.replaceFirst("\\.java$", ".txt")), javaNamespaceAndContext.first, javaNamespaceAndContext.second, configuration); + checkJavaNamespace(getTxtFile(javaFileName), javaNamespaceAndContext.first, javaNamespaceAndContext.second, configuration); } protected void doTestSourceJava(@NotNull String javaFileName) throws Exception { File originalJavaFile = new File(javaFileName); - File expectedFile = new File(javaFileName.replaceFirst("\\.java$", ".txt")); + File expectedFile = getTxtFile(javaFileName); File testPackageDir = new File(tmpdir, "test"); assertTrue(testPackageDir.mkdir()); @@ -229,4 +229,8 @@ public abstract class AbstractLoadJavaTest extends TestCaseWithTmpdir { } }); } + + private static File getTxtFile(String javaFileName) { + return new File(javaFileName.replaceFirst("\\.java$", ".txt")); + } } From 97fabf5fc2bbf4a66bd3929607f149aa62a592ce Mon Sep 17 00:00:00 2001 From: Andrey Breslav Date: Tue, 11 Jun 2013 16:03:37 +0400 Subject: [PATCH 118/291] Allow error types for some Java tests --- .../jet/jvm/compiler/AbstractLoadJavaTest.java | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/compiler/tests/org/jetbrains/jet/jvm/compiler/AbstractLoadJavaTest.java b/compiler/tests/org/jetbrains/jet/jvm/compiler/AbstractLoadJavaTest.java index 6a3f80bdd61..0553318517f 100644 --- a/compiler/tests/org/jetbrains/jet/jvm/compiler/AbstractLoadJavaTest.java +++ b/compiler/tests/org/jetbrains/jet/jvm/compiler/AbstractLoadJavaTest.java @@ -44,6 +44,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; @@ -54,6 +55,8 @@ import java.util.Collections; import java.util.List; import static org.jetbrains.jet.jvm.compiler.LoadDescriptorUtil.*; +import static org.jetbrains.jet.test.util.DescriptorValidator.ValidationVisitor.ALLOW_ERROR_TYPES; +import static org.jetbrains.jet.test.util.DescriptorValidator.ValidationVisitor.FORBID_ERROR_TYPES; import static org.jetbrains.jet.test.util.NamespaceComparator.*; /* @@ -114,7 +117,7 @@ public abstract class AbstractLoadJavaTest extends TestCaseWithTmpdir { Pair javaNamespaceAndContext = compileJavaAndLoadTestNamespaceAndBindingContextFromBinary( srcFiles, compiledDir, getTestRootDisposable(), ConfigurationKind.JDK_ONLY); - checkJavaNamespace(getTxtFile(javaFileName), javaNamespaceAndContext.first, javaNamespaceAndContext.second, configuration); + checkJavaNamespace(getTxtFile(javaFileName), javaNamespaceAndContext.first, javaNamespaceAndContext.second, configuration, FORBID_ERROR_TYPES); } protected void doTestSourceJava(@NotNull String javaFileName) throws Exception { @@ -128,7 +131,7 @@ public abstract class AbstractLoadJavaTest extends TestCaseWithTmpdir { Pair javaNamespaceAndContext = loadTestNamespaceAndBindingContextFromJavaRoot( tmpdir, getTestRootDisposable(), ConfigurationKind.JDK_ONLY); - checkJavaNamespace(expectedFile, javaNamespaceAndContext.first, javaNamespaceAndContext.second, DONT_INCLUDE_METHODS_OF_OBJECT); + checkJavaNamespace(expectedFile, javaNamespaceAndContext.first, javaNamespaceAndContext.second, DONT_INCLUDE_METHODS_OF_OBJECT, ALLOW_ERROR_TYPES); } protected void doTestJavaAgainstKotlin(String expectedFileName) throws Exception { @@ -172,7 +175,7 @@ public abstract class AbstractLoadJavaTest extends TestCaseWithTmpdir { LoadDescriptorUtil.TEST_PACKAGE_FQNAME, DescriptorSearchRule.INCLUDE_KOTLIN); assert namespaceDescriptor != null : "Test namespace not found"; - checkJavaNamespace(expectedFile, namespaceDescriptor, trace.getBindingContext(), DONT_INCLUDE_METHODS_OF_OBJECT); + checkJavaNamespace(expectedFile, namespaceDescriptor, trace.getBindingContext(), DONT_INCLUDE_METHODS_OF_OBJECT, FORBID_ERROR_TYPES); } private static void checkForLoadErrorsAndCompare( @@ -220,12 +223,13 @@ public abstract class AbstractLoadJavaTest extends TestCaseWithTmpdir { final File txtFile, final NamespaceDescriptor javaNamespace, BindingContext bindingContext, - final Configuration configuration + final Configuration configuration, + final DescriptorValidator.ValidationVisitor validationStrategy ) { checkForLoadErrorsAndCompare(javaNamespace, bindingContext, new Runnable() { @Override public void run() { - validateAndCompareNamespaceWithFile(javaNamespace, configuration, txtFile); + validateAndCompareNamespaceWithFile(validationStrategy, javaNamespace, configuration, txtFile); } }); } From 88c5aaeaa1930fd7b7eea02d8ab1f73788102eb6 Mon Sep 17 00:00:00 2001 From: Andrey Breslav Date: Tue, 11 Jun 2013 22:08:46 +0400 Subject: [PATCH 119/291] Put validation parameter into Configuration --- .../jvm/compiler/AbstractLoadJavaTest.java | 14 +++-- ...ractLazyResolveNamespaceComparingTest.java | 7 ++- .../jet/test/util/NamespaceComparator.java | 54 +++++++++---------- 3 files changed, 35 insertions(+), 40 deletions(-) diff --git a/compiler/tests/org/jetbrains/jet/jvm/compiler/AbstractLoadJavaTest.java b/compiler/tests/org/jetbrains/jet/jvm/compiler/AbstractLoadJavaTest.java index 0553318517f..c2f1e7f7db3 100644 --- a/compiler/tests/org/jetbrains/jet/jvm/compiler/AbstractLoadJavaTest.java +++ b/compiler/tests/org/jetbrains/jet/jvm/compiler/AbstractLoadJavaTest.java @@ -44,7 +44,6 @@ 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; @@ -56,7 +55,6 @@ import java.util.List; import static org.jetbrains.jet.jvm.compiler.LoadDescriptorUtil.*; import static org.jetbrains.jet.test.util.DescriptorValidator.ValidationVisitor.ALLOW_ERROR_TYPES; -import static org.jetbrains.jet.test.util.DescriptorValidator.ValidationVisitor.FORBID_ERROR_TYPES; import static org.jetbrains.jet.test.util.NamespaceComparator.*; /* @@ -117,7 +115,7 @@ public abstract class AbstractLoadJavaTest extends TestCaseWithTmpdir { Pair javaNamespaceAndContext = compileJavaAndLoadTestNamespaceAndBindingContextFromBinary( srcFiles, compiledDir, getTestRootDisposable(), ConfigurationKind.JDK_ONLY); - checkJavaNamespace(getTxtFile(javaFileName), javaNamespaceAndContext.first, javaNamespaceAndContext.second, configuration, FORBID_ERROR_TYPES); + checkJavaNamespace(getTxtFile(javaFileName), javaNamespaceAndContext.first, javaNamespaceAndContext.second, configuration); } protected void doTestSourceJava(@NotNull String javaFileName) throws Exception { @@ -131,7 +129,8 @@ public abstract class AbstractLoadJavaTest extends TestCaseWithTmpdir { Pair javaNamespaceAndContext = loadTestNamespaceAndBindingContextFromJavaRoot( tmpdir, getTestRootDisposable(), ConfigurationKind.JDK_ONLY); - checkJavaNamespace(expectedFile, javaNamespaceAndContext.first, javaNamespaceAndContext.second, DONT_INCLUDE_METHODS_OF_OBJECT, ALLOW_ERROR_TYPES); + checkJavaNamespace(expectedFile, javaNamespaceAndContext.first, javaNamespaceAndContext.second, + DONT_INCLUDE_METHODS_OF_OBJECT.withValidationStrategy(ALLOW_ERROR_TYPES)); } protected void doTestJavaAgainstKotlin(String expectedFileName) throws Exception { @@ -175,7 +174,7 @@ public abstract class AbstractLoadJavaTest extends TestCaseWithTmpdir { LoadDescriptorUtil.TEST_PACKAGE_FQNAME, DescriptorSearchRule.INCLUDE_KOTLIN); assert namespaceDescriptor != null : "Test namespace not found"; - checkJavaNamespace(expectedFile, namespaceDescriptor, trace.getBindingContext(), DONT_INCLUDE_METHODS_OF_OBJECT, FORBID_ERROR_TYPES); + checkJavaNamespace(expectedFile, namespaceDescriptor, trace.getBindingContext(), DONT_INCLUDE_METHODS_OF_OBJECT); } private static void checkForLoadErrorsAndCompare( @@ -223,13 +222,12 @@ public abstract class AbstractLoadJavaTest extends TestCaseWithTmpdir { final File txtFile, final NamespaceDescriptor javaNamespace, BindingContext bindingContext, - final Configuration configuration, - final DescriptorValidator.ValidationVisitor validationStrategy + final Configuration configuration ) { checkForLoadErrorsAndCompare(javaNamespace, bindingContext, new Runnable() { @Override public void run() { - validateAndCompareNamespaceWithFile(validationStrategy, javaNamespace, configuration, txtFile); + validateAndCompareNamespaceWithFile(javaNamespace, configuration, txtFile); } }); } 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 1b18c6fcc17..40a3f0100e9 100644 --- a/compiler/tests/org/jetbrains/jet/lang/resolve/lazy/AbstractLazyResolveNamespaceComparingTest.java +++ b/compiler/tests/org/jetbrains/jet/lang/resolve/lazy/AbstractLazyResolveNamespaceComparingTest.java @@ -81,13 +81,16 @@ public abstract class AbstractLazyResolveNamespaceComparingTest extends KotlinTe File serializeResultsTo = new File(FileUtil.getNameWithoutExtension(testFileName) + ".txt"); NamespaceComparator.validateAndCompareNamespaces( - allowErrorTypes ? ALLOW_ERROR_TYPES : FORBID_ERROR_TYPES, expected, actual, NamespaceComparator.DONT_INCLUDE_METHODS_OF_OBJECT.filterRecursion( new Predicate() { @Override public boolean apply(FqNameUnsafe fqName) { return !KotlinBuiltIns.BUILT_INS_PACKAGE_FQ_NAME.toUnsafe().equals(fqName); } - }).checkPrimaryConstructors(checkPrimaryConstructors).checkPropertyAccessors(checkPropertyAccessors), serializeResultsTo); + }) + .checkPrimaryConstructors(checkPrimaryConstructors) + .checkPropertyAccessors(checkPropertyAccessors) + .withValidationStrategy(allowErrorTypes ? ALLOW_ERROR_TYPES : FORBID_ERROR_TYPES), + serializeResultsTo); } } diff --git a/compiler/tests/org/jetbrains/jet/test/util/NamespaceComparator.java b/compiler/tests/org/jetbrains/jet/test/util/NamespaceComparator.java index c5acc602a85..8b4d413ea7c 100644 --- a/compiler/tests/org/jetbrains/jet/test/util/NamespaceComparator.java +++ b/compiler/tests/org/jetbrains/jet/test/util/NamespaceComparator.java @@ -47,9 +47,10 @@ import java.util.List; import static org.jetbrains.jet.test.util.DescriptorValidator.ValidationVisitor.FORBID_ERROR_TYPES; 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()); + public static final Configuration DONT_INCLUDE_METHODS_OF_OBJECT = new Configuration(false, false, false, Predicates.alwaysTrue(), + FORBID_ERROR_TYPES); + public static final Configuration RECURSIVE = new Configuration(false, false, true, Predicates.alwaysTrue(), FORBID_ERROR_TYPES); + public static final Configuration RECURSIVE_ALL = new Configuration(true, true, true, Predicates.alwaysTrue(), FORBID_ERROR_TYPES); private static final DescriptorRenderer RENDERER = new DescriptorRendererBuilder() .setWithDefinedIn(false) @@ -160,7 +161,7 @@ public class NamespaceComparator { } } - public static void compareNamespaceWithFile( + private static void compareNamespaceWithFile( @NotNull NamespaceDescriptor actualNamespace, @NotNull Configuration configuration, @NotNull File txtFile @@ -168,7 +169,7 @@ public class NamespaceComparator { doCompareNamespaces(null, actualNamespace, configuration, txtFile); } - public static void compareNamespaces( + private static void compareNamespaces( @NotNull NamespaceDescriptor expectedNamespace, @NotNull NamespaceDescriptor actualNamespace, @NotNull Configuration configuration, @@ -182,40 +183,21 @@ public class NamespaceComparator { } public static void validateAndCompareNamespaceWithFile( - @NotNull NamespaceDescriptor actualNamespace, - @NotNull Configuration configuration, - @NotNull File txtFile - ) { - validateAndCompareNamespaceWithFile(FORBID_ERROR_TYPES, actualNamespace, configuration, txtFile); - } - - public static void validateAndCompareNamespaceWithFile( - @NotNull DescriptorValidator.ValidationVisitor validationStrategy, @NotNull NamespaceDescriptor actualNamespace, @NotNull Configuration configuration, @NotNull File txtFile ) { - DescriptorValidator.validate(validationStrategy, actualNamespace); + DescriptorValidator.validate(configuration.validationStrategy, actualNamespace); compareNamespaceWithFile(actualNamespace, configuration, txtFile); } public static void validateAndCompareNamespaces( - @NotNull NamespaceDescriptor expectedNamespace, - @NotNull NamespaceDescriptor actualNamespace, - @NotNull Configuration configuration, - @Nullable File txtFile - ) { - validateAndCompareNamespaces(FORBID_ERROR_TYPES, expectedNamespace, actualNamespace, configuration, txtFile); - } - - public static void validateAndCompareNamespaces( - @NotNull DescriptorValidator.ValidationVisitor validationStrategy, @NotNull NamespaceDescriptor expectedNamespace, @NotNull NamespaceDescriptor actualNamespace, @NotNull Configuration configuration, @Nullable File txtFile ) { - DescriptorValidator.validate(validationStrategy, expectedNamespace, actualNamespace); + DescriptorValidator.validate(configuration.validationStrategy, expectedNamespace, actualNamespace); compareNamespaces(expectedNamespace, actualNamespace, configuration, txtFile); } @@ -260,28 +242,40 @@ public class NamespaceComparator { private final boolean includeMethodsOfJavaObject; private final Predicate recurseIntoPackage; + private final DescriptorValidator.ValidationVisitor validationStrategy; + public Configuration( boolean checkPrimaryConstructors, boolean checkPropertyAccessors, boolean includeMethodsOfJavaObject, - Predicate recurseIntoPackage + Predicate recurseIntoPackage, + DescriptorValidator.ValidationVisitor validationStrategy ) { this.checkPrimaryConstructors = checkPrimaryConstructors; this.checkPropertyAccessors = checkPropertyAccessors; this.includeMethodsOfJavaObject = includeMethodsOfJavaObject; this.recurseIntoPackage = recurseIntoPackage; + this.validationStrategy = validationStrategy; } public Configuration filterRecursion(@NotNull Predicate recurseIntoPackage) { - return new Configuration(checkPrimaryConstructors, checkPropertyAccessors, includeMethodsOfJavaObject, recurseIntoPackage); + return new Configuration(checkPrimaryConstructors, checkPropertyAccessors, includeMethodsOfJavaObject, recurseIntoPackage, + validationStrategy); } public Configuration checkPrimaryConstructors(boolean checkPrimaryConstructors) { - return new Configuration(checkPrimaryConstructors, checkPropertyAccessors, includeMethodsOfJavaObject, recurseIntoPackage); + return new Configuration(checkPrimaryConstructors, checkPropertyAccessors, includeMethodsOfJavaObject, recurseIntoPackage, + validationStrategy); } public Configuration checkPropertyAccessors(boolean checkPropertyAccessors) { - return new Configuration(checkPrimaryConstructors, checkPropertyAccessors, includeMethodsOfJavaObject, recurseIntoPackage); + return new Configuration(checkPrimaryConstructors, checkPropertyAccessors, includeMethodsOfJavaObject, recurseIntoPackage, + validationStrategy); + } + + public Configuration withValidationStrategy(@NotNull DescriptorValidator.ValidationVisitor validationStrategy) { + return new Configuration(checkPrimaryConstructors, checkPropertyAccessors, includeMethodsOfJavaObject, recurseIntoPackage, + validationStrategy); } } } From bca243727c854427b5238b681c082ebf5401dbf6 Mon Sep 17 00:00:00 2001 From: Zalim Bashorov Date: Thu, 13 Jun 2013 11:38:36 +0400 Subject: [PATCH 120/291] Changed GitHub's authorization method. --- libraries/maven-settings.xml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/libraries/maven-settings.xml b/libraries/maven-settings.xml index 833542dc62a..5a85de484ae 100644 --- a/libraries/maven-settings.xml +++ b/libraries/maven-settings.xml @@ -20,7 +20,8 @@ jetbrains-kotlin-github - ${KOTLIN_GITHUB_OAUTH_TOKEN} + ${GITHUB_LOGIN} + ${GITHUB_PASSWORD} From 1f45e309d217da3e1d888425ded8a188bec8f3aa Mon Sep 17 00:00:00 2001 From: Andrey Breslav Date: Thu, 13 Jun 2013 11:55:49 +0400 Subject: [PATCH 121/291] Do not dispose environments outside tearDown() This caused exceptions (write access assertions) when tests with mock application ran after tests with full Application --- .../AbstractLoadCompiledKotlinTest.java | 38 ++++++++----------- .../jvm/compiler/AbstractLoadJavaTest.java | 16 ++------ .../jet/jvm/compiler/LoadDescriptorUtil.java | 3 -- 3 files changed, 19 insertions(+), 38 deletions(-) diff --git a/compiler/tests/org/jetbrains/jet/jvm/compiler/AbstractLoadCompiledKotlinTest.java b/compiler/tests/org/jetbrains/jet/jvm/compiler/AbstractLoadCompiledKotlinTest.java index f50084a18db..ceabcd5a33d 100644 --- a/compiler/tests/org/jetbrains/jet/jvm/compiler/AbstractLoadCompiledKotlinTest.java +++ b/compiler/tests/org/jetbrains/jet/jvm/compiler/AbstractLoadCompiledKotlinTest.java @@ -16,8 +16,6 @@ package org.jetbrains.jet.jvm.compiler; -import com.intellij.openapi.Disposable; -import com.intellij.openapi.util.Disposer; import junit.framework.Assert; import org.jetbrains.annotations.NotNull; import org.jetbrains.jet.ConfigurationKind; @@ -48,29 +46,23 @@ public abstract class AbstractLoadCompiledKotlinTest extends TestCaseWithTmpdir } private void doTest(@NotNull String ktFileName, boolean includeAccessors) throws Exception { - Disposable tmpDisposable = Disposer.newDisposable(); - try { - File ktFile = new File(ktFileName); - File txtFile = new File(ktFileName.replaceFirst("\\.kt$", ".txt")); - AnalyzeExhaust exhaust = compileKotlinToDirAndGetAnalyzeExhaust(ktFile, tmpdir, tmpDisposable, - ConfigurationKind.JDK_ONLY); + File ktFile = new File(ktFileName); + File txtFile = new File(ktFileName.replaceFirst("\\.kt$", ".txt")); + AnalyzeExhaust exhaust = compileKotlinToDirAndGetAnalyzeExhaust(ktFile, tmpdir, getTestRootDisposable(), + ConfigurationKind.JDK_ONLY); - NamespaceDescriptor namespaceFromSource = exhaust.getBindingContext().get(BindingContext.FQNAME_TO_NAMESPACE_DESCRIPTOR, - TEST_PACKAGE_FQNAME); - assert namespaceFromSource != null; - Assert.assertEquals("test", namespaceFromSource.getName().asString()); + NamespaceDescriptor namespaceFromSource = exhaust.getBindingContext().get(BindingContext.FQNAME_TO_NAMESPACE_DESCRIPTOR, + TEST_PACKAGE_FQNAME); + assert namespaceFromSource != null; + Assert.assertEquals("test", namespaceFromSource.getName().asString()); - NamespaceDescriptor namespaceFromClass = LoadDescriptorUtil.loadTestNamespaceAndBindingContextFromJavaRoot( - tmpdir, getTestRootDisposable(), ConfigurationKind.JDK_ONLY).first; + NamespaceDescriptor namespaceFromClass = LoadDescriptorUtil.loadTestNamespaceAndBindingContextFromJavaRoot( + tmpdir, getTestRootDisposable(), ConfigurationKind.JDK_ONLY).first; - validateAndCompareNamespaces(namespaceFromSource, namespaceFromClass, - NamespaceComparator.DONT_INCLUDE_METHODS_OF_OBJECT - .checkPrimaryConstructors(true) - .checkPropertyAccessors(includeAccessors), - txtFile); - } - finally { - Disposer.dispose(tmpDisposable); - } + validateAndCompareNamespaces(namespaceFromSource, namespaceFromClass, + NamespaceComparator.DONT_INCLUDE_METHODS_OF_OBJECT + .checkPrimaryConstructors(true) + .checkPropertyAccessors(includeAccessors), + txtFile); } } diff --git a/compiler/tests/org/jetbrains/jet/jvm/compiler/AbstractLoadJavaTest.java b/compiler/tests/org/jetbrains/jet/jvm/compiler/AbstractLoadJavaTest.java index c2f1e7f7db3..784f7402d6f 100644 --- a/compiler/tests/org/jetbrains/jet/jvm/compiler/AbstractLoadJavaTest.java +++ b/compiler/tests/org/jetbrains/jet/jvm/compiler/AbstractLoadJavaTest.java @@ -17,8 +17,6 @@ package org.jetbrains.jet.jvm.compiler; import com.google.common.base.Predicates; -import com.intellij.openapi.Disposable; -import com.intellij.openapi.util.Disposer; import com.intellij.openapi.util.Pair; import com.intellij.openapi.util.io.FileUtil; import com.intellij.psi.PsiFile; @@ -67,16 +65,10 @@ public abstract class AbstractLoadJavaTest extends TestCaseWithTmpdir { File javaFile = new File(javaFileName); File ktFile = new File(javaFile.getPath().replaceFirst("\\.java$", ".kt")); File txtFile = getTxtFile(javaFile.getPath()); - Disposable tmpDisposable = Disposer.newDisposable(); - try { - NamespaceDescriptor kotlinNamespace = analyzeKotlinAndLoadTestNamespace(ktFile, tmpDisposable, ConfigurationKind.JDK_AND_ANNOTATIONS); - Pair javaNamespaceAndContext = compileJavaAndLoadTestNamespaceAndBindingContextFromBinary( - Arrays.asList(javaFile), tmpdir, myTestRootDisposable, ConfigurationKind.JDK_AND_ANNOTATIONS); - checkLoadedNamespaces(txtFile, kotlinNamespace, javaNamespaceAndContext.first, javaNamespaceAndContext.second); - } - finally { - Disposer.dispose(tmpDisposable); - } + NamespaceDescriptor kotlinNamespace = analyzeKotlinAndLoadTestNamespace(ktFile, myTestRootDisposable, ConfigurationKind.JDK_AND_ANNOTATIONS); + Pair javaNamespaceAndContext = compileJavaAndLoadTestNamespaceAndBindingContextFromBinary( + Arrays.asList(javaFile), tmpdir, myTestRootDisposable, ConfigurationKind.JDK_AND_ANNOTATIONS); + checkLoadedNamespaces(txtFile, kotlinNamespace, javaNamespaceAndContext.first, javaNamespaceAndContext.second); } protected void doTestCompiledJava(@NotNull String javaFileName) throws Exception { diff --git a/compiler/tests/org/jetbrains/jet/jvm/compiler/LoadDescriptorUtil.java b/compiler/tests/org/jetbrains/jet/jvm/compiler/LoadDescriptorUtil.java index cc5a56fd4a4..6e32282bec7 100644 --- a/compiler/tests/org/jetbrains/jet/jvm/compiler/LoadDescriptorUtil.java +++ b/compiler/tests/org/jetbrains/jet/jvm/compiler/LoadDescriptorUtil.java @@ -17,7 +17,6 @@ package org.jetbrains.jet.jvm.compiler; import com.intellij.openapi.Disposable; -import com.intellij.openapi.util.Disposer; import com.intellij.openapi.util.Pair; import com.intellij.openapi.util.io.FileUtil; import org.jetbrains.annotations.NotNull; @@ -92,8 +91,6 @@ public final class LoadDescriptorUtil { @NotNull Disposable disposable, @NotNull ConfigurationKind configurationKind ) { - Disposer.dispose(disposable); - CompilerConfiguration configuration = JetTestUtils.compilerConfigurationForTests( configurationKind, TestJdkKind.MOCK_JDK, JetTestUtils.getAnnotationsJar(), javaRoot, From 6629892dad548df3a6cdddde9e460251e936eaa6 Mon Sep 17 00:00:00 2001 From: Andrey Breslav Date: Thu, 13 Jun 2013 14:40:41 +0400 Subject: [PATCH 122/291] Convert both strings to \n before comparing --- .../jet/test/util/RecursiveDescriptorProcessorTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/tests/org/jetbrains/jet/test/util/RecursiveDescriptorProcessorTest.java b/compiler/tests/org/jetbrains/jet/test/util/RecursiveDescriptorProcessorTest.java index 842d68ffb3e..5fd6153054f 100644 --- a/compiler/tests/org/jetbrains/jet/test/util/RecursiveDescriptorProcessorTest.java +++ b/compiler/tests/org/jetbrains/jet/test/util/RecursiveDescriptorProcessorTest.java @@ -61,7 +61,7 @@ public class RecursiveDescriptorProcessorTest extends KotlinTestWithEnvironment fail("Test data file did not exist and was created from the results of the test: " + txtFile); } - assertEquals(FileUtil.loadFile(txtFile), actualText); + assertSameLinesWithFile(txtFile.getAbsolutePath(), actualText); } private static Class closestInterface(Class aClass) { From e13508c22b22db5119cebb309853e527a67418d7 Mon Sep 17 00:00:00 2001 From: Alexey Sedunov Date: Thu, 13 Jun 2013 18:33:57 +0400 Subject: [PATCH 123/291] Add support of backticks in JetPsiMatcher --- .../jetbrains/jet/plugin/util/JetPsiMatcher.java | 15 ++++++++++++++- .../expressions/simpleName/simpleName2.kt | 1 + .../expressions/simpleName/simpleName2.kt.2 | 1 + .../org/jetbrains/jet/psi/JetPsiMatcherTest.java | 5 +++++ 4 files changed, 21 insertions(+), 1 deletion(-) create mode 100644 idea/testData/jetPsiMatcher/expressions/simpleName/simpleName2.kt create mode 100644 idea/testData/jetPsiMatcher/expressions/simpleName/simpleName2.kt.2 diff --git a/idea/src/org/jetbrains/jet/plugin/util/JetPsiMatcher.java b/idea/src/org/jetbrains/jet/plugin/util/JetPsiMatcher.java index da964464410..62fc91e7022 100644 --- a/idea/src/org/jetbrains/jet/plugin/util/JetPsiMatcher.java +++ b/idea/src/org/jetbrains/jet/plugin/util/JetPsiMatcher.java @@ -16,6 +16,7 @@ package org.jetbrains.jet.plugin.util; +import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.jet.lang.psi.*; @@ -126,7 +127,7 @@ public class JetPsiMatcher { @Override public Boolean visitSimpleNameExpression(JetSimpleNameExpression expression, JetElement data) { - return expression.getText().equals(data.getText()); + return checkIdentifierMatch(expression.getText(), data.getText()); } @Override @@ -254,4 +255,16 @@ public class JetPsiMatcher { return e1.accept(VISITOR, e2); } + + @NotNull + private static String unquote(@NotNull String s) { + return (s.startsWith("`") && s.endsWith("`")) ? s.substring(1, s.length() - 1) : s; + } + + public static boolean checkIdentifierMatch(@Nullable String s1, @Nullable String s2) { + if (s1 == s2) return true; + if (s1 == null || s2 == null) return false; + + return unquote(s1).equals(unquote(s2)); + } } diff --git a/idea/testData/jetPsiMatcher/expressions/simpleName/simpleName2.kt b/idea/testData/jetPsiMatcher/expressions/simpleName/simpleName2.kt new file mode 100644 index 00000000000..30d74d25844 --- /dev/null +++ b/idea/testData/jetPsiMatcher/expressions/simpleName/simpleName2.kt @@ -0,0 +1 @@ +test \ No newline at end of file diff --git a/idea/testData/jetPsiMatcher/expressions/simpleName/simpleName2.kt.2 b/idea/testData/jetPsiMatcher/expressions/simpleName/simpleName2.kt.2 new file mode 100644 index 00000000000..666f3d302b9 --- /dev/null +++ b/idea/testData/jetPsiMatcher/expressions/simpleName/simpleName2.kt.2 @@ -0,0 +1 @@ +`test` \ No newline at end of file diff --git a/idea/tests/org/jetbrains/jet/psi/JetPsiMatcherTest.java b/idea/tests/org/jetbrains/jet/psi/JetPsiMatcherTest.java index c365371af18..70b7b9c3c66 100644 --- a/idea/tests/org/jetbrains/jet/psi/JetPsiMatcherTest.java +++ b/idea/tests/org/jetbrains/jet/psi/JetPsiMatcherTest.java @@ -250,6 +250,11 @@ public class JetPsiMatcherTest extends AbstractJetPsiMatcherTest { doTestExpressions("idea/testData/jetPsiMatcher/expressions/simpleName/simpleName.kt"); } + @TestMetadata("simpleName2.kt") + public void testSimpleName2() throws Exception { + doTestExpressions("idea/testData/jetPsiMatcher/expressions/simpleName/simpleName2.kt"); + } + @TestMetadata("_simpleName.kt") public void test_simpleName() throws Exception { doTestExpressions("idea/testData/jetPsiMatcher/expressions/simpleName/_simpleName.kt"); From f9c46061289b0f6625062df54e78a62cf085b6c0 Mon Sep 17 00:00:00 2001 From: Alexey Sedunov Date: Mon, 10 Jun 2013 18:01:21 +0400 Subject: [PATCH 124/291] Introduce 'when' subject: consider equality right-hand side as subject candidate --- .../branchedTransformations/WhenUtils.java | 16 +++++++++++++--- .../whenWithMultipleConditionTypes.kt | 1 + .../whenWithMultipleConditionTypes.kt.after | 1 + .../whenWithSwappedEqualityTests.kt | 8 ++++++++ .../whenWithSwappedEqualityTests.kt.after | 8 ++++++++ .../CodeTransformationsTestGenerated.java | 5 +++++ 6 files changed, 36 insertions(+), 3 deletions(-) create mode 100644 idea/testData/codeInsight/codeTransformations/branched/when/introduceSubject/whenWithSwappedEqualityTests.kt create mode 100644 idea/testData/codeInsight/codeTransformations/branched/when/introduceSubject/whenWithSwappedEqualityTests.kt.after 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 cc79bb83b4a..53bea0419bc 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 @@ -28,9 +28,14 @@ public class WhenUtils { if (condition instanceof JetBinaryExpression) { JetBinaryExpression binaryExpression = (JetBinaryExpression) condition; + JetExpression lhs = binaryExpression.getLeft(); + IElementType op = binaryExpression.getOperationToken(); - if (op == JetTokens.EQEQ || op == JetTokens.IN_KEYWORD || op == JetTokens.NOT_IN) { - return ((JetBinaryExpression) condition).getLeft(); + if (op == JetTokens.IN_KEYWORD || op == JetTokens.NOT_IN) { + return lhs; + } + if (op == JetTokens.EQEQ) { + return lhs instanceof JetSimpleNameExpression ? lhs : binaryExpression.getRight(); } } @@ -144,6 +149,7 @@ public class WhenUtils { else if (conditionExpression instanceof JetBinaryExpression) { JetBinaryExpression binaryExpression = (JetBinaryExpression) conditionExpression; + JetExpression lhs = binaryExpression.getLeft(); JetExpression rhs = binaryExpression.getRight(); IElementType op = binaryExpression.getOperationToken(); @@ -154,7 +160,11 @@ public class WhenUtils { builder.range(rhs, true); } else if (op == JetTokens.EQEQ) { - builder.condition(rhs); + if (JetPsiMatcher.checkElementMatch(subject, lhs)) { + builder.condition(rhs); + } else { + builder.condition(lhs); + } } else assert false : TRANSFORM_WITHOUT_CHECK; } diff --git a/idea/testData/codeInsight/codeTransformations/branched/when/introduceSubject/whenWithMultipleConditionTypes.kt b/idea/testData/codeInsight/codeTransformations/branched/when/introduceSubject/whenWithMultipleConditionTypes.kt index 6babe750cc6..82d48bf0783 100644 --- a/idea/testData/codeInsight/codeTransformations/branched/when/introduceSubject/whenWithMultipleConditionTypes.kt +++ b/idea/testData/codeInsight/codeTransformations/branched/when/introduceSubject/whenWithMultipleConditionTypes.kt @@ -5,6 +5,7 @@ fun test(n: Int): String { n in 10..100 -> "average" n in 100..1000 -> "big" n == 1000000 -> "million" + 2000000 == n -> "two millions" n !in -100..-10 -> "good" n is Int -> "unknown" else -> "unknown" diff --git a/idea/testData/codeInsight/codeTransformations/branched/when/introduceSubject/whenWithMultipleConditionTypes.kt.after b/idea/testData/codeInsight/codeTransformations/branched/when/introduceSubject/whenWithMultipleConditionTypes.kt.after index ea4d863fb5d..234c61995c4 100644 --- a/idea/testData/codeInsight/codeTransformations/branched/when/introduceSubject/whenWithMultipleConditionTypes.kt.after +++ b/idea/testData/codeInsight/codeTransformations/branched/when/introduceSubject/whenWithMultipleConditionTypes.kt.after @@ -5,6 +5,7 @@ fun test(n: Int): String { in 10..100 -> "average" in 100..1000 -> "big" 1000000 -> "million" + 2000000 -> "two millions" !in -100..-10 -> "good" is Int -> "unknown" else -> "unknown" diff --git a/idea/testData/codeInsight/codeTransformations/branched/when/introduceSubject/whenWithSwappedEqualityTests.kt b/idea/testData/codeInsight/codeTransformations/branched/when/introduceSubject/whenWithSwappedEqualityTests.kt new file mode 100644 index 00000000000..74a2f6a0f6e --- /dev/null +++ b/idea/testData/codeInsight/codeTransformations/branched/when/introduceSubject/whenWithSwappedEqualityTests.kt @@ -0,0 +1,8 @@ +fun test(n: Int): String { + return when { + n == 0 -> "zero" + 1 == n -> "one" + n == 2 -> "two" + else -> "unknown" + } +} \ No newline at end of file diff --git a/idea/testData/codeInsight/codeTransformations/branched/when/introduceSubject/whenWithSwappedEqualityTests.kt.after b/idea/testData/codeInsight/codeTransformations/branched/when/introduceSubject/whenWithSwappedEqualityTests.kt.after new file mode 100644 index 00000000000..dba5a8e64d6 --- /dev/null +++ b/idea/testData/codeInsight/codeTransformations/branched/when/introduceSubject/whenWithSwappedEqualityTests.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/tests/org/jetbrains/jet/plugin/codeInsight/codeTransformations/CodeTransformationsTestGenerated.java b/idea/tests/org/jetbrains/jet/plugin/codeInsight/codeTransformations/CodeTransformationsTestGenerated.java index e13ed3d5a4c..458a15e5641 100644 --- a/idea/tests/org/jetbrains/jet/plugin/codeInsight/codeTransformations/CodeTransformationsTestGenerated.java +++ b/idea/tests/org/jetbrains/jet/plugin/codeInsight/codeTransformations/CodeTransformationsTestGenerated.java @@ -585,6 +585,11 @@ public class CodeTransformationsTestGenerated extends AbstractCodeTransformation doTestIntroduceWhenSubject("idea/testData/codeInsight/codeTransformations/branched/when/introduceSubject/whenWithSubject.kt"); } + @TestMetadata("whenWithSwappedEqualityTests.kt") + public void testWhenWithSwappedEqualityTests() throws Exception { + doTestIntroduceWhenSubject("idea/testData/codeInsight/codeTransformations/branched/when/introduceSubject/whenWithSwappedEqualityTests.kt"); + } + @TestMetadata("whenWithUnmatchedCandidateSubjects.kt") public void testWhenWithUnmatchedCandidateSubjects() throws Exception { doTestIntroduceWhenSubject("idea/testData/codeInsight/codeTransformations/branched/when/introduceSubject/whenWithUnmatchedCandidateSubjects.kt"); From da2055862ef169dac7a18e4d0bcef9f43d0e35a9 Mon Sep 17 00:00:00 2001 From: Alexey Sedunov Date: Mon, 10 Jun 2013 14:34:42 +0400 Subject: [PATCH 125/291] Move common code transformation classes --- .../AbstractCodeTransformationIntention.java | 4 ++-- .../{branchedTransformations/core => }/Transformer.java | 2 +- .../branchedTransformations/FoldableKind.java | 2 +- .../branchedTransformations/UnfoldableKind.java | 2 +- .../intentions/EliminateWhenSubjectIntention.java | 4 ++-- .../intentions/FlattenWhenIntention.java | 4 ++-- .../intentions/FoldBranchedExpressionIntention.java | 2 +- .../branchedTransformations/intentions/IfToWhenIntention.java | 4 ++-- .../intentions/IntroduceWhenSubjectIntention.java | 4 ++-- .../intentions/UnfoldBranchedExpressionIntention.java | 1 + .../branchedTransformations/intentions/WhenToIfIntention.java | 4 ++-- 11 files changed, 17 insertions(+), 16 deletions(-) rename idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/{branchedTransformations => }/AbstractCodeTransformationIntention.java (97%) rename idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/{branchedTransformations/core => }/Transformer.java (96%) diff --git a/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/AbstractCodeTransformationIntention.java b/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/AbstractCodeTransformationIntention.java similarity index 97% rename from idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/AbstractCodeTransformationIntention.java rename to idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/AbstractCodeTransformationIntention.java index 4358b53dc57..d965e443028 100644 --- a/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/AbstractCodeTransformationIntention.java +++ b/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/AbstractCodeTransformationIntention.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.jetbrains.jet.plugin.codeInsight.codeTransformations.branchedTransformations; +package org.jetbrains.jet.plugin.codeInsight.codeTransformations; import com.google.common.base.Predicate; import com.intellij.codeInsight.intention.impl.BaseIntentionAction; @@ -29,7 +29,7 @@ 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; +import org.jetbrains.jet.plugin.codeInsight.codeTransformations.Transformer; public abstract class AbstractCodeTransformationIntention extends BaseIntentionAction { private final T transformer; diff --git a/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/core/Transformer.java b/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/Transformer.java similarity index 96% rename from idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/core/Transformer.java rename to idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/Transformer.java index 956ee756b1a..6fa2790ac05 100644 --- a/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/core/Transformer.java +++ b/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/Transformer.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.jetbrains.jet.plugin.codeInsight.codeTransformations.branchedTransformations.core; +package org.jetbrains.jet.plugin.codeInsight.codeTransformations; import com.intellij.openapi.editor.Editor; import com.intellij.psi.PsiElement; 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 4f1cfabb32a..4207d42ea51 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 @@ -22,7 +22,7 @@ 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; +import org.jetbrains.jet.plugin.codeInsight.codeTransformations.Transformer; public enum FoldableKind implements Transformer { IF_TO_ASSIGNMENT("fold.if.to.assignment") { 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 5a78db9b0d0..4cc9162e237 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 @@ -23,7 +23,7 @@ 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; +import org.jetbrains.jet.plugin.codeInsight.codeTransformations.Transformer; public enum UnfoldableKind implements Transformer { ASSIGNMENT_TO_IF("unfold.assignment.to.if") { 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 9c2dd1c00af..06113ada000 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 @@ -7,9 +7,9 @@ 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.AbstractCodeTransformationIntention; import org.jetbrains.jet.plugin.codeInsight.codeTransformations.branchedTransformations.WhenUtils; -import org.jetbrains.jet.plugin.codeInsight.codeTransformations.branchedTransformations.core.Transformer; +import org.jetbrains.jet.plugin.codeInsight.codeTransformations.Transformer; public class EliminateWhenSubjectIntention extends AbstractCodeTransformationIntention { private static final Transformer TRANSFORMER = new Transformer() { 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 bd2a4ac55e7..f687d649bfd 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 @@ -7,9 +7,9 @@ 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.AbstractCodeTransformationIntention; import org.jetbrains.jet.plugin.codeInsight.codeTransformations.branchedTransformations.WhenUtils; -import org.jetbrains.jet.plugin.codeInsight.codeTransformations.branchedTransformations.core.Transformer; +import org.jetbrains.jet.plugin.codeInsight.codeTransformations.Transformer; public class FlattenWhenIntention extends AbstractCodeTransformationIntention { private static final Transformer TRANSFORMER = new Transformer() { 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 1c07527fe46..c0328548790 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 @@ -21,7 +21,7 @@ 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.AbstractCodeTransformationIntention; import org.jetbrains.jet.plugin.codeInsight.codeTransformations.branchedTransformations.BranchedFoldingUtils; import org.jetbrains.jet.plugin.codeInsight.codeTransformations.branchedTransformations.FoldableKind; 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 index cdeb04ef445..df3b9cb712f 100644 --- 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 @@ -7,9 +7,9 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.jet.lang.psi.JetFile; import org.jetbrains.jet.lang.psi.JetIfExpression; -import org.jetbrains.jet.plugin.codeInsight.codeTransformations.branchedTransformations.AbstractCodeTransformationIntention; +import org.jetbrains.jet.plugin.codeInsight.codeTransformations.AbstractCodeTransformationIntention; import org.jetbrains.jet.plugin.codeInsight.codeTransformations.branchedTransformations.IfWhenUtils; -import org.jetbrains.jet.plugin.codeInsight.codeTransformations.branchedTransformations.core.Transformer; +import org.jetbrains.jet.plugin.codeInsight.codeTransformations.Transformer; public class IfToWhenIntention extends AbstractCodeTransformationIntention { private static final Transformer TRANSFORMER = new Transformer() { 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 index f43c023dfb9..8ddadc2364e 100644 --- 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 @@ -7,9 +7,9 @@ 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.AbstractCodeTransformationIntention; import org.jetbrains.jet.plugin.codeInsight.codeTransformations.branchedTransformations.WhenUtils; -import org.jetbrains.jet.plugin.codeInsight.codeTransformations.branchedTransformations.core.Transformer; +import org.jetbrains.jet.plugin.codeInsight.codeTransformations.Transformer; public class IntroduceWhenSubjectIntention extends AbstractCodeTransformationIntention { private static final Transformer TRANSFORMER = new Transformer() { 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 dae76bfdaf4..45caf8e5583 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 @@ -22,6 +22,7 @@ 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.*; +import org.jetbrains.jet.plugin.codeInsight.codeTransformations.AbstractCodeTransformationIntention; public abstract class UnfoldBranchedExpressionIntention extends AbstractCodeTransformationIntention { protected UnfoldBranchedExpressionIntention(@NotNull final UnfoldableKind unfoldableKind) { 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 index b16bb8a3114..c503d03f031 100644 --- 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 @@ -23,9 +23,9 @@ 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.AbstractCodeTransformationIntention; import org.jetbrains.jet.plugin.codeInsight.codeTransformations.branchedTransformations.IfWhenUtils; -import org.jetbrains.jet.plugin.codeInsight.codeTransformations.branchedTransformations.core.Transformer; +import org.jetbrains.jet.plugin.codeInsight.codeTransformations.Transformer; public class WhenToIfIntention extends AbstractCodeTransformationIntention { private static final Transformer TRANSFORMER = new Transformer() { From 42910395fc7463e461e395b5177ff98f6786bf49 Mon Sep 17 00:00:00 2001 From: Alexey Sedunov Date: Mon, 10 Jun 2013 18:08:02 +0400 Subject: [PATCH 126/291] Remove unused utility methods --- .../org/jetbrains/jet/lang/psi/JetPsiUtil.java | 16 +++------------- 1 file changed, 3 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 829fc43661d..218b48bec3e 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetPsiUtil.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetPsiUtil.java @@ -653,8 +653,9 @@ public class JetPsiUtil { JetTokens.ALL_ASSIGNMENTS.contains(((JetBinaryExpression) element).getOperationToken()); } - public static boolean isBranchedExpression(@Nullable PsiElement element) { - return element instanceof JetIfExpression || element instanceof JetWhenExpression; + public static boolean isOrdinaryAssignment(@NotNull PsiElement element) { + return element instanceof JetBinaryExpression && + ((JetBinaryExpression) element).getOperationToken().equals(JetTokens.EQ); } @Nullable @@ -705,17 +706,6 @@ 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) { - collection.add((JetVariableDeclaration) element); - } - } - - return collection; - } - public static boolean checkWhenExpressionHasSingleElse(@NotNull JetWhenExpression whenExpression) { int elseCount = 0; for (JetWhenEntry entry : whenExpression.getEntries()) { From 3ab393e460f8df537b3cdd61cdd00e49e4ac73a5 Mon Sep 17 00:00:00 2001 From: Alexey Sedunov Date: Mon, 10 Jun 2013 17:56:58 +0400 Subject: [PATCH 127/291] Implement split/join property declaration --- .../jetbrains/jet/lang/psi/JetPsiUtil.java | 20 ++ .../jet/generators/tests/GenerateTests.java | 4 +- .../after.kt.template | 2 + .../before.kt.template | 1 + .../description.html | 5 + idea/src/META-INF/plugin.xml | 7 + .../jetbrains/jet/plugin/JetBundle.properties | 2 + .../declarations/DeclarationUtils.java | 171 ++++++++++++++++++ .../JetDeclarationJoinLinesHandler.java | 34 ++++ .../SplitPropertyDeclarationIntention.java | 53 ++++++ .../declarations/join/longInit.kt | 7 + .../declarations/join/longInit.kt.after | 6 + .../declarations/join/longInit2.kt | 7 + .../declarations/join/longInit2.kt.after | 6 + .../declarations/join/simpleInit.kt | 4 + .../declarations/join/simpleInit.kt.after | 3 + .../declarations/join/simpleInit2.kt | 4 + .../declarations/join/simpleInit2.kt.after | 3 + .../join/simpleInitWithBackticks.kt | 4 + .../join/simpleInitWithBackticks.kt.after | 3 + .../join/simpleInitWithBackticks2.kt | 4 + .../join/simpleInitWithBackticks2.kt.after | 3 + .../join/simpleInitWithBackticks3.kt | 4 + .../join/simpleInitWithBackticks3.kt.after | 3 + .../join/simpleInitWithComments.kt | 6 + .../join/simpleInitWithComments.kt.after | 5 + .../join/simpleInitWithComments2.kt | 6 + .../join/simpleInitWithComments2.kt.after | 5 + .../join/simpleInitWithSemicolons.kt | 4 + .../join/simpleInitWithSemicolons.kt.after | 3 + .../join/simpleInitWithSemicolons2.kt | 4 + .../join/simpleInitWithSemicolons2.kt.after | 3 + .../join/simpleInitWithSemicolons3.kt | 5 + .../join/simpleInitWithSemicolons3.kt.after | 3 + .../declarations/join/simpleInitWithType.kt | 4 + .../join/simpleInitWithType.kt.after | 3 + .../declarations/join/simpleInitWithType2.kt | 4 + .../join/simpleInitWithType2.kt.after | 3 + .../declarations/split/longInit.kt | 7 + .../declarations/split/longInit.kt.after | 7 + .../declarations/split/longInit2.kt | 7 + .../declarations/split/longInit2.kt.after | 7 + .../declarations/split/noInitializer.kt | 5 + .../declarations/split/noInitializer2.kt | 5 + .../declarations/split/nonLocalProperty.kt | 2 + .../declarations/split/nonLocalProperty2.kt | 2 + .../declarations/split/simpleInit.kt | 3 + .../declarations/split/simpleInit.kt.after | 4 + .../declarations/split/simpleInit2.kt | 3 + .../declarations/split/simpleInit2.kt.after | 4 + .../split/simpleInitWithErrorType.kt | 3 + .../split/simpleInitWithErrorType.kt.after | 4 + .../split/simpleInitWithErrorType2.kt | 3 + .../split/simpleInitWithErrorType2.kt.after | 4 + .../declarations/split/simpleInitWithType.kt | 3 + .../split/simpleInitWithType.kt.after | 4 + .../declarations/split/simpleInitWithType2.kt | 3 + .../split/simpleInitWithType2.kt.after | 4 + .../AbstractCodeTransformationTest.java | 55 +++--- .../CodeTransformationsTestGenerated.java | 150 ++++++++++++++- 60 files changed, 684 insertions(+), 23 deletions(-) create mode 100644 idea/resources/intentionDescriptions/SplitPropertyDeclarationIntention/after.kt.template create mode 100644 idea/resources/intentionDescriptions/SplitPropertyDeclarationIntention/before.kt.template create mode 100644 idea/resources/intentionDescriptions/SplitPropertyDeclarationIntention/description.html create mode 100644 idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/declarations/DeclarationUtils.java create mode 100644 idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/declarations/JetDeclarationJoinLinesHandler.java create mode 100644 idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/declarations/SplitPropertyDeclarationIntention.java create mode 100644 idea/testData/codeInsight/codeTransformations/declarations/join/longInit.kt create mode 100644 idea/testData/codeInsight/codeTransformations/declarations/join/longInit.kt.after create mode 100644 idea/testData/codeInsight/codeTransformations/declarations/join/longInit2.kt create mode 100644 idea/testData/codeInsight/codeTransformations/declarations/join/longInit2.kt.after create mode 100644 idea/testData/codeInsight/codeTransformations/declarations/join/simpleInit.kt create mode 100644 idea/testData/codeInsight/codeTransformations/declarations/join/simpleInit.kt.after create mode 100644 idea/testData/codeInsight/codeTransformations/declarations/join/simpleInit2.kt create mode 100644 idea/testData/codeInsight/codeTransformations/declarations/join/simpleInit2.kt.after create mode 100644 idea/testData/codeInsight/codeTransformations/declarations/join/simpleInitWithBackticks.kt create mode 100644 idea/testData/codeInsight/codeTransformations/declarations/join/simpleInitWithBackticks.kt.after create mode 100644 idea/testData/codeInsight/codeTransformations/declarations/join/simpleInitWithBackticks2.kt create mode 100644 idea/testData/codeInsight/codeTransformations/declarations/join/simpleInitWithBackticks2.kt.after create mode 100644 idea/testData/codeInsight/codeTransformations/declarations/join/simpleInitWithBackticks3.kt create mode 100644 idea/testData/codeInsight/codeTransformations/declarations/join/simpleInitWithBackticks3.kt.after create mode 100644 idea/testData/codeInsight/codeTransformations/declarations/join/simpleInitWithComments.kt create mode 100644 idea/testData/codeInsight/codeTransformations/declarations/join/simpleInitWithComments.kt.after create mode 100644 idea/testData/codeInsight/codeTransformations/declarations/join/simpleInitWithComments2.kt create mode 100644 idea/testData/codeInsight/codeTransformations/declarations/join/simpleInitWithComments2.kt.after create mode 100644 idea/testData/codeInsight/codeTransformations/declarations/join/simpleInitWithSemicolons.kt create mode 100644 idea/testData/codeInsight/codeTransformations/declarations/join/simpleInitWithSemicolons.kt.after create mode 100644 idea/testData/codeInsight/codeTransformations/declarations/join/simpleInitWithSemicolons2.kt create mode 100644 idea/testData/codeInsight/codeTransformations/declarations/join/simpleInitWithSemicolons2.kt.after create mode 100644 idea/testData/codeInsight/codeTransformations/declarations/join/simpleInitWithSemicolons3.kt create mode 100644 idea/testData/codeInsight/codeTransformations/declarations/join/simpleInitWithSemicolons3.kt.after create mode 100644 idea/testData/codeInsight/codeTransformations/declarations/join/simpleInitWithType.kt create mode 100644 idea/testData/codeInsight/codeTransformations/declarations/join/simpleInitWithType.kt.after create mode 100644 idea/testData/codeInsight/codeTransformations/declarations/join/simpleInitWithType2.kt create mode 100644 idea/testData/codeInsight/codeTransformations/declarations/join/simpleInitWithType2.kt.after create mode 100644 idea/testData/codeInsight/codeTransformations/declarations/split/longInit.kt create mode 100644 idea/testData/codeInsight/codeTransformations/declarations/split/longInit.kt.after create mode 100644 idea/testData/codeInsight/codeTransformations/declarations/split/longInit2.kt create mode 100644 idea/testData/codeInsight/codeTransformations/declarations/split/longInit2.kt.after create mode 100644 idea/testData/codeInsight/codeTransformations/declarations/split/noInitializer.kt create mode 100644 idea/testData/codeInsight/codeTransformations/declarations/split/noInitializer2.kt create mode 100644 idea/testData/codeInsight/codeTransformations/declarations/split/nonLocalProperty.kt create mode 100644 idea/testData/codeInsight/codeTransformations/declarations/split/nonLocalProperty2.kt create mode 100644 idea/testData/codeInsight/codeTransformations/declarations/split/simpleInit.kt create mode 100644 idea/testData/codeInsight/codeTransformations/declarations/split/simpleInit.kt.after create mode 100644 idea/testData/codeInsight/codeTransformations/declarations/split/simpleInit2.kt create mode 100644 idea/testData/codeInsight/codeTransformations/declarations/split/simpleInit2.kt.after create mode 100644 idea/testData/codeInsight/codeTransformations/declarations/split/simpleInitWithErrorType.kt create mode 100644 idea/testData/codeInsight/codeTransformations/declarations/split/simpleInitWithErrorType.kt.after create mode 100644 idea/testData/codeInsight/codeTransformations/declarations/split/simpleInitWithErrorType2.kt create mode 100644 idea/testData/codeInsight/codeTransformations/declarations/split/simpleInitWithErrorType2.kt.after create mode 100644 idea/testData/codeInsight/codeTransformations/declarations/split/simpleInitWithType.kt create mode 100644 idea/testData/codeInsight/codeTransformations/declarations/split/simpleInitWithType.kt.after create mode 100644 idea/testData/codeInsight/codeTransformations/declarations/split/simpleInitWithType2.kt create mode 100644 idea/testData/codeInsight/codeTransformations/declarations/split/simpleInitWithType2.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 218b48bec3e..d56b23b3cff 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetPsiUtil.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetPsiUtil.java @@ -830,4 +830,24 @@ public class JetPsiUtil { } return null; } + + @Nullable + public static PsiElement skipSiblingsBackwardByPredicate(@Nullable PsiElement element, Predicate elementsToSkip) { + if (element == null) return null; + for (PsiElement e = element.getPrevSibling(); e != null; e = e.getPrevSibling()) { + if (elementsToSkip.apply(e)) continue; + return e; + } + return null; + } + + @Nullable + public static PsiElement skipSiblingsForwardByPredicate(@Nullable PsiElement element, Predicate elementsToSkip) { + if (element == null) return null; + for (PsiElement e = element.getNextSibling(); e != null; e = e.getNextSibling()) { + if (elementsToSkip.apply(e)) continue; + return e; + } + return null; + } } diff --git a/generators/org/jetbrains/jet/generators/tests/GenerateTests.java b/generators/org/jetbrains/jet/generators/tests/GenerateTests.java index 9e5468b3c6a..2986708dde8 100644 --- a/generators/org/jetbrains/jet/generators/tests/GenerateTests.java +++ b/generators/org/jetbrains/jet/generators/tests/GenerateTests.java @@ -345,7 +345,9 @@ public class GenerateTests { 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") + testModel("idea/testData/codeInsight/codeTransformations/branched/when/eliminateSubject", "doTestEliminateWhenSubject"), + testModel("idea/testData/codeInsight/codeTransformations/declarations/split", "doTestSplitProperty"), + testModel("idea/testData/codeInsight/codeTransformations/declarations/join", "doTestJoinProperty") ); generateTest( diff --git a/idea/resources/intentionDescriptions/SplitPropertyDeclarationIntention/after.kt.template b/idea/resources/intentionDescriptions/SplitPropertyDeclarationIntention/after.kt.template new file mode 100644 index 00000000000..a3df810f61a --- /dev/null +++ b/idea/resources/intentionDescriptions/SplitPropertyDeclarationIntention/after.kt.template @@ -0,0 +1,2 @@ +val n: Int +n = a + b \ No newline at end of file diff --git a/idea/resources/intentionDescriptions/SplitPropertyDeclarationIntention/before.kt.template b/idea/resources/intentionDescriptions/SplitPropertyDeclarationIntention/before.kt.template new file mode 100644 index 00000000000..c009c3df64f --- /dev/null +++ b/idea/resources/intentionDescriptions/SplitPropertyDeclarationIntention/before.kt.template @@ -0,0 +1 @@ +val n = a + b \ No newline at end of file diff --git a/idea/resources/intentionDescriptions/SplitPropertyDeclarationIntention/description.html b/idea/resources/intentionDescriptions/SplitPropertyDeclarationIntention/description.html new file mode 100644 index 00000000000..90f46cf38d9 --- /dev/null +++ b/idea/resources/intentionDescriptions/SplitPropertyDeclarationIntention/description.html @@ -0,0 +1,5 @@ + + +This intention splits property declaration with initializer and turns initializer to assignment. + + \ No newline at end of file diff --git a/idea/src/META-INF/plugin.xml b/idea/src/META-INF/plugin.xml index 02374c1d6e9..e9d773c8e00 100644 --- a/idea/src/META-INF/plugin.xml +++ b/idea/src/META-INF/plugin.xml @@ -291,6 +291,8 @@ implementation="org.jetbrains.jet.plugin.codeInsight.upDownMover.JetDeclarationMover" order="before jetExpression" /> + + org.jetbrains.jet.plugin.intentions.SpecifyTypeExplicitlyAction Kotlin @@ -386,6 +388,11 @@ Kotlin + + org.jetbrains.jet.plugin.codeInsight.codeTransformations.declarations.SplitPropertyDeclarationIntention + Kotlin + + diff --git a/idea/src/org/jetbrains/jet/plugin/JetBundle.properties b/idea/src/org/jetbrains/jet/plugin/JetBundle.properties index eb0de967683..d5268f23f8b 100644 --- a/idea/src/org/jetbrains/jet/plugin/JetBundle.properties +++ b/idea/src/org/jetbrains/jet/plugin/JetBundle.properties @@ -201,6 +201,8 @@ transform.if.statement.with.assignments.to.expression=Transform 'if' statement w 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 transform.assignment.with.if.expression.to.statement.family=Transform Assignment with 'if' Expression to Statement +split.property.declaration=Split property declaration +split.property.declaration.family=Split Property Declaration change.function.signature.action.single=Change function signature to ''{0}'' change.function.signature.action.multiple=Change function signature... change.function.signature.family=Change function signature diff --git a/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/declarations/DeclarationUtils.java b/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/declarations/DeclarationUtils.java new file mode 100644 index 00000000000..c802625201b --- /dev/null +++ b/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/declarations/DeclarationUtils.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.codeInsight.codeTransformations.declarations; + +import com.google.common.base.Predicate; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.Pair; +import com.intellij.psi.PsiComment; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiWhiteSpace; +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.ErrorUtils; +import org.jetbrains.jet.lang.types.JetType; +import org.jetbrains.jet.lexer.JetTokens; +import org.jetbrains.jet.plugin.codeInsight.ReferenceToClassesShortening; +import org.jetbrains.jet.plugin.project.AnalyzerFacadeWithCache; +import org.jetbrains.jet.plugin.util.JetPsiMatcher; +import org.jetbrains.jet.renderer.DescriptorRenderer; + +import java.util.Collections; + +public class DeclarationUtils { + private DeclarationUtils() { + } + + private static void assertNotNull(Object value) { + assert value != null : "Expression must be checked before applying transformation"; + } + + public static boolean checkSplitProperty(@NotNull JetProperty property) { + return property.getInitializer() != null && property.isLocal(); + } + + public static final Predicate SKIP_DELIMITERS = new Predicate() { + @Override + public boolean apply(@Nullable PsiElement input) { + return input == null + || input instanceof PsiWhiteSpace || input instanceof PsiComment + || input.getNode().getElementType() == JetTokens.SEMICOLON; + } + }; + + @Nullable + public static Pair checkAndGetPropertyAndInitializer(@NotNull PsiElement element) { + JetProperty property = null; + JetExpression initializer = null; + + if (element instanceof JetProperty) { + PsiElement nextElement = JetPsiUtil.skipSiblingsForwardByPredicate(element, SKIP_DELIMITERS); + if (nextElement instanceof JetExpression) { + property = (JetProperty) element; + initializer = (JetExpression) nextElement; + } + } + + if (property == null) return null; + if (property.getInitializer() != null) return null; + if (!JetPsiUtil.isOrdinaryAssignment(initializer)) return null; + + JetBinaryExpression assignment = (JetBinaryExpression) initializer; + + if (!(assignment.getLeft() instanceof JetSimpleNameExpression)) return null; + if (assignment.getRight() == null) return null; + //noinspection ConstantConditions + if (!JetPsiMatcher.checkIdentifierMatch(property.getNameIdentifier().getText(), assignment.getLeft().getText())) return null; + + return new Pair(property, assignment); + } + + @Nullable + private static JetType getPropertyTypeIfNeeded(@NotNull JetProperty property, @NotNull JetFile file) { + if (property.getTypeRef() != null) return null; + + JetType type = AnalyzerFacadeWithCache.analyzeFileWithCache(file).getBindingContext().get( + BindingContext.EXPRESSION_TYPE, + property.getInitializer() + ); + + return type == null || ErrorUtils.isErrorType(type) ? null : type; + } + + // returns assignment which replaces initializer + @NotNull + public static JetBinaryExpression splitPropertyDeclaration(@NotNull JetProperty property, @NotNull JetFile file) { + Project project = property.getProject(); + + PsiElement parent = property.getParent(); + assertNotNull(parent); + + //noinspection unchecked + JetExpression initializer = property.getInitializer(); + assertNotNull(initializer); + + //noinspection ConstantConditions, unchecked + JetBinaryExpression newInitializer = JetPsiFactory.createBinaryExpression( + project, JetPsiFactory.createSimpleName(project, property.getName()), "=", initializer + ); + + newInitializer = (JetBinaryExpression) 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()); + + //noinspection ConstantConditions + property = (JetProperty) property.replace( + JetPsiFactory.createProperty(project, property.getNameIdentifier().getText(), typeStr, property.isVar()) + ); + + if (inferredType != null) { + ReferenceToClassesShortening.compactReferenceToClasses(Collections.singletonList(property.getTypeRef())); + } + + return newInitializer; + } + + // Returns joined property + @NotNull + public static JetProperty joinPropertyDeclarationWithInitializer( + @NotNull Pair propertyAndInitializer + ) { + JetProperty property = propertyAndInitializer.first; + assertNotNull(property); + + JetBinaryExpression assignment = propertyAndInitializer.second; + assertNotNull(assignment); + + //noinspection ConstantConditions + JetProperty newProperty = JetPsiFactory.createProperty( + property.getProject(), + property.getNameIdentifier().getText(), + JetPsiUtil.getNullableText(property.getTypeRef()), + property.isVar(), + JetPsiUtil.getNullableText(assignment.getRight()) + ); + + property.getParent().deleteChildRange(property.getNextSibling(), assignment); + return (JetProperty) property.replace(newProperty); + } + + // Returns joined property + @NotNull + public static JetProperty joinPropertyDeclarationWithInitializer(@NotNull PsiElement element) { + Pair propertyAndInitializer = checkAndGetPropertyAndInitializer(element); + assertNotNull(propertyAndInitializer); + + //noinspection ConstantConditions + return joinPropertyDeclarationWithInitializer(propertyAndInitializer); + } +} diff --git a/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/declarations/JetDeclarationJoinLinesHandler.java b/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/declarations/JetDeclarationJoinLinesHandler.java new file mode 100644 index 00000000000..b5717a8d868 --- /dev/null +++ b/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/declarations/JetDeclarationJoinLinesHandler.java @@ -0,0 +1,34 @@ +package org.jetbrains.jet.plugin.codeInsight.codeTransformations.declarations; + +import com.google.common.base.Predicate; +import com.intellij.codeInsight.editorActions.JoinRawLinesHandlerDelegate; +import com.intellij.openapi.editor.Document; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiFile; +import org.jetbrains.annotations.Nullable; +import org.jetbrains.jet.lang.psi.JetElement; +import org.jetbrains.jet.lang.psi.JetPsiUtil; + +public class JetDeclarationJoinLinesHandler implements JoinRawLinesHandlerDelegate { + private static final Predicate IS_APPLICABLE = new Predicate() { + @Override + public boolean apply(@Nullable PsiElement input) { + return input != null && DeclarationUtils.checkAndGetPropertyAndInitializer(input) != null; + } + }; + + @Override + public int tryJoinRawLines(Document document, PsiFile file, int start, int end) { + PsiElement element = JetPsiUtil.skipSiblingsBackwardByPredicate(file.findElementAt(start), DeclarationUtils.SKIP_DELIMITERS); + + PsiElement target = JetPsiUtil.getParentByTypeAndPredicate(element, JetElement.class, IS_APPLICABLE, false); + if (target == null) return -1; + + return DeclarationUtils.joinPropertyDeclarationWithInitializer(target).getTextRange().getStartOffset(); + } + + @Override + public int tryJoinLines(Document document, PsiFile file, int start, int end) { + return -1; + } +} diff --git a/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/declarations/SplitPropertyDeclarationIntention.java b/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/declarations/SplitPropertyDeclarationIntention.java new file mode 100644 index 00000000000..8d72546f57b --- /dev/null +++ b/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/declarations/SplitPropertyDeclarationIntention.java @@ -0,0 +1,53 @@ +/* + * 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.declarations; + +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; +import org.jetbrains.jet.lang.psi.JetFile; +import org.jetbrains.jet.lang.psi.JetProperty; +import org.jetbrains.jet.plugin.codeInsight.codeTransformations.AbstractCodeTransformationIntention; +import org.jetbrains.jet.plugin.codeInsight.codeTransformations.Transformer; + +public class SplitPropertyDeclarationIntention extends AbstractCodeTransformationIntention { + private static final Transformer TRANSFORMER = new Transformer() { + @NotNull + @Override + public String getKey() { + return "split.property.declaration"; + } + + @Override + public void transform(@NotNull PsiElement element, @NotNull Editor editor, @NotNull JetFile file) { + DeclarationUtils.splitPropertyDeclaration((JetProperty) element, file); + } + }; + + private static final Predicate IS_APPLICABLE = new Predicate() { + @Override + public boolean apply(@Nullable PsiElement input) { + return (input instanceof JetProperty) && DeclarationUtils.checkSplitProperty((JetProperty) input); + } + }; + + public SplitPropertyDeclarationIntention() { + super(TRANSFORMER, IS_APPLICABLE); + } +} diff --git a/idea/testData/codeInsight/codeTransformations/declarations/join/longInit.kt b/idea/testData/codeInsight/codeTransformations/declarations/join/longInit.kt new file mode 100644 index 00000000000..e1e22d286ed --- /dev/null +++ b/idea/testData/codeInsight/codeTransformations/declarations/join/longInit.kt @@ -0,0 +1,7 @@ +fun foo(n: Int) { + val x: String + x = if (n > 0) + "> 0" + else + "<= 0" +} \ No newline at end of file diff --git a/idea/testData/codeInsight/codeTransformations/declarations/join/longInit.kt.after b/idea/testData/codeInsight/codeTransformations/declarations/join/longInit.kt.after new file mode 100644 index 00000000000..80667621272 --- /dev/null +++ b/idea/testData/codeInsight/codeTransformations/declarations/join/longInit.kt.after @@ -0,0 +1,6 @@ +fun foo(n: Int) { + val x: String = if (n > 0) + "> 0" + else + "<= 0" +} \ No newline at end of file diff --git a/idea/testData/codeInsight/codeTransformations/declarations/join/longInit2.kt b/idea/testData/codeInsight/codeTransformations/declarations/join/longInit2.kt new file mode 100644 index 00000000000..7b6faaa3e20 --- /dev/null +++ b/idea/testData/codeInsight/codeTransformations/declarations/join/longInit2.kt @@ -0,0 +1,7 @@ +fun foo(n: Int) { + val x: String + x = if (n > 0) + "> 0" + else + "<= 0" +} \ No newline at end of file diff --git a/idea/testData/codeInsight/codeTransformations/declarations/join/longInit2.kt.after b/idea/testData/codeInsight/codeTransformations/declarations/join/longInit2.kt.after new file mode 100644 index 00000000000..80667621272 --- /dev/null +++ b/idea/testData/codeInsight/codeTransformations/declarations/join/longInit2.kt.after @@ -0,0 +1,6 @@ +fun foo(n: Int) { + val x: String = if (n > 0) + "> 0" + else + "<= 0" +} \ No newline at end of file diff --git a/idea/testData/codeInsight/codeTransformations/declarations/join/simpleInit.kt b/idea/testData/codeInsight/codeTransformations/declarations/join/simpleInit.kt new file mode 100644 index 00000000000..46137147953 --- /dev/null +++ b/idea/testData/codeInsight/codeTransformations/declarations/join/simpleInit.kt @@ -0,0 +1,4 @@ +fun foo(n: Int) { + val x: String + x = "" +} \ No newline at end of file diff --git a/idea/testData/codeInsight/codeTransformations/declarations/join/simpleInit.kt.after b/idea/testData/codeInsight/codeTransformations/declarations/join/simpleInit.kt.after new file mode 100644 index 00000000000..ef7e1ba3bdb --- /dev/null +++ b/idea/testData/codeInsight/codeTransformations/declarations/join/simpleInit.kt.after @@ -0,0 +1,3 @@ +fun foo(n: Int) { + val x: String = "" +} \ No newline at end of file diff --git a/idea/testData/codeInsight/codeTransformations/declarations/join/simpleInit2.kt b/idea/testData/codeInsight/codeTransformations/declarations/join/simpleInit2.kt new file mode 100644 index 00000000000..1f6db4d3138 --- /dev/null +++ b/idea/testData/codeInsight/codeTransformations/declarations/join/simpleInit2.kt @@ -0,0 +1,4 @@ +fun foo(n: Int) { + val x: String + x = "" +} \ No newline at end of file diff --git a/idea/testData/codeInsight/codeTransformations/declarations/join/simpleInit2.kt.after b/idea/testData/codeInsight/codeTransformations/declarations/join/simpleInit2.kt.after new file mode 100644 index 00000000000..ef7e1ba3bdb --- /dev/null +++ b/idea/testData/codeInsight/codeTransformations/declarations/join/simpleInit2.kt.after @@ -0,0 +1,3 @@ +fun foo(n: Int) { + val x: String = "" +} \ No newline at end of file diff --git a/idea/testData/codeInsight/codeTransformations/declarations/join/simpleInitWithBackticks.kt b/idea/testData/codeInsight/codeTransformations/declarations/join/simpleInitWithBackticks.kt new file mode 100644 index 00000000000..022012639ee --- /dev/null +++ b/idea/testData/codeInsight/codeTransformations/declarations/join/simpleInitWithBackticks.kt @@ -0,0 +1,4 @@ +fun foo(n: Int) { + val x: String + `x` = "" +} \ No newline at end of file diff --git a/idea/testData/codeInsight/codeTransformations/declarations/join/simpleInitWithBackticks.kt.after b/idea/testData/codeInsight/codeTransformations/declarations/join/simpleInitWithBackticks.kt.after new file mode 100644 index 00000000000..ef7e1ba3bdb --- /dev/null +++ b/idea/testData/codeInsight/codeTransformations/declarations/join/simpleInitWithBackticks.kt.after @@ -0,0 +1,3 @@ +fun foo(n: Int) { + val x: String = "" +} \ No newline at end of file diff --git a/idea/testData/codeInsight/codeTransformations/declarations/join/simpleInitWithBackticks2.kt b/idea/testData/codeInsight/codeTransformations/declarations/join/simpleInitWithBackticks2.kt new file mode 100644 index 00000000000..a2f3816a230 --- /dev/null +++ b/idea/testData/codeInsight/codeTransformations/declarations/join/simpleInitWithBackticks2.kt @@ -0,0 +1,4 @@ +fun foo(n: Int) { + val `x`: String + `x` = "" +} \ No newline at end of file diff --git a/idea/testData/codeInsight/codeTransformations/declarations/join/simpleInitWithBackticks2.kt.after b/idea/testData/codeInsight/codeTransformations/declarations/join/simpleInitWithBackticks2.kt.after new file mode 100644 index 00000000000..fbcef7338d0 --- /dev/null +++ b/idea/testData/codeInsight/codeTransformations/declarations/join/simpleInitWithBackticks2.kt.after @@ -0,0 +1,3 @@ +fun foo(n: Int) { + val `x`: String = "" +} \ No newline at end of file diff --git a/idea/testData/codeInsight/codeTransformations/declarations/join/simpleInitWithBackticks3.kt b/idea/testData/codeInsight/codeTransformations/declarations/join/simpleInitWithBackticks3.kt new file mode 100644 index 00000000000..6a6659f3fcb --- /dev/null +++ b/idea/testData/codeInsight/codeTransformations/declarations/join/simpleInitWithBackticks3.kt @@ -0,0 +1,4 @@ +fun foo(n: Int) { + val `x`: String + x = "" +} \ No newline at end of file diff --git a/idea/testData/codeInsight/codeTransformations/declarations/join/simpleInitWithBackticks3.kt.after b/idea/testData/codeInsight/codeTransformations/declarations/join/simpleInitWithBackticks3.kt.after new file mode 100644 index 00000000000..fbcef7338d0 --- /dev/null +++ b/idea/testData/codeInsight/codeTransformations/declarations/join/simpleInitWithBackticks3.kt.after @@ -0,0 +1,3 @@ +fun foo(n: Int) { + val `x`: String = "" +} \ No newline at end of file diff --git a/idea/testData/codeInsight/codeTransformations/declarations/join/simpleInitWithComments.kt b/idea/testData/codeInsight/codeTransformations/declarations/join/simpleInitWithComments.kt new file mode 100644 index 00000000000..b49c9a9ebc0 --- /dev/null +++ b/idea/testData/codeInsight/codeTransformations/declarations/join/simpleInitWithComments.kt @@ -0,0 +1,6 @@ +fun foo(n: Int) { + // foo3 + val /* foo */ x: String // foo2 + x = /* bar2 */ "" // bar3 + /* baz */ +} \ No newline at end of file diff --git a/idea/testData/codeInsight/codeTransformations/declarations/join/simpleInitWithComments.kt.after b/idea/testData/codeInsight/codeTransformations/declarations/join/simpleInitWithComments.kt.after new file mode 100644 index 00000000000..5548a74c627 --- /dev/null +++ b/idea/testData/codeInsight/codeTransformations/declarations/join/simpleInitWithComments.kt.after @@ -0,0 +1,5 @@ +fun foo(n: Int) { + // foo3 + val x: String = "" // bar3 + /* baz */ +} \ No newline at end of file diff --git a/idea/testData/codeInsight/codeTransformations/declarations/join/simpleInitWithComments2.kt b/idea/testData/codeInsight/codeTransformations/declarations/join/simpleInitWithComments2.kt new file mode 100644 index 00000000000..ba90e151465 --- /dev/null +++ b/idea/testData/codeInsight/codeTransformations/declarations/join/simpleInitWithComments2.kt @@ -0,0 +1,6 @@ +fun foo(n: Int) { + // foo3 + val /* foo */ x: String // foo2 + x = /* bar2 */ "" // bar3 + /* baz */ +} \ No newline at end of file diff --git a/idea/testData/codeInsight/codeTransformations/declarations/join/simpleInitWithComments2.kt.after b/idea/testData/codeInsight/codeTransformations/declarations/join/simpleInitWithComments2.kt.after new file mode 100644 index 00000000000..5548a74c627 --- /dev/null +++ b/idea/testData/codeInsight/codeTransformations/declarations/join/simpleInitWithComments2.kt.after @@ -0,0 +1,5 @@ +fun foo(n: Int) { + // foo3 + val x: String = "" // bar3 + /* baz */ +} \ No newline at end of file diff --git a/idea/testData/codeInsight/codeTransformations/declarations/join/simpleInitWithSemicolons.kt b/idea/testData/codeInsight/codeTransformations/declarations/join/simpleInitWithSemicolons.kt new file mode 100644 index 00000000000..5246f1e36f2 --- /dev/null +++ b/idea/testData/codeInsight/codeTransformations/declarations/join/simpleInitWithSemicolons.kt @@ -0,0 +1,4 @@ +fun foo(n: Int) { + val x: String; ; + x = "" +} \ No newline at end of file diff --git a/idea/testData/codeInsight/codeTransformations/declarations/join/simpleInitWithSemicolons.kt.after b/idea/testData/codeInsight/codeTransformations/declarations/join/simpleInitWithSemicolons.kt.after new file mode 100644 index 00000000000..ef7e1ba3bdb --- /dev/null +++ b/idea/testData/codeInsight/codeTransformations/declarations/join/simpleInitWithSemicolons.kt.after @@ -0,0 +1,3 @@ +fun foo(n: Int) { + val x: String = "" +} \ No newline at end of file diff --git a/idea/testData/codeInsight/codeTransformations/declarations/join/simpleInitWithSemicolons2.kt b/idea/testData/codeInsight/codeTransformations/declarations/join/simpleInitWithSemicolons2.kt new file mode 100644 index 00000000000..99b66a867d8 --- /dev/null +++ b/idea/testData/codeInsight/codeTransformations/declarations/join/simpleInitWithSemicolons2.kt @@ -0,0 +1,4 @@ +fun foo(n: Int) { + val x: String; ; + x = "" +} \ No newline at end of file diff --git a/idea/testData/codeInsight/codeTransformations/declarations/join/simpleInitWithSemicolons2.kt.after b/idea/testData/codeInsight/codeTransformations/declarations/join/simpleInitWithSemicolons2.kt.after new file mode 100644 index 00000000000..ef7e1ba3bdb --- /dev/null +++ b/idea/testData/codeInsight/codeTransformations/declarations/join/simpleInitWithSemicolons2.kt.after @@ -0,0 +1,3 @@ +fun foo(n: Int) { + val x: String = "" +} \ No newline at end of file diff --git a/idea/testData/codeInsight/codeTransformations/declarations/join/simpleInitWithSemicolons3.kt b/idea/testData/codeInsight/codeTransformations/declarations/join/simpleInitWithSemicolons3.kt new file mode 100644 index 00000000000..45887333aaf --- /dev/null +++ b/idea/testData/codeInsight/codeTransformations/declarations/join/simpleInitWithSemicolons3.kt @@ -0,0 +1,5 @@ +fun foo(n: Int) { + val x: String; + ; + x = "" +} \ No newline at end of file diff --git a/idea/testData/codeInsight/codeTransformations/declarations/join/simpleInitWithSemicolons3.kt.after b/idea/testData/codeInsight/codeTransformations/declarations/join/simpleInitWithSemicolons3.kt.after new file mode 100644 index 00000000000..ef7e1ba3bdb --- /dev/null +++ b/idea/testData/codeInsight/codeTransformations/declarations/join/simpleInitWithSemicolons3.kt.after @@ -0,0 +1,3 @@ +fun foo(n: Int) { + val x: String = "" +} \ No newline at end of file diff --git a/idea/testData/codeInsight/codeTransformations/declarations/join/simpleInitWithType.kt b/idea/testData/codeInsight/codeTransformations/declarations/join/simpleInitWithType.kt new file mode 100644 index 00000000000..cff228fae7c --- /dev/null +++ b/idea/testData/codeInsight/codeTransformations/declarations/join/simpleInitWithType.kt @@ -0,0 +1,4 @@ +fun foo(n: Int) { + val x: jet.String? + x = "" +} \ No newline at end of file diff --git a/idea/testData/codeInsight/codeTransformations/declarations/join/simpleInitWithType.kt.after b/idea/testData/codeInsight/codeTransformations/declarations/join/simpleInitWithType.kt.after new file mode 100644 index 00000000000..bf7e5c44409 --- /dev/null +++ b/idea/testData/codeInsight/codeTransformations/declarations/join/simpleInitWithType.kt.after @@ -0,0 +1,3 @@ +fun foo(n: Int) { + val x: jet.String? = "" +} \ No newline at end of file diff --git a/idea/testData/codeInsight/codeTransformations/declarations/join/simpleInitWithType2.kt b/idea/testData/codeInsight/codeTransformations/declarations/join/simpleInitWithType2.kt new file mode 100644 index 00000000000..350bb1b3954 --- /dev/null +++ b/idea/testData/codeInsight/codeTransformations/declarations/join/simpleInitWithType2.kt @@ -0,0 +1,4 @@ +fun foo(n: Int) { + val x: jet.String? + x = "" +} \ No newline at end of file diff --git a/idea/testData/codeInsight/codeTransformations/declarations/join/simpleInitWithType2.kt.after b/idea/testData/codeInsight/codeTransformations/declarations/join/simpleInitWithType2.kt.after new file mode 100644 index 00000000000..bf7e5c44409 --- /dev/null +++ b/idea/testData/codeInsight/codeTransformations/declarations/join/simpleInitWithType2.kt.after @@ -0,0 +1,3 @@ +fun foo(n: Int) { + val x: jet.String? = "" +} \ No newline at end of file diff --git a/idea/testData/codeInsight/codeTransformations/declarations/split/longInit.kt b/idea/testData/codeInsight/codeTransformations/declarations/split/longInit.kt new file mode 100644 index 00000000000..fc700c8174b --- /dev/null +++ b/idea/testData/codeInsight/codeTransformations/declarations/split/longInit.kt @@ -0,0 +1,7 @@ +fun foo(n: Int) { + val x = + if (n > 0) + "> 0" + else + "<= 0" +} \ No newline at end of file diff --git a/idea/testData/codeInsight/codeTransformations/declarations/split/longInit.kt.after b/idea/testData/codeInsight/codeTransformations/declarations/split/longInit.kt.after new file mode 100644 index 00000000000..e1e22d286ed --- /dev/null +++ b/idea/testData/codeInsight/codeTransformations/declarations/split/longInit.kt.after @@ -0,0 +1,7 @@ +fun foo(n: Int) { + val x: String + x = if (n > 0) + "> 0" + else + "<= 0" +} \ No newline at end of file diff --git a/idea/testData/codeInsight/codeTransformations/declarations/split/longInit2.kt b/idea/testData/codeInsight/codeTransformations/declarations/split/longInit2.kt new file mode 100644 index 00000000000..263b64b5172 --- /dev/null +++ b/idea/testData/codeInsight/codeTransformations/declarations/split/longInit2.kt @@ -0,0 +1,7 @@ +fun foo(n: Int) { + var x = + if (n > 0) + "> 0" + else + "<= 0" +} \ No newline at end of file diff --git a/idea/testData/codeInsight/codeTransformations/declarations/split/longInit2.kt.after b/idea/testData/codeInsight/codeTransformations/declarations/split/longInit2.kt.after new file mode 100644 index 00000000000..635703d3a2e --- /dev/null +++ b/idea/testData/codeInsight/codeTransformations/declarations/split/longInit2.kt.after @@ -0,0 +1,7 @@ +fun foo(n: Int) { + var x: String + x = if (n > 0) + "> 0" + else + "<= 0" +} \ No newline at end of file diff --git a/idea/testData/codeInsight/codeTransformations/declarations/split/noInitializer.kt b/idea/testData/codeInsight/codeTransformations/declarations/split/noInitializer.kt new file mode 100644 index 00000000000..fc532bafe49 --- /dev/null +++ b/idea/testData/codeInsight/codeTransformations/declarations/split/noInitializer.kt @@ -0,0 +1,5 @@ +// IS_APPLICABLE: false +fun foo(n: Int) { + val x: String + x = "" +} \ No newline at end of file diff --git a/idea/testData/codeInsight/codeTransformations/declarations/split/noInitializer2.kt b/idea/testData/codeInsight/codeTransformations/declarations/split/noInitializer2.kt new file mode 100644 index 00000000000..e76f2b43397 --- /dev/null +++ b/idea/testData/codeInsight/codeTransformations/declarations/split/noInitializer2.kt @@ -0,0 +1,5 @@ +// IS_APPLICABLE: false +fun foo(n: Int) { + var x: String + x = "" +} \ No newline at end of file diff --git a/idea/testData/codeInsight/codeTransformations/declarations/split/nonLocalProperty.kt b/idea/testData/codeInsight/codeTransformations/declarations/split/nonLocalProperty.kt new file mode 100644 index 00000000000..b35d6d646b5 --- /dev/null +++ b/idea/testData/codeInsight/codeTransformations/declarations/split/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/declarations/split/nonLocalProperty2.kt b/idea/testData/codeInsight/codeTransformations/declarations/split/nonLocalProperty2.kt new file mode 100644 index 00000000000..b737d711db2 --- /dev/null +++ b/idea/testData/codeInsight/codeTransformations/declarations/split/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/declarations/split/simpleInit.kt b/idea/testData/codeInsight/codeTransformations/declarations/split/simpleInit.kt new file mode 100644 index 00000000000..2febbf214c0 --- /dev/null +++ b/idea/testData/codeInsight/codeTransformations/declarations/split/simpleInit.kt @@ -0,0 +1,3 @@ +fun foo(n: Int) { + val x = "" +} \ No newline at end of file diff --git a/idea/testData/codeInsight/codeTransformations/declarations/split/simpleInit.kt.after b/idea/testData/codeInsight/codeTransformations/declarations/split/simpleInit.kt.after new file mode 100644 index 00000000000..46137147953 --- /dev/null +++ b/idea/testData/codeInsight/codeTransformations/declarations/split/simpleInit.kt.after @@ -0,0 +1,4 @@ +fun foo(n: Int) { + val x: String + x = "" +} \ No newline at end of file diff --git a/idea/testData/codeInsight/codeTransformations/declarations/split/simpleInit2.kt b/idea/testData/codeInsight/codeTransformations/declarations/split/simpleInit2.kt new file mode 100644 index 00000000000..05d7e765d9b --- /dev/null +++ b/idea/testData/codeInsight/codeTransformations/declarations/split/simpleInit2.kt @@ -0,0 +1,3 @@ +fun foo(n: Int) { + var x = "" +} \ No newline at end of file diff --git a/idea/testData/codeInsight/codeTransformations/declarations/split/simpleInit2.kt.after b/idea/testData/codeInsight/codeTransformations/declarations/split/simpleInit2.kt.after new file mode 100644 index 00000000000..1d649485621 --- /dev/null +++ b/idea/testData/codeInsight/codeTransformations/declarations/split/simpleInit2.kt.after @@ -0,0 +1,4 @@ +fun foo(n: Int) { + var x: String + x = "" +} \ No newline at end of file diff --git a/idea/testData/codeInsight/codeTransformations/declarations/split/simpleInitWithErrorType.kt b/idea/testData/codeInsight/codeTransformations/declarations/split/simpleInitWithErrorType.kt new file mode 100644 index 00000000000..51bd3dcd82d --- /dev/null +++ b/idea/testData/codeInsight/codeTransformations/declarations/split/simpleInitWithErrorType.kt @@ -0,0 +1,3 @@ +fun foo(n: Int) { + var x = X<>() +} \ No newline at end of file diff --git a/idea/testData/codeInsight/codeTransformations/declarations/split/simpleInitWithErrorType.kt.after b/idea/testData/codeInsight/codeTransformations/declarations/split/simpleInitWithErrorType.kt.after new file mode 100644 index 00000000000..9dcfc7aecd4 --- /dev/null +++ b/idea/testData/codeInsight/codeTransformations/declarations/split/simpleInitWithErrorType.kt.after @@ -0,0 +1,4 @@ +fun foo(n: Int) { + var x + x = X<>() +} \ No newline at end of file diff --git a/idea/testData/codeInsight/codeTransformations/declarations/split/simpleInitWithErrorType2.kt b/idea/testData/codeInsight/codeTransformations/declarations/split/simpleInitWithErrorType2.kt new file mode 100644 index 00000000000..bb139cd5e98 --- /dev/null +++ b/idea/testData/codeInsight/codeTransformations/declarations/split/simpleInitWithErrorType2.kt @@ -0,0 +1,3 @@ +fun foo(n: Int) { + val x = X<>() +} \ No newline at end of file diff --git a/idea/testData/codeInsight/codeTransformations/declarations/split/simpleInitWithErrorType2.kt.after b/idea/testData/codeInsight/codeTransformations/declarations/split/simpleInitWithErrorType2.kt.after new file mode 100644 index 00000000000..d62ed3fdfe2 --- /dev/null +++ b/idea/testData/codeInsight/codeTransformations/declarations/split/simpleInitWithErrorType2.kt.after @@ -0,0 +1,4 @@ +fun foo(n: Int) { + val x + x = X<>() +} \ No newline at end of file diff --git a/idea/testData/codeInsight/codeTransformations/declarations/split/simpleInitWithType.kt b/idea/testData/codeInsight/codeTransformations/declarations/split/simpleInitWithType.kt new file mode 100644 index 00000000000..bf7e5c44409 --- /dev/null +++ b/idea/testData/codeInsight/codeTransformations/declarations/split/simpleInitWithType.kt @@ -0,0 +1,3 @@ +fun foo(n: Int) { + val x: jet.String? = "" +} \ No newline at end of file diff --git a/idea/testData/codeInsight/codeTransformations/declarations/split/simpleInitWithType.kt.after b/idea/testData/codeInsight/codeTransformations/declarations/split/simpleInitWithType.kt.after new file mode 100644 index 00000000000..cff228fae7c --- /dev/null +++ b/idea/testData/codeInsight/codeTransformations/declarations/split/simpleInitWithType.kt.after @@ -0,0 +1,4 @@ +fun foo(n: Int) { + val x: jet.String? + x = "" +} \ No newline at end of file diff --git a/idea/testData/codeInsight/codeTransformations/declarations/split/simpleInitWithType2.kt b/idea/testData/codeInsight/codeTransformations/declarations/split/simpleInitWithType2.kt new file mode 100644 index 00000000000..a22d8ea95da --- /dev/null +++ b/idea/testData/codeInsight/codeTransformations/declarations/split/simpleInitWithType2.kt @@ -0,0 +1,3 @@ +fun foo(n: Int) { + var x: jet.String? = "" +} \ No newline at end of file diff --git a/idea/testData/codeInsight/codeTransformations/declarations/split/simpleInitWithType2.kt.after b/idea/testData/codeInsight/codeTransformations/declarations/split/simpleInitWithType2.kt.after new file mode 100644 index 00000000000..9d063035f45 --- /dev/null +++ b/idea/testData/codeInsight/codeTransformations/declarations/split/simpleInitWithType2.kt.after @@ -0,0 +1,4 @@ +fun foo(n: Int) { + var x: jet.String? + x = "" +} \ 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 918cfc7349c..b5407f37d2b 100644 --- a/idea/tests/org/jetbrains/jet/plugin/codeInsight/codeTransformations/AbstractCodeTransformationTest.java +++ b/idea/tests/org/jetbrains/jet/plugin/codeInsight/codeTransformations/AbstractCodeTransformationTest.java @@ -16,85 +16,96 @@ package org.jetbrains.jet.plugin.codeInsight.codeTransformations; +import com.intellij.codeInsight.editorActions.JoinLinesHandler; import com.intellij.codeInsight.intention.IntentionAction; +import com.intellij.openapi.editor.actionSystem.EditorActionHandler; 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.intentions.*; +import org.jetbrains.jet.plugin.codeInsight.codeTransformations.declarations.SplitPropertyDeclarationIntention; import java.io.File; public abstract class AbstractCodeTransformationTest extends LightCodeInsightTestCase { public void doTestFoldIfToAssignment(@NotNull String path) throws Exception { - doTest(path, new FoldBranchedExpressionIntention.FoldIfToAssignmentIntention()); + doTestIntention(path, new FoldBranchedExpressionIntention.FoldIfToAssignmentIntention()); } public void doTestFoldIfToReturn(@NotNull String path) throws Exception { - doTest(path, new FoldBranchedExpressionIntention.FoldIfToReturnIntention()); + doTestIntention(path, new FoldBranchedExpressionIntention.FoldIfToReturnIntention()); } public void doTestFoldIfToReturnAsymmetrically(@NotNull String path) throws Exception { - doTest(path, new FoldBranchedExpressionIntention.FoldIfToReturnAsymmetricallyIntention()); + doTestIntention(path, new FoldBranchedExpressionIntention.FoldIfToReturnAsymmetricallyIntention()); } public void doTestFoldWhenToAssignment(@NotNull String path) throws Exception { - doTest(path, new FoldBranchedExpressionIntention.FoldWhenToAssignmentIntention()); + doTestIntention(path, new FoldBranchedExpressionIntention.FoldWhenToAssignmentIntention()); } public void doTestFoldWhenToReturn(@NotNull String path) throws Exception { - doTest(path, new FoldBranchedExpressionIntention.FoldWhenToReturnIntention()); + doTestIntention(path, new FoldBranchedExpressionIntention.FoldWhenToReturnIntention()); } public void doTestUnfoldAssignmentToIf(@NotNull String path) throws Exception { - doTest(path, new UnfoldBranchedExpressionIntention.UnfoldAssignmentToIfIntention()); + doTestIntention(path, new UnfoldBranchedExpressionIntention.UnfoldAssignmentToIfIntention()); } public void doTestUnfoldAssignmentToWhen(@NotNull String path) throws Exception { - doTest(path, new UnfoldBranchedExpressionIntention.UnfoldAssignmentToWhenIntention()); + doTestIntention(path, new UnfoldBranchedExpressionIntention.UnfoldAssignmentToWhenIntention()); } public void doTestUnfoldPropertyToIf(@NotNull String path) throws Exception { - doTest(path, new UnfoldBranchedExpressionIntention.UnfoldPropertyToIfIntention()); + doTestIntention(path, new UnfoldBranchedExpressionIntention.UnfoldPropertyToIfIntention()); } public void doTestUnfoldPropertyToWhen(@NotNull String path) throws Exception { - doTest(path, new UnfoldBranchedExpressionIntention.UnfoldPropertyToWhenIntention()); + doTestIntention(path, new UnfoldBranchedExpressionIntention.UnfoldPropertyToWhenIntention()); } public void doTestUnfoldReturnToIf(@NotNull String path) throws Exception { - doTest(path, new UnfoldBranchedExpressionIntention.UnfoldReturnToIfIntention()); + doTestIntention(path, new UnfoldBranchedExpressionIntention.UnfoldReturnToIfIntention()); } public void doTestUnfoldReturnToWhen(@NotNull String path) throws Exception { - doTest(path, new UnfoldBranchedExpressionIntention.UnfoldReturnToWhenIntention()); + doTestIntention(path, new UnfoldBranchedExpressionIntention.UnfoldReturnToWhenIntention()); } public void doTestIfToWhen(@NotNull String path) throws Exception { - doTest(path, new IfToWhenIntention()); + doTestIntention(path, new IfToWhenIntention()); } public void doTestWhenToIf(@NotNull String path) throws Exception { - doTest(path, new WhenToIfIntention()); + doTestIntention(path, new WhenToIfIntention()); } public void doTestFlattenWhen(@NotNull String path) throws Exception { - doTest(path, new FlattenWhenIntention()); + doTestIntention(path, new FlattenWhenIntention()); } public void doTestIntroduceWhenSubject(@NotNull String path) throws Exception { - doTest(path, new IntroduceWhenSubjectIntention()); + doTestIntention(path, new IntroduceWhenSubjectIntention()); } public void doTestEliminateWhenSubject(@NotNull String path) throws Exception { - doTest(path, new EliminateWhenSubjectIntention()); + doTestIntention(path, new EliminateWhenSubjectIntention()); + } + + public void doTestSplitProperty(@NotNull String path) throws Exception { + doTestIntention(path, new SplitPropertyDeclarationIntention()); + } + + public void doTestJoinProperty(@NotNull String path) throws Exception { + doTestAction(path, new JoinLinesHandler(null)); } public void doTestRemoveUnnecessaryParentheses(@NotNull String path) throws Exception { - doTest(path, new RemoveUnnecessaryParenthesesIntention()); + doTestIntention(path, new RemoveUnnecessaryParenthesesIntention()); } - private void doTest(@NotNull String path, @NotNull IntentionAction intentionAction) throws Exception { + private void doTestIntention(@NotNull String path, @NotNull IntentionAction intentionAction) throws Exception { configureByFile(path); String fileText = FileUtil.loadFile(new File(path)); @@ -104,12 +115,14 @@ public abstract class AbstractCodeTransformationTest extends LightCodeInsightTes assert isApplicableExpected == intentionAction.isAvailable(getProject(), getEditor(), getFile()) : "isAvailable() for " + intentionAction.getClass() + " should return " + isApplicableExpected; if (isApplicableExpected) { - invokeAndCheck(path, intentionAction); + intentionAction.invoke(getProject(), getEditor(), getFile()); + checkResultByFile(path + ".after"); } } - private void invokeAndCheck(@NotNull String path, @NotNull IntentionAction intentionAction) { - intentionAction.invoke(getProject(), getEditor(), getFile()); + private void doTestAction(@NotNull String path, @NotNull EditorActionHandler actionHandler) throws Exception { + configureByFile(path); + actionHandler.execute(getEditor(), getCurrentEditorDataContext()); checkResultByFile(path + ".after"); } 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 458a15e5641..d5ee04fb06f 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.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}) +@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, CodeTransformationsTestGenerated.Split.class, CodeTransformationsTestGenerated.Join.class}) public class CodeTransformationsTestGenerated extends AbstractCodeTransformationTest { @TestMetadata("idea/testData/codeInsight/codeTransformations/branched/folding/ifToAssignment") public static class IfToAssignment extends AbstractCodeTransformationTest { @@ -645,6 +645,152 @@ public class CodeTransformationsTestGenerated extends AbstractCodeTransformation } + @TestMetadata("idea/testData/codeInsight/codeTransformations/declarations/split") + public static class Split extends AbstractCodeTransformationTest { + public void testAllFilesPresentInSplit() throws Exception { + JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.GenerateTests", new File("idea/testData/codeInsight/codeTransformations/declarations/split"), Pattern.compile("^(.+)\\.kt$"), true); + } + + @TestMetadata("longInit.kt") + public void testLongInit() throws Exception { + doTestSplitProperty("idea/testData/codeInsight/codeTransformations/declarations/split/longInit.kt"); + } + + @TestMetadata("longInit2.kt") + public void testLongInit2() throws Exception { + doTestSplitProperty("idea/testData/codeInsight/codeTransformations/declarations/split/longInit2.kt"); + } + + @TestMetadata("noInitializer.kt") + public void testNoInitializer() throws Exception { + doTestSplitProperty("idea/testData/codeInsight/codeTransformations/declarations/split/noInitializer.kt"); + } + + @TestMetadata("noInitializer2.kt") + public void testNoInitializer2() throws Exception { + doTestSplitProperty("idea/testData/codeInsight/codeTransformations/declarations/split/noInitializer2.kt"); + } + + @TestMetadata("nonLocalProperty.kt") + public void testNonLocalProperty() throws Exception { + doTestSplitProperty("idea/testData/codeInsight/codeTransformations/declarations/split/nonLocalProperty.kt"); + } + + @TestMetadata("nonLocalProperty2.kt") + public void testNonLocalProperty2() throws Exception { + doTestSplitProperty("idea/testData/codeInsight/codeTransformations/declarations/split/nonLocalProperty2.kt"); + } + + @TestMetadata("simpleInit.kt") + public void testSimpleInit() throws Exception { + doTestSplitProperty("idea/testData/codeInsight/codeTransformations/declarations/split/simpleInit.kt"); + } + + @TestMetadata("simpleInit2.kt") + public void testSimpleInit2() throws Exception { + doTestSplitProperty("idea/testData/codeInsight/codeTransformations/declarations/split/simpleInit2.kt"); + } + + @TestMetadata("simpleInitWithErrorType.kt") + public void testSimpleInitWithErrorType() throws Exception { + doTestSplitProperty("idea/testData/codeInsight/codeTransformations/declarations/split/simpleInitWithErrorType.kt"); + } + + @TestMetadata("simpleInitWithErrorType2.kt") + public void testSimpleInitWithErrorType2() throws Exception { + doTestSplitProperty("idea/testData/codeInsight/codeTransformations/declarations/split/simpleInitWithErrorType2.kt"); + } + + @TestMetadata("simpleInitWithType.kt") + public void testSimpleInitWithType() throws Exception { + doTestSplitProperty("idea/testData/codeInsight/codeTransformations/declarations/split/simpleInitWithType.kt"); + } + + @TestMetadata("simpleInitWithType2.kt") + public void testSimpleInitWithType2() throws Exception { + doTestSplitProperty("idea/testData/codeInsight/codeTransformations/declarations/split/simpleInitWithType2.kt"); + } + + } + + @TestMetadata("idea/testData/codeInsight/codeTransformations/declarations/join") + public static class Join extends AbstractCodeTransformationTest { + public void testAllFilesPresentInJoin() throws Exception { + JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.GenerateTests", new File("idea/testData/codeInsight/codeTransformations/declarations/join"), Pattern.compile("^(.+)\\.kt$"), true); + } + + @TestMetadata("longInit.kt") + public void testLongInit() throws Exception { + doTestJoinProperty("idea/testData/codeInsight/codeTransformations/declarations/join/longInit.kt"); + } + + @TestMetadata("longInit2.kt") + public void testLongInit2() throws Exception { + doTestJoinProperty("idea/testData/codeInsight/codeTransformations/declarations/join/longInit2.kt"); + } + + @TestMetadata("simpleInit.kt") + public void testSimpleInit() throws Exception { + doTestJoinProperty("idea/testData/codeInsight/codeTransformations/declarations/join/simpleInit.kt"); + } + + @TestMetadata("simpleInit2.kt") + public void testSimpleInit2() throws Exception { + doTestJoinProperty("idea/testData/codeInsight/codeTransformations/declarations/join/simpleInit2.kt"); + } + + @TestMetadata("simpleInitWithBackticks.kt") + public void testSimpleInitWithBackticks() throws Exception { + doTestJoinProperty("idea/testData/codeInsight/codeTransformations/declarations/join/simpleInitWithBackticks.kt"); + } + + @TestMetadata("simpleInitWithBackticks2.kt") + public void testSimpleInitWithBackticks2() throws Exception { + doTestJoinProperty("idea/testData/codeInsight/codeTransformations/declarations/join/simpleInitWithBackticks2.kt"); + } + + @TestMetadata("simpleInitWithBackticks3.kt") + public void testSimpleInitWithBackticks3() throws Exception { + doTestJoinProperty("idea/testData/codeInsight/codeTransformations/declarations/join/simpleInitWithBackticks3.kt"); + } + + @TestMetadata("simpleInitWithComments.kt") + public void testSimpleInitWithComments() throws Exception { + doTestJoinProperty("idea/testData/codeInsight/codeTransformations/declarations/join/simpleInitWithComments.kt"); + } + + @TestMetadata("simpleInitWithComments2.kt") + public void testSimpleInitWithComments2() throws Exception { + doTestJoinProperty("idea/testData/codeInsight/codeTransformations/declarations/join/simpleInitWithComments2.kt"); + } + + @TestMetadata("simpleInitWithSemicolons.kt") + public void testSimpleInitWithSemicolons() throws Exception { + doTestJoinProperty("idea/testData/codeInsight/codeTransformations/declarations/join/simpleInitWithSemicolons.kt"); + } + + @TestMetadata("simpleInitWithSemicolons2.kt") + public void testSimpleInitWithSemicolons2() throws Exception { + doTestJoinProperty("idea/testData/codeInsight/codeTransformations/declarations/join/simpleInitWithSemicolons2.kt"); + } + + @TestMetadata("simpleInitWithSemicolons3.kt") + public void testSimpleInitWithSemicolons3() throws Exception { + doTestJoinProperty("idea/testData/codeInsight/codeTransformations/declarations/join/simpleInitWithSemicolons3.kt"); + } + + @TestMetadata("simpleInitWithType.kt") + public void testSimpleInitWithType() throws Exception { + doTestJoinProperty("idea/testData/codeInsight/codeTransformations/declarations/join/simpleInitWithType.kt"); + } + + @TestMetadata("simpleInitWithType2.kt") + public void testSimpleInitWithType2() throws Exception { + doTestJoinProperty("idea/testData/codeInsight/codeTransformations/declarations/join/simpleInitWithType2.kt"); + } + + } + public static Test suite() { TestSuite suite = new TestSuite("CodeTransformationsTestGenerated"); suite.addTestSuite(IfToAssignment.class); @@ -663,6 +809,8 @@ public class CodeTransformationsTestGenerated extends AbstractCodeTransformation suite.addTestSuite(Flatten.class); suite.addTestSuite(IntroduceSubject.class); suite.addTestSuite(EliminateSubject.class); + suite.addTestSuite(Split.class); + suite.addTestSuite(Join.class); return suite; } } From 12ea273ac02408f6b4aa5f99eab38a690bd804e1 Mon Sep 17 00:00:00 2001 From: Alexey Sedunov Date: Mon, 10 Jun 2013 18:02:15 +0400 Subject: [PATCH 128/291] Simplify unfolding of properties, fix caret position --- .../BranchedUnfoldingUtils.java | 97 ++----------------- .../UnfoldableKind.java | 4 +- .../unfolding/propertyToIf/nestedIfs.kt.after | 4 +- .../propertyToIf/nestedIfs2.kt.after | 4 +- .../unfolding/propertyToIf/simpleIf.kt.after | 4 +- .../unfolding/propertyToIf/simpleIf2.kt.after | 4 +- .../propertyToIf/simpleIfWithBlocks.kt.after | 4 +- .../propertyToIf/simpleIfWithBlocks2.kt.after | 4 +- .../propertyToIf/simpleIfWithType.kt.after | 4 +- .../propertyToWhen/simpleWhen.kt.after | 4 +- .../propertyToWhen/simpleWhen2.kt.after | 4 +- .../simpleWhenWithBlocks.kt.after | 4 +- .../simpleWhenWithBlocks2.kt.after | 4 +- .../simpleWhenWithType.kt.after | 4 +- 14 files changed, 33 insertions(+), 116 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 61ca1c961bf..a3fccc42a96 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,13 +22,7 @@ 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; +import org.jetbrains.jet.plugin.codeInsight.codeTransformations.declarations.DeclarationUtils; public class BranchedUnfoldingUtils { private BranchedUnfoldingUtils() { @@ -133,91 +127,14 @@ 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()); + public static void unfoldPropertyToIf(@NotNull JetProperty property, @NotNull JetFile file, @NotNull Editor editor) { + JetBinaryExpression assignment = DeclarationUtils.splitPropertyDeclaration(property, file); + unfoldAssignmentToIf(assignment, editor); } - 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 unfoldPropertyToWhen(@NotNull JetProperty property, @NotNull JetFile file, @NotNull Editor editor) { + JetBinaryExpression assignment = DeclarationUtils.splitPropertyDeclaration(property, file); + unfoldAssignmentToWhen(assignment, editor); } public static void unfoldReturnToIf(@NotNull JetReturnExpression returnExpression) { 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 4cc9162e237..bb14756bafb 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 @@ -35,7 +35,7 @@ public enum UnfoldableKind implements Transformer { PROPERTY_TO_IF("unfold.property.to.if") { @Override public void transform(@NotNull PsiElement element, @NotNull Editor editor, JetFile file) { - BranchedUnfoldingUtils.unfoldPropertyToIf((JetProperty) element, file); + BranchedUnfoldingUtils.unfoldPropertyToIf((JetProperty) element, file, editor); } }, RETURN_TO_IF("unfold.return.to.if") { @@ -53,7 +53,7 @@ public enum UnfoldableKind implements Transformer { PROPERTY_TO_WHEN("unfold.property.to.when") { @Override public void transform(@NotNull PsiElement element, @NotNull Editor editor, JetFile file) { - BranchedUnfoldingUtils.unfoldPropertyToWhen((JetProperty) element, file); + BranchedUnfoldingUtils.unfoldPropertyToWhen((JetProperty) element, file, editor); } }, RETURN_TO_WHEN("unfold.return.to.when") { diff --git a/idea/testData/codeInsight/codeTransformations/branched/unfolding/propertyToIf/nestedIfs.kt.after b/idea/testData/codeInsight/codeTransformations/branched/unfolding/propertyToIf/nestedIfs.kt.after index c0344100f46..5b1471d1878 100644 --- a/idea/testData/codeInsight/codeTransformations/branched/unfolding/propertyToIf/nestedIfs.kt.after +++ b/idea/testData/codeInsight/codeTransformations/branched/unfolding/propertyToIf/nestedIfs.kt.after @@ -1,6 +1,6 @@ fun test(n: Int): String? { - val res: String? - if (n == 1) { + val res: String? + if (n == 1) { res = if (3 > 2) { println("***") "one" diff --git a/idea/testData/codeInsight/codeTransformations/branched/unfolding/propertyToIf/nestedIfs2.kt.after b/idea/testData/codeInsight/codeTransformations/branched/unfolding/propertyToIf/nestedIfs2.kt.after index f560c0b982b..a8fb5588cc6 100644 --- a/idea/testData/codeInsight/codeTransformations/branched/unfolding/propertyToIf/nestedIfs2.kt.after +++ b/idea/testData/codeInsight/codeTransformations/branched/unfolding/propertyToIf/nestedIfs2.kt.after @@ -1,6 +1,6 @@ fun test(n: Int): String? { - var res: String? - if (n == 1) { + var res: String? + if (n == 1) { res = if (3 > 2) { println("***") "one" diff --git a/idea/testData/codeInsight/codeTransformations/branched/unfolding/propertyToIf/simpleIf.kt.after b/idea/testData/codeInsight/codeTransformations/branched/unfolding/propertyToIf/simpleIf.kt.after index 7025c616a42..ee420221776 100644 --- a/idea/testData/codeInsight/codeTransformations/branched/unfolding/propertyToIf/simpleIf.kt.after +++ b/idea/testData/codeInsight/codeTransformations/branched/unfolding/propertyToIf/simpleIf.kt.after @@ -1,6 +1,6 @@ fun test(n: Int): String { - val res: String - if (n == 1) res = "one" else res = "two" + 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.after b/idea/testData/codeInsight/codeTransformations/branched/unfolding/propertyToIf/simpleIf2.kt.after index 7e2a0315bd6..43088f87ac5 100644 --- a/idea/testData/codeInsight/codeTransformations/branched/unfolding/propertyToIf/simpleIf2.kt.after +++ b/idea/testData/codeInsight/codeTransformations/branched/unfolding/propertyToIf/simpleIf2.kt.after @@ -1,6 +1,6 @@ fun test(n: Int): String { - var res: String - if (n == 1) res = "one" else res = "two" + 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.after b/idea/testData/codeInsight/codeTransformations/branched/unfolding/propertyToIf/simpleIfWithBlocks.kt.after index d1471a6142e..953ab6c8863 100644 --- a/idea/testData/codeInsight/codeTransformations/branched/unfolding/propertyToIf/simpleIfWithBlocks.kt.after +++ b/idea/testData/codeInsight/codeTransformations/branched/unfolding/propertyToIf/simpleIfWithBlocks.kt.after @@ -1,6 +1,6 @@ fun test(n: Int): String { - val res: String - if (n == 1) { + val res: String + if (n == 1) { println("***") res = "one" } else { diff --git a/idea/testData/codeInsight/codeTransformations/branched/unfolding/propertyToIf/simpleIfWithBlocks2.kt.after b/idea/testData/codeInsight/codeTransformations/branched/unfolding/propertyToIf/simpleIfWithBlocks2.kt.after index c16a32371c6..705e0ce8b89 100644 --- a/idea/testData/codeInsight/codeTransformations/branched/unfolding/propertyToIf/simpleIfWithBlocks2.kt.after +++ b/idea/testData/codeInsight/codeTransformations/branched/unfolding/propertyToIf/simpleIfWithBlocks2.kt.after @@ -1,6 +1,6 @@ fun test(n: Int): String { - var res: String - if (n == 1) { + var res: String + if (n == 1) { println("***") res = "one" } else { diff --git a/idea/testData/codeInsight/codeTransformations/branched/unfolding/propertyToIf/simpleIfWithType.kt.after b/idea/testData/codeInsight/codeTransformations/branched/unfolding/propertyToIf/simpleIfWithType.kt.after index 3460d3bda79..b9b19d16ac9 100644 --- a/idea/testData/codeInsight/codeTransformations/branched/unfolding/propertyToIf/simpleIfWithType.kt.after +++ b/idea/testData/codeInsight/codeTransformations/branched/unfolding/propertyToIf/simpleIfWithType.kt.after @@ -1,6 +1,6 @@ fun test(n: Int): String { - val res: jet.String - if (n == 1) res = "one" else res = "two" + 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/simpleWhen.kt.after b/idea/testData/codeInsight/codeTransformations/branched/unfolding/propertyToWhen/simpleWhen.kt.after index d0be88b8b7f..c7e7082f1ca 100644 --- a/idea/testData/codeInsight/codeTransformations/branched/unfolding/propertyToWhen/simpleWhen.kt.after +++ b/idea/testData/codeInsight/codeTransformations/branched/unfolding/propertyToWhen/simpleWhen.kt.after @@ -1,6 +1,6 @@ fun test(n: Int): String? { - val res: String? - when(n) { + val res: String? + when(n) { 1 -> res = "one" 2 -> res = "two" else -> res = null diff --git a/idea/testData/codeInsight/codeTransformations/branched/unfolding/propertyToWhen/simpleWhen2.kt.after b/idea/testData/codeInsight/codeTransformations/branched/unfolding/propertyToWhen/simpleWhen2.kt.after index a0dd0c4c2c8..b4971e0feae 100644 --- a/idea/testData/codeInsight/codeTransformations/branched/unfolding/propertyToWhen/simpleWhen2.kt.after +++ b/idea/testData/codeInsight/codeTransformations/branched/unfolding/propertyToWhen/simpleWhen2.kt.after @@ -1,6 +1,6 @@ fun test(n: Int): String? { - var res: String? - when(n) { + var res: String? + when(n) { 1 -> res = "one" 2 -> res = "two" else -> res = null diff --git a/idea/testData/codeInsight/codeTransformations/branched/unfolding/propertyToWhen/simpleWhenWithBlocks.kt.after b/idea/testData/codeInsight/codeTransformations/branched/unfolding/propertyToWhen/simpleWhenWithBlocks.kt.after index b900cde5fc2..b16b90b3c81 100644 --- a/idea/testData/codeInsight/codeTransformations/branched/unfolding/propertyToWhen/simpleWhenWithBlocks.kt.after +++ b/idea/testData/codeInsight/codeTransformations/branched/unfolding/propertyToWhen/simpleWhenWithBlocks.kt.after @@ -1,6 +1,6 @@ fun test(n: Int): String { - val res: String - when (n) { + val res: String + when (n) { 1 -> { println("***") res = "one" diff --git a/idea/testData/codeInsight/codeTransformations/branched/unfolding/propertyToWhen/simpleWhenWithBlocks2.kt.after b/idea/testData/codeInsight/codeTransformations/branched/unfolding/propertyToWhen/simpleWhenWithBlocks2.kt.after index 4487e97042d..74f9623e053 100644 --- a/idea/testData/codeInsight/codeTransformations/branched/unfolding/propertyToWhen/simpleWhenWithBlocks2.kt.after +++ b/idea/testData/codeInsight/codeTransformations/branched/unfolding/propertyToWhen/simpleWhenWithBlocks2.kt.after @@ -1,6 +1,6 @@ fun test(n: Int): String { - var res: String - when (n) { + var res: String + when (n) { 1 -> { println("***") res = "one" diff --git a/idea/testData/codeInsight/codeTransformations/branched/unfolding/propertyToWhen/simpleWhenWithType.kt.after b/idea/testData/codeInsight/codeTransformations/branched/unfolding/propertyToWhen/simpleWhenWithType.kt.after index 7bf0f8006d3..994e41451e5 100644 --- a/idea/testData/codeInsight/codeTransformations/branched/unfolding/propertyToWhen/simpleWhenWithType.kt.after +++ b/idea/testData/codeInsight/codeTransformations/branched/unfolding/propertyToWhen/simpleWhenWithType.kt.after @@ -1,6 +1,6 @@ fun test(n: Int): String? { - val res: jet.String? - when(n) { + val res: jet.String? + when(n) { 1 -> res = "one" 2 -> res = "two" else -> res = null From 57252ea491905be0130e99303b269ac60c6ea20a Mon Sep 17 00:00:00 2001 From: Alexey Sedunov Date: Tue, 11 Jun 2013 14:40:47 +0400 Subject: [PATCH 129/291] Add missing tests --- .../jet/generators/tests/GenerateTests.java | 3 +- .../CodeTransformationsTestGenerated.java | 71 ++++++++++++++++++- 2 files changed, 72 insertions(+), 2 deletions(-) diff --git a/generators/org/jetbrains/jet/generators/tests/GenerateTests.java b/generators/org/jetbrains/jet/generators/tests/GenerateTests.java index 2986708dde8..fb53e2a6a2b 100644 --- a/generators/org/jetbrains/jet/generators/tests/GenerateTests.java +++ b/generators/org/jetbrains/jet/generators/tests/GenerateTests.java @@ -347,7 +347,8 @@ public class GenerateTests { testModel("idea/testData/codeInsight/codeTransformations/branched/when/introduceSubject", "doTestIntroduceWhenSubject"), testModel("idea/testData/codeInsight/codeTransformations/branched/when/eliminateSubject", "doTestEliminateWhenSubject"), testModel("idea/testData/codeInsight/codeTransformations/declarations/split", "doTestSplitProperty"), - testModel("idea/testData/codeInsight/codeTransformations/declarations/join", "doTestJoinProperty") + testModel("idea/testData/codeInsight/codeTransformations/declarations/join", "doTestJoinProperty"), + testModel("idea/testData/codeInsight/codeTransformations/removeUnnecessaryParentheses", "doTestRemoveUnnecessaryParentheses") ); generateTest( 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 d5ee04fb06f..abc0b628fe8 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.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, CodeTransformationsTestGenerated.Split.class, CodeTransformationsTestGenerated.Join.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, CodeTransformationsTestGenerated.Split.class, CodeTransformationsTestGenerated.Join.class, CodeTransformationsTestGenerated.RemoveUnnecessaryParentheses.class}) public class CodeTransformationsTestGenerated extends AbstractCodeTransformationTest { @TestMetadata("idea/testData/codeInsight/codeTransformations/branched/folding/ifToAssignment") public static class IfToAssignment extends AbstractCodeTransformationTest { @@ -791,6 +791,74 @@ public class CodeTransformationsTestGenerated extends AbstractCodeTransformation } + @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(IfToAssignment.class); @@ -811,6 +879,7 @@ public class CodeTransformationsTestGenerated extends AbstractCodeTransformation suite.addTestSuite(EliminateSubject.class); suite.addTestSuite(Split.class); suite.addTestSuite(Join.class); + suite.addTestSuite(RemoveUnnecessaryParentheses.class); return suite; } } From 6f942a21de5bd1e061fcf8f1a0932f58aa4c0c01 Mon Sep 17 00:00:00 2001 From: Alexey Sedunov Date: Thu, 13 Jun 2013 18:56:54 +0400 Subject: [PATCH 130/291] Move intention-related classes and tests to "intentions" directory --- .../jet/generators/tests/GenerateTests.java | 40 +- idea/src/META-INF/plugin.xml | 46 +-- .../AbstractCodeTransformationIntention.java | 3 +- ...RemoveUnnecessaryParenthesesIntention.java | 2 +- .../Transformer.java | 2 +- .../BranchedFoldingUtils.java | 2 +- .../BranchedUnfoldingUtils.java | 4 +- .../branchedTransformations/FoldableKind.java | 4 +- .../branchedTransformations/IfWhenUtils.java | 2 +- .../UnfoldableKind.java | 4 +- .../branchedTransformations/WhenUtils.java | 2 +- .../EliminateWhenSubjectIntention.java | 8 +- .../intentions/FlattenWhenIntention.java | 8 +- .../FoldBranchedExpressionIntention.java | 8 +- .../intentions/IfToWhenIntention.java | 8 +- .../IntroduceWhenSubjectIntention.java | 8 +- .../UnfoldBranchedExpressionIntention.java | 6 +- .../intentions/WhenToIfIntention.java | 8 +- .../declarations/DeclarationUtils.java | 2 +- .../JetDeclarationJoinLinesHandler.java | 2 +- .../SplitPropertyDeclarationIntention.java | 6 +- .../ktSignature/DeleteSignatureAction.java | 14 +- .../ktSignature/EditSignatureAction.java | 14 +- .../ktSignature/EditSignatureBalloon.java | 8 +- .../KotlinSignatureAnnotationIntention.java | 17 +- .../KotlinSignatureInJavaMarkerProvider.java | 14 +- .../KotlinSignatureInJavaMarkerUpdater.java | 2 +- .../ktSignature/KotlinSignatureUtil.java | 2 +- .../ShowKotlinSignaturesAction.java | 2 +- .../ifToAssignment/innerIfTransformed.kt | 0 .../innerIfTransformed.kt.after | 0 .../folding/ifToAssignment/simpleIf.kt | 0 .../folding/ifToAssignment/simpleIf.kt.after | 0 .../simpleIfWithAugmentedAssignment.kt | 0 .../simpleIfWithAugmentedAssignment.kt.after | 0 .../ifToAssignment/simpleIfWithBlocks.kt | 0 .../simpleIfWithBlocks.kt.after | 0 .../ifToAssignment/simpleIfWithShadowedVar.kt | 0 .../simpleIfWithUnmatchedAssignmentOps.kt | 0 .../simpleIfWithUnmatchedAssignments.kt | 0 .../ifToAssignment/simpleIfWithoutElse.kt | 0 .../simpleIfWithoutTerminatingAssignment.kt | 0 .../folding/ifToReturn/innerIfTransformed.kt | 0 .../ifToReturn/innerIfTransformed.kt.after | 0 .../branched/folding/ifToReturn/simpleIf.kt | 0 .../folding/ifToReturn/simpleIf.kt.after | 0 .../folding/ifToReturn/simpleIfWithBlocks.kt | 0 .../ifToReturn/simpleIfWithBlocks.kt.after | 0 .../ifToReturnAsymmetrically/simpleIf.kt | 0 .../simpleIf.kt.after | 0 .../simpleIfWithBlocks.kt | 0 .../simpleIfWithBlocks.kt.after | 0 .../simpleIfWithComments.kt | 0 .../simpleIfWithComments.kt.after | 0 .../whenToAssignment/innerWhenTransformed.kt | 0 .../innerWhenTransformed.kt.after | 0 .../folding/whenToAssignment/simpleWhen.kt | 0 .../whenToAssignment/simpleWhen.kt.after | 0 .../whenToAssignment/simpleWhenWithBlocks.kt | 0 .../simpleWhenWithBlocks.kt.after | 0 .../simpleWhenWithShadowedVar.kt | 0 .../simpleWhenWithUnmatchedAssignments.kt | 0 .../simpleWhenWithoutTerminatingAssignment.kt | 0 .../whenToReturn/innerWhenTransformed.kt | 0 .../innerWhenTransformed.kt.after | 0 .../folding/whenToReturn/simpleWhen.kt | 0 .../folding/whenToReturn/simpleWhen.kt.after | 0 .../whenToReturn/simpleWhenWithBlocks.kt | 0 .../simpleWhenWithBlocks.kt.after | 0 .../ifWhen/ifToWhen/ifWithEqualityTests.kt | 0 .../ifToWhen/ifWithEqualityTests.kt.after | 0 .../branched/ifWhen/ifToWhen/ifWithIs.kt | 0 .../ifWhen/ifToWhen/ifWithIs.kt.after | 0 .../ifWhen/ifToWhen/ifWithMultiConditions.kt | 0 .../ifToWhen/ifWithMultiConditions.kt.after | 0 .../ifWhen/ifToWhen/ifWithNegativeIs.kt | 0 .../ifWhen/ifToWhen/ifWithNegativeIs.kt.after | 0 .../ifToWhen/ifWithNegativeRangeTests.kt | 0 .../ifWithNegativeRangeTests.kt.after | 0 .../ifWhen/ifToWhen/ifWithRangeTests.kt | 0 .../ifWhen/ifToWhen/ifWithRangeTests.kt.after | 0 .../ifWithRangeTestsAndMultiConditions.kt | 0 ...fWithRangeTestsAndMultiConditions.kt.after | 0 ...eTestsAndUnparenthesizedMultiConditions.kt | 0 ...AndUnparenthesizedMultiConditions.kt.after | 0 .../whenWithMultipleConditionTypes.kt | 0 .../whenWithMultipleConditionTypes.kt.after | 0 .../ifWhen/whenToIf/whenWithEqualityTests.kt | 0 .../whenToIf/whenWithEqualityTests.kt.after | 0 .../whenToIf/whenWithMultiConditions.kt | 0 .../whenToIf/whenWithMultiConditions.kt.after | 0 .../whenWithMultipleConditionTypes.kt | 0 .../whenWithMultipleConditionTypes.kt.after | 0 .../whenToIf/whenWithNegativePatterns.kt | 0 .../whenWithNegativePatterns.kt.after | 0 .../whenToIf/whenWithNegativeRangeTests.kt | 0 .../whenWithNegativeRangeTests.kt.after | 0 .../ifWhen/whenToIf/whenWithPatterns.kt | 0 .../ifWhen/whenToIf/whenWithPatterns.kt.after | 0 .../ifWhen/whenToIf/whenWithRangeTests.kt | 0 .../whenToIf/whenWithRangeTests.kt.after | 0 .../whenWithRangeTestsAndMultiConditions.kt | 0 ...nWithRangeTestsAndMultiConditions.kt.after | 0 .../ifWhen/whenToIf/whenWithoutSubject.kt | 0 .../whenToIf/whenWithoutSubject.kt.after | 0 .../assignmentToIf/innerIfTransformed.kt | 0 .../innerIfTransformed.kt.after | 0 .../unfolding/assignmentToIf/nestedIfs.kt | 0 .../assignmentToIf/nestedIfs.kt.after | 0 .../unfolding/assignmentToIf/simpleIf.kt | 0 .../assignmentToIf/simpleIf.kt.after | 0 .../simpleIfWithAugmentedAssignment.kt | 0 .../simpleIfWithAugmentedAssignment.kt.after | 0 .../assignmentToIf/simpleIfWithBlocks.kt | 0 .../simpleIfWithBlocks.kt.after | 0 .../simpleIfWithComplexAssignmentLHS.kt | 0 .../simpleIfWithComplexAssignmentLHS.kt.after | 0 .../simpleIfWithoutAssignment.kt | 0 .../assignmentToWhen/innerWhenTransformed.kt | 0 .../innerWhenTransformed.kt.after | 0 .../unfolding/assignmentToWhen/simpleWhen.kt | 0 .../assignmentToWhen/simpleWhen.kt.after | 0 .../assignmentToWhen/simpleWhenWithBlocks.kt | 0 .../simpleWhenWithBlocks.kt.after | 0 .../simpleWhenWithComplexAssignmentLHS.kt | 0 ...impleWhenWithComplexAssignmentLHS.kt.after | 0 .../unfolding/propertyToIf/nestedIfs.kt | 0 .../unfolding/propertyToIf/nestedIfs.kt.after | 0 .../unfolding/propertyToIf/nestedIfs2.kt | 0 .../propertyToIf/nestedIfs2.kt.after | 0 .../propertyToIf/nonLocalProperty.kt | 0 .../propertyToIf/nonLocalProperty2.kt | 0 .../unfolding/propertyToIf/simpleIf.kt | 0 .../unfolding/propertyToIf/simpleIf.kt.after | 0 .../unfolding/propertyToIf/simpleIf2.kt | 0 .../unfolding/propertyToIf/simpleIf2.kt.after | 0 .../propertyToIf/simpleIfWithBlocks.kt | 0 .../propertyToIf/simpleIfWithBlocks.kt.after | 0 .../propertyToIf/simpleIfWithBlocks2.kt | 0 .../propertyToIf/simpleIfWithBlocks2.kt.after | 0 .../propertyToIf/simpleIfWithType.kt | 0 .../propertyToIf/simpleIfWithType.kt.after | 0 .../propertyToWhen/nonLocalProperty.kt | 0 .../propertyToWhen/nonLocalProperty2.kt | 0 .../unfolding/propertyToWhen/simpleWhen.kt | 0 .../propertyToWhen/simpleWhen.kt.after | 0 .../unfolding/propertyToWhen/simpleWhen2.kt | 0 .../propertyToWhen/simpleWhen2.kt.after | 0 .../propertyToWhen/simpleWhenWithBlocks.kt | 0 .../simpleWhenWithBlocks.kt.after | 0 .../propertyToWhen/simpleWhenWithBlocks2.kt | 0 .../simpleWhenWithBlocks2.kt.after | 0 .../propertyToWhen/simpleWhenWithType.kt | 0 .../simpleWhenWithType.kt.after | 0 .../returnToIf/innerIfTransformed.kt | 0 .../returnToIf/innerIfTransformed.kt.after | 0 .../branched/unfolding/returnToIf/simpleIf.kt | 0 .../unfolding/returnToIf/simpleIf.kt.after | 0 .../returnToIf/simpleIfWithBlocks.kt | 0 .../returnToIf/simpleIfWithBlocks.kt.after | 0 .../returnToWhen/innerWhenTransformed.kt | 0 .../innerWhenTransformed.kt.after | 0 .../unfolding/returnToWhen/simpleWhen.kt | 0 .../returnToWhen/simpleWhen.kt.after | 0 .../returnToWhen/simpleWhenWithBlocks.kt | 0 .../simpleWhenWithBlocks.kt.after | 0 .../eliminateSubject/whenWithEqualityTests.kt | 0 .../whenWithEqualityTests.kt.after | 0 .../whenWithMultipleConditionTypes.kt | 0 .../whenWithMultipleConditionTypes.kt.after | 0 .../whenWithNegativePatterns.kt | 0 .../whenWithNegativePatterns.kt.after | 0 .../whenWithNegativeRangeTests.kt | 0 .../whenWithNegativeRangeTests.kt.after | 0 .../when/eliminateSubject/whenWithPatterns.kt | 0 .../whenWithPatterns.kt.after | 0 .../eliminateSubject/whenWithRangeTests.kt | 0 .../whenWithRangeTests.kt.after | 0 .../whenWithRangeTestsAndMultiConditions.kt | 0 ...nWithRangeTestsAndMultiConditions.kt.after | 0 .../eliminateSubject/whenWithoutSubject.kt | 0 .../when/flatten/flattenWithSubject.kt | 0 .../when/flatten/flattenWithSubject.kt.after | 0 .../flatten/flattenWithUnmatchedSubjects.kt | 0 .../when/flatten/flattenWithoutSubject.kt | 0 .../flatten/flattenWithoutSubject.kt.after | 0 .../introduceSubject/whenWithEqualityTests.kt | 0 .../whenWithEqualityTests.kt.after | 0 .../whenWithMultipleConditionTypes.kt | 0 .../whenWithMultipleConditionTypes.kt.after | 0 .../whenWithNegativePatterns.kt | 0 .../whenWithNegativePatterns.kt.after | 0 .../whenWithNegativeRangeTests.kt | 0 .../whenWithNegativeRangeTests.kt.after | 0 .../whenWithNondivisibleConditions.kt | 0 .../when/introduceSubject/whenWithPatterns.kt | 0 .../whenWithPatterns.kt.after | 0 .../introduceSubject/whenWithRangeTests.kt | 0 .../whenWithRangeTests.kt.after | 0 .../whenWithRangeTestsAndMultiConditions.kt | 0 ...nWithRangeTestsAndMultiConditions.kt.after | 0 .../when/introduceSubject/whenWithSubject.kt | 0 .../whenWithSwappedEqualityTests.kt | 0 .../whenWithSwappedEqualityTests.kt.after | 0 .../whenWithUnmatchedCandidateSubjects.kt | 0 .../declarations/join/longInit.kt | 0 .../declarations/join/longInit.kt.after | 0 .../declarations/join/longInit2.kt | 0 .../declarations/join/longInit2.kt.after | 0 .../declarations/join/simpleInit.kt | 0 .../declarations/join/simpleInit.kt.after | 0 .../declarations/join/simpleInit2.kt | 0 .../declarations/join/simpleInit2.kt.after | 0 .../join/simpleInitWithBackticks.kt | 0 .../join/simpleInitWithBackticks.kt.after | 0 .../join/simpleInitWithBackticks2.kt | 0 .../join/simpleInitWithBackticks2.kt.after | 0 .../join/simpleInitWithBackticks3.kt | 0 .../join/simpleInitWithBackticks3.kt.after | 0 .../join/simpleInitWithComments.kt | 0 .../join/simpleInitWithComments.kt.after | 0 .../join/simpleInitWithComments2.kt | 0 .../join/simpleInitWithComments2.kt.after | 0 .../join/simpleInitWithSemicolons.kt | 0 .../join/simpleInitWithSemicolons.kt.after | 0 .../join/simpleInitWithSemicolons2.kt | 0 .../join/simpleInitWithSemicolons2.kt.after | 0 .../join/simpleInitWithSemicolons3.kt | 0 .../join/simpleInitWithSemicolons3.kt.after | 0 .../declarations/join/simpleInitWithType.kt | 0 .../join/simpleInitWithType.kt.after | 0 .../declarations/join/simpleInitWithType2.kt | 0 .../join/simpleInitWithType2.kt.after | 0 .../declarations/split/longInit.kt | 0 .../declarations/split/longInit.kt.after | 0 .../declarations/split/longInit2.kt | 0 .../declarations/split/longInit2.kt.after | 0 .../declarations/split/noInitializer.kt | 0 .../declarations/split/noInitializer2.kt | 0 .../declarations/split/nonLocalProperty.kt | 0 .../declarations/split/nonLocalProperty2.kt | 0 .../declarations/split/simpleInit.kt | 0 .../declarations/split/simpleInit.kt.after | 0 .../declarations/split/simpleInit2.kt | 0 .../declarations/split/simpleInit2.kt.after | 0 .../split/simpleInitWithErrorType.kt | 0 .../split/simpleInitWithErrorType.kt.after | 0 .../split/simpleInitWithErrorType2.kt | 0 .../split/simpleInitWithErrorType2.kt.after | 0 .../declarations/split/simpleInitWithType.kt | 0 .../split/simpleInitWithType.kt.after | 0 .../declarations/split/simpleInitWithType2.kt | 0 .../split/simpleInitWithType2.kt.after | 0 .../necessaryParentheses1.kt | 0 .../necessaryParentheses2.kt | 0 .../necessaryParentheses3.kt | 0 .../necessaryParentheses4.kt | 0 .../necessaryParentheses5.kt | 0 .../unnecessaryParentheses1.kt | 0 .../unnecessaryParentheses1.kt.after | 0 .../unnecessaryParentheses2.kt | 0 .../unnecessaryParentheses2.kt.after | 0 .../unnecessaryParentheses3.kt | 0 .../unnecessaryParentheses3.kt.after | 0 .../unnecessaryParentheses4.kt | 0 .../unnecessaryParentheses4.kt.after | 0 .../unnecessaryParentheses5.kt | 0 .../unnecessaryParentheses5.kt.after | 0 .../unnecessaryParentheses6.kt | 0 .../unnecessaryParentheses6.kt.after | 0 .../unnecessaryParentheses7.kt | 0 .../unnecessaryParentheses7.kt.after | 0 .../AbstractCodeTransformationTest.java | 7 +- .../CodeTransformationsTestGenerated.java | 350 +++++++++--------- .../SignatureMarkerProviderTest.java | 7 +- 275 files changed, 303 insertions(+), 309 deletions(-) rename idea/src/org/jetbrains/jet/plugin/{codeInsight/codeTransformations => intentions}/AbstractCodeTransformationIntention.java (94%) rename idea/src/org/jetbrains/jet/plugin/{codeInsight/codeTransformations => intentions}/RemoveUnnecessaryParenthesesIntention.java (97%) rename idea/src/org/jetbrains/jet/plugin/{codeInsight/codeTransformations => intentions}/Transformer.java (93%) rename idea/src/org/jetbrains/jet/plugin/{codeInsight/codeTransformations => intentions}/branchedTransformations/BranchedFoldingUtils.java (99%) rename idea/src/org/jetbrains/jet/plugin/{codeInsight/codeTransformations => intentions}/branchedTransformations/BranchedUnfoldingUtils.java (97%) rename idea/src/org/jetbrains/jet/plugin/{codeInsight/codeTransformations => intentions}/branchedTransformations/FoldableKind.java (93%) rename idea/src/org/jetbrains/jet/plugin/{codeInsight/codeTransformations => intentions}/branchedTransformations/IfWhenUtils.java (98%) rename idea/src/org/jetbrains/jet/plugin/{codeInsight/codeTransformations => intentions}/branchedTransformations/UnfoldableKind.java (94%) rename idea/src/org/jetbrains/jet/plugin/{codeInsight/codeTransformations => intentions}/branchedTransformations/WhenUtils.java (99%) rename idea/src/org/jetbrains/jet/plugin/{codeInsight/codeTransformations => intentions}/branchedTransformations/intentions/EliminateWhenSubjectIntention.java (76%) rename idea/src/org/jetbrains/jet/plugin/{codeInsight/codeTransformations => intentions}/branchedTransformations/intentions/FlattenWhenIntention.java (75%) rename idea/src/org/jetbrains/jet/plugin/{codeInsight/codeTransformations => intentions}/branchedTransformations/intentions/FoldBranchedExpressionIntention.java (85%) rename idea/src/org/jetbrains/jet/plugin/{codeInsight/codeTransformations => intentions}/branchedTransformations/intentions/IfToWhenIntention.java (75%) rename idea/src/org/jetbrains/jet/plugin/{codeInsight/codeTransformations => intentions}/branchedTransformations/intentions/IntroduceWhenSubjectIntention.java (76%) rename idea/src/org/jetbrains/jet/plugin/{codeInsight/codeTransformations => intentions}/branchedTransformations/intentions/UnfoldBranchedExpressionIntention.java (90%) rename idea/src/org/jetbrains/jet/plugin/{codeInsight/codeTransformations => intentions}/branchedTransformations/intentions/WhenToIfIntention.java (82%) rename idea/src/org/jetbrains/jet/plugin/{codeInsight/codeTransformations => intentions}/declarations/DeclarationUtils.java (98%) rename idea/src/org/jetbrains/jet/plugin/{codeInsight/codeTransformations => intentions}/declarations/JetDeclarationJoinLinesHandler.java (94%) rename idea/src/org/jetbrains/jet/plugin/{codeInsight/codeTransformations => intentions}/declarations/SplitPropertyDeclarationIntention.java (87%) rename idea/src/org/jetbrains/jet/plugin/{codeInsight => }/ktSignature/DeleteSignatureAction.java (81%) rename idea/src/org/jetbrains/jet/plugin/{codeInsight => }/ktSignature/EditSignatureAction.java (85%) rename idea/src/org/jetbrains/jet/plugin/{codeInsight => }/ktSignature/EditSignatureBalloon.java (95%) rename idea/src/org/jetbrains/jet/plugin/{codeInsight => }/ktSignature/KotlinSignatureAnnotationIntention.java (93%) rename idea/src/org/jetbrains/jet/plugin/{codeInsight => }/ktSignature/KotlinSignatureInJavaMarkerProvider.java (95%) rename idea/src/org/jetbrains/jet/plugin/{codeInsight => }/ktSignature/KotlinSignatureInJavaMarkerUpdater.java (95%) rename idea/src/org/jetbrains/jet/plugin/{codeInsight => }/ktSignature/KotlinSignatureUtil.java (98%) rename idea/src/org/jetbrains/jet/plugin/{codeInsight => }/ktSignature/ShowKotlinSignaturesAction.java (96%) rename idea/testData/{codeInsight/codeTransformations => intentions}/branched/folding/ifToAssignment/innerIfTransformed.kt (100%) rename idea/testData/{codeInsight/codeTransformations => intentions}/branched/folding/ifToAssignment/innerIfTransformed.kt.after (100%) rename idea/testData/{codeInsight/codeTransformations => intentions}/branched/folding/ifToAssignment/simpleIf.kt (100%) rename idea/testData/{codeInsight/codeTransformations => intentions}/branched/folding/ifToAssignment/simpleIf.kt.after (100%) rename idea/testData/{codeInsight/codeTransformations => intentions}/branched/folding/ifToAssignment/simpleIfWithAugmentedAssignment.kt (100%) rename idea/testData/{codeInsight/codeTransformations => intentions}/branched/folding/ifToAssignment/simpleIfWithAugmentedAssignment.kt.after (100%) rename idea/testData/{codeInsight/codeTransformations => intentions}/branched/folding/ifToAssignment/simpleIfWithBlocks.kt (100%) rename idea/testData/{codeInsight/codeTransformations => intentions}/branched/folding/ifToAssignment/simpleIfWithBlocks.kt.after (100%) rename idea/testData/{codeInsight/codeTransformations => intentions}/branched/folding/ifToAssignment/simpleIfWithShadowedVar.kt (100%) rename idea/testData/{codeInsight/codeTransformations => intentions}/branched/folding/ifToAssignment/simpleIfWithUnmatchedAssignmentOps.kt (100%) rename idea/testData/{codeInsight/codeTransformations => intentions}/branched/folding/ifToAssignment/simpleIfWithUnmatchedAssignments.kt (100%) rename idea/testData/{codeInsight/codeTransformations => intentions}/branched/folding/ifToAssignment/simpleIfWithoutElse.kt (100%) rename idea/testData/{codeInsight/codeTransformations => intentions}/branched/folding/ifToAssignment/simpleIfWithoutTerminatingAssignment.kt (100%) rename idea/testData/{codeInsight/codeTransformations => intentions}/branched/folding/ifToReturn/innerIfTransformed.kt (100%) rename idea/testData/{codeInsight/codeTransformations => intentions}/branched/folding/ifToReturn/innerIfTransformed.kt.after (100%) rename idea/testData/{codeInsight/codeTransformations => intentions}/branched/folding/ifToReturn/simpleIf.kt (100%) rename idea/testData/{codeInsight/codeTransformations => intentions}/branched/folding/ifToReturn/simpleIf.kt.after (100%) rename idea/testData/{codeInsight/codeTransformations => intentions}/branched/folding/ifToReturn/simpleIfWithBlocks.kt (100%) rename idea/testData/{codeInsight/codeTransformations => intentions}/branched/folding/ifToReturn/simpleIfWithBlocks.kt.after (100%) rename idea/testData/{codeInsight/codeTransformations => intentions}/branched/folding/ifToReturnAsymmetrically/simpleIf.kt (100%) rename idea/testData/{codeInsight/codeTransformations => intentions}/branched/folding/ifToReturnAsymmetrically/simpleIf.kt.after (100%) rename idea/testData/{codeInsight/codeTransformations => intentions}/branched/folding/ifToReturnAsymmetrically/simpleIfWithBlocks.kt (100%) rename idea/testData/{codeInsight/codeTransformations => intentions}/branched/folding/ifToReturnAsymmetrically/simpleIfWithBlocks.kt.after (100%) rename idea/testData/{codeInsight/codeTransformations => intentions}/branched/folding/ifToReturnAsymmetrically/simpleIfWithComments.kt (100%) rename idea/testData/{codeInsight/codeTransformations => intentions}/branched/folding/ifToReturnAsymmetrically/simpleIfWithComments.kt.after (100%) rename idea/testData/{codeInsight/codeTransformations => intentions}/branched/folding/whenToAssignment/innerWhenTransformed.kt (100%) rename idea/testData/{codeInsight/codeTransformations => intentions}/branched/folding/whenToAssignment/innerWhenTransformed.kt.after (100%) rename idea/testData/{codeInsight/codeTransformations => intentions}/branched/folding/whenToAssignment/simpleWhen.kt (100%) rename idea/testData/{codeInsight/codeTransformations => intentions}/branched/folding/whenToAssignment/simpleWhen.kt.after (100%) rename idea/testData/{codeInsight/codeTransformations => intentions}/branched/folding/whenToAssignment/simpleWhenWithBlocks.kt (100%) rename idea/testData/{codeInsight/codeTransformations => intentions}/branched/folding/whenToAssignment/simpleWhenWithBlocks.kt.after (100%) rename idea/testData/{codeInsight/codeTransformations => intentions}/branched/folding/whenToAssignment/simpleWhenWithShadowedVar.kt (100%) rename idea/testData/{codeInsight/codeTransformations => intentions}/branched/folding/whenToAssignment/simpleWhenWithUnmatchedAssignments.kt (100%) rename idea/testData/{codeInsight/codeTransformations => intentions}/branched/folding/whenToAssignment/simpleWhenWithoutTerminatingAssignment.kt (100%) rename idea/testData/{codeInsight/codeTransformations => intentions}/branched/folding/whenToReturn/innerWhenTransformed.kt (100%) rename idea/testData/{codeInsight/codeTransformations => intentions}/branched/folding/whenToReturn/innerWhenTransformed.kt.after (100%) rename idea/testData/{codeInsight/codeTransformations => intentions}/branched/folding/whenToReturn/simpleWhen.kt (100%) rename idea/testData/{codeInsight/codeTransformations => intentions}/branched/folding/whenToReturn/simpleWhen.kt.after (100%) rename idea/testData/{codeInsight/codeTransformations => intentions}/branched/folding/whenToReturn/simpleWhenWithBlocks.kt (100%) rename idea/testData/{codeInsight/codeTransformations => intentions}/branched/folding/whenToReturn/simpleWhenWithBlocks.kt.after (100%) rename idea/testData/{codeInsight/codeTransformations => intentions}/branched/ifWhen/ifToWhen/ifWithEqualityTests.kt (100%) rename idea/testData/{codeInsight/codeTransformations => intentions}/branched/ifWhen/ifToWhen/ifWithEqualityTests.kt.after (100%) rename idea/testData/{codeInsight/codeTransformations => intentions}/branched/ifWhen/ifToWhen/ifWithIs.kt (100%) rename idea/testData/{codeInsight/codeTransformations => intentions}/branched/ifWhen/ifToWhen/ifWithIs.kt.after (100%) rename idea/testData/{codeInsight/codeTransformations => intentions}/branched/ifWhen/ifToWhen/ifWithMultiConditions.kt (100%) rename idea/testData/{codeInsight/codeTransformations => intentions}/branched/ifWhen/ifToWhen/ifWithMultiConditions.kt.after (100%) rename idea/testData/{codeInsight/codeTransformations => intentions}/branched/ifWhen/ifToWhen/ifWithNegativeIs.kt (100%) rename idea/testData/{codeInsight/codeTransformations => intentions}/branched/ifWhen/ifToWhen/ifWithNegativeIs.kt.after (100%) rename idea/testData/{codeInsight/codeTransformations => intentions}/branched/ifWhen/ifToWhen/ifWithNegativeRangeTests.kt (100%) rename idea/testData/{codeInsight/codeTransformations => intentions}/branched/ifWhen/ifToWhen/ifWithNegativeRangeTests.kt.after (100%) rename idea/testData/{codeInsight/codeTransformations => intentions}/branched/ifWhen/ifToWhen/ifWithRangeTests.kt (100%) rename idea/testData/{codeInsight/codeTransformations => intentions}/branched/ifWhen/ifToWhen/ifWithRangeTests.kt.after (100%) rename idea/testData/{codeInsight/codeTransformations => intentions}/branched/ifWhen/ifToWhen/ifWithRangeTestsAndMultiConditions.kt (100%) rename idea/testData/{codeInsight/codeTransformations => intentions}/branched/ifWhen/ifToWhen/ifWithRangeTestsAndMultiConditions.kt.after (100%) rename idea/testData/{codeInsight/codeTransformations => intentions}/branched/ifWhen/ifToWhen/ifWithRangeTestsAndUnparenthesizedMultiConditions.kt (100%) rename idea/testData/{codeInsight/codeTransformations => intentions}/branched/ifWhen/ifToWhen/ifWithRangeTestsAndUnparenthesizedMultiConditions.kt.after (100%) rename idea/testData/{codeInsight/codeTransformations => intentions}/branched/ifWhen/ifToWhen/whenWithMultipleConditionTypes.kt (100%) rename idea/testData/{codeInsight/codeTransformations => intentions}/branched/ifWhen/ifToWhen/whenWithMultipleConditionTypes.kt.after (100%) rename idea/testData/{codeInsight/codeTransformations => intentions}/branched/ifWhen/whenToIf/whenWithEqualityTests.kt (100%) rename idea/testData/{codeInsight/codeTransformations => intentions}/branched/ifWhen/whenToIf/whenWithEqualityTests.kt.after (100%) rename idea/testData/{codeInsight/codeTransformations => intentions}/branched/ifWhen/whenToIf/whenWithMultiConditions.kt (100%) rename idea/testData/{codeInsight/codeTransformations => intentions}/branched/ifWhen/whenToIf/whenWithMultiConditions.kt.after (100%) rename idea/testData/{codeInsight/codeTransformations => intentions}/branched/ifWhen/whenToIf/whenWithMultipleConditionTypes.kt (100%) rename idea/testData/{codeInsight/codeTransformations => intentions}/branched/ifWhen/whenToIf/whenWithMultipleConditionTypes.kt.after (100%) rename idea/testData/{codeInsight/codeTransformations => intentions}/branched/ifWhen/whenToIf/whenWithNegativePatterns.kt (100%) rename idea/testData/{codeInsight/codeTransformations => intentions}/branched/ifWhen/whenToIf/whenWithNegativePatterns.kt.after (100%) rename idea/testData/{codeInsight/codeTransformations => intentions}/branched/ifWhen/whenToIf/whenWithNegativeRangeTests.kt (100%) rename idea/testData/{codeInsight/codeTransformations => intentions}/branched/ifWhen/whenToIf/whenWithNegativeRangeTests.kt.after (100%) rename idea/testData/{codeInsight/codeTransformations => intentions}/branched/ifWhen/whenToIf/whenWithPatterns.kt (100%) rename idea/testData/{codeInsight/codeTransformations => intentions}/branched/ifWhen/whenToIf/whenWithPatterns.kt.after (100%) rename idea/testData/{codeInsight/codeTransformations => intentions}/branched/ifWhen/whenToIf/whenWithRangeTests.kt (100%) rename idea/testData/{codeInsight/codeTransformations => intentions}/branched/ifWhen/whenToIf/whenWithRangeTests.kt.after (100%) rename idea/testData/{codeInsight/codeTransformations => intentions}/branched/ifWhen/whenToIf/whenWithRangeTestsAndMultiConditions.kt (100%) rename idea/testData/{codeInsight/codeTransformations => intentions}/branched/ifWhen/whenToIf/whenWithRangeTestsAndMultiConditions.kt.after (100%) rename idea/testData/{codeInsight/codeTransformations => intentions}/branched/ifWhen/whenToIf/whenWithoutSubject.kt (100%) rename idea/testData/{codeInsight/codeTransformations => intentions}/branched/ifWhen/whenToIf/whenWithoutSubject.kt.after (100%) rename idea/testData/{codeInsight/codeTransformations => intentions}/branched/unfolding/assignmentToIf/innerIfTransformed.kt (100%) rename idea/testData/{codeInsight/codeTransformations => intentions}/branched/unfolding/assignmentToIf/innerIfTransformed.kt.after (100%) rename idea/testData/{codeInsight/codeTransformations => intentions}/branched/unfolding/assignmentToIf/nestedIfs.kt (100%) rename idea/testData/{codeInsight/codeTransformations => intentions}/branched/unfolding/assignmentToIf/nestedIfs.kt.after (100%) rename idea/testData/{codeInsight/codeTransformations => intentions}/branched/unfolding/assignmentToIf/simpleIf.kt (100%) rename idea/testData/{codeInsight/codeTransformations => intentions}/branched/unfolding/assignmentToIf/simpleIf.kt.after (100%) rename idea/testData/{codeInsight/codeTransformations => intentions}/branched/unfolding/assignmentToIf/simpleIfWithAugmentedAssignment.kt (100%) rename idea/testData/{codeInsight/codeTransformations => intentions}/branched/unfolding/assignmentToIf/simpleIfWithAugmentedAssignment.kt.after (100%) rename idea/testData/{codeInsight/codeTransformations => intentions}/branched/unfolding/assignmentToIf/simpleIfWithBlocks.kt (100%) rename idea/testData/{codeInsight/codeTransformations => intentions}/branched/unfolding/assignmentToIf/simpleIfWithBlocks.kt.after (100%) rename idea/testData/{codeInsight/codeTransformations => intentions}/branched/unfolding/assignmentToIf/simpleIfWithComplexAssignmentLHS.kt (100%) rename idea/testData/{codeInsight/codeTransformations => intentions}/branched/unfolding/assignmentToIf/simpleIfWithComplexAssignmentLHS.kt.after (100%) rename idea/testData/{codeInsight/codeTransformations => intentions}/branched/unfolding/assignmentToIf/simpleIfWithoutAssignment.kt (100%) rename idea/testData/{codeInsight/codeTransformations => intentions}/branched/unfolding/assignmentToWhen/innerWhenTransformed.kt (100%) rename idea/testData/{codeInsight/codeTransformations => intentions}/branched/unfolding/assignmentToWhen/innerWhenTransformed.kt.after (100%) rename idea/testData/{codeInsight/codeTransformations => intentions}/branched/unfolding/assignmentToWhen/simpleWhen.kt (100%) rename idea/testData/{codeInsight/codeTransformations => intentions}/branched/unfolding/assignmentToWhen/simpleWhen.kt.after (100%) rename idea/testData/{codeInsight/codeTransformations => intentions}/branched/unfolding/assignmentToWhen/simpleWhenWithBlocks.kt (100%) rename idea/testData/{codeInsight/codeTransformations => intentions}/branched/unfolding/assignmentToWhen/simpleWhenWithBlocks.kt.after (100%) rename idea/testData/{codeInsight/codeTransformations => intentions}/branched/unfolding/assignmentToWhen/simpleWhenWithComplexAssignmentLHS.kt (100%) rename idea/testData/{codeInsight/codeTransformations => intentions}/branched/unfolding/assignmentToWhen/simpleWhenWithComplexAssignmentLHS.kt.after (100%) rename idea/testData/{codeInsight/codeTransformations => intentions}/branched/unfolding/propertyToIf/nestedIfs.kt (100%) rename idea/testData/{codeInsight/codeTransformations => intentions}/branched/unfolding/propertyToIf/nestedIfs.kt.after (100%) rename idea/testData/{codeInsight/codeTransformations => intentions}/branched/unfolding/propertyToIf/nestedIfs2.kt (100%) rename idea/testData/{codeInsight/codeTransformations => intentions}/branched/unfolding/propertyToIf/nestedIfs2.kt.after (100%) rename idea/testData/{codeInsight/codeTransformations => intentions}/branched/unfolding/propertyToIf/nonLocalProperty.kt (100%) rename idea/testData/{codeInsight/codeTransformations => intentions}/branched/unfolding/propertyToIf/nonLocalProperty2.kt (100%) rename idea/testData/{codeInsight/codeTransformations => intentions}/branched/unfolding/propertyToIf/simpleIf.kt (100%) rename idea/testData/{codeInsight/codeTransformations => intentions}/branched/unfolding/propertyToIf/simpleIf.kt.after (100%) rename idea/testData/{codeInsight/codeTransformations => intentions}/branched/unfolding/propertyToIf/simpleIf2.kt (100%) rename idea/testData/{codeInsight/codeTransformations => intentions}/branched/unfolding/propertyToIf/simpleIf2.kt.after (100%) rename idea/testData/{codeInsight/codeTransformations => intentions}/branched/unfolding/propertyToIf/simpleIfWithBlocks.kt (100%) rename idea/testData/{codeInsight/codeTransformations => intentions}/branched/unfolding/propertyToIf/simpleIfWithBlocks.kt.after (100%) rename idea/testData/{codeInsight/codeTransformations => intentions}/branched/unfolding/propertyToIf/simpleIfWithBlocks2.kt (100%) rename idea/testData/{codeInsight/codeTransformations => intentions}/branched/unfolding/propertyToIf/simpleIfWithBlocks2.kt.after (100%) rename idea/testData/{codeInsight/codeTransformations => intentions}/branched/unfolding/propertyToIf/simpleIfWithType.kt (100%) rename idea/testData/{codeInsight/codeTransformations => intentions}/branched/unfolding/propertyToIf/simpleIfWithType.kt.after (100%) rename idea/testData/{codeInsight/codeTransformations => intentions}/branched/unfolding/propertyToWhen/nonLocalProperty.kt (100%) rename idea/testData/{codeInsight/codeTransformations => intentions}/branched/unfolding/propertyToWhen/nonLocalProperty2.kt (100%) rename idea/testData/{codeInsight/codeTransformations => intentions}/branched/unfolding/propertyToWhen/simpleWhen.kt (100%) rename idea/testData/{codeInsight/codeTransformations => intentions}/branched/unfolding/propertyToWhen/simpleWhen.kt.after (100%) rename idea/testData/{codeInsight/codeTransformations => intentions}/branched/unfolding/propertyToWhen/simpleWhen2.kt (100%) rename idea/testData/{codeInsight/codeTransformations => intentions}/branched/unfolding/propertyToWhen/simpleWhen2.kt.after (100%) rename idea/testData/{codeInsight/codeTransformations => intentions}/branched/unfolding/propertyToWhen/simpleWhenWithBlocks.kt (100%) rename idea/testData/{codeInsight/codeTransformations => intentions}/branched/unfolding/propertyToWhen/simpleWhenWithBlocks.kt.after (100%) rename idea/testData/{codeInsight/codeTransformations => intentions}/branched/unfolding/propertyToWhen/simpleWhenWithBlocks2.kt (100%) rename idea/testData/{codeInsight/codeTransformations => intentions}/branched/unfolding/propertyToWhen/simpleWhenWithBlocks2.kt.after (100%) rename idea/testData/{codeInsight/codeTransformations => intentions}/branched/unfolding/propertyToWhen/simpleWhenWithType.kt (100%) rename idea/testData/{codeInsight/codeTransformations => intentions}/branched/unfolding/propertyToWhen/simpleWhenWithType.kt.after (100%) rename idea/testData/{codeInsight/codeTransformations => intentions}/branched/unfolding/returnToIf/innerIfTransformed.kt (100%) rename idea/testData/{codeInsight/codeTransformations => intentions}/branched/unfolding/returnToIf/innerIfTransformed.kt.after (100%) rename idea/testData/{codeInsight/codeTransformations => intentions}/branched/unfolding/returnToIf/simpleIf.kt (100%) rename idea/testData/{codeInsight/codeTransformations => intentions}/branched/unfolding/returnToIf/simpleIf.kt.after (100%) rename idea/testData/{codeInsight/codeTransformations => intentions}/branched/unfolding/returnToIf/simpleIfWithBlocks.kt (100%) rename idea/testData/{codeInsight/codeTransformations => intentions}/branched/unfolding/returnToIf/simpleIfWithBlocks.kt.after (100%) rename idea/testData/{codeInsight/codeTransformations => intentions}/branched/unfolding/returnToWhen/innerWhenTransformed.kt (100%) rename idea/testData/{codeInsight/codeTransformations => intentions}/branched/unfolding/returnToWhen/innerWhenTransformed.kt.after (100%) rename idea/testData/{codeInsight/codeTransformations => intentions}/branched/unfolding/returnToWhen/simpleWhen.kt (100%) rename idea/testData/{codeInsight/codeTransformations => intentions}/branched/unfolding/returnToWhen/simpleWhen.kt.after (100%) rename idea/testData/{codeInsight/codeTransformations => intentions}/branched/unfolding/returnToWhen/simpleWhenWithBlocks.kt (100%) rename idea/testData/{codeInsight/codeTransformations => intentions}/branched/unfolding/returnToWhen/simpleWhenWithBlocks.kt.after (100%) rename idea/testData/{codeInsight/codeTransformations => intentions}/branched/when/eliminateSubject/whenWithEqualityTests.kt (100%) rename idea/testData/{codeInsight/codeTransformations => intentions}/branched/when/eliminateSubject/whenWithEqualityTests.kt.after (100%) rename idea/testData/{codeInsight/codeTransformations => intentions}/branched/when/eliminateSubject/whenWithMultipleConditionTypes.kt (100%) rename idea/testData/{codeInsight/codeTransformations => intentions}/branched/when/eliminateSubject/whenWithMultipleConditionTypes.kt.after (100%) rename idea/testData/{codeInsight/codeTransformations => intentions}/branched/when/eliminateSubject/whenWithNegativePatterns.kt (100%) rename idea/testData/{codeInsight/codeTransformations => intentions}/branched/when/eliminateSubject/whenWithNegativePatterns.kt.after (100%) rename idea/testData/{codeInsight/codeTransformations => intentions}/branched/when/eliminateSubject/whenWithNegativeRangeTests.kt (100%) rename idea/testData/{codeInsight/codeTransformations => intentions}/branched/when/eliminateSubject/whenWithNegativeRangeTests.kt.after (100%) rename idea/testData/{codeInsight/codeTransformations => intentions}/branched/when/eliminateSubject/whenWithPatterns.kt (100%) rename idea/testData/{codeInsight/codeTransformations => intentions}/branched/when/eliminateSubject/whenWithPatterns.kt.after (100%) rename idea/testData/{codeInsight/codeTransformations => intentions}/branched/when/eliminateSubject/whenWithRangeTests.kt (100%) rename idea/testData/{codeInsight/codeTransformations => intentions}/branched/when/eliminateSubject/whenWithRangeTests.kt.after (100%) rename idea/testData/{codeInsight/codeTransformations => intentions}/branched/when/eliminateSubject/whenWithRangeTestsAndMultiConditions.kt (100%) rename idea/testData/{codeInsight/codeTransformations => intentions}/branched/when/eliminateSubject/whenWithRangeTestsAndMultiConditions.kt.after (100%) rename idea/testData/{codeInsight/codeTransformations => intentions}/branched/when/eliminateSubject/whenWithoutSubject.kt (100%) rename idea/testData/{codeInsight/codeTransformations => intentions}/branched/when/flatten/flattenWithSubject.kt (100%) rename idea/testData/{codeInsight/codeTransformations => intentions}/branched/when/flatten/flattenWithSubject.kt.after (100%) rename idea/testData/{codeInsight/codeTransformations => intentions}/branched/when/flatten/flattenWithUnmatchedSubjects.kt (100%) rename idea/testData/{codeInsight/codeTransformations => intentions}/branched/when/flatten/flattenWithoutSubject.kt (100%) rename idea/testData/{codeInsight/codeTransformations => intentions}/branched/when/flatten/flattenWithoutSubject.kt.after (100%) rename idea/testData/{codeInsight/codeTransformations => intentions}/branched/when/introduceSubject/whenWithEqualityTests.kt (100%) rename idea/testData/{codeInsight/codeTransformations => intentions}/branched/when/introduceSubject/whenWithEqualityTests.kt.after (100%) rename idea/testData/{codeInsight/codeTransformations => intentions}/branched/when/introduceSubject/whenWithMultipleConditionTypes.kt (100%) rename idea/testData/{codeInsight/codeTransformations => intentions}/branched/when/introduceSubject/whenWithMultipleConditionTypes.kt.after (100%) rename idea/testData/{codeInsight/codeTransformations => intentions}/branched/when/introduceSubject/whenWithNegativePatterns.kt (100%) rename idea/testData/{codeInsight/codeTransformations => intentions}/branched/when/introduceSubject/whenWithNegativePatterns.kt.after (100%) rename idea/testData/{codeInsight/codeTransformations => intentions}/branched/when/introduceSubject/whenWithNegativeRangeTests.kt (100%) rename idea/testData/{codeInsight/codeTransformations => intentions}/branched/when/introduceSubject/whenWithNegativeRangeTests.kt.after (100%) rename idea/testData/{codeInsight/codeTransformations => intentions}/branched/when/introduceSubject/whenWithNondivisibleConditions.kt (100%) rename idea/testData/{codeInsight/codeTransformations => intentions}/branched/when/introduceSubject/whenWithPatterns.kt (100%) rename idea/testData/{codeInsight/codeTransformations => intentions}/branched/when/introduceSubject/whenWithPatterns.kt.after (100%) rename idea/testData/{codeInsight/codeTransformations => intentions}/branched/when/introduceSubject/whenWithRangeTests.kt (100%) rename idea/testData/{codeInsight/codeTransformations => intentions}/branched/when/introduceSubject/whenWithRangeTests.kt.after (100%) rename idea/testData/{codeInsight/codeTransformations => intentions}/branched/when/introduceSubject/whenWithRangeTestsAndMultiConditions.kt (100%) rename idea/testData/{codeInsight/codeTransformations => intentions}/branched/when/introduceSubject/whenWithRangeTestsAndMultiConditions.kt.after (100%) rename idea/testData/{codeInsight/codeTransformations => intentions}/branched/when/introduceSubject/whenWithSubject.kt (100%) rename idea/testData/{codeInsight/codeTransformations => intentions}/branched/when/introduceSubject/whenWithSwappedEqualityTests.kt (100%) rename idea/testData/{codeInsight/codeTransformations => intentions}/branched/when/introduceSubject/whenWithSwappedEqualityTests.kt.after (100%) rename idea/testData/{codeInsight/codeTransformations => intentions}/branched/when/introduceSubject/whenWithUnmatchedCandidateSubjects.kt (100%) rename idea/testData/{codeInsight/codeTransformations => intentions}/declarations/join/longInit.kt (100%) rename idea/testData/{codeInsight/codeTransformations => intentions}/declarations/join/longInit.kt.after (100%) rename idea/testData/{codeInsight/codeTransformations => intentions}/declarations/join/longInit2.kt (100%) rename idea/testData/{codeInsight/codeTransformations => intentions}/declarations/join/longInit2.kt.after (100%) rename idea/testData/{codeInsight/codeTransformations => intentions}/declarations/join/simpleInit.kt (100%) rename idea/testData/{codeInsight/codeTransformations => intentions}/declarations/join/simpleInit.kt.after (100%) rename idea/testData/{codeInsight/codeTransformations => intentions}/declarations/join/simpleInit2.kt (100%) rename idea/testData/{codeInsight/codeTransformations => intentions}/declarations/join/simpleInit2.kt.after (100%) rename idea/testData/{codeInsight/codeTransformations => intentions}/declarations/join/simpleInitWithBackticks.kt (100%) rename idea/testData/{codeInsight/codeTransformations => intentions}/declarations/join/simpleInitWithBackticks.kt.after (100%) rename idea/testData/{codeInsight/codeTransformations => intentions}/declarations/join/simpleInitWithBackticks2.kt (100%) rename idea/testData/{codeInsight/codeTransformations => intentions}/declarations/join/simpleInitWithBackticks2.kt.after (100%) rename idea/testData/{codeInsight/codeTransformations => intentions}/declarations/join/simpleInitWithBackticks3.kt (100%) rename idea/testData/{codeInsight/codeTransformations => intentions}/declarations/join/simpleInitWithBackticks3.kt.after (100%) rename idea/testData/{codeInsight/codeTransformations => intentions}/declarations/join/simpleInitWithComments.kt (100%) rename idea/testData/{codeInsight/codeTransformations => intentions}/declarations/join/simpleInitWithComments.kt.after (100%) rename idea/testData/{codeInsight/codeTransformations => intentions}/declarations/join/simpleInitWithComments2.kt (100%) rename idea/testData/{codeInsight/codeTransformations => intentions}/declarations/join/simpleInitWithComments2.kt.after (100%) rename idea/testData/{codeInsight/codeTransformations => intentions}/declarations/join/simpleInitWithSemicolons.kt (100%) rename idea/testData/{codeInsight/codeTransformations => intentions}/declarations/join/simpleInitWithSemicolons.kt.after (100%) rename idea/testData/{codeInsight/codeTransformations => intentions}/declarations/join/simpleInitWithSemicolons2.kt (100%) rename idea/testData/{codeInsight/codeTransformations => intentions}/declarations/join/simpleInitWithSemicolons2.kt.after (100%) rename idea/testData/{codeInsight/codeTransformations => intentions}/declarations/join/simpleInitWithSemicolons3.kt (100%) rename idea/testData/{codeInsight/codeTransformations => intentions}/declarations/join/simpleInitWithSemicolons3.kt.after (100%) rename idea/testData/{codeInsight/codeTransformations => intentions}/declarations/join/simpleInitWithType.kt (100%) rename idea/testData/{codeInsight/codeTransformations => intentions}/declarations/join/simpleInitWithType.kt.after (100%) rename idea/testData/{codeInsight/codeTransformations => intentions}/declarations/join/simpleInitWithType2.kt (100%) rename idea/testData/{codeInsight/codeTransformations => intentions}/declarations/join/simpleInitWithType2.kt.after (100%) rename idea/testData/{codeInsight/codeTransformations => intentions}/declarations/split/longInit.kt (100%) rename idea/testData/{codeInsight/codeTransformations => intentions}/declarations/split/longInit.kt.after (100%) rename idea/testData/{codeInsight/codeTransformations => intentions}/declarations/split/longInit2.kt (100%) rename idea/testData/{codeInsight/codeTransformations => intentions}/declarations/split/longInit2.kt.after (100%) rename idea/testData/{codeInsight/codeTransformations => intentions}/declarations/split/noInitializer.kt (100%) rename idea/testData/{codeInsight/codeTransformations => intentions}/declarations/split/noInitializer2.kt (100%) rename idea/testData/{codeInsight/codeTransformations => intentions}/declarations/split/nonLocalProperty.kt (100%) rename idea/testData/{codeInsight/codeTransformations => intentions}/declarations/split/nonLocalProperty2.kt (100%) rename idea/testData/{codeInsight/codeTransformations => intentions}/declarations/split/simpleInit.kt (100%) rename idea/testData/{codeInsight/codeTransformations => intentions}/declarations/split/simpleInit.kt.after (100%) rename idea/testData/{codeInsight/codeTransformations => intentions}/declarations/split/simpleInit2.kt (100%) rename idea/testData/{codeInsight/codeTransformations => intentions}/declarations/split/simpleInit2.kt.after (100%) rename idea/testData/{codeInsight/codeTransformations => intentions}/declarations/split/simpleInitWithErrorType.kt (100%) rename idea/testData/{codeInsight/codeTransformations => intentions}/declarations/split/simpleInitWithErrorType.kt.after (100%) rename idea/testData/{codeInsight/codeTransformations => intentions}/declarations/split/simpleInitWithErrorType2.kt (100%) rename idea/testData/{codeInsight/codeTransformations => intentions}/declarations/split/simpleInitWithErrorType2.kt.after (100%) rename idea/testData/{codeInsight/codeTransformations => intentions}/declarations/split/simpleInitWithType.kt (100%) rename idea/testData/{codeInsight/codeTransformations => intentions}/declarations/split/simpleInitWithType.kt.after (100%) rename idea/testData/{codeInsight/codeTransformations => intentions}/declarations/split/simpleInitWithType2.kt (100%) rename idea/testData/{codeInsight/codeTransformations => intentions}/declarations/split/simpleInitWithType2.kt.after (100%) rename idea/testData/{codeInsight/codeTransformations => intentions}/removeUnnecessaryParentheses/necessaryParentheses1.kt (100%) rename idea/testData/{codeInsight/codeTransformations => intentions}/removeUnnecessaryParentheses/necessaryParentheses2.kt (100%) rename idea/testData/{codeInsight/codeTransformations => intentions}/removeUnnecessaryParentheses/necessaryParentheses3.kt (100%) rename idea/testData/{codeInsight/codeTransformations => intentions}/removeUnnecessaryParentheses/necessaryParentheses4.kt (100%) rename idea/testData/{codeInsight/codeTransformations => intentions}/removeUnnecessaryParentheses/necessaryParentheses5.kt (100%) rename idea/testData/{codeInsight/codeTransformations => intentions}/removeUnnecessaryParentheses/unnecessaryParentheses1.kt (100%) rename idea/testData/{codeInsight/codeTransformations => intentions}/removeUnnecessaryParentheses/unnecessaryParentheses1.kt.after (100%) rename idea/testData/{codeInsight/codeTransformations => intentions}/removeUnnecessaryParentheses/unnecessaryParentheses2.kt (100%) rename idea/testData/{codeInsight/codeTransformations => intentions}/removeUnnecessaryParentheses/unnecessaryParentheses2.kt.after (100%) rename idea/testData/{codeInsight/codeTransformations => intentions}/removeUnnecessaryParentheses/unnecessaryParentheses3.kt (100%) rename idea/testData/{codeInsight/codeTransformations => intentions}/removeUnnecessaryParentheses/unnecessaryParentheses3.kt.after (100%) rename idea/testData/{codeInsight/codeTransformations => intentions}/removeUnnecessaryParentheses/unnecessaryParentheses4.kt (100%) rename idea/testData/{codeInsight/codeTransformations => intentions}/removeUnnecessaryParentheses/unnecessaryParentheses4.kt.after (100%) rename idea/testData/{codeInsight/codeTransformations => intentions}/removeUnnecessaryParentheses/unnecessaryParentheses5.kt (100%) rename idea/testData/{codeInsight/codeTransformations => intentions}/removeUnnecessaryParentheses/unnecessaryParentheses5.kt.after (100%) rename idea/testData/{codeInsight/codeTransformations => intentions}/removeUnnecessaryParentheses/unnecessaryParentheses6.kt (100%) rename idea/testData/{codeInsight/codeTransformations => intentions}/removeUnnecessaryParentheses/unnecessaryParentheses6.kt.after (100%) rename idea/testData/{codeInsight/codeTransformations => intentions}/removeUnnecessaryParentheses/unnecessaryParentheses7.kt (100%) rename idea/testData/{codeInsight/codeTransformations => intentions}/removeUnnecessaryParentheses/unnecessaryParentheses7.kt.after (100%) rename idea/tests/org/jetbrains/jet/plugin/{codeInsight/codeTransformations => intentions}/AbstractCodeTransformationTest.java (94%) rename idea/tests/org/jetbrains/jet/plugin/{codeInsight/codeTransformations => intentions}/CodeTransformationsTestGenerated.java (54%) rename idea/tests/org/jetbrains/jet/plugin/{codeInsight => }/ktSignature/SignatureMarkerProviderTest.java (92%) diff --git a/generators/org/jetbrains/jet/generators/tests/GenerateTests.java b/generators/org/jetbrains/jet/generators/tests/GenerateTests.java index fb53e2a6a2b..62a775547c2 100644 --- a/generators/org/jetbrains/jet/generators/tests/GenerateTests.java +++ b/generators/org/jetbrains/jet/generators/tests/GenerateTests.java @@ -38,7 +38,7 @@ import org.jetbrains.jet.lang.resolve.lazy.AbstractLazyResolveDescriptorRenderer import org.jetbrains.jet.lang.resolve.lazy.AbstractLazyResolveNamespaceComparingTest; import org.jetbrains.jet.lang.resolve.lazy.AbstractLazyResolveTest; import org.jetbrains.jet.modules.xml.AbstractModuleXmlParserTest; -import org.jetbrains.jet.plugin.codeInsight.codeTransformations.AbstractCodeTransformationTest; +import org.jetbrains.jet.plugin.intentions.AbstractCodeTransformationTest; import org.jetbrains.jet.plugin.codeInsight.surroundWith.AbstractSurroundWithTest; import org.jetbrains.jet.plugin.folding.AbstractKotlinFoldingTest; import org.jetbrains.jet.plugin.hierarchy.AbstractHierarchyTest; @@ -330,25 +330,25 @@ public class GenerateTests { "idea/tests/", "CodeTransformationsTestGenerated", AbstractCodeTransformationTest.class, - 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/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"), - 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"), - testModel("idea/testData/codeInsight/codeTransformations/declarations/split", "doTestSplitProperty"), - testModel("idea/testData/codeInsight/codeTransformations/declarations/join", "doTestJoinProperty"), - testModel("idea/testData/codeInsight/codeTransformations/removeUnnecessaryParentheses", "doTestRemoveUnnecessaryParentheses") + testModel("idea/testData/intentions/branched/folding/ifToAssignment", "doTestFoldIfToAssignment"), + testModel("idea/testData/intentions/branched/folding/ifToReturn", "doTestFoldIfToReturn"), + testModel("idea/testData/intentions/branched/folding/ifToReturnAsymmetrically", "doTestFoldIfToReturnAsymmetrically"), + testModel("idea/testData/intentions/branched/folding/whenToAssignment", "doTestFoldWhenToAssignment"), + testModel("idea/testData/intentions/branched/folding/whenToReturn", "doTestFoldWhenToReturn"), + testModel("idea/testData/intentions/branched/unfolding/assignmentToIf", "doTestUnfoldAssignmentToIf"), + testModel("idea/testData/intentions/branched/unfolding/assignmentToWhen", "doTestUnfoldAssignmentToWhen"), + testModel("idea/testData/intentions/branched/unfolding/propertyToIf", "doTestUnfoldPropertyToIf"), + testModel("idea/testData/intentions/branched/unfolding/propertyToWhen", "doTestUnfoldPropertyToWhen"), + testModel("idea/testData/intentions/branched/unfolding/returnToIf", "doTestUnfoldReturnToIf"), + testModel("idea/testData/intentions/branched/unfolding/returnToWhen", "doTestUnfoldReturnToWhen"), + testModel("idea/testData/intentions/branched/ifWhen/ifToWhen", "doTestIfToWhen"), + testModel("idea/testData/intentions/branched/ifWhen/whenToIf", "doTestWhenToIf"), + testModel("idea/testData/intentions/branched/when/flatten", "doTestFlattenWhen"), + testModel("idea/testData/intentions/branched/when/introduceSubject", "doTestIntroduceWhenSubject"), + testModel("idea/testData/intentions/branched/when/eliminateSubject", "doTestEliminateWhenSubject"), + testModel("idea/testData/intentions/declarations/split", "doTestSplitProperty"), + testModel("idea/testData/intentions/declarations/join", "doTestJoinProperty"), + testModel("idea/testData/intentions/removeUnnecessaryParentheses", "doTestRemoveUnnecessaryParentheses") ); generateTest( diff --git a/idea/src/META-INF/plugin.xml b/idea/src/META-INF/plugin.xml index e9d773c8e00..fcf0e0c2ae7 100644 --- a/idea/src/META-INF/plugin.xml +++ b/idea/src/META-INF/plugin.xml @@ -28,7 +28,7 @@ org.jetbrains.jet.plugin.versions.OutdatedKotlinRuntimeNotification - org.jetbrains.jet.plugin.codeInsight.ktSignature.KotlinSignatureInJavaMarkerUpdater + org.jetbrains.jet.plugin.ktSignature.KotlinSignatureInJavaMarkerUpdater @@ -71,7 +71,7 @@ - + @@ -211,7 +211,7 @@ + implementationClass="org.jetbrains.jet.plugin.ktSignature.KotlinSignatureInJavaMarkerProvider"/> @@ -291,7 +291,7 @@ implementation="org.jetbrains.jet.plugin.codeInsight.upDownMover.JetDeclarationMover" order="before jetExpression" /> - + org.jetbrains.jet.plugin.intentions.SpecifyTypeExplicitlyAction @@ -299,97 +299,97 @@ - org.jetbrains.jet.plugin.codeInsight.ktSignature.KotlinSignatureAnnotationIntention + org.jetbrains.jet.plugin.ktSignature.KotlinSignatureAnnotationIntention Kotlin - org.jetbrains.jet.plugin.codeInsight.codeTransformations.branchedTransformations.intentions.FoldBranchedExpressionIntention$FoldIfToAssignmentIntention + org.jetbrains.jet.plugin.intentions.branchedTransformations.intentions.FoldBranchedExpressionIntention$FoldIfToAssignmentIntention Kotlin - org.jetbrains.jet.plugin.codeInsight.codeTransformations.branchedTransformations.intentions.FoldBranchedExpressionIntention$FoldIfToReturnAsymmetricallyIntention + org.jetbrains.jet.plugin.intentions.branchedTransformations.intentions.FoldBranchedExpressionIntention$FoldIfToReturnAsymmetricallyIntention Kotlin - org.jetbrains.jet.plugin.codeInsight.codeTransformations.branchedTransformations.intentions.FoldBranchedExpressionIntention$FoldIfToReturnIntention + org.jetbrains.jet.plugin.intentions.branchedTransformations.intentions.FoldBranchedExpressionIntention$FoldIfToReturnIntention Kotlin - org.jetbrains.jet.plugin.codeInsight.codeTransformations.branchedTransformations.intentions.FoldBranchedExpressionIntention$FoldWhenToAssignmentIntention + org.jetbrains.jet.plugin.intentions.branchedTransformations.intentions.FoldBranchedExpressionIntention$FoldWhenToAssignmentIntention Kotlin - org.jetbrains.jet.plugin.codeInsight.codeTransformations.branchedTransformations.intentions.FoldBranchedExpressionIntention$FoldWhenToReturnIntention + org.jetbrains.jet.plugin.intentions.branchedTransformations.intentions.FoldBranchedExpressionIntention$FoldWhenToReturnIntention Kotlin - org.jetbrains.jet.plugin.codeInsight.codeTransformations.branchedTransformations.intentions.UnfoldBranchedExpressionIntention$UnfoldAssignmentToIfIntention + org.jetbrains.jet.plugin.intentions.branchedTransformations.intentions.UnfoldBranchedExpressionIntention$UnfoldAssignmentToIfIntention Kotlin - org.jetbrains.jet.plugin.codeInsight.codeTransformations.branchedTransformations.intentions.UnfoldBranchedExpressionIntention$UnfoldPropertyToIfIntention + org.jetbrains.jet.plugin.intentions.branchedTransformations.intentions.UnfoldBranchedExpressionIntention$UnfoldPropertyToIfIntention Kotlin - org.jetbrains.jet.plugin.codeInsight.codeTransformations.branchedTransformations.intentions.UnfoldBranchedExpressionIntention$UnfoldAssignmentToWhenIntention + org.jetbrains.jet.plugin.intentions.branchedTransformations.intentions.UnfoldBranchedExpressionIntention$UnfoldAssignmentToWhenIntention Kotlin - org.jetbrains.jet.plugin.codeInsight.codeTransformations.branchedTransformations.intentions.UnfoldBranchedExpressionIntention$UnfoldPropertyToWhenIntention + org.jetbrains.jet.plugin.intentions.branchedTransformations.intentions.UnfoldBranchedExpressionIntention$UnfoldPropertyToWhenIntention Kotlin - org.jetbrains.jet.plugin.codeInsight.codeTransformations.branchedTransformations.intentions.UnfoldBranchedExpressionIntention$UnfoldReturnToIfIntention + org.jetbrains.jet.plugin.intentions.branchedTransformations.intentions.UnfoldBranchedExpressionIntention$UnfoldReturnToIfIntention Kotlin - org.jetbrains.jet.plugin.codeInsight.codeTransformations.branchedTransformations.intentions.UnfoldBranchedExpressionIntention$UnfoldReturnToWhenIntention + org.jetbrains.jet.plugin.intentions.branchedTransformations.intentions.UnfoldBranchedExpressionIntention$UnfoldReturnToWhenIntention Kotlin - org.jetbrains.jet.plugin.codeInsight.codeTransformations.branchedTransformations.intentions.IfToWhenIntention + org.jetbrains.jet.plugin.intentions.branchedTransformations.intentions.IfToWhenIntention Kotlin - org.jetbrains.jet.plugin.codeInsight.codeTransformations.branchedTransformations.intentions.WhenToIfIntention + org.jetbrains.jet.plugin.intentions.branchedTransformations.intentions.WhenToIfIntention Kotlin - org.jetbrains.jet.plugin.codeInsight.codeTransformations.branchedTransformations.intentions.FlattenWhenIntention + org.jetbrains.jet.plugin.intentions.branchedTransformations.intentions.FlattenWhenIntention Kotlin - org.jetbrains.jet.plugin.codeInsight.codeTransformations.branchedTransformations.intentions.IntroduceWhenSubjectIntention + org.jetbrains.jet.plugin.intentions.branchedTransformations.intentions.IntroduceWhenSubjectIntention Kotlin - org.jetbrains.jet.plugin.codeInsight.codeTransformations.branchedTransformations.intentions.EliminateWhenSubjectIntention + org.jetbrains.jet.plugin.intentions.branchedTransformations.intentions.EliminateWhenSubjectIntention Kotlin - org.jetbrains.jet.plugin.codeInsight.codeTransformations.RemoveUnnecessaryParenthesesIntention + org.jetbrains.jet.plugin.intentions.RemoveUnnecessaryParenthesesIntention Kotlin - org.jetbrains.jet.plugin.codeInsight.codeTransformations.declarations.SplitPropertyDeclarationIntention + org.jetbrains.jet.plugin.intentions.declarations.SplitPropertyDeclarationIntention Kotlin diff --git a/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/AbstractCodeTransformationIntention.java b/idea/src/org/jetbrains/jet/plugin/intentions/AbstractCodeTransformationIntention.java similarity index 94% rename from idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/AbstractCodeTransformationIntention.java rename to idea/src/org/jetbrains/jet/plugin/intentions/AbstractCodeTransformationIntention.java index d965e443028..5990e926e7f 100644 --- a/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/AbstractCodeTransformationIntention.java +++ b/idea/src/org/jetbrains/jet/plugin/intentions/AbstractCodeTransformationIntention.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.jetbrains.jet.plugin.codeInsight.codeTransformations; +package org.jetbrains.jet.plugin.intentions; import com.google.common.base.Predicate; import com.intellij.codeInsight.intention.impl.BaseIntentionAction; @@ -29,7 +29,6 @@ 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.Transformer; public abstract class AbstractCodeTransformationIntention extends BaseIntentionAction { private final T transformer; diff --git a/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/RemoveUnnecessaryParenthesesIntention.java b/idea/src/org/jetbrains/jet/plugin/intentions/RemoveUnnecessaryParenthesesIntention.java similarity index 97% rename from idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/RemoveUnnecessaryParenthesesIntention.java rename to idea/src/org/jetbrains/jet/plugin/intentions/RemoveUnnecessaryParenthesesIntention.java index 6ccb7e3ac7d..fec605186b1 100644 --- a/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/RemoveUnnecessaryParenthesesIntention.java +++ b/idea/src/org/jetbrains/jet/plugin/intentions/RemoveUnnecessaryParenthesesIntention.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.jetbrains.jet.plugin.codeInsight.codeTransformations; +package org.jetbrains.jet.plugin.intentions; import com.intellij.codeInsight.intention.impl.BaseIntentionAction; import com.intellij.openapi.editor.Editor; diff --git a/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/Transformer.java b/idea/src/org/jetbrains/jet/plugin/intentions/Transformer.java similarity index 93% rename from idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/Transformer.java rename to idea/src/org/jetbrains/jet/plugin/intentions/Transformer.java index 6fa2790ac05..e975e842b3d 100644 --- a/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/Transformer.java +++ b/idea/src/org/jetbrains/jet/plugin/intentions/Transformer.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.jetbrains.jet.plugin.codeInsight.codeTransformations; +package org.jetbrains.jet.plugin.intentions; import com.intellij.openapi.editor.Editor; import com.intellij.psi.PsiElement; diff --git a/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/BranchedFoldingUtils.java b/idea/src/org/jetbrains/jet/plugin/intentions/branchedTransformations/BranchedFoldingUtils.java similarity index 99% rename from idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/BranchedFoldingUtils.java rename to idea/src/org/jetbrains/jet/plugin/intentions/branchedTransformations/BranchedFoldingUtils.java index ca8dc54d57f..f071b96d725 100644 --- a/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/BranchedFoldingUtils.java +++ b/idea/src/org/jetbrains/jet/plugin/intentions/branchedTransformations/BranchedFoldingUtils.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.jetbrains.jet.plugin.codeInsight.codeTransformations.branchedTransformations; +package org.jetbrains.jet.plugin.intentions.branchedTransformations; import com.google.common.base.Predicate; import com.intellij.openapi.project.Project; diff --git a/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/BranchedUnfoldingUtils.java b/idea/src/org/jetbrains/jet/plugin/intentions/branchedTransformations/BranchedUnfoldingUtils.java similarity index 97% rename from idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/BranchedUnfoldingUtils.java rename to idea/src/org/jetbrains/jet/plugin/intentions/branchedTransformations/BranchedUnfoldingUtils.java index a3fccc42a96..b456b4876c4 100644 --- a/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/BranchedUnfoldingUtils.java +++ b/idea/src/org/jetbrains/jet/plugin/intentions/branchedTransformations/BranchedUnfoldingUtils.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.jetbrains.jet.plugin.codeInsight.codeTransformations.branchedTransformations; +package org.jetbrains.jet.plugin.intentions.branchedTransformations; import com.intellij.openapi.editor.Editor; import com.intellij.openapi.project.Project; @@ -22,7 +22,7 @@ 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.plugin.codeInsight.codeTransformations.declarations.DeclarationUtils; +import org.jetbrains.jet.plugin.intentions.declarations.DeclarationUtils; public class BranchedUnfoldingUtils { private BranchedUnfoldingUtils() { diff --git a/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/FoldableKind.java b/idea/src/org/jetbrains/jet/plugin/intentions/branchedTransformations/FoldableKind.java similarity index 93% rename from idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/FoldableKind.java rename to idea/src/org/jetbrains/jet/plugin/intentions/branchedTransformations/FoldableKind.java index 4207d42ea51..7f3d8531209 100644 --- a/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/FoldableKind.java +++ b/idea/src/org/jetbrains/jet/plugin/intentions/branchedTransformations/FoldableKind.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.jetbrains.jet.plugin.codeInsight.codeTransformations.branchedTransformations; +package org.jetbrains.jet.plugin.intentions.branchedTransformations; import com.intellij.openapi.editor.Editor; import com.intellij.psi.PsiElement; @@ -22,7 +22,7 @@ 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.Transformer; +import org.jetbrains.jet.plugin.intentions.Transformer; public enum FoldableKind implements Transformer { IF_TO_ASSIGNMENT("fold.if.to.assignment") { diff --git a/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/IfWhenUtils.java b/idea/src/org/jetbrains/jet/plugin/intentions/branchedTransformations/IfWhenUtils.java similarity index 98% rename from idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/IfWhenUtils.java rename to idea/src/org/jetbrains/jet/plugin/intentions/branchedTransformations/IfWhenUtils.java index b0a9ec4aa07..d13b1727371 100644 --- a/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/IfWhenUtils.java +++ b/idea/src/org/jetbrains/jet/plugin/intentions/branchedTransformations/IfWhenUtils.java @@ -1,4 +1,4 @@ -package org.jetbrains.jet.plugin.codeInsight.codeTransformations.branchedTransformations; +package org.jetbrains.jet.plugin.intentions.branchedTransformations; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; diff --git a/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/UnfoldableKind.java b/idea/src/org/jetbrains/jet/plugin/intentions/branchedTransformations/UnfoldableKind.java similarity index 94% rename from idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/UnfoldableKind.java rename to idea/src/org/jetbrains/jet/plugin/intentions/branchedTransformations/UnfoldableKind.java index bb14756bafb..9c99d7eb807 100644 --- a/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/UnfoldableKind.java +++ b/idea/src/org/jetbrains/jet/plugin/intentions/branchedTransformations/UnfoldableKind.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.jetbrains.jet.plugin.codeInsight.codeTransformations.branchedTransformations; +package org.jetbrains.jet.plugin.intentions.branchedTransformations; import com.intellij.openapi.editor.Editor; import com.intellij.psi.PsiElement; @@ -23,7 +23,7 @@ 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.Transformer; +import org.jetbrains.jet.plugin.intentions.Transformer; public enum UnfoldableKind implements Transformer { ASSIGNMENT_TO_IF("unfold.assignment.to.if") { diff --git a/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/WhenUtils.java b/idea/src/org/jetbrains/jet/plugin/intentions/branchedTransformations/WhenUtils.java similarity index 99% rename from idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/WhenUtils.java rename to idea/src/org/jetbrains/jet/plugin/intentions/branchedTransformations/WhenUtils.java index 53bea0419bc..08ddc198924 100644 --- a/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/WhenUtils.java +++ b/idea/src/org/jetbrains/jet/plugin/intentions/branchedTransformations/WhenUtils.java @@ -1,4 +1,4 @@ -package org.jetbrains.jet.plugin.codeInsight.codeTransformations.branchedTransformations; +package org.jetbrains.jet.plugin.intentions.branchedTransformations; import com.intellij.psi.tree.IElementType; import org.jetbrains.annotations.NotNull; diff --git a/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/intentions/EliminateWhenSubjectIntention.java b/idea/src/org/jetbrains/jet/plugin/intentions/branchedTransformations/intentions/EliminateWhenSubjectIntention.java similarity index 76% rename from idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/intentions/EliminateWhenSubjectIntention.java rename to idea/src/org/jetbrains/jet/plugin/intentions/branchedTransformations/intentions/EliminateWhenSubjectIntention.java index 06113ada000..84b31f0a872 100644 --- a/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/intentions/EliminateWhenSubjectIntention.java +++ b/idea/src/org/jetbrains/jet/plugin/intentions/branchedTransformations/intentions/EliminateWhenSubjectIntention.java @@ -1,4 +1,4 @@ -package org.jetbrains.jet.plugin.codeInsight.codeTransformations.branchedTransformations.intentions; +package org.jetbrains.jet.plugin.intentions.branchedTransformations.intentions; import com.google.common.base.Predicate; import com.intellij.openapi.editor.Editor; @@ -7,9 +7,9 @@ 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.AbstractCodeTransformationIntention; -import org.jetbrains.jet.plugin.codeInsight.codeTransformations.branchedTransformations.WhenUtils; -import org.jetbrains.jet.plugin.codeInsight.codeTransformations.Transformer; +import org.jetbrains.jet.plugin.intentions.AbstractCodeTransformationIntention; +import org.jetbrains.jet.plugin.intentions.branchedTransformations.WhenUtils; +import org.jetbrains.jet.plugin.intentions.Transformer; public class EliminateWhenSubjectIntention extends AbstractCodeTransformationIntention { private static final Transformer TRANSFORMER = new Transformer() { diff --git a/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/intentions/FlattenWhenIntention.java b/idea/src/org/jetbrains/jet/plugin/intentions/branchedTransformations/intentions/FlattenWhenIntention.java similarity index 75% rename from idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/intentions/FlattenWhenIntention.java rename to idea/src/org/jetbrains/jet/plugin/intentions/branchedTransformations/intentions/FlattenWhenIntention.java index f687d649bfd..4dc17519b5b 100644 --- a/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/intentions/FlattenWhenIntention.java +++ b/idea/src/org/jetbrains/jet/plugin/intentions/branchedTransformations/intentions/FlattenWhenIntention.java @@ -1,4 +1,4 @@ -package org.jetbrains.jet.plugin.codeInsight.codeTransformations.branchedTransformations.intentions; +package org.jetbrains.jet.plugin.intentions.branchedTransformations.intentions; import com.google.common.base.Predicate; import com.intellij.openapi.editor.Editor; @@ -7,9 +7,9 @@ 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.AbstractCodeTransformationIntention; -import org.jetbrains.jet.plugin.codeInsight.codeTransformations.branchedTransformations.WhenUtils; -import org.jetbrains.jet.plugin.codeInsight.codeTransformations.Transformer; +import org.jetbrains.jet.plugin.intentions.AbstractCodeTransformationIntention; +import org.jetbrains.jet.plugin.intentions.branchedTransformations.WhenUtils; +import org.jetbrains.jet.plugin.intentions.Transformer; public class FlattenWhenIntention extends AbstractCodeTransformationIntention { private static final Transformer TRANSFORMER = new Transformer() { diff --git a/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/intentions/FoldBranchedExpressionIntention.java b/idea/src/org/jetbrains/jet/plugin/intentions/branchedTransformations/intentions/FoldBranchedExpressionIntention.java similarity index 85% rename from idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/intentions/FoldBranchedExpressionIntention.java rename to idea/src/org/jetbrains/jet/plugin/intentions/branchedTransformations/intentions/FoldBranchedExpressionIntention.java index c0328548790..152ae94e32b 100644 --- a/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/intentions/FoldBranchedExpressionIntention.java +++ b/idea/src/org/jetbrains/jet/plugin/intentions/branchedTransformations/intentions/FoldBranchedExpressionIntention.java @@ -14,16 +14,16 @@ * limitations under the License. */ -package org.jetbrains.jet.plugin.codeInsight.codeTransformations.branchedTransformations.intentions; +package org.jetbrains.jet.plugin.intentions.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.AbstractCodeTransformationIntention; -import org.jetbrains.jet.plugin.codeInsight.codeTransformations.branchedTransformations.BranchedFoldingUtils; -import org.jetbrains.jet.plugin.codeInsight.codeTransformations.branchedTransformations.FoldableKind; +import org.jetbrains.jet.plugin.intentions.AbstractCodeTransformationIntention; +import org.jetbrains.jet.plugin.intentions.branchedTransformations.BranchedFoldingUtils; +import org.jetbrains.jet.plugin.intentions.branchedTransformations.FoldableKind; public abstract class FoldBranchedExpressionIntention extends AbstractCodeTransformationIntention { protected FoldBranchedExpressionIntention(@NotNull final FoldableKind foldableKind) { diff --git a/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/intentions/IfToWhenIntention.java b/idea/src/org/jetbrains/jet/plugin/intentions/branchedTransformations/intentions/IfToWhenIntention.java similarity index 75% rename from idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/intentions/IfToWhenIntention.java rename to idea/src/org/jetbrains/jet/plugin/intentions/branchedTransformations/intentions/IfToWhenIntention.java index df3b9cb712f..25ebc93c548 100644 --- a/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/intentions/IfToWhenIntention.java +++ b/idea/src/org/jetbrains/jet/plugin/intentions/branchedTransformations/intentions/IfToWhenIntention.java @@ -1,4 +1,4 @@ -package org.jetbrains.jet.plugin.codeInsight.codeTransformations.branchedTransformations.intentions; +package org.jetbrains.jet.plugin.intentions.branchedTransformations.intentions; import com.google.common.base.Predicate; import com.intellij.openapi.editor.Editor; @@ -7,9 +7,9 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.jet.lang.psi.JetFile; import org.jetbrains.jet.lang.psi.JetIfExpression; -import org.jetbrains.jet.plugin.codeInsight.codeTransformations.AbstractCodeTransformationIntention; -import org.jetbrains.jet.plugin.codeInsight.codeTransformations.branchedTransformations.IfWhenUtils; -import org.jetbrains.jet.plugin.codeInsight.codeTransformations.Transformer; +import org.jetbrains.jet.plugin.intentions.AbstractCodeTransformationIntention; +import org.jetbrains.jet.plugin.intentions.branchedTransformations.IfWhenUtils; +import org.jetbrains.jet.plugin.intentions.Transformer; public class IfToWhenIntention extends AbstractCodeTransformationIntention { private static final Transformer TRANSFORMER = new Transformer() { diff --git a/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/intentions/IntroduceWhenSubjectIntention.java b/idea/src/org/jetbrains/jet/plugin/intentions/branchedTransformations/intentions/IntroduceWhenSubjectIntention.java similarity index 76% rename from idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/intentions/IntroduceWhenSubjectIntention.java rename to idea/src/org/jetbrains/jet/plugin/intentions/branchedTransformations/intentions/IntroduceWhenSubjectIntention.java index 8ddadc2364e..96989b42600 100644 --- a/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/intentions/IntroduceWhenSubjectIntention.java +++ b/idea/src/org/jetbrains/jet/plugin/intentions/branchedTransformations/intentions/IntroduceWhenSubjectIntention.java @@ -1,4 +1,4 @@ -package org.jetbrains.jet.plugin.codeInsight.codeTransformations.branchedTransformations.intentions; +package org.jetbrains.jet.plugin.intentions.branchedTransformations.intentions; import com.google.common.base.Predicate; import com.intellij.openapi.editor.Editor; @@ -7,9 +7,9 @@ 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.AbstractCodeTransformationIntention; -import org.jetbrains.jet.plugin.codeInsight.codeTransformations.branchedTransformations.WhenUtils; -import org.jetbrains.jet.plugin.codeInsight.codeTransformations.Transformer; +import org.jetbrains.jet.plugin.intentions.AbstractCodeTransformationIntention; +import org.jetbrains.jet.plugin.intentions.branchedTransformations.WhenUtils; +import org.jetbrains.jet.plugin.intentions.Transformer; public class IntroduceWhenSubjectIntention extends AbstractCodeTransformationIntention { private static final Transformer TRANSFORMER = new Transformer() { diff --git a/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/intentions/UnfoldBranchedExpressionIntention.java b/idea/src/org/jetbrains/jet/plugin/intentions/branchedTransformations/intentions/UnfoldBranchedExpressionIntention.java similarity index 90% rename from idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/intentions/UnfoldBranchedExpressionIntention.java rename to idea/src/org/jetbrains/jet/plugin/intentions/branchedTransformations/intentions/UnfoldBranchedExpressionIntention.java index 45caf8e5583..d90c5f90378 100644 --- a/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/intentions/UnfoldBranchedExpressionIntention.java +++ b/idea/src/org/jetbrains/jet/plugin/intentions/branchedTransformations/intentions/UnfoldBranchedExpressionIntention.java @@ -14,15 +14,15 @@ * limitations under the License. */ -package org.jetbrains.jet.plugin.codeInsight.codeTransformations.branchedTransformations.intentions; +package org.jetbrains.jet.plugin.intentions.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.*; -import org.jetbrains.jet.plugin.codeInsight.codeTransformations.AbstractCodeTransformationIntention; +import org.jetbrains.jet.plugin.intentions.branchedTransformations.*; +import org.jetbrains.jet.plugin.intentions.AbstractCodeTransformationIntention; public abstract class UnfoldBranchedExpressionIntention extends AbstractCodeTransformationIntention { protected UnfoldBranchedExpressionIntention(@NotNull final UnfoldableKind unfoldableKind) { diff --git a/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/intentions/WhenToIfIntention.java b/idea/src/org/jetbrains/jet/plugin/intentions/branchedTransformations/intentions/WhenToIfIntention.java similarity index 82% rename from idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/intentions/WhenToIfIntention.java rename to idea/src/org/jetbrains/jet/plugin/intentions/branchedTransformations/intentions/WhenToIfIntention.java index c503d03f031..081b0588c92 100644 --- a/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/branchedTransformations/intentions/WhenToIfIntention.java +++ b/idea/src/org/jetbrains/jet/plugin/intentions/branchedTransformations/intentions/WhenToIfIntention.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.jetbrains.jet.plugin.codeInsight.codeTransformations.branchedTransformations.intentions; +package org.jetbrains.jet.plugin.intentions.branchedTransformations.intentions; import com.google.common.base.Predicate; import com.intellij.openapi.editor.Editor; @@ -23,9 +23,9 @@ 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.AbstractCodeTransformationIntention; -import org.jetbrains.jet.plugin.codeInsight.codeTransformations.branchedTransformations.IfWhenUtils; -import org.jetbrains.jet.plugin.codeInsight.codeTransformations.Transformer; +import org.jetbrains.jet.plugin.intentions.AbstractCodeTransformationIntention; +import org.jetbrains.jet.plugin.intentions.branchedTransformations.IfWhenUtils; +import org.jetbrains.jet.plugin.intentions.Transformer; public class WhenToIfIntention extends AbstractCodeTransformationIntention { private static final Transformer TRANSFORMER = new Transformer() { diff --git a/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/declarations/DeclarationUtils.java b/idea/src/org/jetbrains/jet/plugin/intentions/declarations/DeclarationUtils.java similarity index 98% rename from idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/declarations/DeclarationUtils.java rename to idea/src/org/jetbrains/jet/plugin/intentions/declarations/DeclarationUtils.java index c802625201b..f5356ab0649 100644 --- a/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/declarations/DeclarationUtils.java +++ b/idea/src/org/jetbrains/jet/plugin/intentions/declarations/DeclarationUtils.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.jetbrains.jet.plugin.codeInsight.codeTransformations.declarations; +package org.jetbrains.jet.plugin.intentions.declarations; import com.google.common.base.Predicate; import com.intellij.openapi.project.Project; diff --git a/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/declarations/JetDeclarationJoinLinesHandler.java b/idea/src/org/jetbrains/jet/plugin/intentions/declarations/JetDeclarationJoinLinesHandler.java similarity index 94% rename from idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/declarations/JetDeclarationJoinLinesHandler.java rename to idea/src/org/jetbrains/jet/plugin/intentions/declarations/JetDeclarationJoinLinesHandler.java index b5717a8d868..9513626474f 100644 --- a/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/declarations/JetDeclarationJoinLinesHandler.java +++ b/idea/src/org/jetbrains/jet/plugin/intentions/declarations/JetDeclarationJoinLinesHandler.java @@ -1,4 +1,4 @@ -package org.jetbrains.jet.plugin.codeInsight.codeTransformations.declarations; +package org.jetbrains.jet.plugin.intentions.declarations; import com.google.common.base.Predicate; import com.intellij.codeInsight.editorActions.JoinRawLinesHandlerDelegate; diff --git a/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/declarations/SplitPropertyDeclarationIntention.java b/idea/src/org/jetbrains/jet/plugin/intentions/declarations/SplitPropertyDeclarationIntention.java similarity index 87% rename from idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/declarations/SplitPropertyDeclarationIntention.java rename to idea/src/org/jetbrains/jet/plugin/intentions/declarations/SplitPropertyDeclarationIntention.java index 8d72546f57b..b582f6c9cd0 100644 --- a/idea/src/org/jetbrains/jet/plugin/codeInsight/codeTransformations/declarations/SplitPropertyDeclarationIntention.java +++ b/idea/src/org/jetbrains/jet/plugin/intentions/declarations/SplitPropertyDeclarationIntention.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.jetbrains.jet.plugin.codeInsight.codeTransformations.declarations; +package org.jetbrains.jet.plugin.intentions.declarations; import com.google.common.base.Predicate; import com.intellij.openapi.editor.Editor; @@ -23,8 +23,8 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.jet.lang.psi.JetFile; import org.jetbrains.jet.lang.psi.JetProperty; -import org.jetbrains.jet.plugin.codeInsight.codeTransformations.AbstractCodeTransformationIntention; -import org.jetbrains.jet.plugin.codeInsight.codeTransformations.Transformer; +import org.jetbrains.jet.plugin.intentions.AbstractCodeTransformationIntention; +import org.jetbrains.jet.plugin.intentions.Transformer; public class SplitPropertyDeclarationIntention extends AbstractCodeTransformationIntention { private static final Transformer TRANSFORMER = new Transformer() { diff --git a/idea/src/org/jetbrains/jet/plugin/codeInsight/ktSignature/DeleteSignatureAction.java b/idea/src/org/jetbrains/jet/plugin/ktSignature/DeleteSignatureAction.java similarity index 81% rename from idea/src/org/jetbrains/jet/plugin/codeInsight/ktSignature/DeleteSignatureAction.java rename to idea/src/org/jetbrains/jet/plugin/ktSignature/DeleteSignatureAction.java index 1c9390c255d..dc9df7b0b70 100644 --- a/idea/src/org/jetbrains/jet/plugin/codeInsight/ktSignature/DeleteSignatureAction.java +++ b/idea/src/org/jetbrains/jet/plugin/ktSignature/DeleteSignatureAction.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.jetbrains.jet.plugin.codeInsight.ktSignature; +package org.jetbrains.jet.plugin.ktSignature; import com.intellij.codeInsight.ExternalAnnotationsManager; import com.intellij.openapi.actionSystem.AnAction; @@ -26,15 +26,13 @@ import com.intellij.psi.PsiAnnotation; import com.intellij.psi.PsiModifierListOwner; import org.jetbrains.annotations.NotNull; -import static org.jetbrains.jet.plugin.codeInsight.ktSignature.KotlinSignatureUtil.*; - public class DeleteSignatureAction extends AnAction { private final PsiModifierListOwner annotationOwner; public DeleteSignatureAction(@NotNull PsiModifierListOwner elementInEditor) { super("Delete"); - this.annotationOwner = getAnnotationOwner(elementInEditor); - getTemplatePresentation().setVisible(isAnnotationEditable(elementInEditor)); + this.annotationOwner = KotlinSignatureUtil.getAnnotationOwner(elementInEditor); + getTemplatePresentation().setVisible(KotlinSignatureUtil.isAnnotationEditable(elementInEditor)); } @Override @@ -42,7 +40,7 @@ public class DeleteSignatureAction extends AnAction { final Project project = e.getProject(); assert project != null; - final PsiAnnotation annotation = findKotlinSignatureAnnotation(annotationOwner); + final PsiAnnotation annotation = KotlinSignatureUtil.findKotlinSignatureAnnotation(annotationOwner); assert annotation != null; if (annotation.getContainingFile() != annotationOwner.getContainingFile()) { @@ -50,7 +48,7 @@ public class DeleteSignatureAction extends AnAction { new WriteCommandAction(project) { @Override protected void run(Result result) throws Throwable { - ExternalAnnotationsManager.getInstance(project).deannotate(annotationOwner, KOTLIN_SIGNATURE_ANNOTATION); + ExternalAnnotationsManager.getInstance(project).deannotate(annotationOwner, KotlinSignatureUtil.KOTLIN_SIGNATURE_ANNOTATION); } }.execute(); } @@ -64,6 +62,6 @@ public class DeleteSignatureAction extends AnAction { } - refreshMarkers(project); + KotlinSignatureUtil.refreshMarkers(project); } } diff --git a/idea/src/org/jetbrains/jet/plugin/codeInsight/ktSignature/EditSignatureAction.java b/idea/src/org/jetbrains/jet/plugin/ktSignature/EditSignatureAction.java similarity index 85% rename from idea/src/org/jetbrains/jet/plugin/codeInsight/ktSignature/EditSignatureAction.java rename to idea/src/org/jetbrains/jet/plugin/ktSignature/EditSignatureAction.java index 578b7374ef6..e48c5627a56 100644 --- a/idea/src/org/jetbrains/jet/plugin/codeInsight/ktSignature/EditSignatureAction.java +++ b/idea/src/org/jetbrains/jet/plugin/ktSignature/EditSignatureAction.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.jetbrains.jet.plugin.codeInsight.ktSignature; +package org.jetbrains.jet.plugin.ktSignature; import com.intellij.codeInsight.navigation.NavigationUtil; import com.intellij.openapi.actionSystem.AnAction; @@ -30,13 +30,11 @@ import org.jetbrains.annotations.Nullable; import java.awt.*; -import static org.jetbrains.jet.plugin.codeInsight.ktSignature.KotlinSignatureUtil.*; - public class EditSignatureAction extends AnAction { private final PsiModifierListOwner elementInEditor; public EditSignatureAction(@NotNull PsiModifierListOwner elementInEditor) { - super(isAnnotationEditable(elementInEditor) ? "Edit" : "View"); + super(KotlinSignatureUtil.isAnnotationEditable(elementInEditor) ? "Edit" : "View"); this.elementInEditor = elementInEditor; } @@ -52,7 +50,7 @@ public class EditSignatureAction extends AnAction { } static void invokeEditSignature(@NotNull PsiElement elementInEditor, @NotNull Editor editor, @Nullable Point point) { - PsiAnnotation annotation = findKotlinSignatureAnnotation(elementInEditor); + PsiAnnotation annotation = KotlinSignatureUtil.findKotlinSignatureAnnotation(elementInEditor); assert annotation != null; if (annotation.getContainingFile() == elementInEditor.getContainingFile()) { // not external, go to @@ -75,9 +73,9 @@ public class EditSignatureAction extends AnAction { } } else { - PsiModifierListOwner annotationOwner = getAnnotationOwner(elementInEditor); - boolean editable = isAnnotationEditable(elementInEditor); - EditSignatureBalloon balloon = new EditSignatureBalloon(annotationOwner, getKotlinSignature(annotation), editable); + PsiModifierListOwner annotationOwner = KotlinSignatureUtil.getAnnotationOwner(elementInEditor); + boolean editable = KotlinSignatureUtil.isAnnotationEditable(elementInEditor); + EditSignatureBalloon balloon = new EditSignatureBalloon(annotationOwner, KotlinSignatureUtil.getKotlinSignature(annotation), editable); balloon.show(point, editor, elementInEditor); } } diff --git a/idea/src/org/jetbrains/jet/plugin/codeInsight/ktSignature/EditSignatureBalloon.java b/idea/src/org/jetbrains/jet/plugin/ktSignature/EditSignatureBalloon.java similarity index 95% rename from idea/src/org/jetbrains/jet/plugin/codeInsight/ktSignature/EditSignatureBalloon.java rename to idea/src/org/jetbrains/jet/plugin/ktSignature/EditSignatureBalloon.java index 52e3ed00f2b..1366643086c 100644 --- a/idea/src/org/jetbrains/jet/plugin/codeInsight/ktSignature/EditSignatureBalloon.java +++ b/idea/src/org/jetbrains/jet/plugin/ktSignature/EditSignatureBalloon.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.jetbrains.jet.plugin.codeInsight.ktSignature; +package org.jetbrains.jet.plugin.ktSignature; import com.intellij.codeInsight.ExternalAnnotationsManager; import com.intellij.openapi.Disposable; @@ -54,9 +54,6 @@ import java.awt.event.ActionListener; import java.awt.event.InputEvent; import java.awt.event.KeyEvent; -import static org.jetbrains.jet.plugin.codeInsight.ktSignature.KotlinSignatureUtil.KOTLIN_SIGNATURE_ANNOTATION; -import static org.jetbrains.jet.plugin.codeInsight.ktSignature.KotlinSignatureUtil.signatureToNameValuePairs; - class EditSignatureBalloon implements Disposable { private final Editor editor; private final PsiModifierListOwner annotatedElement; @@ -179,7 +176,8 @@ class EditSignatureBalloon implements Disposable { @Override protected void run(Result result) throws Throwable { ExternalAnnotationsManager.getInstance(project).editExternalAnnotation( - annotatedElement, KOTLIN_SIGNATURE_ANNOTATION, signatureToNameValuePairs(project, newSignature)); + annotatedElement, KotlinSignatureUtil.KOTLIN_SIGNATURE_ANNOTATION, KotlinSignatureUtil + .signatureToNameValuePairs(project, newSignature)); } }.execute(); } diff --git a/idea/src/org/jetbrains/jet/plugin/codeInsight/ktSignature/KotlinSignatureAnnotationIntention.java b/idea/src/org/jetbrains/jet/plugin/ktSignature/KotlinSignatureAnnotationIntention.java similarity index 93% rename from idea/src/org/jetbrains/jet/plugin/codeInsight/ktSignature/KotlinSignatureAnnotationIntention.java rename to idea/src/org/jetbrains/jet/plugin/ktSignature/KotlinSignatureAnnotationIntention.java index 05789d76979..7de28e34a82 100644 --- a/idea/src/org/jetbrains/jet/plugin/codeInsight/ktSignature/KotlinSignatureAnnotationIntention.java +++ b/idea/src/org/jetbrains/jet/plugin/ktSignature/KotlinSignatureAnnotationIntention.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.jetbrains.jet.plugin.codeInsight.ktSignature; +package org.jetbrains.jet.plugin.ktSignature; import com.intellij.codeInsight.ExternalAnnotationsListener; import com.intellij.codeInsight.ExternalAnnotationsManager; @@ -47,8 +47,6 @@ import org.jetbrains.jet.renderer.DescriptorRendererBuilder; import javax.swing.*; -import static org.jetbrains.jet.plugin.codeInsight.ktSignature.KotlinSignatureUtil.*; - public class KotlinSignatureAnnotationIntention extends BaseIntentionAction implements Iconable { private static final DescriptorRenderer RENDERER = new DescriptorRendererBuilder() .setShortNames(true) @@ -80,8 +78,8 @@ public class KotlinSignatureAnnotationIntention extends BaseIntentionAction impl if (!PsiUtil.isLanguageLevel5OrHigher(annotationOwner)) return false; - if (findKotlinSignatureAnnotation(annotationOwner) != null) { - if (isAnnotationEditable(annotationOwner)) { + if (KotlinSignatureUtil.findKotlinSignatureAnnotation(annotationOwner) != null) { + if (KotlinSignatureUtil.isAnnotationEditable(annotationOwner)) { setText(JetBundle.message("edit.kotlin.signature.action.text")); } else { @@ -100,7 +98,7 @@ public class KotlinSignatureAnnotationIntention extends BaseIntentionAction impl assert annotatedElement != null; - if (findKotlinSignatureAnnotation(annotatedElement) != null) { + if (KotlinSignatureUtil.findKotlinSignatureAnnotation(annotatedElement) != null) { EditSignatureAction.invokeEditSignature(annotatedElement, editor, null); return; } @@ -113,11 +111,11 @@ public class KotlinSignatureAnnotationIntention extends BaseIntentionAction impl public void afterExternalAnnotationChanging(@NotNull PsiModifierListOwner owner, @NotNull String annotationFQName, boolean successful) { busConnection.disconnect(); - if (successful && owner == annotatedElement && KOTLIN_SIGNATURE_ANNOTATION.equals(annotationFQName)) { + if (successful && owner == annotatedElement && KotlinSignatureUtil.KOTLIN_SIGNATURE_ANNOTATION.equals(annotationFQName)) { ApplicationManager.getApplication().invokeLater(new Runnable() { @Override public void run() { - refreshMarkers(project); + KotlinSignatureUtil.refreshMarkers(project); EditSignatureAction.invokeEditSignature(annotatedElement, editor, null); } }, ModalityState.NON_MODAL); @@ -126,7 +124,8 @@ public class KotlinSignatureAnnotationIntention extends BaseIntentionAction impl }); AddAnnotationFix addAnnotationFix = new AddAnnotationFix( - KOTLIN_SIGNATURE_ANNOTATION, annotatedElement, signatureToNameValuePairs(annotatedElement.getProject(), signature)); + KotlinSignatureUtil.KOTLIN_SIGNATURE_ANNOTATION, annotatedElement, KotlinSignatureUtil + .signatureToNameValuePairs(annotatedElement.getProject(), signature)); addAnnotationFix.invoke(project, editor, file); } diff --git a/idea/src/org/jetbrains/jet/plugin/codeInsight/ktSignature/KotlinSignatureInJavaMarkerProvider.java b/idea/src/org/jetbrains/jet/plugin/ktSignature/KotlinSignatureInJavaMarkerProvider.java similarity index 95% rename from idea/src/org/jetbrains/jet/plugin/codeInsight/ktSignature/KotlinSignatureInJavaMarkerProvider.java rename to idea/src/org/jetbrains/jet/plugin/ktSignature/KotlinSignatureInJavaMarkerProvider.java index bc1851e5744..7209e3a414d 100644 --- a/idea/src/org/jetbrains/jet/plugin/codeInsight/ktSignature/KotlinSignatureInJavaMarkerProvider.java +++ b/idea/src/org/jetbrains/jet/plugin/ktSignature/KotlinSignatureInJavaMarkerProvider.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.jetbrains.jet.plugin.codeInsight.ktSignature; +package org.jetbrains.jet.plugin.ktSignature; import com.intellij.codeHighlighting.Pass; import com.intellij.codeInsight.daemon.GutterIconNavigationHandler; @@ -53,8 +53,6 @@ import java.awt.event.MouseEvent; import java.util.Collection; import java.util.List; -import static org.jetbrains.jet.plugin.codeInsight.ktSignature.KotlinSignatureUtil.*; - public class KotlinSignatureInJavaMarkerProvider implements LineMarkerProvider { private static final String SHOW_MARKERS_PROPERTY = "kotlin.signature.markers.enabled"; @@ -104,7 +102,7 @@ public class KotlinSignatureInJavaMarkerProvider implements LineMarkerProvider { if (memberDescriptor == null) continue; List errors = trace.get(BindingContext.LOAD_FROM_JAVA_SIGNATURE_ERRORS, memberDescriptor); - boolean hasSignatureAnnotation = findKotlinSignatureAnnotation(element) != null; + boolean hasSignatureAnnotation = KotlinSignatureUtil.findKotlinSignatureAnnotation(element) != null; if (errors != null || hasSignatureAnnotation) { result.add(new MyLineMarkerInfo((PsiModifierListOwner) element, errors, hasSignatureAnnotation)); @@ -200,7 +198,7 @@ public class KotlinSignatureInJavaMarkerProvider implements LineMarkerProvider { memberScope.getProperties(name); } - PsiModifierListOwner annotationOwner = getAnnotationOwner(member); + PsiModifierListOwner annotationOwner = KotlinSignatureUtil.getAnnotationOwner(member); return trace.get(BindingContext.DECLARATION_TO_DESCRIPTOR, annotationOwner); } @@ -210,7 +208,7 @@ public class KotlinSignatureInJavaMarkerProvider implements LineMarkerProvider { public static void setMarkersEnabled(@NotNull Project project, boolean value) { PropertiesComponent.getInstance(project).setValue(SHOW_MARKERS_PROPERTY, Boolean.toString(value)); - refreshMarkers(project); + KotlinSignatureUtil.refreshMarkers(project); } private static class MyLineMarkerInfo extends LineMarkerInfo { @@ -245,11 +243,11 @@ public class KotlinSignatureInJavaMarkerProvider implements LineMarkerProvider { @Nullable @Override public String fun(PsiElement element) { - PsiAnnotation annotation = findKotlinSignatureAnnotation(element); + PsiAnnotation annotation = KotlinSignatureUtil.findKotlinSignatureAnnotation(element); if (annotation == null) return errorsString(); - String signature = getKotlinSignature(annotation); + String signature = KotlinSignatureUtil.getKotlinSignature(annotation); String text = "Alternative Kotlin signature is available for this method:\n" + StringUtil.escapeXml(signature); if (errors == null) { diff --git a/idea/src/org/jetbrains/jet/plugin/codeInsight/ktSignature/KotlinSignatureInJavaMarkerUpdater.java b/idea/src/org/jetbrains/jet/plugin/ktSignature/KotlinSignatureInJavaMarkerUpdater.java similarity index 95% rename from idea/src/org/jetbrains/jet/plugin/codeInsight/ktSignature/KotlinSignatureInJavaMarkerUpdater.java rename to idea/src/org/jetbrains/jet/plugin/ktSignature/KotlinSignatureInJavaMarkerUpdater.java index 2baee5fdde3..5365c21d448 100644 --- a/idea/src/org/jetbrains/jet/plugin/codeInsight/ktSignature/KotlinSignatureInJavaMarkerUpdater.java +++ b/idea/src/org/jetbrains/jet/plugin/ktSignature/KotlinSignatureInJavaMarkerUpdater.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.jetbrains.jet.plugin.codeInsight.ktSignature; +package org.jetbrains.jet.plugin.ktSignature; import com.intellij.codeInsight.ExternalAnnotationsListener; import com.intellij.codeInsight.ExternalAnnotationsManager; diff --git a/idea/src/org/jetbrains/jet/plugin/codeInsight/ktSignature/KotlinSignatureUtil.java b/idea/src/org/jetbrains/jet/plugin/ktSignature/KotlinSignatureUtil.java similarity index 98% rename from idea/src/org/jetbrains/jet/plugin/codeInsight/ktSignature/KotlinSignatureUtil.java rename to idea/src/org/jetbrains/jet/plugin/ktSignature/KotlinSignatureUtil.java index 65af5942ce2..2b1070fe8ac 100644 --- a/idea/src/org/jetbrains/jet/plugin/codeInsight/ktSignature/KotlinSignatureUtil.java +++ b/idea/src/org/jetbrains/jet/plugin/ktSignature/KotlinSignatureUtil.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.jetbrains.jet.plugin.codeInsight.ktSignature; +package org.jetbrains.jet.plugin.ktSignature; import com.intellij.codeInsight.ExternalAnnotationsManager; import com.intellij.codeInsight.daemon.DaemonCodeAnalyzer; diff --git a/idea/src/org/jetbrains/jet/plugin/codeInsight/ktSignature/ShowKotlinSignaturesAction.java b/idea/src/org/jetbrains/jet/plugin/ktSignature/ShowKotlinSignaturesAction.java similarity index 96% rename from idea/src/org/jetbrains/jet/plugin/codeInsight/ktSignature/ShowKotlinSignaturesAction.java rename to idea/src/org/jetbrains/jet/plugin/ktSignature/ShowKotlinSignaturesAction.java index 82d3f37b61a..acb3644f446 100644 --- a/idea/src/org/jetbrains/jet/plugin/codeInsight/ktSignature/ShowKotlinSignaturesAction.java +++ b/idea/src/org/jetbrains/jet/plugin/ktSignature/ShowKotlinSignaturesAction.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.jetbrains.jet.plugin.codeInsight.ktSignature; +package org.jetbrains.jet.plugin.ktSignature; import com.intellij.lang.java.JavaLanguage; import com.intellij.openapi.actionSystem.AnActionEvent; diff --git a/idea/testData/codeInsight/codeTransformations/branched/folding/ifToAssignment/innerIfTransformed.kt b/idea/testData/intentions/branched/folding/ifToAssignment/innerIfTransformed.kt similarity index 100% rename from idea/testData/codeInsight/codeTransformations/branched/folding/ifToAssignment/innerIfTransformed.kt rename to idea/testData/intentions/branched/folding/ifToAssignment/innerIfTransformed.kt diff --git a/idea/testData/codeInsight/codeTransformations/branched/folding/ifToAssignment/innerIfTransformed.kt.after b/idea/testData/intentions/branched/folding/ifToAssignment/innerIfTransformed.kt.after similarity index 100% rename from idea/testData/codeInsight/codeTransformations/branched/folding/ifToAssignment/innerIfTransformed.kt.after rename to idea/testData/intentions/branched/folding/ifToAssignment/innerIfTransformed.kt.after diff --git a/idea/testData/codeInsight/codeTransformations/branched/folding/ifToAssignment/simpleIf.kt b/idea/testData/intentions/branched/folding/ifToAssignment/simpleIf.kt similarity index 100% rename from idea/testData/codeInsight/codeTransformations/branched/folding/ifToAssignment/simpleIf.kt rename to idea/testData/intentions/branched/folding/ifToAssignment/simpleIf.kt diff --git a/idea/testData/codeInsight/codeTransformations/branched/folding/ifToAssignment/simpleIf.kt.after b/idea/testData/intentions/branched/folding/ifToAssignment/simpleIf.kt.after similarity index 100% rename from idea/testData/codeInsight/codeTransformations/branched/folding/ifToAssignment/simpleIf.kt.after rename to idea/testData/intentions/branched/folding/ifToAssignment/simpleIf.kt.after diff --git a/idea/testData/codeInsight/codeTransformations/branched/folding/ifToAssignment/simpleIfWithAugmentedAssignment.kt b/idea/testData/intentions/branched/folding/ifToAssignment/simpleIfWithAugmentedAssignment.kt similarity index 100% rename from idea/testData/codeInsight/codeTransformations/branched/folding/ifToAssignment/simpleIfWithAugmentedAssignment.kt rename to idea/testData/intentions/branched/folding/ifToAssignment/simpleIfWithAugmentedAssignment.kt diff --git a/idea/testData/codeInsight/codeTransformations/branched/folding/ifToAssignment/simpleIfWithAugmentedAssignment.kt.after b/idea/testData/intentions/branched/folding/ifToAssignment/simpleIfWithAugmentedAssignment.kt.after similarity index 100% rename from idea/testData/codeInsight/codeTransformations/branched/folding/ifToAssignment/simpleIfWithAugmentedAssignment.kt.after rename to idea/testData/intentions/branched/folding/ifToAssignment/simpleIfWithAugmentedAssignment.kt.after diff --git a/idea/testData/codeInsight/codeTransformations/branched/folding/ifToAssignment/simpleIfWithBlocks.kt b/idea/testData/intentions/branched/folding/ifToAssignment/simpleIfWithBlocks.kt similarity index 100% rename from idea/testData/codeInsight/codeTransformations/branched/folding/ifToAssignment/simpleIfWithBlocks.kt rename to idea/testData/intentions/branched/folding/ifToAssignment/simpleIfWithBlocks.kt diff --git a/idea/testData/codeInsight/codeTransformations/branched/folding/ifToAssignment/simpleIfWithBlocks.kt.after b/idea/testData/intentions/branched/folding/ifToAssignment/simpleIfWithBlocks.kt.after similarity index 100% rename from idea/testData/codeInsight/codeTransformations/branched/folding/ifToAssignment/simpleIfWithBlocks.kt.after rename to idea/testData/intentions/branched/folding/ifToAssignment/simpleIfWithBlocks.kt.after diff --git a/idea/testData/codeInsight/codeTransformations/branched/folding/ifToAssignment/simpleIfWithShadowedVar.kt b/idea/testData/intentions/branched/folding/ifToAssignment/simpleIfWithShadowedVar.kt similarity index 100% rename from idea/testData/codeInsight/codeTransformations/branched/folding/ifToAssignment/simpleIfWithShadowedVar.kt rename to idea/testData/intentions/branched/folding/ifToAssignment/simpleIfWithShadowedVar.kt diff --git a/idea/testData/codeInsight/codeTransformations/branched/folding/ifToAssignment/simpleIfWithUnmatchedAssignmentOps.kt b/idea/testData/intentions/branched/folding/ifToAssignment/simpleIfWithUnmatchedAssignmentOps.kt similarity index 100% rename from idea/testData/codeInsight/codeTransformations/branched/folding/ifToAssignment/simpleIfWithUnmatchedAssignmentOps.kt rename to idea/testData/intentions/branched/folding/ifToAssignment/simpleIfWithUnmatchedAssignmentOps.kt diff --git a/idea/testData/codeInsight/codeTransformations/branched/folding/ifToAssignment/simpleIfWithUnmatchedAssignments.kt b/idea/testData/intentions/branched/folding/ifToAssignment/simpleIfWithUnmatchedAssignments.kt similarity index 100% rename from idea/testData/codeInsight/codeTransformations/branched/folding/ifToAssignment/simpleIfWithUnmatchedAssignments.kt rename to idea/testData/intentions/branched/folding/ifToAssignment/simpleIfWithUnmatchedAssignments.kt diff --git a/idea/testData/codeInsight/codeTransformations/branched/folding/ifToAssignment/simpleIfWithoutElse.kt b/idea/testData/intentions/branched/folding/ifToAssignment/simpleIfWithoutElse.kt similarity index 100% rename from idea/testData/codeInsight/codeTransformations/branched/folding/ifToAssignment/simpleIfWithoutElse.kt rename to idea/testData/intentions/branched/folding/ifToAssignment/simpleIfWithoutElse.kt diff --git a/idea/testData/codeInsight/codeTransformations/branched/folding/ifToAssignment/simpleIfWithoutTerminatingAssignment.kt b/idea/testData/intentions/branched/folding/ifToAssignment/simpleIfWithoutTerminatingAssignment.kt similarity index 100% rename from idea/testData/codeInsight/codeTransformations/branched/folding/ifToAssignment/simpleIfWithoutTerminatingAssignment.kt rename to idea/testData/intentions/branched/folding/ifToAssignment/simpleIfWithoutTerminatingAssignment.kt diff --git a/idea/testData/codeInsight/codeTransformations/branched/folding/ifToReturn/innerIfTransformed.kt b/idea/testData/intentions/branched/folding/ifToReturn/innerIfTransformed.kt similarity index 100% rename from idea/testData/codeInsight/codeTransformations/branched/folding/ifToReturn/innerIfTransformed.kt rename to idea/testData/intentions/branched/folding/ifToReturn/innerIfTransformed.kt diff --git a/idea/testData/codeInsight/codeTransformations/branched/folding/ifToReturn/innerIfTransformed.kt.after b/idea/testData/intentions/branched/folding/ifToReturn/innerIfTransformed.kt.after similarity index 100% rename from idea/testData/codeInsight/codeTransformations/branched/folding/ifToReturn/innerIfTransformed.kt.after rename to idea/testData/intentions/branched/folding/ifToReturn/innerIfTransformed.kt.after diff --git a/idea/testData/codeInsight/codeTransformations/branched/folding/ifToReturn/simpleIf.kt b/idea/testData/intentions/branched/folding/ifToReturn/simpleIf.kt similarity index 100% rename from idea/testData/codeInsight/codeTransformations/branched/folding/ifToReturn/simpleIf.kt rename to idea/testData/intentions/branched/folding/ifToReturn/simpleIf.kt diff --git a/idea/testData/codeInsight/codeTransformations/branched/folding/ifToReturn/simpleIf.kt.after b/idea/testData/intentions/branched/folding/ifToReturn/simpleIf.kt.after similarity index 100% rename from idea/testData/codeInsight/codeTransformations/branched/folding/ifToReturn/simpleIf.kt.after rename to idea/testData/intentions/branched/folding/ifToReturn/simpleIf.kt.after diff --git a/idea/testData/codeInsight/codeTransformations/branched/folding/ifToReturn/simpleIfWithBlocks.kt b/idea/testData/intentions/branched/folding/ifToReturn/simpleIfWithBlocks.kt similarity index 100% rename from idea/testData/codeInsight/codeTransformations/branched/folding/ifToReturn/simpleIfWithBlocks.kt rename to idea/testData/intentions/branched/folding/ifToReturn/simpleIfWithBlocks.kt diff --git a/idea/testData/codeInsight/codeTransformations/branched/folding/ifToReturn/simpleIfWithBlocks.kt.after b/idea/testData/intentions/branched/folding/ifToReturn/simpleIfWithBlocks.kt.after similarity index 100% rename from idea/testData/codeInsight/codeTransformations/branched/folding/ifToReturn/simpleIfWithBlocks.kt.after rename to idea/testData/intentions/branched/folding/ifToReturn/simpleIfWithBlocks.kt.after diff --git a/idea/testData/codeInsight/codeTransformations/branched/folding/ifToReturnAsymmetrically/simpleIf.kt b/idea/testData/intentions/branched/folding/ifToReturnAsymmetrically/simpleIf.kt similarity index 100% rename from idea/testData/codeInsight/codeTransformations/branched/folding/ifToReturnAsymmetrically/simpleIf.kt rename to idea/testData/intentions/branched/folding/ifToReturnAsymmetrically/simpleIf.kt diff --git a/idea/testData/codeInsight/codeTransformations/branched/folding/ifToReturnAsymmetrically/simpleIf.kt.after b/idea/testData/intentions/branched/folding/ifToReturnAsymmetrically/simpleIf.kt.after similarity index 100% rename from idea/testData/codeInsight/codeTransformations/branched/folding/ifToReturnAsymmetrically/simpleIf.kt.after rename to idea/testData/intentions/branched/folding/ifToReturnAsymmetrically/simpleIf.kt.after diff --git a/idea/testData/codeInsight/codeTransformations/branched/folding/ifToReturnAsymmetrically/simpleIfWithBlocks.kt b/idea/testData/intentions/branched/folding/ifToReturnAsymmetrically/simpleIfWithBlocks.kt similarity index 100% rename from idea/testData/codeInsight/codeTransformations/branched/folding/ifToReturnAsymmetrically/simpleIfWithBlocks.kt rename to idea/testData/intentions/branched/folding/ifToReturnAsymmetrically/simpleIfWithBlocks.kt diff --git a/idea/testData/codeInsight/codeTransformations/branched/folding/ifToReturnAsymmetrically/simpleIfWithBlocks.kt.after b/idea/testData/intentions/branched/folding/ifToReturnAsymmetrically/simpleIfWithBlocks.kt.after similarity index 100% rename from idea/testData/codeInsight/codeTransformations/branched/folding/ifToReturnAsymmetrically/simpleIfWithBlocks.kt.after rename to idea/testData/intentions/branched/folding/ifToReturnAsymmetrically/simpleIfWithBlocks.kt.after diff --git a/idea/testData/codeInsight/codeTransformations/branched/folding/ifToReturnAsymmetrically/simpleIfWithComments.kt b/idea/testData/intentions/branched/folding/ifToReturnAsymmetrically/simpleIfWithComments.kt similarity index 100% rename from idea/testData/codeInsight/codeTransformations/branched/folding/ifToReturnAsymmetrically/simpleIfWithComments.kt rename to idea/testData/intentions/branched/folding/ifToReturnAsymmetrically/simpleIfWithComments.kt diff --git a/idea/testData/codeInsight/codeTransformations/branched/folding/ifToReturnAsymmetrically/simpleIfWithComments.kt.after b/idea/testData/intentions/branched/folding/ifToReturnAsymmetrically/simpleIfWithComments.kt.after similarity index 100% rename from idea/testData/codeInsight/codeTransformations/branched/folding/ifToReturnAsymmetrically/simpleIfWithComments.kt.after rename to idea/testData/intentions/branched/folding/ifToReturnAsymmetrically/simpleIfWithComments.kt.after diff --git a/idea/testData/codeInsight/codeTransformations/branched/folding/whenToAssignment/innerWhenTransformed.kt b/idea/testData/intentions/branched/folding/whenToAssignment/innerWhenTransformed.kt similarity index 100% rename from idea/testData/codeInsight/codeTransformations/branched/folding/whenToAssignment/innerWhenTransformed.kt rename to idea/testData/intentions/branched/folding/whenToAssignment/innerWhenTransformed.kt diff --git a/idea/testData/codeInsight/codeTransformations/branched/folding/whenToAssignment/innerWhenTransformed.kt.after b/idea/testData/intentions/branched/folding/whenToAssignment/innerWhenTransformed.kt.after similarity index 100% rename from idea/testData/codeInsight/codeTransformations/branched/folding/whenToAssignment/innerWhenTransformed.kt.after rename to idea/testData/intentions/branched/folding/whenToAssignment/innerWhenTransformed.kt.after diff --git a/idea/testData/codeInsight/codeTransformations/branched/folding/whenToAssignment/simpleWhen.kt b/idea/testData/intentions/branched/folding/whenToAssignment/simpleWhen.kt similarity index 100% rename from idea/testData/codeInsight/codeTransformations/branched/folding/whenToAssignment/simpleWhen.kt rename to idea/testData/intentions/branched/folding/whenToAssignment/simpleWhen.kt diff --git a/idea/testData/codeInsight/codeTransformations/branched/folding/whenToAssignment/simpleWhen.kt.after b/idea/testData/intentions/branched/folding/whenToAssignment/simpleWhen.kt.after similarity index 100% rename from idea/testData/codeInsight/codeTransformations/branched/folding/whenToAssignment/simpleWhen.kt.after rename to idea/testData/intentions/branched/folding/whenToAssignment/simpleWhen.kt.after diff --git a/idea/testData/codeInsight/codeTransformations/branched/folding/whenToAssignment/simpleWhenWithBlocks.kt b/idea/testData/intentions/branched/folding/whenToAssignment/simpleWhenWithBlocks.kt similarity index 100% rename from idea/testData/codeInsight/codeTransformations/branched/folding/whenToAssignment/simpleWhenWithBlocks.kt rename to idea/testData/intentions/branched/folding/whenToAssignment/simpleWhenWithBlocks.kt diff --git a/idea/testData/codeInsight/codeTransformations/branched/folding/whenToAssignment/simpleWhenWithBlocks.kt.after b/idea/testData/intentions/branched/folding/whenToAssignment/simpleWhenWithBlocks.kt.after similarity index 100% rename from idea/testData/codeInsight/codeTransformations/branched/folding/whenToAssignment/simpleWhenWithBlocks.kt.after rename to idea/testData/intentions/branched/folding/whenToAssignment/simpleWhenWithBlocks.kt.after diff --git a/idea/testData/codeInsight/codeTransformations/branched/folding/whenToAssignment/simpleWhenWithShadowedVar.kt b/idea/testData/intentions/branched/folding/whenToAssignment/simpleWhenWithShadowedVar.kt similarity index 100% rename from idea/testData/codeInsight/codeTransformations/branched/folding/whenToAssignment/simpleWhenWithShadowedVar.kt rename to idea/testData/intentions/branched/folding/whenToAssignment/simpleWhenWithShadowedVar.kt diff --git a/idea/testData/codeInsight/codeTransformations/branched/folding/whenToAssignment/simpleWhenWithUnmatchedAssignments.kt b/idea/testData/intentions/branched/folding/whenToAssignment/simpleWhenWithUnmatchedAssignments.kt similarity index 100% rename from idea/testData/codeInsight/codeTransformations/branched/folding/whenToAssignment/simpleWhenWithUnmatchedAssignments.kt rename to idea/testData/intentions/branched/folding/whenToAssignment/simpleWhenWithUnmatchedAssignments.kt diff --git a/idea/testData/codeInsight/codeTransformations/branched/folding/whenToAssignment/simpleWhenWithoutTerminatingAssignment.kt b/idea/testData/intentions/branched/folding/whenToAssignment/simpleWhenWithoutTerminatingAssignment.kt similarity index 100% rename from idea/testData/codeInsight/codeTransformations/branched/folding/whenToAssignment/simpleWhenWithoutTerminatingAssignment.kt rename to idea/testData/intentions/branched/folding/whenToAssignment/simpleWhenWithoutTerminatingAssignment.kt diff --git a/idea/testData/codeInsight/codeTransformations/branched/folding/whenToReturn/innerWhenTransformed.kt b/idea/testData/intentions/branched/folding/whenToReturn/innerWhenTransformed.kt similarity index 100% rename from idea/testData/codeInsight/codeTransformations/branched/folding/whenToReturn/innerWhenTransformed.kt rename to idea/testData/intentions/branched/folding/whenToReturn/innerWhenTransformed.kt diff --git a/idea/testData/codeInsight/codeTransformations/branched/folding/whenToReturn/innerWhenTransformed.kt.after b/idea/testData/intentions/branched/folding/whenToReturn/innerWhenTransformed.kt.after similarity index 100% rename from idea/testData/codeInsight/codeTransformations/branched/folding/whenToReturn/innerWhenTransformed.kt.after rename to idea/testData/intentions/branched/folding/whenToReturn/innerWhenTransformed.kt.after diff --git a/idea/testData/codeInsight/codeTransformations/branched/folding/whenToReturn/simpleWhen.kt b/idea/testData/intentions/branched/folding/whenToReturn/simpleWhen.kt similarity index 100% rename from idea/testData/codeInsight/codeTransformations/branched/folding/whenToReturn/simpleWhen.kt rename to idea/testData/intentions/branched/folding/whenToReturn/simpleWhen.kt diff --git a/idea/testData/codeInsight/codeTransformations/branched/folding/whenToReturn/simpleWhen.kt.after b/idea/testData/intentions/branched/folding/whenToReturn/simpleWhen.kt.after similarity index 100% rename from idea/testData/codeInsight/codeTransformations/branched/folding/whenToReturn/simpleWhen.kt.after rename to idea/testData/intentions/branched/folding/whenToReturn/simpleWhen.kt.after diff --git a/idea/testData/codeInsight/codeTransformations/branched/folding/whenToReturn/simpleWhenWithBlocks.kt b/idea/testData/intentions/branched/folding/whenToReturn/simpleWhenWithBlocks.kt similarity index 100% rename from idea/testData/codeInsight/codeTransformations/branched/folding/whenToReturn/simpleWhenWithBlocks.kt rename to idea/testData/intentions/branched/folding/whenToReturn/simpleWhenWithBlocks.kt diff --git a/idea/testData/codeInsight/codeTransformations/branched/folding/whenToReturn/simpleWhenWithBlocks.kt.after b/idea/testData/intentions/branched/folding/whenToReturn/simpleWhenWithBlocks.kt.after similarity index 100% rename from idea/testData/codeInsight/codeTransformations/branched/folding/whenToReturn/simpleWhenWithBlocks.kt.after rename to idea/testData/intentions/branched/folding/whenToReturn/simpleWhenWithBlocks.kt.after diff --git a/idea/testData/codeInsight/codeTransformations/branched/ifWhen/ifToWhen/ifWithEqualityTests.kt b/idea/testData/intentions/branched/ifWhen/ifToWhen/ifWithEqualityTests.kt similarity index 100% rename from idea/testData/codeInsight/codeTransformations/branched/ifWhen/ifToWhen/ifWithEqualityTests.kt rename to idea/testData/intentions/branched/ifWhen/ifToWhen/ifWithEqualityTests.kt diff --git a/idea/testData/codeInsight/codeTransformations/branched/ifWhen/ifToWhen/ifWithEqualityTests.kt.after b/idea/testData/intentions/branched/ifWhen/ifToWhen/ifWithEqualityTests.kt.after similarity index 100% rename from idea/testData/codeInsight/codeTransformations/branched/ifWhen/ifToWhen/ifWithEqualityTests.kt.after rename to idea/testData/intentions/branched/ifWhen/ifToWhen/ifWithEqualityTests.kt.after diff --git a/idea/testData/codeInsight/codeTransformations/branched/ifWhen/ifToWhen/ifWithIs.kt b/idea/testData/intentions/branched/ifWhen/ifToWhen/ifWithIs.kt similarity index 100% rename from idea/testData/codeInsight/codeTransformations/branched/ifWhen/ifToWhen/ifWithIs.kt rename to idea/testData/intentions/branched/ifWhen/ifToWhen/ifWithIs.kt diff --git a/idea/testData/codeInsight/codeTransformations/branched/ifWhen/ifToWhen/ifWithIs.kt.after b/idea/testData/intentions/branched/ifWhen/ifToWhen/ifWithIs.kt.after similarity index 100% rename from idea/testData/codeInsight/codeTransformations/branched/ifWhen/ifToWhen/ifWithIs.kt.after rename to idea/testData/intentions/branched/ifWhen/ifToWhen/ifWithIs.kt.after diff --git a/idea/testData/codeInsight/codeTransformations/branched/ifWhen/ifToWhen/ifWithMultiConditions.kt b/idea/testData/intentions/branched/ifWhen/ifToWhen/ifWithMultiConditions.kt similarity index 100% rename from idea/testData/codeInsight/codeTransformations/branched/ifWhen/ifToWhen/ifWithMultiConditions.kt rename to idea/testData/intentions/branched/ifWhen/ifToWhen/ifWithMultiConditions.kt diff --git a/idea/testData/codeInsight/codeTransformations/branched/ifWhen/ifToWhen/ifWithMultiConditions.kt.after b/idea/testData/intentions/branched/ifWhen/ifToWhen/ifWithMultiConditions.kt.after similarity index 100% rename from idea/testData/codeInsight/codeTransformations/branched/ifWhen/ifToWhen/ifWithMultiConditions.kt.after rename to idea/testData/intentions/branched/ifWhen/ifToWhen/ifWithMultiConditions.kt.after diff --git a/idea/testData/codeInsight/codeTransformations/branched/ifWhen/ifToWhen/ifWithNegativeIs.kt b/idea/testData/intentions/branched/ifWhen/ifToWhen/ifWithNegativeIs.kt similarity index 100% rename from idea/testData/codeInsight/codeTransformations/branched/ifWhen/ifToWhen/ifWithNegativeIs.kt rename to idea/testData/intentions/branched/ifWhen/ifToWhen/ifWithNegativeIs.kt diff --git a/idea/testData/codeInsight/codeTransformations/branched/ifWhen/ifToWhen/ifWithNegativeIs.kt.after b/idea/testData/intentions/branched/ifWhen/ifToWhen/ifWithNegativeIs.kt.after similarity index 100% rename from idea/testData/codeInsight/codeTransformations/branched/ifWhen/ifToWhen/ifWithNegativeIs.kt.after rename to idea/testData/intentions/branched/ifWhen/ifToWhen/ifWithNegativeIs.kt.after diff --git a/idea/testData/codeInsight/codeTransformations/branched/ifWhen/ifToWhen/ifWithNegativeRangeTests.kt b/idea/testData/intentions/branched/ifWhen/ifToWhen/ifWithNegativeRangeTests.kt similarity index 100% rename from idea/testData/codeInsight/codeTransformations/branched/ifWhen/ifToWhen/ifWithNegativeRangeTests.kt rename to idea/testData/intentions/branched/ifWhen/ifToWhen/ifWithNegativeRangeTests.kt diff --git a/idea/testData/codeInsight/codeTransformations/branched/ifWhen/ifToWhen/ifWithNegativeRangeTests.kt.after b/idea/testData/intentions/branched/ifWhen/ifToWhen/ifWithNegativeRangeTests.kt.after similarity index 100% rename from idea/testData/codeInsight/codeTransformations/branched/ifWhen/ifToWhen/ifWithNegativeRangeTests.kt.after rename to idea/testData/intentions/branched/ifWhen/ifToWhen/ifWithNegativeRangeTests.kt.after diff --git a/idea/testData/codeInsight/codeTransformations/branched/ifWhen/ifToWhen/ifWithRangeTests.kt b/idea/testData/intentions/branched/ifWhen/ifToWhen/ifWithRangeTests.kt similarity index 100% rename from idea/testData/codeInsight/codeTransformations/branched/ifWhen/ifToWhen/ifWithRangeTests.kt rename to idea/testData/intentions/branched/ifWhen/ifToWhen/ifWithRangeTests.kt diff --git a/idea/testData/codeInsight/codeTransformations/branched/ifWhen/ifToWhen/ifWithRangeTests.kt.after b/idea/testData/intentions/branched/ifWhen/ifToWhen/ifWithRangeTests.kt.after similarity index 100% rename from idea/testData/codeInsight/codeTransformations/branched/ifWhen/ifToWhen/ifWithRangeTests.kt.after rename to idea/testData/intentions/branched/ifWhen/ifToWhen/ifWithRangeTests.kt.after diff --git a/idea/testData/codeInsight/codeTransformations/branched/ifWhen/ifToWhen/ifWithRangeTestsAndMultiConditions.kt b/idea/testData/intentions/branched/ifWhen/ifToWhen/ifWithRangeTestsAndMultiConditions.kt similarity index 100% rename from idea/testData/codeInsight/codeTransformations/branched/ifWhen/ifToWhen/ifWithRangeTestsAndMultiConditions.kt rename to idea/testData/intentions/branched/ifWhen/ifToWhen/ifWithRangeTestsAndMultiConditions.kt diff --git a/idea/testData/codeInsight/codeTransformations/branched/ifWhen/ifToWhen/ifWithRangeTestsAndMultiConditions.kt.after b/idea/testData/intentions/branched/ifWhen/ifToWhen/ifWithRangeTestsAndMultiConditions.kt.after similarity index 100% rename from idea/testData/codeInsight/codeTransformations/branched/ifWhen/ifToWhen/ifWithRangeTestsAndMultiConditions.kt.after rename to idea/testData/intentions/branched/ifWhen/ifToWhen/ifWithRangeTestsAndMultiConditions.kt.after diff --git a/idea/testData/codeInsight/codeTransformations/branched/ifWhen/ifToWhen/ifWithRangeTestsAndUnparenthesizedMultiConditions.kt b/idea/testData/intentions/branched/ifWhen/ifToWhen/ifWithRangeTestsAndUnparenthesizedMultiConditions.kt similarity index 100% rename from idea/testData/codeInsight/codeTransformations/branched/ifWhen/ifToWhen/ifWithRangeTestsAndUnparenthesizedMultiConditions.kt rename to idea/testData/intentions/branched/ifWhen/ifToWhen/ifWithRangeTestsAndUnparenthesizedMultiConditions.kt diff --git a/idea/testData/codeInsight/codeTransformations/branched/ifWhen/ifToWhen/ifWithRangeTestsAndUnparenthesizedMultiConditions.kt.after b/idea/testData/intentions/branched/ifWhen/ifToWhen/ifWithRangeTestsAndUnparenthesizedMultiConditions.kt.after similarity index 100% rename from idea/testData/codeInsight/codeTransformations/branched/ifWhen/ifToWhen/ifWithRangeTestsAndUnparenthesizedMultiConditions.kt.after rename to idea/testData/intentions/branched/ifWhen/ifToWhen/ifWithRangeTestsAndUnparenthesizedMultiConditions.kt.after diff --git a/idea/testData/codeInsight/codeTransformations/branched/ifWhen/ifToWhen/whenWithMultipleConditionTypes.kt b/idea/testData/intentions/branched/ifWhen/ifToWhen/whenWithMultipleConditionTypes.kt similarity index 100% rename from idea/testData/codeInsight/codeTransformations/branched/ifWhen/ifToWhen/whenWithMultipleConditionTypes.kt rename to idea/testData/intentions/branched/ifWhen/ifToWhen/whenWithMultipleConditionTypes.kt diff --git a/idea/testData/codeInsight/codeTransformations/branched/ifWhen/ifToWhen/whenWithMultipleConditionTypes.kt.after b/idea/testData/intentions/branched/ifWhen/ifToWhen/whenWithMultipleConditionTypes.kt.after similarity index 100% rename from idea/testData/codeInsight/codeTransformations/branched/ifWhen/ifToWhen/whenWithMultipleConditionTypes.kt.after rename to idea/testData/intentions/branched/ifWhen/ifToWhen/whenWithMultipleConditionTypes.kt.after diff --git a/idea/testData/codeInsight/codeTransformations/branched/ifWhen/whenToIf/whenWithEqualityTests.kt b/idea/testData/intentions/branched/ifWhen/whenToIf/whenWithEqualityTests.kt similarity index 100% rename from idea/testData/codeInsight/codeTransformations/branched/ifWhen/whenToIf/whenWithEqualityTests.kt rename to idea/testData/intentions/branched/ifWhen/whenToIf/whenWithEqualityTests.kt diff --git a/idea/testData/codeInsight/codeTransformations/branched/ifWhen/whenToIf/whenWithEqualityTests.kt.after b/idea/testData/intentions/branched/ifWhen/whenToIf/whenWithEqualityTests.kt.after similarity index 100% rename from idea/testData/codeInsight/codeTransformations/branched/ifWhen/whenToIf/whenWithEqualityTests.kt.after rename to idea/testData/intentions/branched/ifWhen/whenToIf/whenWithEqualityTests.kt.after diff --git a/idea/testData/codeInsight/codeTransformations/branched/ifWhen/whenToIf/whenWithMultiConditions.kt b/idea/testData/intentions/branched/ifWhen/whenToIf/whenWithMultiConditions.kt similarity index 100% rename from idea/testData/codeInsight/codeTransformations/branched/ifWhen/whenToIf/whenWithMultiConditions.kt rename to idea/testData/intentions/branched/ifWhen/whenToIf/whenWithMultiConditions.kt diff --git a/idea/testData/codeInsight/codeTransformations/branched/ifWhen/whenToIf/whenWithMultiConditions.kt.after b/idea/testData/intentions/branched/ifWhen/whenToIf/whenWithMultiConditions.kt.after similarity index 100% rename from idea/testData/codeInsight/codeTransformations/branched/ifWhen/whenToIf/whenWithMultiConditions.kt.after rename to idea/testData/intentions/branched/ifWhen/whenToIf/whenWithMultiConditions.kt.after diff --git a/idea/testData/codeInsight/codeTransformations/branched/ifWhen/whenToIf/whenWithMultipleConditionTypes.kt b/idea/testData/intentions/branched/ifWhen/whenToIf/whenWithMultipleConditionTypes.kt similarity index 100% rename from idea/testData/codeInsight/codeTransformations/branched/ifWhen/whenToIf/whenWithMultipleConditionTypes.kt rename to idea/testData/intentions/branched/ifWhen/whenToIf/whenWithMultipleConditionTypes.kt diff --git a/idea/testData/codeInsight/codeTransformations/branched/ifWhen/whenToIf/whenWithMultipleConditionTypes.kt.after b/idea/testData/intentions/branched/ifWhen/whenToIf/whenWithMultipleConditionTypes.kt.after similarity index 100% rename from idea/testData/codeInsight/codeTransformations/branched/ifWhen/whenToIf/whenWithMultipleConditionTypes.kt.after rename to idea/testData/intentions/branched/ifWhen/whenToIf/whenWithMultipleConditionTypes.kt.after diff --git a/idea/testData/codeInsight/codeTransformations/branched/ifWhen/whenToIf/whenWithNegativePatterns.kt b/idea/testData/intentions/branched/ifWhen/whenToIf/whenWithNegativePatterns.kt similarity index 100% rename from idea/testData/codeInsight/codeTransformations/branched/ifWhen/whenToIf/whenWithNegativePatterns.kt rename to idea/testData/intentions/branched/ifWhen/whenToIf/whenWithNegativePatterns.kt diff --git a/idea/testData/codeInsight/codeTransformations/branched/ifWhen/whenToIf/whenWithNegativePatterns.kt.after b/idea/testData/intentions/branched/ifWhen/whenToIf/whenWithNegativePatterns.kt.after similarity index 100% rename from idea/testData/codeInsight/codeTransformations/branched/ifWhen/whenToIf/whenWithNegativePatterns.kt.after rename to idea/testData/intentions/branched/ifWhen/whenToIf/whenWithNegativePatterns.kt.after diff --git a/idea/testData/codeInsight/codeTransformations/branched/ifWhen/whenToIf/whenWithNegativeRangeTests.kt b/idea/testData/intentions/branched/ifWhen/whenToIf/whenWithNegativeRangeTests.kt similarity index 100% rename from idea/testData/codeInsight/codeTransformations/branched/ifWhen/whenToIf/whenWithNegativeRangeTests.kt rename to idea/testData/intentions/branched/ifWhen/whenToIf/whenWithNegativeRangeTests.kt diff --git a/idea/testData/codeInsight/codeTransformations/branched/ifWhen/whenToIf/whenWithNegativeRangeTests.kt.after b/idea/testData/intentions/branched/ifWhen/whenToIf/whenWithNegativeRangeTests.kt.after similarity index 100% rename from idea/testData/codeInsight/codeTransformations/branched/ifWhen/whenToIf/whenWithNegativeRangeTests.kt.after rename to idea/testData/intentions/branched/ifWhen/whenToIf/whenWithNegativeRangeTests.kt.after diff --git a/idea/testData/codeInsight/codeTransformations/branched/ifWhen/whenToIf/whenWithPatterns.kt b/idea/testData/intentions/branched/ifWhen/whenToIf/whenWithPatterns.kt similarity index 100% rename from idea/testData/codeInsight/codeTransformations/branched/ifWhen/whenToIf/whenWithPatterns.kt rename to idea/testData/intentions/branched/ifWhen/whenToIf/whenWithPatterns.kt diff --git a/idea/testData/codeInsight/codeTransformations/branched/ifWhen/whenToIf/whenWithPatterns.kt.after b/idea/testData/intentions/branched/ifWhen/whenToIf/whenWithPatterns.kt.after similarity index 100% rename from idea/testData/codeInsight/codeTransformations/branched/ifWhen/whenToIf/whenWithPatterns.kt.after rename to idea/testData/intentions/branched/ifWhen/whenToIf/whenWithPatterns.kt.after diff --git a/idea/testData/codeInsight/codeTransformations/branched/ifWhen/whenToIf/whenWithRangeTests.kt b/idea/testData/intentions/branched/ifWhen/whenToIf/whenWithRangeTests.kt similarity index 100% rename from idea/testData/codeInsight/codeTransformations/branched/ifWhen/whenToIf/whenWithRangeTests.kt rename to idea/testData/intentions/branched/ifWhen/whenToIf/whenWithRangeTests.kt diff --git a/idea/testData/codeInsight/codeTransformations/branched/ifWhen/whenToIf/whenWithRangeTests.kt.after b/idea/testData/intentions/branched/ifWhen/whenToIf/whenWithRangeTests.kt.after similarity index 100% rename from idea/testData/codeInsight/codeTransformations/branched/ifWhen/whenToIf/whenWithRangeTests.kt.after rename to idea/testData/intentions/branched/ifWhen/whenToIf/whenWithRangeTests.kt.after diff --git a/idea/testData/codeInsight/codeTransformations/branched/ifWhen/whenToIf/whenWithRangeTestsAndMultiConditions.kt b/idea/testData/intentions/branched/ifWhen/whenToIf/whenWithRangeTestsAndMultiConditions.kt similarity index 100% rename from idea/testData/codeInsight/codeTransformations/branched/ifWhen/whenToIf/whenWithRangeTestsAndMultiConditions.kt rename to idea/testData/intentions/branched/ifWhen/whenToIf/whenWithRangeTestsAndMultiConditions.kt diff --git a/idea/testData/codeInsight/codeTransformations/branched/ifWhen/whenToIf/whenWithRangeTestsAndMultiConditions.kt.after b/idea/testData/intentions/branched/ifWhen/whenToIf/whenWithRangeTestsAndMultiConditions.kt.after similarity index 100% rename from idea/testData/codeInsight/codeTransformations/branched/ifWhen/whenToIf/whenWithRangeTestsAndMultiConditions.kt.after rename to idea/testData/intentions/branched/ifWhen/whenToIf/whenWithRangeTestsAndMultiConditions.kt.after diff --git a/idea/testData/codeInsight/codeTransformations/branched/ifWhen/whenToIf/whenWithoutSubject.kt b/idea/testData/intentions/branched/ifWhen/whenToIf/whenWithoutSubject.kt similarity index 100% rename from idea/testData/codeInsight/codeTransformations/branched/ifWhen/whenToIf/whenWithoutSubject.kt rename to idea/testData/intentions/branched/ifWhen/whenToIf/whenWithoutSubject.kt diff --git a/idea/testData/codeInsight/codeTransformations/branched/ifWhen/whenToIf/whenWithoutSubject.kt.after b/idea/testData/intentions/branched/ifWhen/whenToIf/whenWithoutSubject.kt.after similarity index 100% rename from idea/testData/codeInsight/codeTransformations/branched/ifWhen/whenToIf/whenWithoutSubject.kt.after rename to idea/testData/intentions/branched/ifWhen/whenToIf/whenWithoutSubject.kt.after diff --git a/idea/testData/codeInsight/codeTransformations/branched/unfolding/assignmentToIf/innerIfTransformed.kt b/idea/testData/intentions/branched/unfolding/assignmentToIf/innerIfTransformed.kt similarity index 100% rename from idea/testData/codeInsight/codeTransformations/branched/unfolding/assignmentToIf/innerIfTransformed.kt rename to idea/testData/intentions/branched/unfolding/assignmentToIf/innerIfTransformed.kt diff --git a/idea/testData/codeInsight/codeTransformations/branched/unfolding/assignmentToIf/innerIfTransformed.kt.after b/idea/testData/intentions/branched/unfolding/assignmentToIf/innerIfTransformed.kt.after similarity index 100% rename from idea/testData/codeInsight/codeTransformations/branched/unfolding/assignmentToIf/innerIfTransformed.kt.after rename to idea/testData/intentions/branched/unfolding/assignmentToIf/innerIfTransformed.kt.after diff --git a/idea/testData/codeInsight/codeTransformations/branched/unfolding/assignmentToIf/nestedIfs.kt b/idea/testData/intentions/branched/unfolding/assignmentToIf/nestedIfs.kt similarity index 100% rename from idea/testData/codeInsight/codeTransformations/branched/unfolding/assignmentToIf/nestedIfs.kt rename to idea/testData/intentions/branched/unfolding/assignmentToIf/nestedIfs.kt diff --git a/idea/testData/codeInsight/codeTransformations/branched/unfolding/assignmentToIf/nestedIfs.kt.after b/idea/testData/intentions/branched/unfolding/assignmentToIf/nestedIfs.kt.after similarity index 100% rename from idea/testData/codeInsight/codeTransformations/branched/unfolding/assignmentToIf/nestedIfs.kt.after rename to idea/testData/intentions/branched/unfolding/assignmentToIf/nestedIfs.kt.after diff --git a/idea/testData/codeInsight/codeTransformations/branched/unfolding/assignmentToIf/simpleIf.kt b/idea/testData/intentions/branched/unfolding/assignmentToIf/simpleIf.kt similarity index 100% rename from idea/testData/codeInsight/codeTransformations/branched/unfolding/assignmentToIf/simpleIf.kt rename to idea/testData/intentions/branched/unfolding/assignmentToIf/simpleIf.kt diff --git a/idea/testData/codeInsight/codeTransformations/branched/unfolding/assignmentToIf/simpleIf.kt.after b/idea/testData/intentions/branched/unfolding/assignmentToIf/simpleIf.kt.after similarity index 100% rename from idea/testData/codeInsight/codeTransformations/branched/unfolding/assignmentToIf/simpleIf.kt.after rename to idea/testData/intentions/branched/unfolding/assignmentToIf/simpleIf.kt.after diff --git a/idea/testData/codeInsight/codeTransformations/branched/unfolding/assignmentToIf/simpleIfWithAugmentedAssignment.kt b/idea/testData/intentions/branched/unfolding/assignmentToIf/simpleIfWithAugmentedAssignment.kt similarity index 100% rename from idea/testData/codeInsight/codeTransformations/branched/unfolding/assignmentToIf/simpleIfWithAugmentedAssignment.kt rename to idea/testData/intentions/branched/unfolding/assignmentToIf/simpleIfWithAugmentedAssignment.kt diff --git a/idea/testData/codeInsight/codeTransformations/branched/unfolding/assignmentToIf/simpleIfWithAugmentedAssignment.kt.after b/idea/testData/intentions/branched/unfolding/assignmentToIf/simpleIfWithAugmentedAssignment.kt.after similarity index 100% rename from idea/testData/codeInsight/codeTransformations/branched/unfolding/assignmentToIf/simpleIfWithAugmentedAssignment.kt.after rename to idea/testData/intentions/branched/unfolding/assignmentToIf/simpleIfWithAugmentedAssignment.kt.after diff --git a/idea/testData/codeInsight/codeTransformations/branched/unfolding/assignmentToIf/simpleIfWithBlocks.kt b/idea/testData/intentions/branched/unfolding/assignmentToIf/simpleIfWithBlocks.kt similarity index 100% rename from idea/testData/codeInsight/codeTransformations/branched/unfolding/assignmentToIf/simpleIfWithBlocks.kt rename to idea/testData/intentions/branched/unfolding/assignmentToIf/simpleIfWithBlocks.kt diff --git a/idea/testData/codeInsight/codeTransformations/branched/unfolding/assignmentToIf/simpleIfWithBlocks.kt.after b/idea/testData/intentions/branched/unfolding/assignmentToIf/simpleIfWithBlocks.kt.after similarity index 100% rename from idea/testData/codeInsight/codeTransformations/branched/unfolding/assignmentToIf/simpleIfWithBlocks.kt.after rename to idea/testData/intentions/branched/unfolding/assignmentToIf/simpleIfWithBlocks.kt.after diff --git a/idea/testData/codeInsight/codeTransformations/branched/unfolding/assignmentToIf/simpleIfWithComplexAssignmentLHS.kt b/idea/testData/intentions/branched/unfolding/assignmentToIf/simpleIfWithComplexAssignmentLHS.kt similarity index 100% rename from idea/testData/codeInsight/codeTransformations/branched/unfolding/assignmentToIf/simpleIfWithComplexAssignmentLHS.kt rename to idea/testData/intentions/branched/unfolding/assignmentToIf/simpleIfWithComplexAssignmentLHS.kt diff --git a/idea/testData/codeInsight/codeTransformations/branched/unfolding/assignmentToIf/simpleIfWithComplexAssignmentLHS.kt.after b/idea/testData/intentions/branched/unfolding/assignmentToIf/simpleIfWithComplexAssignmentLHS.kt.after similarity index 100% rename from idea/testData/codeInsight/codeTransformations/branched/unfolding/assignmentToIf/simpleIfWithComplexAssignmentLHS.kt.after rename to idea/testData/intentions/branched/unfolding/assignmentToIf/simpleIfWithComplexAssignmentLHS.kt.after diff --git a/idea/testData/codeInsight/codeTransformations/branched/unfolding/assignmentToIf/simpleIfWithoutAssignment.kt b/idea/testData/intentions/branched/unfolding/assignmentToIf/simpleIfWithoutAssignment.kt similarity index 100% rename from idea/testData/codeInsight/codeTransformations/branched/unfolding/assignmentToIf/simpleIfWithoutAssignment.kt rename to idea/testData/intentions/branched/unfolding/assignmentToIf/simpleIfWithoutAssignment.kt diff --git a/idea/testData/codeInsight/codeTransformations/branched/unfolding/assignmentToWhen/innerWhenTransformed.kt b/idea/testData/intentions/branched/unfolding/assignmentToWhen/innerWhenTransformed.kt similarity index 100% rename from idea/testData/codeInsight/codeTransformations/branched/unfolding/assignmentToWhen/innerWhenTransformed.kt rename to idea/testData/intentions/branched/unfolding/assignmentToWhen/innerWhenTransformed.kt diff --git a/idea/testData/codeInsight/codeTransformations/branched/unfolding/assignmentToWhen/innerWhenTransformed.kt.after b/idea/testData/intentions/branched/unfolding/assignmentToWhen/innerWhenTransformed.kt.after similarity index 100% rename from idea/testData/codeInsight/codeTransformations/branched/unfolding/assignmentToWhen/innerWhenTransformed.kt.after rename to idea/testData/intentions/branched/unfolding/assignmentToWhen/innerWhenTransformed.kt.after diff --git a/idea/testData/codeInsight/codeTransformations/branched/unfolding/assignmentToWhen/simpleWhen.kt b/idea/testData/intentions/branched/unfolding/assignmentToWhen/simpleWhen.kt similarity index 100% rename from idea/testData/codeInsight/codeTransformations/branched/unfolding/assignmentToWhen/simpleWhen.kt rename to idea/testData/intentions/branched/unfolding/assignmentToWhen/simpleWhen.kt diff --git a/idea/testData/codeInsight/codeTransformations/branched/unfolding/assignmentToWhen/simpleWhen.kt.after b/idea/testData/intentions/branched/unfolding/assignmentToWhen/simpleWhen.kt.after similarity index 100% rename from idea/testData/codeInsight/codeTransformations/branched/unfolding/assignmentToWhen/simpleWhen.kt.after rename to idea/testData/intentions/branched/unfolding/assignmentToWhen/simpleWhen.kt.after diff --git a/idea/testData/codeInsight/codeTransformations/branched/unfolding/assignmentToWhen/simpleWhenWithBlocks.kt b/idea/testData/intentions/branched/unfolding/assignmentToWhen/simpleWhenWithBlocks.kt similarity index 100% rename from idea/testData/codeInsight/codeTransformations/branched/unfolding/assignmentToWhen/simpleWhenWithBlocks.kt rename to idea/testData/intentions/branched/unfolding/assignmentToWhen/simpleWhenWithBlocks.kt diff --git a/idea/testData/codeInsight/codeTransformations/branched/unfolding/assignmentToWhen/simpleWhenWithBlocks.kt.after b/idea/testData/intentions/branched/unfolding/assignmentToWhen/simpleWhenWithBlocks.kt.after similarity index 100% rename from idea/testData/codeInsight/codeTransformations/branched/unfolding/assignmentToWhen/simpleWhenWithBlocks.kt.after rename to idea/testData/intentions/branched/unfolding/assignmentToWhen/simpleWhenWithBlocks.kt.after diff --git a/idea/testData/codeInsight/codeTransformations/branched/unfolding/assignmentToWhen/simpleWhenWithComplexAssignmentLHS.kt b/idea/testData/intentions/branched/unfolding/assignmentToWhen/simpleWhenWithComplexAssignmentLHS.kt similarity index 100% rename from idea/testData/codeInsight/codeTransformations/branched/unfolding/assignmentToWhen/simpleWhenWithComplexAssignmentLHS.kt rename to idea/testData/intentions/branched/unfolding/assignmentToWhen/simpleWhenWithComplexAssignmentLHS.kt diff --git a/idea/testData/codeInsight/codeTransformations/branched/unfolding/assignmentToWhen/simpleWhenWithComplexAssignmentLHS.kt.after b/idea/testData/intentions/branched/unfolding/assignmentToWhen/simpleWhenWithComplexAssignmentLHS.kt.after similarity index 100% rename from idea/testData/codeInsight/codeTransformations/branched/unfolding/assignmentToWhen/simpleWhenWithComplexAssignmentLHS.kt.after rename to idea/testData/intentions/branched/unfolding/assignmentToWhen/simpleWhenWithComplexAssignmentLHS.kt.after diff --git a/idea/testData/codeInsight/codeTransformations/branched/unfolding/propertyToIf/nestedIfs.kt b/idea/testData/intentions/branched/unfolding/propertyToIf/nestedIfs.kt similarity index 100% rename from idea/testData/codeInsight/codeTransformations/branched/unfolding/propertyToIf/nestedIfs.kt rename to idea/testData/intentions/branched/unfolding/propertyToIf/nestedIfs.kt diff --git a/idea/testData/codeInsight/codeTransformations/branched/unfolding/propertyToIf/nestedIfs.kt.after b/idea/testData/intentions/branched/unfolding/propertyToIf/nestedIfs.kt.after similarity index 100% rename from idea/testData/codeInsight/codeTransformations/branched/unfolding/propertyToIf/nestedIfs.kt.after rename to idea/testData/intentions/branched/unfolding/propertyToIf/nestedIfs.kt.after diff --git a/idea/testData/codeInsight/codeTransformations/branched/unfolding/propertyToIf/nestedIfs2.kt b/idea/testData/intentions/branched/unfolding/propertyToIf/nestedIfs2.kt similarity index 100% rename from idea/testData/codeInsight/codeTransformations/branched/unfolding/propertyToIf/nestedIfs2.kt rename to idea/testData/intentions/branched/unfolding/propertyToIf/nestedIfs2.kt diff --git a/idea/testData/codeInsight/codeTransformations/branched/unfolding/propertyToIf/nestedIfs2.kt.after b/idea/testData/intentions/branched/unfolding/propertyToIf/nestedIfs2.kt.after similarity index 100% rename from idea/testData/codeInsight/codeTransformations/branched/unfolding/propertyToIf/nestedIfs2.kt.after rename to idea/testData/intentions/branched/unfolding/propertyToIf/nestedIfs2.kt.after diff --git a/idea/testData/codeInsight/codeTransformations/branched/unfolding/propertyToIf/nonLocalProperty.kt b/idea/testData/intentions/branched/unfolding/propertyToIf/nonLocalProperty.kt similarity index 100% rename from idea/testData/codeInsight/codeTransformations/branched/unfolding/propertyToIf/nonLocalProperty.kt rename to idea/testData/intentions/branched/unfolding/propertyToIf/nonLocalProperty.kt diff --git a/idea/testData/codeInsight/codeTransformations/branched/unfolding/propertyToIf/nonLocalProperty2.kt b/idea/testData/intentions/branched/unfolding/propertyToIf/nonLocalProperty2.kt similarity index 100% rename from idea/testData/codeInsight/codeTransformations/branched/unfolding/propertyToIf/nonLocalProperty2.kt rename to idea/testData/intentions/branched/unfolding/propertyToIf/nonLocalProperty2.kt diff --git a/idea/testData/codeInsight/codeTransformations/branched/unfolding/propertyToIf/simpleIf.kt b/idea/testData/intentions/branched/unfolding/propertyToIf/simpleIf.kt similarity index 100% rename from idea/testData/codeInsight/codeTransformations/branched/unfolding/propertyToIf/simpleIf.kt rename to idea/testData/intentions/branched/unfolding/propertyToIf/simpleIf.kt diff --git a/idea/testData/codeInsight/codeTransformations/branched/unfolding/propertyToIf/simpleIf.kt.after b/idea/testData/intentions/branched/unfolding/propertyToIf/simpleIf.kt.after similarity index 100% rename from idea/testData/codeInsight/codeTransformations/branched/unfolding/propertyToIf/simpleIf.kt.after rename to idea/testData/intentions/branched/unfolding/propertyToIf/simpleIf.kt.after diff --git a/idea/testData/codeInsight/codeTransformations/branched/unfolding/propertyToIf/simpleIf2.kt b/idea/testData/intentions/branched/unfolding/propertyToIf/simpleIf2.kt similarity index 100% rename from idea/testData/codeInsight/codeTransformations/branched/unfolding/propertyToIf/simpleIf2.kt rename to idea/testData/intentions/branched/unfolding/propertyToIf/simpleIf2.kt diff --git a/idea/testData/codeInsight/codeTransformations/branched/unfolding/propertyToIf/simpleIf2.kt.after b/idea/testData/intentions/branched/unfolding/propertyToIf/simpleIf2.kt.after similarity index 100% rename from idea/testData/codeInsight/codeTransformations/branched/unfolding/propertyToIf/simpleIf2.kt.after rename to idea/testData/intentions/branched/unfolding/propertyToIf/simpleIf2.kt.after diff --git a/idea/testData/codeInsight/codeTransformations/branched/unfolding/propertyToIf/simpleIfWithBlocks.kt b/idea/testData/intentions/branched/unfolding/propertyToIf/simpleIfWithBlocks.kt similarity index 100% rename from idea/testData/codeInsight/codeTransformations/branched/unfolding/propertyToIf/simpleIfWithBlocks.kt rename to idea/testData/intentions/branched/unfolding/propertyToIf/simpleIfWithBlocks.kt diff --git a/idea/testData/codeInsight/codeTransformations/branched/unfolding/propertyToIf/simpleIfWithBlocks.kt.after b/idea/testData/intentions/branched/unfolding/propertyToIf/simpleIfWithBlocks.kt.after similarity index 100% rename from idea/testData/codeInsight/codeTransformations/branched/unfolding/propertyToIf/simpleIfWithBlocks.kt.after rename to idea/testData/intentions/branched/unfolding/propertyToIf/simpleIfWithBlocks.kt.after diff --git a/idea/testData/codeInsight/codeTransformations/branched/unfolding/propertyToIf/simpleIfWithBlocks2.kt b/idea/testData/intentions/branched/unfolding/propertyToIf/simpleIfWithBlocks2.kt similarity index 100% rename from idea/testData/codeInsight/codeTransformations/branched/unfolding/propertyToIf/simpleIfWithBlocks2.kt rename to idea/testData/intentions/branched/unfolding/propertyToIf/simpleIfWithBlocks2.kt diff --git a/idea/testData/codeInsight/codeTransformations/branched/unfolding/propertyToIf/simpleIfWithBlocks2.kt.after b/idea/testData/intentions/branched/unfolding/propertyToIf/simpleIfWithBlocks2.kt.after similarity index 100% rename from idea/testData/codeInsight/codeTransformations/branched/unfolding/propertyToIf/simpleIfWithBlocks2.kt.after rename to idea/testData/intentions/branched/unfolding/propertyToIf/simpleIfWithBlocks2.kt.after diff --git a/idea/testData/codeInsight/codeTransformations/branched/unfolding/propertyToIf/simpleIfWithType.kt b/idea/testData/intentions/branched/unfolding/propertyToIf/simpleIfWithType.kt similarity index 100% rename from idea/testData/codeInsight/codeTransformations/branched/unfolding/propertyToIf/simpleIfWithType.kt rename to idea/testData/intentions/branched/unfolding/propertyToIf/simpleIfWithType.kt diff --git a/idea/testData/codeInsight/codeTransformations/branched/unfolding/propertyToIf/simpleIfWithType.kt.after b/idea/testData/intentions/branched/unfolding/propertyToIf/simpleIfWithType.kt.after similarity index 100% rename from idea/testData/codeInsight/codeTransformations/branched/unfolding/propertyToIf/simpleIfWithType.kt.after rename to idea/testData/intentions/branched/unfolding/propertyToIf/simpleIfWithType.kt.after diff --git a/idea/testData/codeInsight/codeTransformations/branched/unfolding/propertyToWhen/nonLocalProperty.kt b/idea/testData/intentions/branched/unfolding/propertyToWhen/nonLocalProperty.kt similarity index 100% rename from idea/testData/codeInsight/codeTransformations/branched/unfolding/propertyToWhen/nonLocalProperty.kt rename to idea/testData/intentions/branched/unfolding/propertyToWhen/nonLocalProperty.kt diff --git a/idea/testData/codeInsight/codeTransformations/branched/unfolding/propertyToWhen/nonLocalProperty2.kt b/idea/testData/intentions/branched/unfolding/propertyToWhen/nonLocalProperty2.kt similarity index 100% rename from idea/testData/codeInsight/codeTransformations/branched/unfolding/propertyToWhen/nonLocalProperty2.kt rename to idea/testData/intentions/branched/unfolding/propertyToWhen/nonLocalProperty2.kt diff --git a/idea/testData/codeInsight/codeTransformations/branched/unfolding/propertyToWhen/simpleWhen.kt b/idea/testData/intentions/branched/unfolding/propertyToWhen/simpleWhen.kt similarity index 100% rename from idea/testData/codeInsight/codeTransformations/branched/unfolding/propertyToWhen/simpleWhen.kt rename to idea/testData/intentions/branched/unfolding/propertyToWhen/simpleWhen.kt diff --git a/idea/testData/codeInsight/codeTransformations/branched/unfolding/propertyToWhen/simpleWhen.kt.after b/idea/testData/intentions/branched/unfolding/propertyToWhen/simpleWhen.kt.after similarity index 100% rename from idea/testData/codeInsight/codeTransformations/branched/unfolding/propertyToWhen/simpleWhen.kt.after rename to idea/testData/intentions/branched/unfolding/propertyToWhen/simpleWhen.kt.after diff --git a/idea/testData/codeInsight/codeTransformations/branched/unfolding/propertyToWhen/simpleWhen2.kt b/idea/testData/intentions/branched/unfolding/propertyToWhen/simpleWhen2.kt similarity index 100% rename from idea/testData/codeInsight/codeTransformations/branched/unfolding/propertyToWhen/simpleWhen2.kt rename to idea/testData/intentions/branched/unfolding/propertyToWhen/simpleWhen2.kt diff --git a/idea/testData/codeInsight/codeTransformations/branched/unfolding/propertyToWhen/simpleWhen2.kt.after b/idea/testData/intentions/branched/unfolding/propertyToWhen/simpleWhen2.kt.after similarity index 100% rename from idea/testData/codeInsight/codeTransformations/branched/unfolding/propertyToWhen/simpleWhen2.kt.after rename to idea/testData/intentions/branched/unfolding/propertyToWhen/simpleWhen2.kt.after diff --git a/idea/testData/codeInsight/codeTransformations/branched/unfolding/propertyToWhen/simpleWhenWithBlocks.kt b/idea/testData/intentions/branched/unfolding/propertyToWhen/simpleWhenWithBlocks.kt similarity index 100% rename from idea/testData/codeInsight/codeTransformations/branched/unfolding/propertyToWhen/simpleWhenWithBlocks.kt rename to idea/testData/intentions/branched/unfolding/propertyToWhen/simpleWhenWithBlocks.kt diff --git a/idea/testData/codeInsight/codeTransformations/branched/unfolding/propertyToWhen/simpleWhenWithBlocks.kt.after b/idea/testData/intentions/branched/unfolding/propertyToWhen/simpleWhenWithBlocks.kt.after similarity index 100% rename from idea/testData/codeInsight/codeTransformations/branched/unfolding/propertyToWhen/simpleWhenWithBlocks.kt.after rename to idea/testData/intentions/branched/unfolding/propertyToWhen/simpleWhenWithBlocks.kt.after diff --git a/idea/testData/codeInsight/codeTransformations/branched/unfolding/propertyToWhen/simpleWhenWithBlocks2.kt b/idea/testData/intentions/branched/unfolding/propertyToWhen/simpleWhenWithBlocks2.kt similarity index 100% rename from idea/testData/codeInsight/codeTransformations/branched/unfolding/propertyToWhen/simpleWhenWithBlocks2.kt rename to idea/testData/intentions/branched/unfolding/propertyToWhen/simpleWhenWithBlocks2.kt diff --git a/idea/testData/codeInsight/codeTransformations/branched/unfolding/propertyToWhen/simpleWhenWithBlocks2.kt.after b/idea/testData/intentions/branched/unfolding/propertyToWhen/simpleWhenWithBlocks2.kt.after similarity index 100% rename from idea/testData/codeInsight/codeTransformations/branched/unfolding/propertyToWhen/simpleWhenWithBlocks2.kt.after rename to idea/testData/intentions/branched/unfolding/propertyToWhen/simpleWhenWithBlocks2.kt.after diff --git a/idea/testData/codeInsight/codeTransformations/branched/unfolding/propertyToWhen/simpleWhenWithType.kt b/idea/testData/intentions/branched/unfolding/propertyToWhen/simpleWhenWithType.kt similarity index 100% rename from idea/testData/codeInsight/codeTransformations/branched/unfolding/propertyToWhen/simpleWhenWithType.kt rename to idea/testData/intentions/branched/unfolding/propertyToWhen/simpleWhenWithType.kt diff --git a/idea/testData/codeInsight/codeTransformations/branched/unfolding/propertyToWhen/simpleWhenWithType.kt.after b/idea/testData/intentions/branched/unfolding/propertyToWhen/simpleWhenWithType.kt.after similarity index 100% rename from idea/testData/codeInsight/codeTransformations/branched/unfolding/propertyToWhen/simpleWhenWithType.kt.after rename to idea/testData/intentions/branched/unfolding/propertyToWhen/simpleWhenWithType.kt.after diff --git a/idea/testData/codeInsight/codeTransformations/branched/unfolding/returnToIf/innerIfTransformed.kt b/idea/testData/intentions/branched/unfolding/returnToIf/innerIfTransformed.kt similarity index 100% rename from idea/testData/codeInsight/codeTransformations/branched/unfolding/returnToIf/innerIfTransformed.kt rename to idea/testData/intentions/branched/unfolding/returnToIf/innerIfTransformed.kt diff --git a/idea/testData/codeInsight/codeTransformations/branched/unfolding/returnToIf/innerIfTransformed.kt.after b/idea/testData/intentions/branched/unfolding/returnToIf/innerIfTransformed.kt.after similarity index 100% rename from idea/testData/codeInsight/codeTransformations/branched/unfolding/returnToIf/innerIfTransformed.kt.after rename to idea/testData/intentions/branched/unfolding/returnToIf/innerIfTransformed.kt.after diff --git a/idea/testData/codeInsight/codeTransformations/branched/unfolding/returnToIf/simpleIf.kt b/idea/testData/intentions/branched/unfolding/returnToIf/simpleIf.kt similarity index 100% rename from idea/testData/codeInsight/codeTransformations/branched/unfolding/returnToIf/simpleIf.kt rename to idea/testData/intentions/branched/unfolding/returnToIf/simpleIf.kt diff --git a/idea/testData/codeInsight/codeTransformations/branched/unfolding/returnToIf/simpleIf.kt.after b/idea/testData/intentions/branched/unfolding/returnToIf/simpleIf.kt.after similarity index 100% rename from idea/testData/codeInsight/codeTransformations/branched/unfolding/returnToIf/simpleIf.kt.after rename to idea/testData/intentions/branched/unfolding/returnToIf/simpleIf.kt.after diff --git a/idea/testData/codeInsight/codeTransformations/branched/unfolding/returnToIf/simpleIfWithBlocks.kt b/idea/testData/intentions/branched/unfolding/returnToIf/simpleIfWithBlocks.kt similarity index 100% rename from idea/testData/codeInsight/codeTransformations/branched/unfolding/returnToIf/simpleIfWithBlocks.kt rename to idea/testData/intentions/branched/unfolding/returnToIf/simpleIfWithBlocks.kt diff --git a/idea/testData/codeInsight/codeTransformations/branched/unfolding/returnToIf/simpleIfWithBlocks.kt.after b/idea/testData/intentions/branched/unfolding/returnToIf/simpleIfWithBlocks.kt.after similarity index 100% rename from idea/testData/codeInsight/codeTransformations/branched/unfolding/returnToIf/simpleIfWithBlocks.kt.after rename to idea/testData/intentions/branched/unfolding/returnToIf/simpleIfWithBlocks.kt.after diff --git a/idea/testData/codeInsight/codeTransformations/branched/unfolding/returnToWhen/innerWhenTransformed.kt b/idea/testData/intentions/branched/unfolding/returnToWhen/innerWhenTransformed.kt similarity index 100% rename from idea/testData/codeInsight/codeTransformations/branched/unfolding/returnToWhen/innerWhenTransformed.kt rename to idea/testData/intentions/branched/unfolding/returnToWhen/innerWhenTransformed.kt diff --git a/idea/testData/codeInsight/codeTransformations/branched/unfolding/returnToWhen/innerWhenTransformed.kt.after b/idea/testData/intentions/branched/unfolding/returnToWhen/innerWhenTransformed.kt.after similarity index 100% rename from idea/testData/codeInsight/codeTransformations/branched/unfolding/returnToWhen/innerWhenTransformed.kt.after rename to idea/testData/intentions/branched/unfolding/returnToWhen/innerWhenTransformed.kt.after diff --git a/idea/testData/codeInsight/codeTransformations/branched/unfolding/returnToWhen/simpleWhen.kt b/idea/testData/intentions/branched/unfolding/returnToWhen/simpleWhen.kt similarity index 100% rename from idea/testData/codeInsight/codeTransformations/branched/unfolding/returnToWhen/simpleWhen.kt rename to idea/testData/intentions/branched/unfolding/returnToWhen/simpleWhen.kt diff --git a/idea/testData/codeInsight/codeTransformations/branched/unfolding/returnToWhen/simpleWhen.kt.after b/idea/testData/intentions/branched/unfolding/returnToWhen/simpleWhen.kt.after similarity index 100% rename from idea/testData/codeInsight/codeTransformations/branched/unfolding/returnToWhen/simpleWhen.kt.after rename to idea/testData/intentions/branched/unfolding/returnToWhen/simpleWhen.kt.after diff --git a/idea/testData/codeInsight/codeTransformations/branched/unfolding/returnToWhen/simpleWhenWithBlocks.kt b/idea/testData/intentions/branched/unfolding/returnToWhen/simpleWhenWithBlocks.kt similarity index 100% rename from idea/testData/codeInsight/codeTransformations/branched/unfolding/returnToWhen/simpleWhenWithBlocks.kt rename to idea/testData/intentions/branched/unfolding/returnToWhen/simpleWhenWithBlocks.kt diff --git a/idea/testData/codeInsight/codeTransformations/branched/unfolding/returnToWhen/simpleWhenWithBlocks.kt.after b/idea/testData/intentions/branched/unfolding/returnToWhen/simpleWhenWithBlocks.kt.after similarity index 100% rename from idea/testData/codeInsight/codeTransformations/branched/unfolding/returnToWhen/simpleWhenWithBlocks.kt.after rename to idea/testData/intentions/branched/unfolding/returnToWhen/simpleWhenWithBlocks.kt.after diff --git a/idea/testData/codeInsight/codeTransformations/branched/when/eliminateSubject/whenWithEqualityTests.kt b/idea/testData/intentions/branched/when/eliminateSubject/whenWithEqualityTests.kt similarity index 100% rename from idea/testData/codeInsight/codeTransformations/branched/when/eliminateSubject/whenWithEqualityTests.kt rename to idea/testData/intentions/branched/when/eliminateSubject/whenWithEqualityTests.kt diff --git a/idea/testData/codeInsight/codeTransformations/branched/when/eliminateSubject/whenWithEqualityTests.kt.after b/idea/testData/intentions/branched/when/eliminateSubject/whenWithEqualityTests.kt.after similarity index 100% rename from idea/testData/codeInsight/codeTransformations/branched/when/eliminateSubject/whenWithEqualityTests.kt.after rename to idea/testData/intentions/branched/when/eliminateSubject/whenWithEqualityTests.kt.after diff --git a/idea/testData/codeInsight/codeTransformations/branched/when/eliminateSubject/whenWithMultipleConditionTypes.kt b/idea/testData/intentions/branched/when/eliminateSubject/whenWithMultipleConditionTypes.kt similarity index 100% rename from idea/testData/codeInsight/codeTransformations/branched/when/eliminateSubject/whenWithMultipleConditionTypes.kt rename to idea/testData/intentions/branched/when/eliminateSubject/whenWithMultipleConditionTypes.kt diff --git a/idea/testData/codeInsight/codeTransformations/branched/when/eliminateSubject/whenWithMultipleConditionTypes.kt.after b/idea/testData/intentions/branched/when/eliminateSubject/whenWithMultipleConditionTypes.kt.after similarity index 100% rename from idea/testData/codeInsight/codeTransformations/branched/when/eliminateSubject/whenWithMultipleConditionTypes.kt.after rename to idea/testData/intentions/branched/when/eliminateSubject/whenWithMultipleConditionTypes.kt.after diff --git a/idea/testData/codeInsight/codeTransformations/branched/when/eliminateSubject/whenWithNegativePatterns.kt b/idea/testData/intentions/branched/when/eliminateSubject/whenWithNegativePatterns.kt similarity index 100% rename from idea/testData/codeInsight/codeTransformations/branched/when/eliminateSubject/whenWithNegativePatterns.kt rename to idea/testData/intentions/branched/when/eliminateSubject/whenWithNegativePatterns.kt diff --git a/idea/testData/codeInsight/codeTransformations/branched/when/eliminateSubject/whenWithNegativePatterns.kt.after b/idea/testData/intentions/branched/when/eliminateSubject/whenWithNegativePatterns.kt.after similarity index 100% rename from idea/testData/codeInsight/codeTransformations/branched/when/eliminateSubject/whenWithNegativePatterns.kt.after rename to idea/testData/intentions/branched/when/eliminateSubject/whenWithNegativePatterns.kt.after diff --git a/idea/testData/codeInsight/codeTransformations/branched/when/eliminateSubject/whenWithNegativeRangeTests.kt b/idea/testData/intentions/branched/when/eliminateSubject/whenWithNegativeRangeTests.kt similarity index 100% rename from idea/testData/codeInsight/codeTransformations/branched/when/eliminateSubject/whenWithNegativeRangeTests.kt rename to idea/testData/intentions/branched/when/eliminateSubject/whenWithNegativeRangeTests.kt diff --git a/idea/testData/codeInsight/codeTransformations/branched/when/eliminateSubject/whenWithNegativeRangeTests.kt.after b/idea/testData/intentions/branched/when/eliminateSubject/whenWithNegativeRangeTests.kt.after similarity index 100% rename from idea/testData/codeInsight/codeTransformations/branched/when/eliminateSubject/whenWithNegativeRangeTests.kt.after rename to idea/testData/intentions/branched/when/eliminateSubject/whenWithNegativeRangeTests.kt.after diff --git a/idea/testData/codeInsight/codeTransformations/branched/when/eliminateSubject/whenWithPatterns.kt b/idea/testData/intentions/branched/when/eliminateSubject/whenWithPatterns.kt similarity index 100% rename from idea/testData/codeInsight/codeTransformations/branched/when/eliminateSubject/whenWithPatterns.kt rename to idea/testData/intentions/branched/when/eliminateSubject/whenWithPatterns.kt diff --git a/idea/testData/codeInsight/codeTransformations/branched/when/eliminateSubject/whenWithPatterns.kt.after b/idea/testData/intentions/branched/when/eliminateSubject/whenWithPatterns.kt.after similarity index 100% rename from idea/testData/codeInsight/codeTransformations/branched/when/eliminateSubject/whenWithPatterns.kt.after rename to idea/testData/intentions/branched/when/eliminateSubject/whenWithPatterns.kt.after diff --git a/idea/testData/codeInsight/codeTransformations/branched/when/eliminateSubject/whenWithRangeTests.kt b/idea/testData/intentions/branched/when/eliminateSubject/whenWithRangeTests.kt similarity index 100% rename from idea/testData/codeInsight/codeTransformations/branched/when/eliminateSubject/whenWithRangeTests.kt rename to idea/testData/intentions/branched/when/eliminateSubject/whenWithRangeTests.kt diff --git a/idea/testData/codeInsight/codeTransformations/branched/when/eliminateSubject/whenWithRangeTests.kt.after b/idea/testData/intentions/branched/when/eliminateSubject/whenWithRangeTests.kt.after similarity index 100% rename from idea/testData/codeInsight/codeTransformations/branched/when/eliminateSubject/whenWithRangeTests.kt.after rename to idea/testData/intentions/branched/when/eliminateSubject/whenWithRangeTests.kt.after diff --git a/idea/testData/codeInsight/codeTransformations/branched/when/eliminateSubject/whenWithRangeTestsAndMultiConditions.kt b/idea/testData/intentions/branched/when/eliminateSubject/whenWithRangeTestsAndMultiConditions.kt similarity index 100% rename from idea/testData/codeInsight/codeTransformations/branched/when/eliminateSubject/whenWithRangeTestsAndMultiConditions.kt rename to idea/testData/intentions/branched/when/eliminateSubject/whenWithRangeTestsAndMultiConditions.kt diff --git a/idea/testData/codeInsight/codeTransformations/branched/when/eliminateSubject/whenWithRangeTestsAndMultiConditions.kt.after b/idea/testData/intentions/branched/when/eliminateSubject/whenWithRangeTestsAndMultiConditions.kt.after similarity index 100% rename from idea/testData/codeInsight/codeTransformations/branched/when/eliminateSubject/whenWithRangeTestsAndMultiConditions.kt.after rename to idea/testData/intentions/branched/when/eliminateSubject/whenWithRangeTestsAndMultiConditions.kt.after diff --git a/idea/testData/codeInsight/codeTransformations/branched/when/eliminateSubject/whenWithoutSubject.kt b/idea/testData/intentions/branched/when/eliminateSubject/whenWithoutSubject.kt similarity index 100% rename from idea/testData/codeInsight/codeTransformations/branched/when/eliminateSubject/whenWithoutSubject.kt rename to idea/testData/intentions/branched/when/eliminateSubject/whenWithoutSubject.kt diff --git a/idea/testData/codeInsight/codeTransformations/branched/when/flatten/flattenWithSubject.kt b/idea/testData/intentions/branched/when/flatten/flattenWithSubject.kt similarity index 100% rename from idea/testData/codeInsight/codeTransformations/branched/when/flatten/flattenWithSubject.kt rename to idea/testData/intentions/branched/when/flatten/flattenWithSubject.kt diff --git a/idea/testData/codeInsight/codeTransformations/branched/when/flatten/flattenWithSubject.kt.after b/idea/testData/intentions/branched/when/flatten/flattenWithSubject.kt.after similarity index 100% rename from idea/testData/codeInsight/codeTransformations/branched/when/flatten/flattenWithSubject.kt.after rename to idea/testData/intentions/branched/when/flatten/flattenWithSubject.kt.after diff --git a/idea/testData/codeInsight/codeTransformations/branched/when/flatten/flattenWithUnmatchedSubjects.kt b/idea/testData/intentions/branched/when/flatten/flattenWithUnmatchedSubjects.kt similarity index 100% rename from idea/testData/codeInsight/codeTransformations/branched/when/flatten/flattenWithUnmatchedSubjects.kt rename to idea/testData/intentions/branched/when/flatten/flattenWithUnmatchedSubjects.kt diff --git a/idea/testData/codeInsight/codeTransformations/branched/when/flatten/flattenWithoutSubject.kt b/idea/testData/intentions/branched/when/flatten/flattenWithoutSubject.kt similarity index 100% rename from idea/testData/codeInsight/codeTransformations/branched/when/flatten/flattenWithoutSubject.kt rename to idea/testData/intentions/branched/when/flatten/flattenWithoutSubject.kt diff --git a/idea/testData/codeInsight/codeTransformations/branched/when/flatten/flattenWithoutSubject.kt.after b/idea/testData/intentions/branched/when/flatten/flattenWithoutSubject.kt.after similarity index 100% rename from idea/testData/codeInsight/codeTransformations/branched/when/flatten/flattenWithoutSubject.kt.after rename to idea/testData/intentions/branched/when/flatten/flattenWithoutSubject.kt.after diff --git a/idea/testData/codeInsight/codeTransformations/branched/when/introduceSubject/whenWithEqualityTests.kt b/idea/testData/intentions/branched/when/introduceSubject/whenWithEqualityTests.kt similarity index 100% rename from idea/testData/codeInsight/codeTransformations/branched/when/introduceSubject/whenWithEqualityTests.kt rename to idea/testData/intentions/branched/when/introduceSubject/whenWithEqualityTests.kt diff --git a/idea/testData/codeInsight/codeTransformations/branched/when/introduceSubject/whenWithEqualityTests.kt.after b/idea/testData/intentions/branched/when/introduceSubject/whenWithEqualityTests.kt.after similarity index 100% rename from idea/testData/codeInsight/codeTransformations/branched/when/introduceSubject/whenWithEqualityTests.kt.after rename to idea/testData/intentions/branched/when/introduceSubject/whenWithEqualityTests.kt.after diff --git a/idea/testData/codeInsight/codeTransformations/branched/when/introduceSubject/whenWithMultipleConditionTypes.kt b/idea/testData/intentions/branched/when/introduceSubject/whenWithMultipleConditionTypes.kt similarity index 100% rename from idea/testData/codeInsight/codeTransformations/branched/when/introduceSubject/whenWithMultipleConditionTypes.kt rename to idea/testData/intentions/branched/when/introduceSubject/whenWithMultipleConditionTypes.kt diff --git a/idea/testData/codeInsight/codeTransformations/branched/when/introduceSubject/whenWithMultipleConditionTypes.kt.after b/idea/testData/intentions/branched/when/introduceSubject/whenWithMultipleConditionTypes.kt.after similarity index 100% rename from idea/testData/codeInsight/codeTransformations/branched/when/introduceSubject/whenWithMultipleConditionTypes.kt.after rename to idea/testData/intentions/branched/when/introduceSubject/whenWithMultipleConditionTypes.kt.after diff --git a/idea/testData/codeInsight/codeTransformations/branched/when/introduceSubject/whenWithNegativePatterns.kt b/idea/testData/intentions/branched/when/introduceSubject/whenWithNegativePatterns.kt similarity index 100% rename from idea/testData/codeInsight/codeTransformations/branched/when/introduceSubject/whenWithNegativePatterns.kt rename to idea/testData/intentions/branched/when/introduceSubject/whenWithNegativePatterns.kt diff --git a/idea/testData/codeInsight/codeTransformations/branched/when/introduceSubject/whenWithNegativePatterns.kt.after b/idea/testData/intentions/branched/when/introduceSubject/whenWithNegativePatterns.kt.after similarity index 100% rename from idea/testData/codeInsight/codeTransformations/branched/when/introduceSubject/whenWithNegativePatterns.kt.after rename to idea/testData/intentions/branched/when/introduceSubject/whenWithNegativePatterns.kt.after diff --git a/idea/testData/codeInsight/codeTransformations/branched/when/introduceSubject/whenWithNegativeRangeTests.kt b/idea/testData/intentions/branched/when/introduceSubject/whenWithNegativeRangeTests.kt similarity index 100% rename from idea/testData/codeInsight/codeTransformations/branched/when/introduceSubject/whenWithNegativeRangeTests.kt rename to idea/testData/intentions/branched/when/introduceSubject/whenWithNegativeRangeTests.kt diff --git a/idea/testData/codeInsight/codeTransformations/branched/when/introduceSubject/whenWithNegativeRangeTests.kt.after b/idea/testData/intentions/branched/when/introduceSubject/whenWithNegativeRangeTests.kt.after similarity index 100% rename from idea/testData/codeInsight/codeTransformations/branched/when/introduceSubject/whenWithNegativeRangeTests.kt.after rename to idea/testData/intentions/branched/when/introduceSubject/whenWithNegativeRangeTests.kt.after diff --git a/idea/testData/codeInsight/codeTransformations/branched/when/introduceSubject/whenWithNondivisibleConditions.kt b/idea/testData/intentions/branched/when/introduceSubject/whenWithNondivisibleConditions.kt similarity index 100% rename from idea/testData/codeInsight/codeTransformations/branched/when/introduceSubject/whenWithNondivisibleConditions.kt rename to idea/testData/intentions/branched/when/introduceSubject/whenWithNondivisibleConditions.kt diff --git a/idea/testData/codeInsight/codeTransformations/branched/when/introduceSubject/whenWithPatterns.kt b/idea/testData/intentions/branched/when/introduceSubject/whenWithPatterns.kt similarity index 100% rename from idea/testData/codeInsight/codeTransformations/branched/when/introduceSubject/whenWithPatterns.kt rename to idea/testData/intentions/branched/when/introduceSubject/whenWithPatterns.kt diff --git a/idea/testData/codeInsight/codeTransformations/branched/when/introduceSubject/whenWithPatterns.kt.after b/idea/testData/intentions/branched/when/introduceSubject/whenWithPatterns.kt.after similarity index 100% rename from idea/testData/codeInsight/codeTransformations/branched/when/introduceSubject/whenWithPatterns.kt.after rename to idea/testData/intentions/branched/when/introduceSubject/whenWithPatterns.kt.after diff --git a/idea/testData/codeInsight/codeTransformations/branched/when/introduceSubject/whenWithRangeTests.kt b/idea/testData/intentions/branched/when/introduceSubject/whenWithRangeTests.kt similarity index 100% rename from idea/testData/codeInsight/codeTransformations/branched/when/introduceSubject/whenWithRangeTests.kt rename to idea/testData/intentions/branched/when/introduceSubject/whenWithRangeTests.kt diff --git a/idea/testData/codeInsight/codeTransformations/branched/when/introduceSubject/whenWithRangeTests.kt.after b/idea/testData/intentions/branched/when/introduceSubject/whenWithRangeTests.kt.after similarity index 100% rename from idea/testData/codeInsight/codeTransformations/branched/when/introduceSubject/whenWithRangeTests.kt.after rename to idea/testData/intentions/branched/when/introduceSubject/whenWithRangeTests.kt.after diff --git a/idea/testData/codeInsight/codeTransformations/branched/when/introduceSubject/whenWithRangeTestsAndMultiConditions.kt b/idea/testData/intentions/branched/when/introduceSubject/whenWithRangeTestsAndMultiConditions.kt similarity index 100% rename from idea/testData/codeInsight/codeTransformations/branched/when/introduceSubject/whenWithRangeTestsAndMultiConditions.kt rename to idea/testData/intentions/branched/when/introduceSubject/whenWithRangeTestsAndMultiConditions.kt diff --git a/idea/testData/codeInsight/codeTransformations/branched/when/introduceSubject/whenWithRangeTestsAndMultiConditions.kt.after b/idea/testData/intentions/branched/when/introduceSubject/whenWithRangeTestsAndMultiConditions.kt.after similarity index 100% rename from idea/testData/codeInsight/codeTransformations/branched/when/introduceSubject/whenWithRangeTestsAndMultiConditions.kt.after rename to idea/testData/intentions/branched/when/introduceSubject/whenWithRangeTestsAndMultiConditions.kt.after diff --git a/idea/testData/codeInsight/codeTransformations/branched/when/introduceSubject/whenWithSubject.kt b/idea/testData/intentions/branched/when/introduceSubject/whenWithSubject.kt similarity index 100% rename from idea/testData/codeInsight/codeTransformations/branched/when/introduceSubject/whenWithSubject.kt rename to idea/testData/intentions/branched/when/introduceSubject/whenWithSubject.kt diff --git a/idea/testData/codeInsight/codeTransformations/branched/when/introduceSubject/whenWithSwappedEqualityTests.kt b/idea/testData/intentions/branched/when/introduceSubject/whenWithSwappedEqualityTests.kt similarity index 100% rename from idea/testData/codeInsight/codeTransformations/branched/when/introduceSubject/whenWithSwappedEqualityTests.kt rename to idea/testData/intentions/branched/when/introduceSubject/whenWithSwappedEqualityTests.kt diff --git a/idea/testData/codeInsight/codeTransformations/branched/when/introduceSubject/whenWithSwappedEqualityTests.kt.after b/idea/testData/intentions/branched/when/introduceSubject/whenWithSwappedEqualityTests.kt.after similarity index 100% rename from idea/testData/codeInsight/codeTransformations/branched/when/introduceSubject/whenWithSwappedEqualityTests.kt.after rename to idea/testData/intentions/branched/when/introduceSubject/whenWithSwappedEqualityTests.kt.after diff --git a/idea/testData/codeInsight/codeTransformations/branched/when/introduceSubject/whenWithUnmatchedCandidateSubjects.kt b/idea/testData/intentions/branched/when/introduceSubject/whenWithUnmatchedCandidateSubjects.kt similarity index 100% rename from idea/testData/codeInsight/codeTransformations/branched/when/introduceSubject/whenWithUnmatchedCandidateSubjects.kt rename to idea/testData/intentions/branched/when/introduceSubject/whenWithUnmatchedCandidateSubjects.kt diff --git a/idea/testData/codeInsight/codeTransformations/declarations/join/longInit.kt b/idea/testData/intentions/declarations/join/longInit.kt similarity index 100% rename from idea/testData/codeInsight/codeTransformations/declarations/join/longInit.kt rename to idea/testData/intentions/declarations/join/longInit.kt diff --git a/idea/testData/codeInsight/codeTransformations/declarations/join/longInit.kt.after b/idea/testData/intentions/declarations/join/longInit.kt.after similarity index 100% rename from idea/testData/codeInsight/codeTransformations/declarations/join/longInit.kt.after rename to idea/testData/intentions/declarations/join/longInit.kt.after diff --git a/idea/testData/codeInsight/codeTransformations/declarations/join/longInit2.kt b/idea/testData/intentions/declarations/join/longInit2.kt similarity index 100% rename from idea/testData/codeInsight/codeTransformations/declarations/join/longInit2.kt rename to idea/testData/intentions/declarations/join/longInit2.kt diff --git a/idea/testData/codeInsight/codeTransformations/declarations/join/longInit2.kt.after b/idea/testData/intentions/declarations/join/longInit2.kt.after similarity index 100% rename from idea/testData/codeInsight/codeTransformations/declarations/join/longInit2.kt.after rename to idea/testData/intentions/declarations/join/longInit2.kt.after diff --git a/idea/testData/codeInsight/codeTransformations/declarations/join/simpleInit.kt b/idea/testData/intentions/declarations/join/simpleInit.kt similarity index 100% rename from idea/testData/codeInsight/codeTransformations/declarations/join/simpleInit.kt rename to idea/testData/intentions/declarations/join/simpleInit.kt diff --git a/idea/testData/codeInsight/codeTransformations/declarations/join/simpleInit.kt.after b/idea/testData/intentions/declarations/join/simpleInit.kt.after similarity index 100% rename from idea/testData/codeInsight/codeTransformations/declarations/join/simpleInit.kt.after rename to idea/testData/intentions/declarations/join/simpleInit.kt.after diff --git a/idea/testData/codeInsight/codeTransformations/declarations/join/simpleInit2.kt b/idea/testData/intentions/declarations/join/simpleInit2.kt similarity index 100% rename from idea/testData/codeInsight/codeTransformations/declarations/join/simpleInit2.kt rename to idea/testData/intentions/declarations/join/simpleInit2.kt diff --git a/idea/testData/codeInsight/codeTransformations/declarations/join/simpleInit2.kt.after b/idea/testData/intentions/declarations/join/simpleInit2.kt.after similarity index 100% rename from idea/testData/codeInsight/codeTransformations/declarations/join/simpleInit2.kt.after rename to idea/testData/intentions/declarations/join/simpleInit2.kt.after diff --git a/idea/testData/codeInsight/codeTransformations/declarations/join/simpleInitWithBackticks.kt b/idea/testData/intentions/declarations/join/simpleInitWithBackticks.kt similarity index 100% rename from idea/testData/codeInsight/codeTransformations/declarations/join/simpleInitWithBackticks.kt rename to idea/testData/intentions/declarations/join/simpleInitWithBackticks.kt diff --git a/idea/testData/codeInsight/codeTransformations/declarations/join/simpleInitWithBackticks.kt.after b/idea/testData/intentions/declarations/join/simpleInitWithBackticks.kt.after similarity index 100% rename from idea/testData/codeInsight/codeTransformations/declarations/join/simpleInitWithBackticks.kt.after rename to idea/testData/intentions/declarations/join/simpleInitWithBackticks.kt.after diff --git a/idea/testData/codeInsight/codeTransformations/declarations/join/simpleInitWithBackticks2.kt b/idea/testData/intentions/declarations/join/simpleInitWithBackticks2.kt similarity index 100% rename from idea/testData/codeInsight/codeTransformations/declarations/join/simpleInitWithBackticks2.kt rename to idea/testData/intentions/declarations/join/simpleInitWithBackticks2.kt diff --git a/idea/testData/codeInsight/codeTransformations/declarations/join/simpleInitWithBackticks2.kt.after b/idea/testData/intentions/declarations/join/simpleInitWithBackticks2.kt.after similarity index 100% rename from idea/testData/codeInsight/codeTransformations/declarations/join/simpleInitWithBackticks2.kt.after rename to idea/testData/intentions/declarations/join/simpleInitWithBackticks2.kt.after diff --git a/idea/testData/codeInsight/codeTransformations/declarations/join/simpleInitWithBackticks3.kt b/idea/testData/intentions/declarations/join/simpleInitWithBackticks3.kt similarity index 100% rename from idea/testData/codeInsight/codeTransformations/declarations/join/simpleInitWithBackticks3.kt rename to idea/testData/intentions/declarations/join/simpleInitWithBackticks3.kt diff --git a/idea/testData/codeInsight/codeTransformations/declarations/join/simpleInitWithBackticks3.kt.after b/idea/testData/intentions/declarations/join/simpleInitWithBackticks3.kt.after similarity index 100% rename from idea/testData/codeInsight/codeTransformations/declarations/join/simpleInitWithBackticks3.kt.after rename to idea/testData/intentions/declarations/join/simpleInitWithBackticks3.kt.after diff --git a/idea/testData/codeInsight/codeTransformations/declarations/join/simpleInitWithComments.kt b/idea/testData/intentions/declarations/join/simpleInitWithComments.kt similarity index 100% rename from idea/testData/codeInsight/codeTransformations/declarations/join/simpleInitWithComments.kt rename to idea/testData/intentions/declarations/join/simpleInitWithComments.kt diff --git a/idea/testData/codeInsight/codeTransformations/declarations/join/simpleInitWithComments.kt.after b/idea/testData/intentions/declarations/join/simpleInitWithComments.kt.after similarity index 100% rename from idea/testData/codeInsight/codeTransformations/declarations/join/simpleInitWithComments.kt.after rename to idea/testData/intentions/declarations/join/simpleInitWithComments.kt.after diff --git a/idea/testData/codeInsight/codeTransformations/declarations/join/simpleInitWithComments2.kt b/idea/testData/intentions/declarations/join/simpleInitWithComments2.kt similarity index 100% rename from idea/testData/codeInsight/codeTransformations/declarations/join/simpleInitWithComments2.kt rename to idea/testData/intentions/declarations/join/simpleInitWithComments2.kt diff --git a/idea/testData/codeInsight/codeTransformations/declarations/join/simpleInitWithComments2.kt.after b/idea/testData/intentions/declarations/join/simpleInitWithComments2.kt.after similarity index 100% rename from idea/testData/codeInsight/codeTransformations/declarations/join/simpleInitWithComments2.kt.after rename to idea/testData/intentions/declarations/join/simpleInitWithComments2.kt.after diff --git a/idea/testData/codeInsight/codeTransformations/declarations/join/simpleInitWithSemicolons.kt b/idea/testData/intentions/declarations/join/simpleInitWithSemicolons.kt similarity index 100% rename from idea/testData/codeInsight/codeTransformations/declarations/join/simpleInitWithSemicolons.kt rename to idea/testData/intentions/declarations/join/simpleInitWithSemicolons.kt diff --git a/idea/testData/codeInsight/codeTransformations/declarations/join/simpleInitWithSemicolons.kt.after b/idea/testData/intentions/declarations/join/simpleInitWithSemicolons.kt.after similarity index 100% rename from idea/testData/codeInsight/codeTransformations/declarations/join/simpleInitWithSemicolons.kt.after rename to idea/testData/intentions/declarations/join/simpleInitWithSemicolons.kt.after diff --git a/idea/testData/codeInsight/codeTransformations/declarations/join/simpleInitWithSemicolons2.kt b/idea/testData/intentions/declarations/join/simpleInitWithSemicolons2.kt similarity index 100% rename from idea/testData/codeInsight/codeTransformations/declarations/join/simpleInitWithSemicolons2.kt rename to idea/testData/intentions/declarations/join/simpleInitWithSemicolons2.kt diff --git a/idea/testData/codeInsight/codeTransformations/declarations/join/simpleInitWithSemicolons2.kt.after b/idea/testData/intentions/declarations/join/simpleInitWithSemicolons2.kt.after similarity index 100% rename from idea/testData/codeInsight/codeTransformations/declarations/join/simpleInitWithSemicolons2.kt.after rename to idea/testData/intentions/declarations/join/simpleInitWithSemicolons2.kt.after diff --git a/idea/testData/codeInsight/codeTransformations/declarations/join/simpleInitWithSemicolons3.kt b/idea/testData/intentions/declarations/join/simpleInitWithSemicolons3.kt similarity index 100% rename from idea/testData/codeInsight/codeTransformations/declarations/join/simpleInitWithSemicolons3.kt rename to idea/testData/intentions/declarations/join/simpleInitWithSemicolons3.kt diff --git a/idea/testData/codeInsight/codeTransformations/declarations/join/simpleInitWithSemicolons3.kt.after b/idea/testData/intentions/declarations/join/simpleInitWithSemicolons3.kt.after similarity index 100% rename from idea/testData/codeInsight/codeTransformations/declarations/join/simpleInitWithSemicolons3.kt.after rename to idea/testData/intentions/declarations/join/simpleInitWithSemicolons3.kt.after diff --git a/idea/testData/codeInsight/codeTransformations/declarations/join/simpleInitWithType.kt b/idea/testData/intentions/declarations/join/simpleInitWithType.kt similarity index 100% rename from idea/testData/codeInsight/codeTransformations/declarations/join/simpleInitWithType.kt rename to idea/testData/intentions/declarations/join/simpleInitWithType.kt diff --git a/idea/testData/codeInsight/codeTransformations/declarations/join/simpleInitWithType.kt.after b/idea/testData/intentions/declarations/join/simpleInitWithType.kt.after similarity index 100% rename from idea/testData/codeInsight/codeTransformations/declarations/join/simpleInitWithType.kt.after rename to idea/testData/intentions/declarations/join/simpleInitWithType.kt.after diff --git a/idea/testData/codeInsight/codeTransformations/declarations/join/simpleInitWithType2.kt b/idea/testData/intentions/declarations/join/simpleInitWithType2.kt similarity index 100% rename from idea/testData/codeInsight/codeTransformations/declarations/join/simpleInitWithType2.kt rename to idea/testData/intentions/declarations/join/simpleInitWithType2.kt diff --git a/idea/testData/codeInsight/codeTransformations/declarations/join/simpleInitWithType2.kt.after b/idea/testData/intentions/declarations/join/simpleInitWithType2.kt.after similarity index 100% rename from idea/testData/codeInsight/codeTransformations/declarations/join/simpleInitWithType2.kt.after rename to idea/testData/intentions/declarations/join/simpleInitWithType2.kt.after diff --git a/idea/testData/codeInsight/codeTransformations/declarations/split/longInit.kt b/idea/testData/intentions/declarations/split/longInit.kt similarity index 100% rename from idea/testData/codeInsight/codeTransformations/declarations/split/longInit.kt rename to idea/testData/intentions/declarations/split/longInit.kt diff --git a/idea/testData/codeInsight/codeTransformations/declarations/split/longInit.kt.after b/idea/testData/intentions/declarations/split/longInit.kt.after similarity index 100% rename from idea/testData/codeInsight/codeTransformations/declarations/split/longInit.kt.after rename to idea/testData/intentions/declarations/split/longInit.kt.after diff --git a/idea/testData/codeInsight/codeTransformations/declarations/split/longInit2.kt b/idea/testData/intentions/declarations/split/longInit2.kt similarity index 100% rename from idea/testData/codeInsight/codeTransformations/declarations/split/longInit2.kt rename to idea/testData/intentions/declarations/split/longInit2.kt diff --git a/idea/testData/codeInsight/codeTransformations/declarations/split/longInit2.kt.after b/idea/testData/intentions/declarations/split/longInit2.kt.after similarity index 100% rename from idea/testData/codeInsight/codeTransformations/declarations/split/longInit2.kt.after rename to idea/testData/intentions/declarations/split/longInit2.kt.after diff --git a/idea/testData/codeInsight/codeTransformations/declarations/split/noInitializer.kt b/idea/testData/intentions/declarations/split/noInitializer.kt similarity index 100% rename from idea/testData/codeInsight/codeTransformations/declarations/split/noInitializer.kt rename to idea/testData/intentions/declarations/split/noInitializer.kt diff --git a/idea/testData/codeInsight/codeTransformations/declarations/split/noInitializer2.kt b/idea/testData/intentions/declarations/split/noInitializer2.kt similarity index 100% rename from idea/testData/codeInsight/codeTransformations/declarations/split/noInitializer2.kt rename to idea/testData/intentions/declarations/split/noInitializer2.kt diff --git a/idea/testData/codeInsight/codeTransformations/declarations/split/nonLocalProperty.kt b/idea/testData/intentions/declarations/split/nonLocalProperty.kt similarity index 100% rename from idea/testData/codeInsight/codeTransformations/declarations/split/nonLocalProperty.kt rename to idea/testData/intentions/declarations/split/nonLocalProperty.kt diff --git a/idea/testData/codeInsight/codeTransformations/declarations/split/nonLocalProperty2.kt b/idea/testData/intentions/declarations/split/nonLocalProperty2.kt similarity index 100% rename from idea/testData/codeInsight/codeTransformations/declarations/split/nonLocalProperty2.kt rename to idea/testData/intentions/declarations/split/nonLocalProperty2.kt diff --git a/idea/testData/codeInsight/codeTransformations/declarations/split/simpleInit.kt b/idea/testData/intentions/declarations/split/simpleInit.kt similarity index 100% rename from idea/testData/codeInsight/codeTransformations/declarations/split/simpleInit.kt rename to idea/testData/intentions/declarations/split/simpleInit.kt diff --git a/idea/testData/codeInsight/codeTransformations/declarations/split/simpleInit.kt.after b/idea/testData/intentions/declarations/split/simpleInit.kt.after similarity index 100% rename from idea/testData/codeInsight/codeTransformations/declarations/split/simpleInit.kt.after rename to idea/testData/intentions/declarations/split/simpleInit.kt.after diff --git a/idea/testData/codeInsight/codeTransformations/declarations/split/simpleInit2.kt b/idea/testData/intentions/declarations/split/simpleInit2.kt similarity index 100% rename from idea/testData/codeInsight/codeTransformations/declarations/split/simpleInit2.kt rename to idea/testData/intentions/declarations/split/simpleInit2.kt diff --git a/idea/testData/codeInsight/codeTransformations/declarations/split/simpleInit2.kt.after b/idea/testData/intentions/declarations/split/simpleInit2.kt.after similarity index 100% rename from idea/testData/codeInsight/codeTransformations/declarations/split/simpleInit2.kt.after rename to idea/testData/intentions/declarations/split/simpleInit2.kt.after diff --git a/idea/testData/codeInsight/codeTransformations/declarations/split/simpleInitWithErrorType.kt b/idea/testData/intentions/declarations/split/simpleInitWithErrorType.kt similarity index 100% rename from idea/testData/codeInsight/codeTransformations/declarations/split/simpleInitWithErrorType.kt rename to idea/testData/intentions/declarations/split/simpleInitWithErrorType.kt diff --git a/idea/testData/codeInsight/codeTransformations/declarations/split/simpleInitWithErrorType.kt.after b/idea/testData/intentions/declarations/split/simpleInitWithErrorType.kt.after similarity index 100% rename from idea/testData/codeInsight/codeTransformations/declarations/split/simpleInitWithErrorType.kt.after rename to idea/testData/intentions/declarations/split/simpleInitWithErrorType.kt.after diff --git a/idea/testData/codeInsight/codeTransformations/declarations/split/simpleInitWithErrorType2.kt b/idea/testData/intentions/declarations/split/simpleInitWithErrorType2.kt similarity index 100% rename from idea/testData/codeInsight/codeTransformations/declarations/split/simpleInitWithErrorType2.kt rename to idea/testData/intentions/declarations/split/simpleInitWithErrorType2.kt diff --git a/idea/testData/codeInsight/codeTransformations/declarations/split/simpleInitWithErrorType2.kt.after b/idea/testData/intentions/declarations/split/simpleInitWithErrorType2.kt.after similarity index 100% rename from idea/testData/codeInsight/codeTransformations/declarations/split/simpleInitWithErrorType2.kt.after rename to idea/testData/intentions/declarations/split/simpleInitWithErrorType2.kt.after diff --git a/idea/testData/codeInsight/codeTransformations/declarations/split/simpleInitWithType.kt b/idea/testData/intentions/declarations/split/simpleInitWithType.kt similarity index 100% rename from idea/testData/codeInsight/codeTransformations/declarations/split/simpleInitWithType.kt rename to idea/testData/intentions/declarations/split/simpleInitWithType.kt diff --git a/idea/testData/codeInsight/codeTransformations/declarations/split/simpleInitWithType.kt.after b/idea/testData/intentions/declarations/split/simpleInitWithType.kt.after similarity index 100% rename from idea/testData/codeInsight/codeTransformations/declarations/split/simpleInitWithType.kt.after rename to idea/testData/intentions/declarations/split/simpleInitWithType.kt.after diff --git a/idea/testData/codeInsight/codeTransformations/declarations/split/simpleInitWithType2.kt b/idea/testData/intentions/declarations/split/simpleInitWithType2.kt similarity index 100% rename from idea/testData/codeInsight/codeTransformations/declarations/split/simpleInitWithType2.kt rename to idea/testData/intentions/declarations/split/simpleInitWithType2.kt diff --git a/idea/testData/codeInsight/codeTransformations/declarations/split/simpleInitWithType2.kt.after b/idea/testData/intentions/declarations/split/simpleInitWithType2.kt.after similarity index 100% rename from idea/testData/codeInsight/codeTransformations/declarations/split/simpleInitWithType2.kt.after rename to idea/testData/intentions/declarations/split/simpleInitWithType2.kt.after diff --git a/idea/testData/codeInsight/codeTransformations/removeUnnecessaryParentheses/necessaryParentheses1.kt b/idea/testData/intentions/removeUnnecessaryParentheses/necessaryParentheses1.kt similarity index 100% rename from idea/testData/codeInsight/codeTransformations/removeUnnecessaryParentheses/necessaryParentheses1.kt rename to idea/testData/intentions/removeUnnecessaryParentheses/necessaryParentheses1.kt diff --git a/idea/testData/codeInsight/codeTransformations/removeUnnecessaryParentheses/necessaryParentheses2.kt b/idea/testData/intentions/removeUnnecessaryParentheses/necessaryParentheses2.kt similarity index 100% rename from idea/testData/codeInsight/codeTransformations/removeUnnecessaryParentheses/necessaryParentheses2.kt rename to idea/testData/intentions/removeUnnecessaryParentheses/necessaryParentheses2.kt diff --git a/idea/testData/codeInsight/codeTransformations/removeUnnecessaryParentheses/necessaryParentheses3.kt b/idea/testData/intentions/removeUnnecessaryParentheses/necessaryParentheses3.kt similarity index 100% rename from idea/testData/codeInsight/codeTransformations/removeUnnecessaryParentheses/necessaryParentheses3.kt rename to idea/testData/intentions/removeUnnecessaryParentheses/necessaryParentheses3.kt diff --git a/idea/testData/codeInsight/codeTransformations/removeUnnecessaryParentheses/necessaryParentheses4.kt b/idea/testData/intentions/removeUnnecessaryParentheses/necessaryParentheses4.kt similarity index 100% rename from idea/testData/codeInsight/codeTransformations/removeUnnecessaryParentheses/necessaryParentheses4.kt rename to idea/testData/intentions/removeUnnecessaryParentheses/necessaryParentheses4.kt diff --git a/idea/testData/codeInsight/codeTransformations/removeUnnecessaryParentheses/necessaryParentheses5.kt b/idea/testData/intentions/removeUnnecessaryParentheses/necessaryParentheses5.kt similarity index 100% rename from idea/testData/codeInsight/codeTransformations/removeUnnecessaryParentheses/necessaryParentheses5.kt rename to idea/testData/intentions/removeUnnecessaryParentheses/necessaryParentheses5.kt diff --git a/idea/testData/codeInsight/codeTransformations/removeUnnecessaryParentheses/unnecessaryParentheses1.kt b/idea/testData/intentions/removeUnnecessaryParentheses/unnecessaryParentheses1.kt similarity index 100% rename from idea/testData/codeInsight/codeTransformations/removeUnnecessaryParentheses/unnecessaryParentheses1.kt rename to idea/testData/intentions/removeUnnecessaryParentheses/unnecessaryParentheses1.kt diff --git a/idea/testData/codeInsight/codeTransformations/removeUnnecessaryParentheses/unnecessaryParentheses1.kt.after b/idea/testData/intentions/removeUnnecessaryParentheses/unnecessaryParentheses1.kt.after similarity index 100% rename from idea/testData/codeInsight/codeTransformations/removeUnnecessaryParentheses/unnecessaryParentheses1.kt.after rename to idea/testData/intentions/removeUnnecessaryParentheses/unnecessaryParentheses1.kt.after diff --git a/idea/testData/codeInsight/codeTransformations/removeUnnecessaryParentheses/unnecessaryParentheses2.kt b/idea/testData/intentions/removeUnnecessaryParentheses/unnecessaryParentheses2.kt similarity index 100% rename from idea/testData/codeInsight/codeTransformations/removeUnnecessaryParentheses/unnecessaryParentheses2.kt rename to idea/testData/intentions/removeUnnecessaryParentheses/unnecessaryParentheses2.kt diff --git a/idea/testData/codeInsight/codeTransformations/removeUnnecessaryParentheses/unnecessaryParentheses2.kt.after b/idea/testData/intentions/removeUnnecessaryParentheses/unnecessaryParentheses2.kt.after similarity index 100% rename from idea/testData/codeInsight/codeTransformations/removeUnnecessaryParentheses/unnecessaryParentheses2.kt.after rename to idea/testData/intentions/removeUnnecessaryParentheses/unnecessaryParentheses2.kt.after diff --git a/idea/testData/codeInsight/codeTransformations/removeUnnecessaryParentheses/unnecessaryParentheses3.kt b/idea/testData/intentions/removeUnnecessaryParentheses/unnecessaryParentheses3.kt similarity index 100% rename from idea/testData/codeInsight/codeTransformations/removeUnnecessaryParentheses/unnecessaryParentheses3.kt rename to idea/testData/intentions/removeUnnecessaryParentheses/unnecessaryParentheses3.kt diff --git a/idea/testData/codeInsight/codeTransformations/removeUnnecessaryParentheses/unnecessaryParentheses3.kt.after b/idea/testData/intentions/removeUnnecessaryParentheses/unnecessaryParentheses3.kt.after similarity index 100% rename from idea/testData/codeInsight/codeTransformations/removeUnnecessaryParentheses/unnecessaryParentheses3.kt.after rename to idea/testData/intentions/removeUnnecessaryParentheses/unnecessaryParentheses3.kt.after diff --git a/idea/testData/codeInsight/codeTransformations/removeUnnecessaryParentheses/unnecessaryParentheses4.kt b/idea/testData/intentions/removeUnnecessaryParentheses/unnecessaryParentheses4.kt similarity index 100% rename from idea/testData/codeInsight/codeTransformations/removeUnnecessaryParentheses/unnecessaryParentheses4.kt rename to idea/testData/intentions/removeUnnecessaryParentheses/unnecessaryParentheses4.kt diff --git a/idea/testData/codeInsight/codeTransformations/removeUnnecessaryParentheses/unnecessaryParentheses4.kt.after b/idea/testData/intentions/removeUnnecessaryParentheses/unnecessaryParentheses4.kt.after similarity index 100% rename from idea/testData/codeInsight/codeTransformations/removeUnnecessaryParentheses/unnecessaryParentheses4.kt.after rename to idea/testData/intentions/removeUnnecessaryParentheses/unnecessaryParentheses4.kt.after diff --git a/idea/testData/codeInsight/codeTransformations/removeUnnecessaryParentheses/unnecessaryParentheses5.kt b/idea/testData/intentions/removeUnnecessaryParentheses/unnecessaryParentheses5.kt similarity index 100% rename from idea/testData/codeInsight/codeTransformations/removeUnnecessaryParentheses/unnecessaryParentheses5.kt rename to idea/testData/intentions/removeUnnecessaryParentheses/unnecessaryParentheses5.kt diff --git a/idea/testData/codeInsight/codeTransformations/removeUnnecessaryParentheses/unnecessaryParentheses5.kt.after b/idea/testData/intentions/removeUnnecessaryParentheses/unnecessaryParentheses5.kt.after similarity index 100% rename from idea/testData/codeInsight/codeTransformations/removeUnnecessaryParentheses/unnecessaryParentheses5.kt.after rename to idea/testData/intentions/removeUnnecessaryParentheses/unnecessaryParentheses5.kt.after diff --git a/idea/testData/codeInsight/codeTransformations/removeUnnecessaryParentheses/unnecessaryParentheses6.kt b/idea/testData/intentions/removeUnnecessaryParentheses/unnecessaryParentheses6.kt similarity index 100% rename from idea/testData/codeInsight/codeTransformations/removeUnnecessaryParentheses/unnecessaryParentheses6.kt rename to idea/testData/intentions/removeUnnecessaryParentheses/unnecessaryParentheses6.kt diff --git a/idea/testData/codeInsight/codeTransformations/removeUnnecessaryParentheses/unnecessaryParentheses6.kt.after b/idea/testData/intentions/removeUnnecessaryParentheses/unnecessaryParentheses6.kt.after similarity index 100% rename from idea/testData/codeInsight/codeTransformations/removeUnnecessaryParentheses/unnecessaryParentheses6.kt.after rename to idea/testData/intentions/removeUnnecessaryParentheses/unnecessaryParentheses6.kt.after diff --git a/idea/testData/codeInsight/codeTransformations/removeUnnecessaryParentheses/unnecessaryParentheses7.kt b/idea/testData/intentions/removeUnnecessaryParentheses/unnecessaryParentheses7.kt similarity index 100% rename from idea/testData/codeInsight/codeTransformations/removeUnnecessaryParentheses/unnecessaryParentheses7.kt rename to idea/testData/intentions/removeUnnecessaryParentheses/unnecessaryParentheses7.kt diff --git a/idea/testData/codeInsight/codeTransformations/removeUnnecessaryParentheses/unnecessaryParentheses7.kt.after b/idea/testData/intentions/removeUnnecessaryParentheses/unnecessaryParentheses7.kt.after similarity index 100% rename from idea/testData/codeInsight/codeTransformations/removeUnnecessaryParentheses/unnecessaryParentheses7.kt.after rename to idea/testData/intentions/removeUnnecessaryParentheses/unnecessaryParentheses7.kt.after diff --git a/idea/tests/org/jetbrains/jet/plugin/codeInsight/codeTransformations/AbstractCodeTransformationTest.java b/idea/tests/org/jetbrains/jet/plugin/intentions/AbstractCodeTransformationTest.java similarity index 94% rename from idea/tests/org/jetbrains/jet/plugin/codeInsight/codeTransformations/AbstractCodeTransformationTest.java rename to idea/tests/org/jetbrains/jet/plugin/intentions/AbstractCodeTransformationTest.java index b5407f37d2b..80382dcdef5 100644 --- a/idea/tests/org/jetbrains/jet/plugin/codeInsight/codeTransformations/AbstractCodeTransformationTest.java +++ b/idea/tests/org/jetbrains/jet/plugin/intentions/AbstractCodeTransformationTest.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.jetbrains.jet.plugin.codeInsight.codeTransformations; +package org.jetbrains.jet.plugin.intentions; import com.intellij.codeInsight.editorActions.JoinLinesHandler; import com.intellij.codeInsight.intention.IntentionAction; @@ -23,8 +23,9 @@ 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.intentions.*; -import org.jetbrains.jet.plugin.codeInsight.codeTransformations.declarations.SplitPropertyDeclarationIntention; +import org.jetbrains.jet.plugin.intentions.RemoveUnnecessaryParenthesesIntention; +import org.jetbrains.jet.plugin.intentions.branchedTransformations.intentions.*; +import org.jetbrains.jet.plugin.intentions.declarations.SplitPropertyDeclarationIntention; import java.io.File; diff --git a/idea/tests/org/jetbrains/jet/plugin/codeInsight/codeTransformations/CodeTransformationsTestGenerated.java b/idea/tests/org/jetbrains/jet/plugin/intentions/CodeTransformationsTestGenerated.java similarity index 54% rename from idea/tests/org/jetbrains/jet/plugin/codeInsight/codeTransformations/CodeTransformationsTestGenerated.java rename to idea/tests/org/jetbrains/jet/plugin/intentions/CodeTransformationsTestGenerated.java index abc0b628fe8..586744b7b3f 100644 --- a/idea/tests/org/jetbrains/jet/plugin/codeInsight/codeTransformations/CodeTransformationsTestGenerated.java +++ b/idea/tests/org/jetbrains/jet/plugin/intentions/CodeTransformationsTestGenerated.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.jetbrains.jet.plugin.codeInsight.codeTransformations; +package org.jetbrains.jet.plugin.intentions; import junit.framework.Assert; import junit.framework.Test; @@ -26,835 +26,835 @@ import org.jetbrains.jet.JetTestUtils; import org.jetbrains.jet.test.InnerTestClasses; import org.jetbrains.jet.test.TestMetadata; -import org.jetbrains.jet.plugin.codeInsight.codeTransformations.AbstractCodeTransformationTest; +import org.jetbrains.jet.plugin.intentions.AbstractCodeTransformationTest; /** 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.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, CodeTransformationsTestGenerated.Split.class, CodeTransformationsTestGenerated.Join.class, CodeTransformationsTestGenerated.RemoveUnnecessaryParentheses.class}) public class CodeTransformationsTestGenerated extends AbstractCodeTransformationTest { - @TestMetadata("idea/testData/codeInsight/codeTransformations/branched/folding/ifToAssignment") + @TestMetadata("idea/testData/intentions/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); + JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.GenerateTests", new File("idea/testData/intentions/branched/folding/ifToAssignment"), Pattern.compile("^(.+)\\.kt$"), true); } @TestMetadata("innerIfTransformed.kt") public void testInnerIfTransformed() throws Exception { - doTestFoldIfToAssignment("idea/testData/codeInsight/codeTransformations/branched/folding/ifToAssignment/innerIfTransformed.kt"); + doTestFoldIfToAssignment("idea/testData/intentions/branched/folding/ifToAssignment/innerIfTransformed.kt"); } @TestMetadata("simpleIf.kt") public void testSimpleIf() throws Exception { - doTestFoldIfToAssignment("idea/testData/codeInsight/codeTransformations/branched/folding/ifToAssignment/simpleIf.kt"); + doTestFoldIfToAssignment("idea/testData/intentions/branched/folding/ifToAssignment/simpleIf.kt"); } @TestMetadata("simpleIfWithAugmentedAssignment.kt") public void testSimpleIfWithAugmentedAssignment() throws Exception { - doTestFoldIfToAssignment("idea/testData/codeInsight/codeTransformations/branched/folding/ifToAssignment/simpleIfWithAugmentedAssignment.kt"); + doTestFoldIfToAssignment("idea/testData/intentions/branched/folding/ifToAssignment/simpleIfWithAugmentedAssignment.kt"); } @TestMetadata("simpleIfWithBlocks.kt") public void testSimpleIfWithBlocks() throws Exception { - doTestFoldIfToAssignment("idea/testData/codeInsight/codeTransformations/branched/folding/ifToAssignment/simpleIfWithBlocks.kt"); + doTestFoldIfToAssignment("idea/testData/intentions/branched/folding/ifToAssignment/simpleIfWithBlocks.kt"); } @TestMetadata("simpleIfWithShadowedVar.kt") public void testSimpleIfWithShadowedVar() throws Exception { - doTestFoldIfToAssignment("idea/testData/codeInsight/codeTransformations/branched/folding/ifToAssignment/simpleIfWithShadowedVar.kt"); + doTestFoldIfToAssignment("idea/testData/intentions/branched/folding/ifToAssignment/simpleIfWithShadowedVar.kt"); } @TestMetadata("simpleIfWithUnmatchedAssignmentOps.kt") public void testSimpleIfWithUnmatchedAssignmentOps() throws Exception { - doTestFoldIfToAssignment("idea/testData/codeInsight/codeTransformations/branched/folding/ifToAssignment/simpleIfWithUnmatchedAssignmentOps.kt"); + doTestFoldIfToAssignment("idea/testData/intentions/branched/folding/ifToAssignment/simpleIfWithUnmatchedAssignmentOps.kt"); } @TestMetadata("simpleIfWithUnmatchedAssignments.kt") public void testSimpleIfWithUnmatchedAssignments() throws Exception { - doTestFoldIfToAssignment("idea/testData/codeInsight/codeTransformations/branched/folding/ifToAssignment/simpleIfWithUnmatchedAssignments.kt"); + doTestFoldIfToAssignment("idea/testData/intentions/branched/folding/ifToAssignment/simpleIfWithUnmatchedAssignments.kt"); } @TestMetadata("simpleIfWithoutElse.kt") public void testSimpleIfWithoutElse() throws Exception { - doTestFoldIfToAssignment("idea/testData/codeInsight/codeTransformations/branched/folding/ifToAssignment/simpleIfWithoutElse.kt"); + doTestFoldIfToAssignment("idea/testData/intentions/branched/folding/ifToAssignment/simpleIfWithoutElse.kt"); } @TestMetadata("simpleIfWithoutTerminatingAssignment.kt") public void testSimpleIfWithoutTerminatingAssignment() throws Exception { - doTestFoldIfToAssignment("idea/testData/codeInsight/codeTransformations/branched/folding/ifToAssignment/simpleIfWithoutTerminatingAssignment.kt"); + doTestFoldIfToAssignment("idea/testData/intentions/branched/folding/ifToAssignment/simpleIfWithoutTerminatingAssignment.kt"); } } - @TestMetadata("idea/testData/codeInsight/codeTransformations/branched/folding/ifToReturn") + @TestMetadata("idea/testData/intentions/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); + JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.GenerateTests", new File("idea/testData/intentions/branched/folding/ifToReturn"), Pattern.compile("^(.+)\\.kt$"), true); } @TestMetadata("innerIfTransformed.kt") public void testInnerIfTransformed() throws Exception { - doTestFoldIfToReturn("idea/testData/codeInsight/codeTransformations/branched/folding/ifToReturn/innerIfTransformed.kt"); + doTestFoldIfToReturn("idea/testData/intentions/branched/folding/ifToReturn/innerIfTransformed.kt"); } @TestMetadata("simpleIf.kt") public void testSimpleIf() throws Exception { - doTestFoldIfToReturn("idea/testData/codeInsight/codeTransformations/branched/folding/ifToReturn/simpleIf.kt"); + doTestFoldIfToReturn("idea/testData/intentions/branched/folding/ifToReturn/simpleIf.kt"); } @TestMetadata("simpleIfWithBlocks.kt") public void testSimpleIfWithBlocks() throws Exception { - doTestFoldIfToReturn("idea/testData/codeInsight/codeTransformations/branched/folding/ifToReturn/simpleIfWithBlocks.kt"); + doTestFoldIfToReturn("idea/testData/intentions/branched/folding/ifToReturn/simpleIfWithBlocks.kt"); } } - @TestMetadata("idea/testData/codeInsight/codeTransformations/branched/folding/ifToReturnAsymmetrically") + @TestMetadata("idea/testData/intentions/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); + JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.GenerateTests", new File("idea/testData/intentions/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"); + doTestFoldIfToReturnAsymmetrically("idea/testData/intentions/branched/folding/ifToReturnAsymmetrically/simpleIf.kt"); } @TestMetadata("simpleIfWithBlocks.kt") public void testSimpleIfWithBlocks() throws Exception { - doTestFoldIfToReturnAsymmetrically("idea/testData/codeInsight/codeTransformations/branched/folding/ifToReturnAsymmetrically/simpleIfWithBlocks.kt"); + doTestFoldIfToReturnAsymmetrically("idea/testData/intentions/branched/folding/ifToReturnAsymmetrically/simpleIfWithBlocks.kt"); } @TestMetadata("simpleIfWithComments.kt") public void testSimpleIfWithComments() throws Exception { - doTestFoldIfToReturnAsymmetrically("idea/testData/codeInsight/codeTransformations/branched/folding/ifToReturnAsymmetrically/simpleIfWithComments.kt"); + doTestFoldIfToReturnAsymmetrically("idea/testData/intentions/branched/folding/ifToReturnAsymmetrically/simpleIfWithComments.kt"); } } - @TestMetadata("idea/testData/codeInsight/codeTransformations/branched/folding/whenToAssignment") + @TestMetadata("idea/testData/intentions/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); + JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.GenerateTests", new File("idea/testData/intentions/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"); + doTestFoldWhenToAssignment("idea/testData/intentions/branched/folding/whenToAssignment/innerWhenTransformed.kt"); } @TestMetadata("simpleWhen.kt") public void testSimpleWhen() throws Exception { - doTestFoldWhenToAssignment("idea/testData/codeInsight/codeTransformations/branched/folding/whenToAssignment/simpleWhen.kt"); + doTestFoldWhenToAssignment("idea/testData/intentions/branched/folding/whenToAssignment/simpleWhen.kt"); } @TestMetadata("simpleWhenWithBlocks.kt") public void testSimpleWhenWithBlocks() throws Exception { - doTestFoldWhenToAssignment("idea/testData/codeInsight/codeTransformations/branched/folding/whenToAssignment/simpleWhenWithBlocks.kt"); + doTestFoldWhenToAssignment("idea/testData/intentions/branched/folding/whenToAssignment/simpleWhenWithBlocks.kt"); } @TestMetadata("simpleWhenWithShadowedVar.kt") public void testSimpleWhenWithShadowedVar() throws Exception { - doTestFoldWhenToAssignment("idea/testData/codeInsight/codeTransformations/branched/folding/whenToAssignment/simpleWhenWithShadowedVar.kt"); + doTestFoldWhenToAssignment("idea/testData/intentions/branched/folding/whenToAssignment/simpleWhenWithShadowedVar.kt"); } @TestMetadata("simpleWhenWithUnmatchedAssignments.kt") public void testSimpleWhenWithUnmatchedAssignments() throws Exception { - doTestFoldWhenToAssignment("idea/testData/codeInsight/codeTransformations/branched/folding/whenToAssignment/simpleWhenWithUnmatchedAssignments.kt"); + doTestFoldWhenToAssignment("idea/testData/intentions/branched/folding/whenToAssignment/simpleWhenWithUnmatchedAssignments.kt"); } @TestMetadata("simpleWhenWithoutTerminatingAssignment.kt") public void testSimpleWhenWithoutTerminatingAssignment() throws Exception { - doTestFoldWhenToAssignment("idea/testData/codeInsight/codeTransformations/branched/folding/whenToAssignment/simpleWhenWithoutTerminatingAssignment.kt"); + doTestFoldWhenToAssignment("idea/testData/intentions/branched/folding/whenToAssignment/simpleWhenWithoutTerminatingAssignment.kt"); } } - @TestMetadata("idea/testData/codeInsight/codeTransformations/branched/folding/whenToReturn") + @TestMetadata("idea/testData/intentions/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); + JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.GenerateTests", new File("idea/testData/intentions/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"); + doTestFoldWhenToReturn("idea/testData/intentions/branched/folding/whenToReturn/innerWhenTransformed.kt"); } @TestMetadata("simpleWhen.kt") public void testSimpleWhen() throws Exception { - doTestFoldWhenToReturn("idea/testData/codeInsight/codeTransformations/branched/folding/whenToReturn/simpleWhen.kt"); + doTestFoldWhenToReturn("idea/testData/intentions/branched/folding/whenToReturn/simpleWhen.kt"); } @TestMetadata("simpleWhenWithBlocks.kt") public void testSimpleWhenWithBlocks() throws Exception { - doTestFoldWhenToReturn("idea/testData/codeInsight/codeTransformations/branched/folding/whenToReturn/simpleWhenWithBlocks.kt"); + doTestFoldWhenToReturn("idea/testData/intentions/branched/folding/whenToReturn/simpleWhenWithBlocks.kt"); } } - @TestMetadata("idea/testData/codeInsight/codeTransformations/branched/unfolding/assignmentToIf") + @TestMetadata("idea/testData/intentions/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); + JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.GenerateTests", new File("idea/testData/intentions/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"); + doTestUnfoldAssignmentToIf("idea/testData/intentions/branched/unfolding/assignmentToIf/innerIfTransformed.kt"); } @TestMetadata("nestedIfs.kt") public void testNestedIfs() throws Exception { - doTestUnfoldAssignmentToIf("idea/testData/codeInsight/codeTransformations/branched/unfolding/assignmentToIf/nestedIfs.kt"); + doTestUnfoldAssignmentToIf("idea/testData/intentions/branched/unfolding/assignmentToIf/nestedIfs.kt"); } @TestMetadata("simpleIf.kt") public void testSimpleIf() throws Exception { - doTestUnfoldAssignmentToIf("idea/testData/codeInsight/codeTransformations/branched/unfolding/assignmentToIf/simpleIf.kt"); + doTestUnfoldAssignmentToIf("idea/testData/intentions/branched/unfolding/assignmentToIf/simpleIf.kt"); } @TestMetadata("simpleIfWithAugmentedAssignment.kt") public void testSimpleIfWithAugmentedAssignment() throws Exception { - doTestUnfoldAssignmentToIf("idea/testData/codeInsight/codeTransformations/branched/unfolding/assignmentToIf/simpleIfWithAugmentedAssignment.kt"); + doTestUnfoldAssignmentToIf("idea/testData/intentions/branched/unfolding/assignmentToIf/simpleIfWithAugmentedAssignment.kt"); } @TestMetadata("simpleIfWithBlocks.kt") public void testSimpleIfWithBlocks() throws Exception { - doTestUnfoldAssignmentToIf("idea/testData/codeInsight/codeTransformations/branched/unfolding/assignmentToIf/simpleIfWithBlocks.kt"); + doTestUnfoldAssignmentToIf("idea/testData/intentions/branched/unfolding/assignmentToIf/simpleIfWithBlocks.kt"); } @TestMetadata("simpleIfWithComplexAssignmentLHS.kt") public void testSimpleIfWithComplexAssignmentLHS() throws Exception { - doTestUnfoldAssignmentToIf("idea/testData/codeInsight/codeTransformations/branched/unfolding/assignmentToIf/simpleIfWithComplexAssignmentLHS.kt"); + doTestUnfoldAssignmentToIf("idea/testData/intentions/branched/unfolding/assignmentToIf/simpleIfWithComplexAssignmentLHS.kt"); } @TestMetadata("simpleIfWithoutAssignment.kt") public void testSimpleIfWithoutAssignment() throws Exception { - doTestUnfoldAssignmentToIf("idea/testData/codeInsight/codeTransformations/branched/unfolding/assignmentToIf/simpleIfWithoutAssignment.kt"); + doTestUnfoldAssignmentToIf("idea/testData/intentions/branched/unfolding/assignmentToIf/simpleIfWithoutAssignment.kt"); } } - @TestMetadata("idea/testData/codeInsight/codeTransformations/branched/unfolding/assignmentToWhen") + @TestMetadata("idea/testData/intentions/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); + JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.GenerateTests", new File("idea/testData/intentions/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"); + doTestUnfoldAssignmentToWhen("idea/testData/intentions/branched/unfolding/assignmentToWhen/innerWhenTransformed.kt"); } @TestMetadata("simpleWhen.kt") public void testSimpleWhen() throws Exception { - doTestUnfoldAssignmentToWhen("idea/testData/codeInsight/codeTransformations/branched/unfolding/assignmentToWhen/simpleWhen.kt"); + doTestUnfoldAssignmentToWhen("idea/testData/intentions/branched/unfolding/assignmentToWhen/simpleWhen.kt"); } @TestMetadata("simpleWhenWithBlocks.kt") public void testSimpleWhenWithBlocks() throws Exception { - doTestUnfoldAssignmentToWhen("idea/testData/codeInsight/codeTransformations/branched/unfolding/assignmentToWhen/simpleWhenWithBlocks.kt"); + doTestUnfoldAssignmentToWhen("idea/testData/intentions/branched/unfolding/assignmentToWhen/simpleWhenWithBlocks.kt"); } @TestMetadata("simpleWhenWithComplexAssignmentLHS.kt") public void testSimpleWhenWithComplexAssignmentLHS() throws Exception { - doTestUnfoldAssignmentToWhen("idea/testData/codeInsight/codeTransformations/branched/unfolding/assignmentToWhen/simpleWhenWithComplexAssignmentLHS.kt"); + doTestUnfoldAssignmentToWhen("idea/testData/intentions/branched/unfolding/assignmentToWhen/simpleWhenWithComplexAssignmentLHS.kt"); } } - @TestMetadata("idea/testData/codeInsight/codeTransformations/branched/unfolding/propertyToIf") + @TestMetadata("idea/testData/intentions/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); + JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.GenerateTests", new File("idea/testData/intentions/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"); + doTestUnfoldPropertyToIf("idea/testData/intentions/branched/unfolding/propertyToIf/nestedIfs.kt"); } @TestMetadata("nestedIfs2.kt") public void testNestedIfs2() throws Exception { - doTestUnfoldPropertyToIf("idea/testData/codeInsight/codeTransformations/branched/unfolding/propertyToIf/nestedIfs2.kt"); + doTestUnfoldPropertyToIf("idea/testData/intentions/branched/unfolding/propertyToIf/nestedIfs2.kt"); } @TestMetadata("nonLocalProperty.kt") public void testNonLocalProperty() throws Exception { - doTestUnfoldPropertyToIf("idea/testData/codeInsight/codeTransformations/branched/unfolding/propertyToIf/nonLocalProperty.kt"); + doTestUnfoldPropertyToIf("idea/testData/intentions/branched/unfolding/propertyToIf/nonLocalProperty.kt"); } @TestMetadata("nonLocalProperty2.kt") public void testNonLocalProperty2() throws Exception { - doTestUnfoldPropertyToIf("idea/testData/codeInsight/codeTransformations/branched/unfolding/propertyToIf/nonLocalProperty2.kt"); + doTestUnfoldPropertyToIf("idea/testData/intentions/branched/unfolding/propertyToIf/nonLocalProperty2.kt"); } @TestMetadata("simpleIf.kt") public void testSimpleIf() throws Exception { - doTestUnfoldPropertyToIf("idea/testData/codeInsight/codeTransformations/branched/unfolding/propertyToIf/simpleIf.kt"); + doTestUnfoldPropertyToIf("idea/testData/intentions/branched/unfolding/propertyToIf/simpleIf.kt"); } @TestMetadata("simpleIf2.kt") public void testSimpleIf2() throws Exception { - doTestUnfoldPropertyToIf("idea/testData/codeInsight/codeTransformations/branched/unfolding/propertyToIf/simpleIf2.kt"); + doTestUnfoldPropertyToIf("idea/testData/intentions/branched/unfolding/propertyToIf/simpleIf2.kt"); } @TestMetadata("simpleIfWithBlocks.kt") public void testSimpleIfWithBlocks() throws Exception { - doTestUnfoldPropertyToIf("idea/testData/codeInsight/codeTransformations/branched/unfolding/propertyToIf/simpleIfWithBlocks.kt"); + doTestUnfoldPropertyToIf("idea/testData/intentions/branched/unfolding/propertyToIf/simpleIfWithBlocks.kt"); } @TestMetadata("simpleIfWithBlocks2.kt") public void testSimpleIfWithBlocks2() throws Exception { - doTestUnfoldPropertyToIf("idea/testData/codeInsight/codeTransformations/branched/unfolding/propertyToIf/simpleIfWithBlocks2.kt"); + doTestUnfoldPropertyToIf("idea/testData/intentions/branched/unfolding/propertyToIf/simpleIfWithBlocks2.kt"); } @TestMetadata("simpleIfWithType.kt") public void testSimpleIfWithType() throws Exception { - doTestUnfoldPropertyToIf("idea/testData/codeInsight/codeTransformations/branched/unfolding/propertyToIf/simpleIfWithType.kt"); + doTestUnfoldPropertyToIf("idea/testData/intentions/branched/unfolding/propertyToIf/simpleIfWithType.kt"); } } - @TestMetadata("idea/testData/codeInsight/codeTransformations/branched/unfolding/propertyToWhen") + @TestMetadata("idea/testData/intentions/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); + JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.GenerateTests", new File("idea/testData/intentions/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"); + doTestUnfoldPropertyToWhen("idea/testData/intentions/branched/unfolding/propertyToWhen/nonLocalProperty.kt"); } @TestMetadata("nonLocalProperty2.kt") public void testNonLocalProperty2() throws Exception { - doTestUnfoldPropertyToWhen("idea/testData/codeInsight/codeTransformations/branched/unfolding/propertyToWhen/nonLocalProperty2.kt"); + doTestUnfoldPropertyToWhen("idea/testData/intentions/branched/unfolding/propertyToWhen/nonLocalProperty2.kt"); } @TestMetadata("simpleWhen.kt") public void testSimpleWhen() throws Exception { - doTestUnfoldPropertyToWhen("idea/testData/codeInsight/codeTransformations/branched/unfolding/propertyToWhen/simpleWhen.kt"); + doTestUnfoldPropertyToWhen("idea/testData/intentions/branched/unfolding/propertyToWhen/simpleWhen.kt"); } @TestMetadata("simpleWhen2.kt") public void testSimpleWhen2() throws Exception { - doTestUnfoldPropertyToWhen("idea/testData/codeInsight/codeTransformations/branched/unfolding/propertyToWhen/simpleWhen2.kt"); + doTestUnfoldPropertyToWhen("idea/testData/intentions/branched/unfolding/propertyToWhen/simpleWhen2.kt"); } @TestMetadata("simpleWhenWithBlocks.kt") public void testSimpleWhenWithBlocks() throws Exception { - doTestUnfoldPropertyToWhen("idea/testData/codeInsight/codeTransformations/branched/unfolding/propertyToWhen/simpleWhenWithBlocks.kt"); + doTestUnfoldPropertyToWhen("idea/testData/intentions/branched/unfolding/propertyToWhen/simpleWhenWithBlocks.kt"); } @TestMetadata("simpleWhenWithBlocks2.kt") public void testSimpleWhenWithBlocks2() throws Exception { - doTestUnfoldPropertyToWhen("idea/testData/codeInsight/codeTransformations/branched/unfolding/propertyToWhen/simpleWhenWithBlocks2.kt"); + doTestUnfoldPropertyToWhen("idea/testData/intentions/branched/unfolding/propertyToWhen/simpleWhenWithBlocks2.kt"); } @TestMetadata("simpleWhenWithType.kt") public void testSimpleWhenWithType() throws Exception { - doTestUnfoldPropertyToWhen("idea/testData/codeInsight/codeTransformations/branched/unfolding/propertyToWhen/simpleWhenWithType.kt"); + doTestUnfoldPropertyToWhen("idea/testData/intentions/branched/unfolding/propertyToWhen/simpleWhenWithType.kt"); } } - @TestMetadata("idea/testData/codeInsight/codeTransformations/branched/unfolding/returnToIf") + @TestMetadata("idea/testData/intentions/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); + JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.GenerateTests", new File("idea/testData/intentions/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"); + doTestUnfoldReturnToIf("idea/testData/intentions/branched/unfolding/returnToIf/innerIfTransformed.kt"); } @TestMetadata("simpleIf.kt") public void testSimpleIf() throws Exception { - doTestUnfoldReturnToIf("idea/testData/codeInsight/codeTransformations/branched/unfolding/returnToIf/simpleIf.kt"); + doTestUnfoldReturnToIf("idea/testData/intentions/branched/unfolding/returnToIf/simpleIf.kt"); } @TestMetadata("simpleIfWithBlocks.kt") public void testSimpleIfWithBlocks() throws Exception { - doTestUnfoldReturnToIf("idea/testData/codeInsight/codeTransformations/branched/unfolding/returnToIf/simpleIfWithBlocks.kt"); + doTestUnfoldReturnToIf("idea/testData/intentions/branched/unfolding/returnToIf/simpleIfWithBlocks.kt"); } } - @TestMetadata("idea/testData/codeInsight/codeTransformations/branched/unfolding/returnToWhen") + @TestMetadata("idea/testData/intentions/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); + JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.GenerateTests", new File("idea/testData/intentions/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"); + doTestUnfoldReturnToWhen("idea/testData/intentions/branched/unfolding/returnToWhen/innerWhenTransformed.kt"); } @TestMetadata("simpleWhen.kt") public void testSimpleWhen() throws Exception { - doTestUnfoldReturnToWhen("idea/testData/codeInsight/codeTransformations/branched/unfolding/returnToWhen/simpleWhen.kt"); + doTestUnfoldReturnToWhen("idea/testData/intentions/branched/unfolding/returnToWhen/simpleWhen.kt"); } @TestMetadata("simpleWhenWithBlocks.kt") public void testSimpleWhenWithBlocks() throws Exception { - doTestUnfoldReturnToWhen("idea/testData/codeInsight/codeTransformations/branched/unfolding/returnToWhen/simpleWhenWithBlocks.kt"); + doTestUnfoldReturnToWhen("idea/testData/intentions/branched/unfolding/returnToWhen/simpleWhenWithBlocks.kt"); } } - @TestMetadata("idea/testData/codeInsight/codeTransformations/branched/ifWhen/ifToWhen") + @TestMetadata("idea/testData/intentions/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); + JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.GenerateTests", new File("idea/testData/intentions/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"); + doTestIfToWhen("idea/testData/intentions/branched/ifWhen/ifToWhen/ifWithEqualityTests.kt"); } @TestMetadata("ifWithIs.kt") public void testIfWithIs() throws Exception { - doTestIfToWhen("idea/testData/codeInsight/codeTransformations/branched/ifWhen/ifToWhen/ifWithIs.kt"); + doTestIfToWhen("idea/testData/intentions/branched/ifWhen/ifToWhen/ifWithIs.kt"); } @TestMetadata("ifWithMultiConditions.kt") public void testIfWithMultiConditions() throws Exception { - doTestIfToWhen("idea/testData/codeInsight/codeTransformations/branched/ifWhen/ifToWhen/ifWithMultiConditions.kt"); + doTestIfToWhen("idea/testData/intentions/branched/ifWhen/ifToWhen/ifWithMultiConditions.kt"); } @TestMetadata("ifWithNegativeIs.kt") public void testIfWithNegativeIs() throws Exception { - doTestIfToWhen("idea/testData/codeInsight/codeTransformations/branched/ifWhen/ifToWhen/ifWithNegativeIs.kt"); + doTestIfToWhen("idea/testData/intentions/branched/ifWhen/ifToWhen/ifWithNegativeIs.kt"); } @TestMetadata("ifWithNegativeRangeTests.kt") public void testIfWithNegativeRangeTests() throws Exception { - doTestIfToWhen("idea/testData/codeInsight/codeTransformations/branched/ifWhen/ifToWhen/ifWithNegativeRangeTests.kt"); + doTestIfToWhen("idea/testData/intentions/branched/ifWhen/ifToWhen/ifWithNegativeRangeTests.kt"); } @TestMetadata("ifWithRangeTests.kt") public void testIfWithRangeTests() throws Exception { - doTestIfToWhen("idea/testData/codeInsight/codeTransformations/branched/ifWhen/ifToWhen/ifWithRangeTests.kt"); + doTestIfToWhen("idea/testData/intentions/branched/ifWhen/ifToWhen/ifWithRangeTests.kt"); } @TestMetadata("ifWithRangeTestsAndMultiConditions.kt") public void testIfWithRangeTestsAndMultiConditions() throws Exception { - doTestIfToWhen("idea/testData/codeInsight/codeTransformations/branched/ifWhen/ifToWhen/ifWithRangeTestsAndMultiConditions.kt"); + doTestIfToWhen("idea/testData/intentions/branched/ifWhen/ifToWhen/ifWithRangeTestsAndMultiConditions.kt"); } @TestMetadata("ifWithRangeTestsAndUnparenthesizedMultiConditions.kt") public void testIfWithRangeTestsAndUnparenthesizedMultiConditions() throws Exception { - doTestIfToWhen("idea/testData/codeInsight/codeTransformations/branched/ifWhen/ifToWhen/ifWithRangeTestsAndUnparenthesizedMultiConditions.kt"); + doTestIfToWhen("idea/testData/intentions/branched/ifWhen/ifToWhen/ifWithRangeTestsAndUnparenthesizedMultiConditions.kt"); } @TestMetadata("whenWithMultipleConditionTypes.kt") public void testWhenWithMultipleConditionTypes() throws Exception { - doTestIfToWhen("idea/testData/codeInsight/codeTransformations/branched/ifWhen/ifToWhen/whenWithMultipleConditionTypes.kt"); + doTestIfToWhen("idea/testData/intentions/branched/ifWhen/ifToWhen/whenWithMultipleConditionTypes.kt"); } } - @TestMetadata("idea/testData/codeInsight/codeTransformations/branched/ifWhen/whenToIf") + @TestMetadata("idea/testData/intentions/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); + JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.GenerateTests", new File("idea/testData/intentions/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"); + doTestWhenToIf("idea/testData/intentions/branched/ifWhen/whenToIf/whenWithEqualityTests.kt"); } @TestMetadata("whenWithMultiConditions.kt") public void testWhenWithMultiConditions() throws Exception { - doTestWhenToIf("idea/testData/codeInsight/codeTransformations/branched/ifWhen/whenToIf/whenWithMultiConditions.kt"); + doTestWhenToIf("idea/testData/intentions/branched/ifWhen/whenToIf/whenWithMultiConditions.kt"); } @TestMetadata("whenWithMultipleConditionTypes.kt") public void testWhenWithMultipleConditionTypes() throws Exception { - doTestWhenToIf("idea/testData/codeInsight/codeTransformations/branched/ifWhen/whenToIf/whenWithMultipleConditionTypes.kt"); + doTestWhenToIf("idea/testData/intentions/branched/ifWhen/whenToIf/whenWithMultipleConditionTypes.kt"); } @TestMetadata("whenWithNegativePatterns.kt") public void testWhenWithNegativePatterns() throws Exception { - doTestWhenToIf("idea/testData/codeInsight/codeTransformations/branched/ifWhen/whenToIf/whenWithNegativePatterns.kt"); + doTestWhenToIf("idea/testData/intentions/branched/ifWhen/whenToIf/whenWithNegativePatterns.kt"); } @TestMetadata("whenWithNegativeRangeTests.kt") public void testWhenWithNegativeRangeTests() throws Exception { - doTestWhenToIf("idea/testData/codeInsight/codeTransformations/branched/ifWhen/whenToIf/whenWithNegativeRangeTests.kt"); + doTestWhenToIf("idea/testData/intentions/branched/ifWhen/whenToIf/whenWithNegativeRangeTests.kt"); } @TestMetadata("whenWithPatterns.kt") public void testWhenWithPatterns() throws Exception { - doTestWhenToIf("idea/testData/codeInsight/codeTransformations/branched/ifWhen/whenToIf/whenWithPatterns.kt"); + doTestWhenToIf("idea/testData/intentions/branched/ifWhen/whenToIf/whenWithPatterns.kt"); } @TestMetadata("whenWithRangeTests.kt") public void testWhenWithRangeTests() throws Exception { - doTestWhenToIf("idea/testData/codeInsight/codeTransformations/branched/ifWhen/whenToIf/whenWithRangeTests.kt"); + doTestWhenToIf("idea/testData/intentions/branched/ifWhen/whenToIf/whenWithRangeTests.kt"); } @TestMetadata("whenWithRangeTestsAndMultiConditions.kt") public void testWhenWithRangeTestsAndMultiConditions() throws Exception { - doTestWhenToIf("idea/testData/codeInsight/codeTransformations/branched/ifWhen/whenToIf/whenWithRangeTestsAndMultiConditions.kt"); + doTestWhenToIf("idea/testData/intentions/branched/ifWhen/whenToIf/whenWithRangeTestsAndMultiConditions.kt"); } @TestMetadata("whenWithoutSubject.kt") public void testWhenWithoutSubject() throws Exception { - doTestWhenToIf("idea/testData/codeInsight/codeTransformations/branched/ifWhen/whenToIf/whenWithoutSubject.kt"); + doTestWhenToIf("idea/testData/intentions/branched/ifWhen/whenToIf/whenWithoutSubject.kt"); } } - @TestMetadata("idea/testData/codeInsight/codeTransformations/branched/when/flatten") + @TestMetadata("idea/testData/intentions/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); + JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.GenerateTests", new File("idea/testData/intentions/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"); + doTestFlattenWhen("idea/testData/intentions/branched/when/flatten/flattenWithSubject.kt"); } @TestMetadata("flattenWithUnmatchedSubjects.kt") public void testFlattenWithUnmatchedSubjects() throws Exception { - doTestFlattenWhen("idea/testData/codeInsight/codeTransformations/branched/when/flatten/flattenWithUnmatchedSubjects.kt"); + doTestFlattenWhen("idea/testData/intentions/branched/when/flatten/flattenWithUnmatchedSubjects.kt"); } @TestMetadata("flattenWithoutSubject.kt") public void testFlattenWithoutSubject() throws Exception { - doTestFlattenWhen("idea/testData/codeInsight/codeTransformations/branched/when/flatten/flattenWithoutSubject.kt"); + doTestFlattenWhen("idea/testData/intentions/branched/when/flatten/flattenWithoutSubject.kt"); } } - @TestMetadata("idea/testData/codeInsight/codeTransformations/branched/when/introduceSubject") + @TestMetadata("idea/testData/intentions/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); + JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.GenerateTests", new File("idea/testData/intentions/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"); + doTestIntroduceWhenSubject("idea/testData/intentions/branched/when/introduceSubject/whenWithEqualityTests.kt"); } @TestMetadata("whenWithMultipleConditionTypes.kt") public void testWhenWithMultipleConditionTypes() throws Exception { - doTestIntroduceWhenSubject("idea/testData/codeInsight/codeTransformations/branched/when/introduceSubject/whenWithMultipleConditionTypes.kt"); + doTestIntroduceWhenSubject("idea/testData/intentions/branched/when/introduceSubject/whenWithMultipleConditionTypes.kt"); } @TestMetadata("whenWithNegativePatterns.kt") public void testWhenWithNegativePatterns() throws Exception { - doTestIntroduceWhenSubject("idea/testData/codeInsight/codeTransformations/branched/when/introduceSubject/whenWithNegativePatterns.kt"); + doTestIntroduceWhenSubject("idea/testData/intentions/branched/when/introduceSubject/whenWithNegativePatterns.kt"); } @TestMetadata("whenWithNegativeRangeTests.kt") public void testWhenWithNegativeRangeTests() throws Exception { - doTestIntroduceWhenSubject("idea/testData/codeInsight/codeTransformations/branched/when/introduceSubject/whenWithNegativeRangeTests.kt"); + doTestIntroduceWhenSubject("idea/testData/intentions/branched/when/introduceSubject/whenWithNegativeRangeTests.kt"); } @TestMetadata("whenWithNondivisibleConditions.kt") public void testWhenWithNondivisibleConditions() throws Exception { - doTestIntroduceWhenSubject("idea/testData/codeInsight/codeTransformations/branched/when/introduceSubject/whenWithNondivisibleConditions.kt"); + doTestIntroduceWhenSubject("idea/testData/intentions/branched/when/introduceSubject/whenWithNondivisibleConditions.kt"); } @TestMetadata("whenWithPatterns.kt") public void testWhenWithPatterns() throws Exception { - doTestIntroduceWhenSubject("idea/testData/codeInsight/codeTransformations/branched/when/introduceSubject/whenWithPatterns.kt"); + doTestIntroduceWhenSubject("idea/testData/intentions/branched/when/introduceSubject/whenWithPatterns.kt"); } @TestMetadata("whenWithRangeTests.kt") public void testWhenWithRangeTests() throws Exception { - doTestIntroduceWhenSubject("idea/testData/codeInsight/codeTransformations/branched/when/introduceSubject/whenWithRangeTests.kt"); + doTestIntroduceWhenSubject("idea/testData/intentions/branched/when/introduceSubject/whenWithRangeTests.kt"); } @TestMetadata("whenWithRangeTestsAndMultiConditions.kt") public void testWhenWithRangeTestsAndMultiConditions() throws Exception { - doTestIntroduceWhenSubject("idea/testData/codeInsight/codeTransformations/branched/when/introduceSubject/whenWithRangeTestsAndMultiConditions.kt"); + doTestIntroduceWhenSubject("idea/testData/intentions/branched/when/introduceSubject/whenWithRangeTestsAndMultiConditions.kt"); } @TestMetadata("whenWithSubject.kt") public void testWhenWithSubject() throws Exception { - doTestIntroduceWhenSubject("idea/testData/codeInsight/codeTransformations/branched/when/introduceSubject/whenWithSubject.kt"); + doTestIntroduceWhenSubject("idea/testData/intentions/branched/when/introduceSubject/whenWithSubject.kt"); } @TestMetadata("whenWithSwappedEqualityTests.kt") public void testWhenWithSwappedEqualityTests() throws Exception { - doTestIntroduceWhenSubject("idea/testData/codeInsight/codeTransformations/branched/when/introduceSubject/whenWithSwappedEqualityTests.kt"); + doTestIntroduceWhenSubject("idea/testData/intentions/branched/when/introduceSubject/whenWithSwappedEqualityTests.kt"); } @TestMetadata("whenWithUnmatchedCandidateSubjects.kt") public void testWhenWithUnmatchedCandidateSubjects() throws Exception { - doTestIntroduceWhenSubject("idea/testData/codeInsight/codeTransformations/branched/when/introduceSubject/whenWithUnmatchedCandidateSubjects.kt"); + doTestIntroduceWhenSubject("idea/testData/intentions/branched/when/introduceSubject/whenWithUnmatchedCandidateSubjects.kt"); } } - @TestMetadata("idea/testData/codeInsight/codeTransformations/branched/when/eliminateSubject") + @TestMetadata("idea/testData/intentions/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); + JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.GenerateTests", new File("idea/testData/intentions/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"); + doTestEliminateWhenSubject("idea/testData/intentions/branched/when/eliminateSubject/whenWithEqualityTests.kt"); } @TestMetadata("whenWithMultipleConditionTypes.kt") public void testWhenWithMultipleConditionTypes() throws Exception { - doTestEliminateWhenSubject("idea/testData/codeInsight/codeTransformations/branched/when/eliminateSubject/whenWithMultipleConditionTypes.kt"); + doTestEliminateWhenSubject("idea/testData/intentions/branched/when/eliminateSubject/whenWithMultipleConditionTypes.kt"); } @TestMetadata("whenWithNegativePatterns.kt") public void testWhenWithNegativePatterns() throws Exception { - doTestEliminateWhenSubject("idea/testData/codeInsight/codeTransformations/branched/when/eliminateSubject/whenWithNegativePatterns.kt"); + doTestEliminateWhenSubject("idea/testData/intentions/branched/when/eliminateSubject/whenWithNegativePatterns.kt"); } @TestMetadata("whenWithNegativeRangeTests.kt") public void testWhenWithNegativeRangeTests() throws Exception { - doTestEliminateWhenSubject("idea/testData/codeInsight/codeTransformations/branched/when/eliminateSubject/whenWithNegativeRangeTests.kt"); + doTestEliminateWhenSubject("idea/testData/intentions/branched/when/eliminateSubject/whenWithNegativeRangeTests.kt"); } @TestMetadata("whenWithPatterns.kt") public void testWhenWithPatterns() throws Exception { - doTestEliminateWhenSubject("idea/testData/codeInsight/codeTransformations/branched/when/eliminateSubject/whenWithPatterns.kt"); + doTestEliminateWhenSubject("idea/testData/intentions/branched/when/eliminateSubject/whenWithPatterns.kt"); } @TestMetadata("whenWithRangeTests.kt") public void testWhenWithRangeTests() throws Exception { - doTestEliminateWhenSubject("idea/testData/codeInsight/codeTransformations/branched/when/eliminateSubject/whenWithRangeTests.kt"); + doTestEliminateWhenSubject("idea/testData/intentions/branched/when/eliminateSubject/whenWithRangeTests.kt"); } @TestMetadata("whenWithRangeTestsAndMultiConditions.kt") public void testWhenWithRangeTestsAndMultiConditions() throws Exception { - doTestEliminateWhenSubject("idea/testData/codeInsight/codeTransformations/branched/when/eliminateSubject/whenWithRangeTestsAndMultiConditions.kt"); + doTestEliminateWhenSubject("idea/testData/intentions/branched/when/eliminateSubject/whenWithRangeTestsAndMultiConditions.kt"); } @TestMetadata("whenWithoutSubject.kt") public void testWhenWithoutSubject() throws Exception { - doTestEliminateWhenSubject("idea/testData/codeInsight/codeTransformations/branched/when/eliminateSubject/whenWithoutSubject.kt"); + doTestEliminateWhenSubject("idea/testData/intentions/branched/when/eliminateSubject/whenWithoutSubject.kt"); } } - @TestMetadata("idea/testData/codeInsight/codeTransformations/declarations/split") + @TestMetadata("idea/testData/intentions/declarations/split") public static class Split extends AbstractCodeTransformationTest { public void testAllFilesPresentInSplit() throws Exception { - JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.GenerateTests", new File("idea/testData/codeInsight/codeTransformations/declarations/split"), Pattern.compile("^(.+)\\.kt$"), true); + JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.GenerateTests", new File("idea/testData/intentions/declarations/split"), Pattern.compile("^(.+)\\.kt$"), true); } @TestMetadata("longInit.kt") public void testLongInit() throws Exception { - doTestSplitProperty("idea/testData/codeInsight/codeTransformations/declarations/split/longInit.kt"); + doTestSplitProperty("idea/testData/intentions/declarations/split/longInit.kt"); } @TestMetadata("longInit2.kt") public void testLongInit2() throws Exception { - doTestSplitProperty("idea/testData/codeInsight/codeTransformations/declarations/split/longInit2.kt"); + doTestSplitProperty("idea/testData/intentions/declarations/split/longInit2.kt"); } @TestMetadata("noInitializer.kt") public void testNoInitializer() throws Exception { - doTestSplitProperty("idea/testData/codeInsight/codeTransformations/declarations/split/noInitializer.kt"); + doTestSplitProperty("idea/testData/intentions/declarations/split/noInitializer.kt"); } @TestMetadata("noInitializer2.kt") public void testNoInitializer2() throws Exception { - doTestSplitProperty("idea/testData/codeInsight/codeTransformations/declarations/split/noInitializer2.kt"); + doTestSplitProperty("idea/testData/intentions/declarations/split/noInitializer2.kt"); } @TestMetadata("nonLocalProperty.kt") public void testNonLocalProperty() throws Exception { - doTestSplitProperty("idea/testData/codeInsight/codeTransformations/declarations/split/nonLocalProperty.kt"); + doTestSplitProperty("idea/testData/intentions/declarations/split/nonLocalProperty.kt"); } @TestMetadata("nonLocalProperty2.kt") public void testNonLocalProperty2() throws Exception { - doTestSplitProperty("idea/testData/codeInsight/codeTransformations/declarations/split/nonLocalProperty2.kt"); + doTestSplitProperty("idea/testData/intentions/declarations/split/nonLocalProperty2.kt"); } @TestMetadata("simpleInit.kt") public void testSimpleInit() throws Exception { - doTestSplitProperty("idea/testData/codeInsight/codeTransformations/declarations/split/simpleInit.kt"); + doTestSplitProperty("idea/testData/intentions/declarations/split/simpleInit.kt"); } @TestMetadata("simpleInit2.kt") public void testSimpleInit2() throws Exception { - doTestSplitProperty("idea/testData/codeInsight/codeTransformations/declarations/split/simpleInit2.kt"); + doTestSplitProperty("idea/testData/intentions/declarations/split/simpleInit2.kt"); } @TestMetadata("simpleInitWithErrorType.kt") public void testSimpleInitWithErrorType() throws Exception { - doTestSplitProperty("idea/testData/codeInsight/codeTransformations/declarations/split/simpleInitWithErrorType.kt"); + doTestSplitProperty("idea/testData/intentions/declarations/split/simpleInitWithErrorType.kt"); } @TestMetadata("simpleInitWithErrorType2.kt") public void testSimpleInitWithErrorType2() throws Exception { - doTestSplitProperty("idea/testData/codeInsight/codeTransformations/declarations/split/simpleInitWithErrorType2.kt"); + doTestSplitProperty("idea/testData/intentions/declarations/split/simpleInitWithErrorType2.kt"); } @TestMetadata("simpleInitWithType.kt") public void testSimpleInitWithType() throws Exception { - doTestSplitProperty("idea/testData/codeInsight/codeTransformations/declarations/split/simpleInitWithType.kt"); + doTestSplitProperty("idea/testData/intentions/declarations/split/simpleInitWithType.kt"); } @TestMetadata("simpleInitWithType2.kt") public void testSimpleInitWithType2() throws Exception { - doTestSplitProperty("idea/testData/codeInsight/codeTransformations/declarations/split/simpleInitWithType2.kt"); + doTestSplitProperty("idea/testData/intentions/declarations/split/simpleInitWithType2.kt"); } } - @TestMetadata("idea/testData/codeInsight/codeTransformations/declarations/join") + @TestMetadata("idea/testData/intentions/declarations/join") public static class Join extends AbstractCodeTransformationTest { public void testAllFilesPresentInJoin() throws Exception { - JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.GenerateTests", new File("idea/testData/codeInsight/codeTransformations/declarations/join"), Pattern.compile("^(.+)\\.kt$"), true); + JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.GenerateTests", new File("idea/testData/intentions/declarations/join"), Pattern.compile("^(.+)\\.kt$"), true); } @TestMetadata("longInit.kt") public void testLongInit() throws Exception { - doTestJoinProperty("idea/testData/codeInsight/codeTransformations/declarations/join/longInit.kt"); + doTestJoinProperty("idea/testData/intentions/declarations/join/longInit.kt"); } @TestMetadata("longInit2.kt") public void testLongInit2() throws Exception { - doTestJoinProperty("idea/testData/codeInsight/codeTransformations/declarations/join/longInit2.kt"); + doTestJoinProperty("idea/testData/intentions/declarations/join/longInit2.kt"); } @TestMetadata("simpleInit.kt") public void testSimpleInit() throws Exception { - doTestJoinProperty("idea/testData/codeInsight/codeTransformations/declarations/join/simpleInit.kt"); + doTestJoinProperty("idea/testData/intentions/declarations/join/simpleInit.kt"); } @TestMetadata("simpleInit2.kt") public void testSimpleInit2() throws Exception { - doTestJoinProperty("idea/testData/codeInsight/codeTransformations/declarations/join/simpleInit2.kt"); + doTestJoinProperty("idea/testData/intentions/declarations/join/simpleInit2.kt"); } @TestMetadata("simpleInitWithBackticks.kt") public void testSimpleInitWithBackticks() throws Exception { - doTestJoinProperty("idea/testData/codeInsight/codeTransformations/declarations/join/simpleInitWithBackticks.kt"); + doTestJoinProperty("idea/testData/intentions/declarations/join/simpleInitWithBackticks.kt"); } @TestMetadata("simpleInitWithBackticks2.kt") public void testSimpleInitWithBackticks2() throws Exception { - doTestJoinProperty("idea/testData/codeInsight/codeTransformations/declarations/join/simpleInitWithBackticks2.kt"); + doTestJoinProperty("idea/testData/intentions/declarations/join/simpleInitWithBackticks2.kt"); } @TestMetadata("simpleInitWithBackticks3.kt") public void testSimpleInitWithBackticks3() throws Exception { - doTestJoinProperty("idea/testData/codeInsight/codeTransformations/declarations/join/simpleInitWithBackticks3.kt"); + doTestJoinProperty("idea/testData/intentions/declarations/join/simpleInitWithBackticks3.kt"); } @TestMetadata("simpleInitWithComments.kt") public void testSimpleInitWithComments() throws Exception { - doTestJoinProperty("idea/testData/codeInsight/codeTransformations/declarations/join/simpleInitWithComments.kt"); + doTestJoinProperty("idea/testData/intentions/declarations/join/simpleInitWithComments.kt"); } @TestMetadata("simpleInitWithComments2.kt") public void testSimpleInitWithComments2() throws Exception { - doTestJoinProperty("idea/testData/codeInsight/codeTransformations/declarations/join/simpleInitWithComments2.kt"); + doTestJoinProperty("idea/testData/intentions/declarations/join/simpleInitWithComments2.kt"); } @TestMetadata("simpleInitWithSemicolons.kt") public void testSimpleInitWithSemicolons() throws Exception { - doTestJoinProperty("idea/testData/codeInsight/codeTransformations/declarations/join/simpleInitWithSemicolons.kt"); + doTestJoinProperty("idea/testData/intentions/declarations/join/simpleInitWithSemicolons.kt"); } @TestMetadata("simpleInitWithSemicolons2.kt") public void testSimpleInitWithSemicolons2() throws Exception { - doTestJoinProperty("idea/testData/codeInsight/codeTransformations/declarations/join/simpleInitWithSemicolons2.kt"); + doTestJoinProperty("idea/testData/intentions/declarations/join/simpleInitWithSemicolons2.kt"); } @TestMetadata("simpleInitWithSemicolons3.kt") public void testSimpleInitWithSemicolons3() throws Exception { - doTestJoinProperty("idea/testData/codeInsight/codeTransformations/declarations/join/simpleInitWithSemicolons3.kt"); + doTestJoinProperty("idea/testData/intentions/declarations/join/simpleInitWithSemicolons3.kt"); } @TestMetadata("simpleInitWithType.kt") public void testSimpleInitWithType() throws Exception { - doTestJoinProperty("idea/testData/codeInsight/codeTransformations/declarations/join/simpleInitWithType.kt"); + doTestJoinProperty("idea/testData/intentions/declarations/join/simpleInitWithType.kt"); } @TestMetadata("simpleInitWithType2.kt") public void testSimpleInitWithType2() throws Exception { - doTestJoinProperty("idea/testData/codeInsight/codeTransformations/declarations/join/simpleInitWithType2.kt"); + doTestJoinProperty("idea/testData/intentions/declarations/join/simpleInitWithType2.kt"); } } - @TestMetadata("idea/testData/codeInsight/codeTransformations/removeUnnecessaryParentheses") + @TestMetadata("idea/testData/intentions/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); + JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.GenerateTests", new File("idea/testData/intentions/removeUnnecessaryParentheses"), Pattern.compile("^(.+)\\.kt$"), true); } @TestMetadata("necessaryParentheses1.kt") public void testNecessaryParentheses1() throws Exception { - doTestRemoveUnnecessaryParentheses("idea/testData/codeInsight/codeTransformations/removeUnnecessaryParentheses/necessaryParentheses1.kt"); + doTestRemoveUnnecessaryParentheses("idea/testData/intentions/removeUnnecessaryParentheses/necessaryParentheses1.kt"); } @TestMetadata("necessaryParentheses2.kt") public void testNecessaryParentheses2() throws Exception { - doTestRemoveUnnecessaryParentheses("idea/testData/codeInsight/codeTransformations/removeUnnecessaryParentheses/necessaryParentheses2.kt"); + doTestRemoveUnnecessaryParentheses("idea/testData/intentions/removeUnnecessaryParentheses/necessaryParentheses2.kt"); } @TestMetadata("necessaryParentheses3.kt") public void testNecessaryParentheses3() throws Exception { - doTestRemoveUnnecessaryParentheses("idea/testData/codeInsight/codeTransformations/removeUnnecessaryParentheses/necessaryParentheses3.kt"); + doTestRemoveUnnecessaryParentheses("idea/testData/intentions/removeUnnecessaryParentheses/necessaryParentheses3.kt"); } @TestMetadata("necessaryParentheses4.kt") public void testNecessaryParentheses4() throws Exception { - doTestRemoveUnnecessaryParentheses("idea/testData/codeInsight/codeTransformations/removeUnnecessaryParentheses/necessaryParentheses4.kt"); + doTestRemoveUnnecessaryParentheses("idea/testData/intentions/removeUnnecessaryParentheses/necessaryParentheses4.kt"); } @TestMetadata("necessaryParentheses5.kt") public void testNecessaryParentheses5() throws Exception { - doTestRemoveUnnecessaryParentheses("idea/testData/codeInsight/codeTransformations/removeUnnecessaryParentheses/necessaryParentheses5.kt"); + doTestRemoveUnnecessaryParentheses("idea/testData/intentions/removeUnnecessaryParentheses/necessaryParentheses5.kt"); } @TestMetadata("unnecessaryParentheses1.kt") public void testUnnecessaryParentheses1() throws Exception { - doTestRemoveUnnecessaryParentheses("idea/testData/codeInsight/codeTransformations/removeUnnecessaryParentheses/unnecessaryParentheses1.kt"); + doTestRemoveUnnecessaryParentheses("idea/testData/intentions/removeUnnecessaryParentheses/unnecessaryParentheses1.kt"); } @TestMetadata("unnecessaryParentheses2.kt") public void testUnnecessaryParentheses2() throws Exception { - doTestRemoveUnnecessaryParentheses("idea/testData/codeInsight/codeTransformations/removeUnnecessaryParentheses/unnecessaryParentheses2.kt"); + doTestRemoveUnnecessaryParentheses("idea/testData/intentions/removeUnnecessaryParentheses/unnecessaryParentheses2.kt"); } @TestMetadata("unnecessaryParentheses3.kt") public void testUnnecessaryParentheses3() throws Exception { - doTestRemoveUnnecessaryParentheses("idea/testData/codeInsight/codeTransformations/removeUnnecessaryParentheses/unnecessaryParentheses3.kt"); + doTestRemoveUnnecessaryParentheses("idea/testData/intentions/removeUnnecessaryParentheses/unnecessaryParentheses3.kt"); } @TestMetadata("unnecessaryParentheses4.kt") public void testUnnecessaryParentheses4() throws Exception { - doTestRemoveUnnecessaryParentheses("idea/testData/codeInsight/codeTransformations/removeUnnecessaryParentheses/unnecessaryParentheses4.kt"); + doTestRemoveUnnecessaryParentheses("idea/testData/intentions/removeUnnecessaryParentheses/unnecessaryParentheses4.kt"); } @TestMetadata("unnecessaryParentheses5.kt") public void testUnnecessaryParentheses5() throws Exception { - doTestRemoveUnnecessaryParentheses("idea/testData/codeInsight/codeTransformations/removeUnnecessaryParentheses/unnecessaryParentheses5.kt"); + doTestRemoveUnnecessaryParentheses("idea/testData/intentions/removeUnnecessaryParentheses/unnecessaryParentheses5.kt"); } @TestMetadata("unnecessaryParentheses6.kt") public void testUnnecessaryParentheses6() throws Exception { - doTestRemoveUnnecessaryParentheses("idea/testData/codeInsight/codeTransformations/removeUnnecessaryParentheses/unnecessaryParentheses6.kt"); + doTestRemoveUnnecessaryParentheses("idea/testData/intentions/removeUnnecessaryParentheses/unnecessaryParentheses6.kt"); } @TestMetadata("unnecessaryParentheses7.kt") public void testUnnecessaryParentheses7() throws Exception { - doTestRemoveUnnecessaryParentheses("idea/testData/codeInsight/codeTransformations/removeUnnecessaryParentheses/unnecessaryParentheses7.kt"); + doTestRemoveUnnecessaryParentheses("idea/testData/intentions/removeUnnecessaryParentheses/unnecessaryParentheses7.kt"); } } diff --git a/idea/tests/org/jetbrains/jet/plugin/codeInsight/ktSignature/SignatureMarkerProviderTest.java b/idea/tests/org/jetbrains/jet/plugin/ktSignature/SignatureMarkerProviderTest.java similarity index 92% rename from idea/tests/org/jetbrains/jet/plugin/codeInsight/ktSignature/SignatureMarkerProviderTest.java rename to idea/tests/org/jetbrains/jet/plugin/ktSignature/SignatureMarkerProviderTest.java index 6d57d6059d6..3a251e44865 100644 --- a/idea/tests/org/jetbrains/jet/plugin/codeInsight/ktSignature/SignatureMarkerProviderTest.java +++ b/idea/tests/org/jetbrains/jet/plugin/ktSignature/SignatureMarkerProviderTest.java @@ -14,7 +14,7 @@ * limitations under the License. */ -package org.jetbrains.jet.plugin.codeInsight.ktSignature; +package org.jetbrains.jet.plugin.ktSignature; import com.intellij.openapi.project.Project; import com.intellij.psi.JavaPsiFacade; @@ -30,6 +30,7 @@ import org.jetbrains.jet.lang.resolve.name.FqName; import org.jetbrains.jet.plugin.JetFileType; import org.jetbrains.jet.plugin.JetLightProjectDescriptor; import org.jetbrains.jet.plugin.caches.resolve.KotlinCacheManager; +import org.jetbrains.jet.plugin.ktSignature.KotlinSignatureInJavaMarkerProvider; import org.jetbrains.jet.plugin.project.TargetPlatform; public class SignatureMarkerProviderTest extends LightCodeInsightFixtureTestCase { @@ -41,7 +42,9 @@ public class SignatureMarkerProviderTest extends LightCodeInsightFixtureTestCase } public void testReResolveJavaClass() { - Project project = myFixture.getProject(); + Project project; + project = myFixture.getProject(); + myFixture.configureByText(JetFileType.INSTANCE, "val t: Thread? = null"); From 60a2f4ef08d9654436281273b893e420ff690093 Mon Sep 17 00:00:00 2001 From: Zalim Bashorov Date: Tue, 4 Jun 2013 16:06:41 +0400 Subject: [PATCH 131/291] Added SingleFileTranslationTest#checkFooBoxIsOk without arguments which use test name as filename. --- .../org/jetbrains/k2js/test/SingleFileTranslationTest.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/js/js.tests/test/org/jetbrains/k2js/test/SingleFileTranslationTest.java b/js/js.tests/test/org/jetbrains/k2js/test/SingleFileTranslationTest.java index ae23763cf02..2209fb90949 100644 --- a/js/js.tests/test/org/jetbrains/k2js/test/SingleFileTranslationTest.java +++ b/js/js.tests/test/org/jetbrains/k2js/test/SingleFileTranslationTest.java @@ -68,6 +68,10 @@ public abstract class SingleFileTranslationTest extends BasicTest { checkFooBoxIsTrue(getTestName(true) + ".kt", ecmaVersions); } + protected void checkFooBoxIsOk() throws Exception { + checkFooBoxIsOk(getTestName(true) + ".kt"); + } + protected void checkFooBoxIsOk(@NotNull String filename) throws Exception { checkFooBoxIsOk(DEFAULT_ECMA_VERSIONS, filename); } From 2bae64741264ff477a76df8bf2f922701f9f09b4 Mon Sep 17 00:00:00 2001 From: Zalim Bashorov Date: Tue, 4 Jun 2013 16:06:41 +0400 Subject: [PATCH 132/291] Make nullable check less verbose in JS-backend. For check what variable is equal null or undefined enough to compare with null (or undefined). See ECMAScript specification 11.9.1, 11.9.2, 11.9.3 --- .../k2js/test/semantics/EqualsTest.java | 4 ++++ .../operation/UnaryOperationTranslator.java | 4 ++-- .../k2js/translate/reference/CallType.java | 4 ++-- .../k2js/translate/utils/TranslationUtils.java | 16 ++++++---------- .../equals/cases/equalsNullOrUndefined.kt | 18 ++++++++++++++++++ 5 files changed, 32 insertions(+), 14 deletions(-) create mode 100644 js/js.translator/testFiles/expression/equals/cases/equalsNullOrUndefined.kt diff --git a/js/js.tests/test/org/jetbrains/k2js/test/semantics/EqualsTest.java b/js/js.tests/test/org/jetbrains/k2js/test/semantics/EqualsTest.java index 2e337c0af8f..30e5d8da47e 100644 --- a/js/js.tests/test/org/jetbrains/k2js/test/semantics/EqualsTest.java +++ b/js/js.tests/test/org/jetbrains/k2js/test/semantics/EqualsTest.java @@ -45,4 +45,8 @@ public final class EqualsTest extends AbstractExpressionTest { public void testKt2370() throws Exception { fooBoxTest(); } + + public void testEqualsNullOrUndefined() throws Exception { + checkFooBoxIsOk(); + } } \ No newline at end of file diff --git a/js/js.translator/src/org/jetbrains/k2js/translate/operation/UnaryOperationTranslator.java b/js/js.translator/src/org/jetbrains/k2js/translate/operation/UnaryOperationTranslator.java index 634f1934ddd..48873acabd4 100644 --- a/js/js.translator/src/org/jetbrains/k2js/translate/operation/UnaryOperationTranslator.java +++ b/js/js.translator/src/org/jetbrains/k2js/translate/operation/UnaryOperationTranslator.java @@ -33,7 +33,7 @@ import static org.jetbrains.k2js.translate.general.Translation.translateAsExpres import static org.jetbrains.k2js.translate.utils.BindingUtils.getResolvedCall; import static org.jetbrains.k2js.translate.utils.PsiUtils.getBaseExpression; import static org.jetbrains.k2js.translate.utils.PsiUtils.getOperationToken; -import static org.jetbrains.k2js.translate.utils.TranslationUtils.notNullConditionalTestExpression; +import static org.jetbrains.k2js.translate.utils.TranslationUtils.isNotNullCheck; public final class UnaryOperationTranslator { @@ -59,7 +59,7 @@ public final class UnaryOperationTranslator { @NotNull private static JsExpression translateExclExclOperator(@NotNull JetUnaryExpression expression, @NotNull TranslationContext context) { TemporaryVariable cachedValue = context.declareTemporary(translateAsExpression(getBaseExpression(expression), context)); - return new JsConditional(notNullConditionalTestExpression(cachedValue), cachedValue.reference(), context.namer().throwNPEFunctionCall()); + return new JsConditional(isNotNullCheck(cachedValue.assignmentExpression()), cachedValue.reference(), context.namer().throwNPEFunctionCall()); } @NotNull diff --git a/js/js.translator/src/org/jetbrains/k2js/translate/reference/CallType.java b/js/js.translator/src/org/jetbrains/k2js/translate/reference/CallType.java index ef7e7cf5603..13b1849df95 100644 --- a/js/js.translator/src/org/jetbrains/k2js/translate/reference/CallType.java +++ b/js/js.translator/src/org/jetbrains/k2js/translate/reference/CallType.java @@ -27,7 +27,7 @@ import org.jetbrains.jet.lang.psi.JetSafeQualifiedExpression; import org.jetbrains.k2js.translate.context.TemporaryVariable; import org.jetbrains.k2js.translate.context.TranslationContext; -import static org.jetbrains.k2js.translate.utils.TranslationUtils.notNullConditionalTestExpression; +import static org.jetbrains.k2js.translate.utils.TranslationUtils.isNotNullCheck; public enum CallType { SAFE { @@ -37,7 +37,7 @@ public enum CallType { @NotNull TranslationContext context) { assert receiver != null; TemporaryVariable cachedValue = context.declareTemporary(receiver); - return new JsConditional(notNullConditionalTestExpression(cachedValue), constructor.construct(cachedValue.reference()), JsLiteral.NULL); + return new JsConditional(isNotNullCheck(cachedValue.assignmentExpression()), constructor.construct(cachedValue.reference()), JsLiteral.NULL); } }, //TODO: bang qualifier is not implemented in frontend for now diff --git a/js/js.translator/src/org/jetbrains/k2js/translate/utils/TranslationUtils.java b/js/js.translator/src/org/jetbrains/k2js/translate/utils/TranslationUtils.java index dd0de2b2437..c507cfafd4f 100644 --- a/js/js.translator/src/org/jetbrains/k2js/translate/utils/TranslationUtils.java +++ b/js/js.translator/src/org/jetbrains/k2js/translate/utils/TranslationUtils.java @@ -24,7 +24,6 @@ import org.jetbrains.jet.lang.descriptors.FunctionDescriptor; import org.jetbrains.jet.lang.descriptors.PropertyDescriptor; import org.jetbrains.jet.lang.descriptors.PropertyGetterDescriptor; import org.jetbrains.jet.lang.psi.*; -import org.jetbrains.k2js.translate.context.TemporaryVariable; import org.jetbrains.k2js.translate.context.TranslationContext; import org.jetbrains.k2js.translate.general.Translation; @@ -32,7 +31,8 @@ import java.util.ArrayList; import java.util.List; import static org.jetbrains.k2js.translate.utils.BindingUtils.getFunctionDescriptorForOperationExpression; -import static org.jetbrains.k2js.translate.utils.JsAstUtils.*; +import static org.jetbrains.k2js.translate.utils.JsAstUtils.assignment; +import static org.jetbrains.k2js.translate.utils.JsAstUtils.setQualifier; public final class TranslationUtils { private TranslationUtils() { @@ -64,19 +64,15 @@ public final class TranslationUtils { } @NotNull - public static JsBinaryOperation notNullConditionalTestExpression(@NotNull TemporaryVariable cachedValue) { - return and(inequality(cachedValue.assignmentExpression(), JsLiteral.NULL), - inequality(cachedValue.reference(), JsLiteral.UNDEFINED)); + public static JsBinaryOperation isNotNullCheck(@NotNull JsExpression expressionToCheck) { + return nullCheck(expressionToCheck, true); } @NotNull public static JsBinaryOperation nullCheck(@NotNull JsExpression expressionToCheck, boolean isNegated) { - JsBinaryOperator operator = isNegated ? JsBinaryOperator.REF_NEQ : JsBinaryOperator.REF_EQ; - return new JsBinaryOperation(isNegated ? JsBinaryOperator.AND : JsBinaryOperator.OR, - new JsBinaryOperation(operator, expressionToCheck, JsLiteral.NULL), - new JsBinaryOperation(operator, expressionToCheck, JsLiteral.UNDEFINED)); + JsBinaryOperator operator = isNegated ? JsBinaryOperator.NEQ : JsBinaryOperator.EQ; + return new JsBinaryOperation(operator, expressionToCheck, JsLiteral.NULL); } - @NotNull public static List translateArgumentList(@NotNull TranslationContext context, @NotNull List jetArguments) { diff --git a/js/js.translator/testFiles/expression/equals/cases/equalsNullOrUndefined.kt b/js/js.translator/testFiles/expression/equals/cases/equalsNullOrUndefined.kt new file mode 100644 index 00000000000..03dd20515b7 --- /dev/null +++ b/js/js.translator/testFiles/expression/equals/cases/equalsNullOrUndefined.kt @@ -0,0 +1,18 @@ +package foo + +fun box() : String { + val a: Int? = null + val r = a == null + if (!r || a != null) + return "wrong result on simple nullable check" + + var i = 0; + fun foo(): Int? = ++i; + if (foo() == null) + return "wrong result on nullable check with side effects" + + if (i != 1) + return "wrong affects when using nullable check with side effects" + + return "OK" +} \ No newline at end of file From ee5c7c8f5cedc9f0365657b2f641a5007d97533c Mon Sep 17 00:00:00 2001 From: Zalim Bashorov Date: Wed, 5 Jun 2013 20:52:59 +0400 Subject: [PATCH 133/291] Added support spread operator in JS-Backend. --- .../k2js/test/semantics/FunctionTest.java | 2 +- .../test/semantics/NativeInteropTest.java | 2 +- .../reference/CallExpressionTranslator.java | 76 +++++++++++++-- .../expression/function/cases/vararg.kt | 56 ++++++++++- .../testFiles/native/cases/vararg.kt | 95 ++++++++++++++++--- .../testFiles/native/native/vararg.js | 36 +++++++ 6 files changed, 239 insertions(+), 28 deletions(-) diff --git a/js/js.tests/test/org/jetbrains/k2js/test/semantics/FunctionTest.java b/js/js.tests/test/org/jetbrains/k2js/test/semantics/FunctionTest.java index 9a621c43758..0ee20a057e5 100644 --- a/js/js.tests/test/org/jetbrains/k2js/test/semantics/FunctionTest.java +++ b/js/js.tests/test/org/jetbrains/k2js/test/semantics/FunctionTest.java @@ -85,7 +85,7 @@ public class FunctionTest extends AbstractExpressionTest { public void testVararg() throws Exception { - fooBoxTest(); + checkFooBoxIsOk(); } public void testKT921() throws Exception { diff --git a/js/js.tests/test/org/jetbrains/k2js/test/semantics/NativeInteropTest.java b/js/js.tests/test/org/jetbrains/k2js/test/semantics/NativeInteropTest.java index c736b354396..6c67e4f7f88 100644 --- a/js/js.tests/test/org/jetbrains/k2js/test/semantics/NativeInteropTest.java +++ b/js/js.tests/test/org/jetbrains/k2js/test/semantics/NativeInteropTest.java @@ -50,7 +50,7 @@ public final class NativeInteropTest extends SingleFileTranslationTest { } public void testVararg() throws Exception { - fooBoxTest(); + checkFooBoxIsOk(); } public void testUndefined() throws Exception { diff --git a/js/js.translator/src/org/jetbrains/k2js/translate/reference/CallExpressionTranslator.java b/js/js.translator/src/org/jetbrains/k2js/translate/reference/CallExpressionTranslator.java index 4c2c1b249a9..d1c9cb177f6 100644 --- a/js/js.translator/src/org/jetbrains/k2js/translate/reference/CallExpressionTranslator.java +++ b/js/js.translator/src/org/jetbrains/k2js/translate/reference/CallExpressionTranslator.java @@ -16,7 +16,8 @@ package org.jetbrains.k2js.translate.reference; -import com.google.dart.compiler.backend.js.ast.JsExpression; +import com.google.dart.compiler.backend.js.ast.*; +import com.intellij.util.SmartList; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.jet.lang.descriptors.CallableDescriptor; @@ -24,10 +25,13 @@ import org.jetbrains.jet.lang.descriptors.ValueParameterDescriptor; import org.jetbrains.jet.lang.psi.JetCallExpression; import org.jetbrains.jet.lang.psi.JetExpression; import org.jetbrains.jet.lang.psi.JetSimpleNameExpression; -import org.jetbrains.jet.lang.resolve.calls.util.ExpressionAsFunctionDescriptor; +import org.jetbrains.jet.lang.psi.ValueArgument; import org.jetbrains.jet.lang.resolve.calls.model.ResolvedCall; import org.jetbrains.jet.lang.resolve.calls.model.ResolvedValueArgument; +import org.jetbrains.jet.lang.resolve.calls.model.VarargValueArgument; import org.jetbrains.jet.lang.resolve.calls.model.VariableAsFunctionResolvedCall; +import org.jetbrains.jet.lang.resolve.calls.util.ExpressionAsFunctionDescriptor; +import org.jetbrains.k2js.translate.context.TemporaryVariable; import org.jetbrains.k2js.translate.context.TranslationContext; import org.jetbrains.k2js.translate.general.Translation; import org.jetbrains.k2js.translate.utils.AnnotationsUtils; @@ -52,6 +56,11 @@ public final class CallExpressionTranslator extends AbstractCallExpressionTransl } private final boolean isNativeFunctionCall; + private boolean hasSpreadOperator = false; + private TemporaryVariable cachedReceiver = null; + private List translatedArguments = null; + private JsExpression translatedReceiver = null; + private JsExpression translatedCallee = null; private CallExpressionTranslator(@NotNull JetCallExpression expression, @Nullable JsExpression receiver, @@ -62,15 +71,23 @@ public final class CallExpressionTranslator extends AbstractCallExpressionTransl @NotNull private JsExpression translate() { + prepareToBuildCall(); + return CallBuilder.build(context()) - .receiver(getReceiver()) - .callee(getCalleeExpression()) - .args(translateArguments()) + .receiver(translatedReceiver) + .callee(translatedCallee) + .args(translatedArguments) .resolvedCall(getResolvedCall()) .type(callType) .translate(); } + private void prepareToBuildCall() { + translatedArguments = translateArguments(); + translatedReceiver = getReceiver(); + translatedCallee = getCalleeExpression(); + } + @NotNull private ResolvedCall getResolvedCall() { if (resolvedCall instanceof VariableAsFunctionResolvedCall) { @@ -81,14 +98,23 @@ public final class CallExpressionTranslator extends AbstractCallExpressionTransl @Nullable private JsExpression getReceiver() { - if (receiver != null) { - return receiver; + assert translatedArguments != null : "the results of this function depends on the results of translateArguments()"; + if (receiver == null) { + return null; } - return null; + if (cachedReceiver != null) { + return cachedReceiver.assignmentExpression(); + } + return receiver; } @Nullable private JsExpression getCalleeExpression() { + assert translatedArguments != null : "the results of this function depends on the results of translateArguments()"; + if (isNativeFunctionCall && hasSpreadOperator) { + String functionName = resolvedCall.getCandidateDescriptor().getOriginal().getName().getIdentifier(); + return new JsNameRef("apply", functionName); + } CallableDescriptor candidateDescriptor = resolvedCall.getCandidateDescriptor(); if (candidateDescriptor instanceof ExpressionAsFunctionDescriptor) { return translateExpressionAsFunction(); @@ -118,15 +144,47 @@ public final class CallExpressionTranslator extends AbstractCallExpressionTransl @NotNull private List translateArguments() { List result = new ArrayList(); + List argsBeforeVararg = null; for (ValueParameterDescriptor parameterDescriptor : resolvedCall.getResultingDescriptor().getValueParameters()) { ResolvedValueArgument actualArgument = resolvedCall.getValueArgumentsByIndex().get(parameterDescriptor.getIndex()); + + if (actualArgument instanceof VarargValueArgument) { + assert !hasSpreadOperator; + + List arguments = actualArgument.getArguments(); + hasSpreadOperator = arguments.size() == 1 && arguments.get(0).getSpreadElement() != null; + + if (isNativeFunctionCall && hasSpreadOperator) { + assert argsBeforeVararg == null; + argsBeforeVararg = result; + result = new SmartList(); + } + } + result.addAll(translateSingleArgument(actualArgument, parameterDescriptor)); } + + if (isNativeFunctionCall && hasSpreadOperator) { + assert argsBeforeVararg != null; + if (!argsBeforeVararg.isEmpty()) { + JsInvocation concatArguments = new JsInvocation(new JsNameRef("concat", new JsArrayLiteral(argsBeforeVararg)), result); + result = new SmartList(concatArguments); + } + + if (receiver != null) { + cachedReceiver = context().declareTemporary(receiver); + result.add(0, cachedReceiver.reference()); + } + else { + result.add(0, JsLiteral.NULL); + } + } + return result; } @Override public boolean shouldWrapVarargInArray() { - return !isNativeFunctionCall; + return !isNativeFunctionCall && !hasSpreadOperator; } } diff --git a/js/js.translator/testFiles/expression/function/cases/vararg.kt b/js/js.translator/testFiles/expression/function/cases/vararg.kt index d3ab09ec173..58796e61419 100644 --- a/js/js.translator/testFiles/expression/function/cases/vararg.kt +++ b/js/js.translator/testFiles/expression/function/cases/vararg.kt @@ -13,5 +13,57 @@ fun testSum(expectedSum : Int, vararg i : Int) : Boolean { return (expectedSum == sum) } -fun box() = testSize(0) && testSum(0) && testSize(3, 1, 1, 1) && testSum(3, 1, 1, 1) && testSize(6, 1, 1, 1, 2, 3, 4) && - testSum(30, 10, 20, 0) \ No newline at end of file +fun testSpreadOperator(vararg args : Int): Boolean { + var sum = 0; + for (a in args) sum += a + + return testSize(args.size, *args) && testSum(sum, *args) +} + +class Bar(val size: Int, val sum: Int) { + fun test(vararg args : Int) = testSize(size, *args) && testSum(sum, *args) +} + +object obj { + fun test(size: Int, sum: Int, vararg args: Int) = testSize(size, *args) && testSum(sum, *args) +} + +fun spreadInMethodCall(size: Int, sum: Int, vararg args: Int) = Bar(size, sum).test(*args) + +fun spreadInObjectMethodCall(size: Int, sum: Int, vararg args: Int) = obj.test(size, sum, *args) + +fun testVarargWithFunLit(vararg args: Int, f: (a: IntArray) -> Boolean): Boolean = f(args) + +fun box(): String { + if (!testSize(0)) + return "wrong vararg size when call function without args" + + if (!testSum(0)) + return "wrong vararg sum (arguments) when call function without args" + + if (!testSize(6, 1, 1, 1, 2, 3, 4)) + return "wrong vararg size when call function with some args (1)" + + if (!testSum(30, 10, 20, 0)) + return "wrong vararg sum (arguments) when call function with some args (1)" + + if (!testSpreadOperator(30, 10, 20, 0)) + return "failed when call function using spread operator" + + if (!Bar(3, 30).test(10, 20, 0)) + return "failed when call method" + + if (!spreadInMethodCall(2, 3, 1, 2)) + return "failed when call method using spread operator" + + if (!obj.test(5, 15, 1, 2, 3, 4, 5)) + return "failed when call method of object" + + if (!spreadInObjectMethodCall(2, 3, 1, 2)) + return "failed when call method of object using spread operator" + + if (!testVarargWithFunLit(1, 2, 3) { args -> args.size == 3 }) + return "failed when call function with vararg and fun literal" + + return "OK" +} \ No newline at end of file diff --git a/js/js.translator/testFiles/native/cases/vararg.kt b/js/js.translator/testFiles/native/cases/vararg.kt index b031e3de2b3..f81532714e9 100644 --- a/js/js.translator/testFiles/native/cases/vararg.kt +++ b/js/js.translator/testFiles/native/cases/vararg.kt @@ -5,20 +5,85 @@ import js.* native fun paramCount(vararg a : Int) : Int = js.noImpl -fun count(vararg a : Int) = a.size +// test spread operator +fun count(vararg a : Int) = paramCount(*a) -fun box() : Boolean { - if (paramCount(1, 2 ,3) != 3) { - return false; - } - if (paramCount() != 0) { - return false; - } - if (count() != 0) { - return false; - } - if (count(1, 1, 1, 1) != 4) { - return false; - } - return true; +native +class Bar(val size: Int, order: Int = 0) { + fun test(order: Int, dummy: Int, vararg args: Int): Boolean = js.noImpl + class object { + fun startNewTest(): Boolean = js.noImpl + var hasOrderProblem: Boolean = false + } +} + +native +object obj { + fun test(size: Int, vararg args: Int): Boolean = js.noImpl +} + +fun spreadInMethodCall(size: Int, vararg args: Int) = Bar(size).test(0, 1, *args) + +fun spreadInObjectMethodCall(size: Int, vararg args: Int) = obj.test(size, *args) + +native +fun testNativeVarargWithFunLit(vararg args: Int, f: (a: IntArray) -> Boolean): Boolean = js.noImpl + +fun testSpreadOperatorWithSafeCall(a: Bar?, expected: Boolean?, vararg args: Int): Boolean { + return a?.test(0, 1, *args) == expected +} + +fun testSpreadOperatorWithSureCall(a: Bar?, vararg args: Int): Boolean { + return a!!.test(0, 1, *args) +} + +fun testCallOrder(vararg args: Int) = + Bar.startNewTest() && + Bar(args.size, 0).test(1, 1, *args) && Bar(args.size, 2).test(3, 1, *args) && + !Bar.hasOrderProblem + +fun box(): String { + if (paramCount() != 0) + return "failed when call native function without args" + + if (paramCount(1, 2 ,3) != 3) + return "failed when call native function with some args" + + if (count() != 0) + return "failed when call native function without args using spread operator" + + if (count(1, 1, 1, 1) != 4) + return "failed when call native function with some args using spread operator" + + if (!Bar(5).test(0, 1, 1, 2, 3, 4, 5)) + return "failed when call method with some args" + + if (!spreadInMethodCall(2, 1, 2)) + return "failed when call method using spread operator" + + if (!(obj.test(5, 1, 2, 3, 4, 5))) + return "failed when call method of object" + + if (!(spreadInObjectMethodCall(2, 1, 2))) + return "failed when call method of object using spread operator" + + if (!(testNativeVarargWithFunLit(1, 2, 3) { args -> args.size == 3 })) + return "failed when call native function with vararg and fun literal" + + if (!(testSpreadOperatorWithSafeCall(null, null))) + return "failed when test spread operator with SafeCall (?.) using null receiver" + + if (!(testSpreadOperatorWithSafeCall(Bar(3), true, 1, 2, 3))) + return "failed when test spread operator with SafeCall (?.)" + + if (!(testSpreadOperatorWithSureCall(Bar(3), 1, 2, 3))) + return "failed when test spread operator with SureCall (!!)" + + if (!(testCallOrder())) + return "failed when test calling order when using spread operator without args" + + if (!(testCallOrder(1, 2, 3, 4))) + return "failed when test calling order when using spread operator without args" + + return "OK" } \ No newline at end of file diff --git a/js/js.translator/testFiles/native/native/vararg.js b/js/js.translator/testFiles/native/native/vararg.js index 39626c647c8..1222cb5d625 100644 --- a/js/js.translator/testFiles/native/native/vararg.js +++ b/js/js.translator/testFiles/native/native/vararg.js @@ -16,4 +16,40 @@ function paramCount() { return arguments.length +} + +function Bar(size, order) { + this.size = size; + Bar.checkOrder(order); +} + +Bar.order = 0; +Bar.hasOrderProblem = false; +Bar.checkOrder = function (expectedOrder) { + var curOrder = Bar.order++; + Bar.hasOrderProblem = Bar.hasOrderProblem || curOrder !== expectedOrder; +}; + +Bar.startNewTest = function () { + Bar.hasOrderProblem = false; + Bar.order = 0; + return true; +}; + + +Bar.prototype.test = function (order, dummy /*, args */) { + Bar.checkOrder(order); + return dummy === 1 && (arguments.length - 2) === this.size; +}; + +var obj = { + test : function (size /*, args */) { + return (arguments.length - 1) === size; + } +}; + +function testNativeVarargWithFunLit(/* args, f */) { + var args = Array.prototype.slice.call(arguments, 0, arguments.length - 1); + var f = arguments[arguments.length - 1]; + return typeof f === "function" && f(args); } \ No newline at end of file From a69744e6fb00e85a82ea7aa61bd589cbe4d8c032 Mon Sep 17 00:00:00 2001 From: Zalim Bashorov Date: Sat, 15 Jun 2013 15:55:10 +0400 Subject: [PATCH 134/291] Introduced the cache of temporary variables and expressions. Used the cached temporary variables in SafeCall and SureCall instead create a new temporary variable. --- .../translate/context/DynamicContext.java | 2 +- .../translate/context/TemporaryVariable.java | 9 +++++-- .../translate/context/TranslationContext.java | 24 +++++++++++++++++++ .../operation/UnaryOperationTranslator.java | 12 +++++++--- .../reference/CallExpressionTranslator.java | 6 ++--- .../k2js/translate/reference/CallType.java | 7 +++--- .../testFiles/native/cases/vararg.kt | 4 ++++ 7 files changed, 52 insertions(+), 12 deletions(-) diff --git a/js/js.translator/src/org/jetbrains/k2js/translate/context/DynamicContext.java b/js/js.translator/src/org/jetbrains/k2js/translate/context/DynamicContext.java index 4245b57f840..0fd7f29bb8f 100644 --- a/js/js.translator/src/org/jetbrains/k2js/translate/context/DynamicContext.java +++ b/js/js.translator/src/org/jetbrains/k2js/translate/context/DynamicContext.java @@ -63,7 +63,7 @@ public final class DynamicContext { JsName temporaryName = currentScope.declareTemporary(); vars.add(new JsVar(temporaryName, null)); - return new TemporaryVariable(temporaryName, initExpression); + return TemporaryVariable.create(temporaryName, initExpression); } @NotNull diff --git a/js/js.translator/src/org/jetbrains/k2js/translate/context/TemporaryVariable.java b/js/js.translator/src/org/jetbrains/k2js/translate/context/TemporaryVariable.java index bd933d3e309..c30ee87d4ab 100644 --- a/js/js.translator/src/org/jetbrains/k2js/translate/context/TemporaryVariable.java +++ b/js/js.translator/src/org/jetbrains/k2js/translate/context/TemporaryVariable.java @@ -24,14 +24,19 @@ import org.jetbrains.annotations.Nullable; import org.jetbrains.k2js.translate.utils.JsAstUtils; public class TemporaryVariable { + + /*package*/ static TemporaryVariable create(@NotNull JsName temporaryName, @Nullable JsExpression initExpression) { + return new TemporaryVariable(temporaryName, initExpression == null ? null : JsAstUtils.assignment(temporaryName.makeRef(), initExpression)); + } + @Nullable private final JsExpression assignmentExpression; @NotNull private final JsName variableName; - /*package*/ TemporaryVariable(@NotNull JsName temporaryName, @Nullable JsExpression initExpression) { + protected TemporaryVariable(@NotNull JsName temporaryName, @Nullable JsExpression assignmentExpression) { this.variableName = temporaryName; - this.assignmentExpression = initExpression == null ? null : JsAstUtils.assignment(variableName.makeRef(), initExpression); + this.assignmentExpression = assignmentExpression; } @NotNull 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 374123af50c..3f584075e1f 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 @@ -28,6 +28,7 @@ import org.jetbrains.jet.lang.resolve.BindingContext; import org.jetbrains.k2js.translate.expression.LiteralFunctionTranslator; import org.jetbrains.k2js.translate.intrinsic.Intrinsics; +import java.util.HashMap; import java.util.Map; import static org.jetbrains.k2js.translate.utils.BindingUtils.getDescriptorForElement; @@ -53,6 +54,8 @@ public class TranslationContext { rootDynamicContext, rootAliasingContext); } + private final HashMap expressionToTempConstVariableCache = new HashMap(); + public boolean isEcma5() { return staticContext.isEcma5(); } @@ -177,6 +180,27 @@ public class TranslationContext { return dynamicContext.declareTemporary(initExpression); } + @NotNull + public TemporaryConstVariable getOrDeclareTemporaryConstVariable(@NotNull JsExpression expression) { + TemporaryConstVariable tempVar = expressionToTempConstVariableCache.get(expression); + + if (tempVar == null) { + TemporaryVariable tmpVar = declareTemporary(expression); + + tempVar = new TemporaryConstVariable(tmpVar.name(), tmpVar.assignmentExpression()); + + expressionToTempConstVariableCache.put(expression, tempVar); + expressionToTempConstVariableCache.put(tmpVar.assignmentExpression(), tempVar); + } + + return tempVar; + } + + public void associateExpressionToLazyValue(JsExpression expression, TemporaryConstVariable temporaryConstVariable) { + assert expression == temporaryConstVariable.assignmentExpression(); + expressionToTempConstVariableCache.put(expression, temporaryConstVariable); + } + @NotNull public Namer namer() { return staticContext.getNamer(); diff --git a/js/js.translator/src/org/jetbrains/k2js/translate/operation/UnaryOperationTranslator.java b/js/js.translator/src/org/jetbrains/k2js/translate/operation/UnaryOperationTranslator.java index 48873acabd4..85a82e04267 100644 --- a/js/js.translator/src/org/jetbrains/k2js/translate/operation/UnaryOperationTranslator.java +++ b/js/js.translator/src/org/jetbrains/k2js/translate/operation/UnaryOperationTranslator.java @@ -21,7 +21,7 @@ import com.google.dart.compiler.backend.js.ast.JsExpression; import org.jetbrains.annotations.NotNull; import org.jetbrains.jet.lang.psi.JetUnaryExpression; import org.jetbrains.jet.lexer.JetTokens; -import org.jetbrains.k2js.translate.context.TemporaryVariable; +import org.jetbrains.k2js.translate.context.TemporaryConstVariable; import org.jetbrains.k2js.translate.context.TranslationContext; import org.jetbrains.k2js.translate.reference.CallBuilder; import org.jetbrains.k2js.translate.reference.CallType; @@ -58,8 +58,14 @@ public final class UnaryOperationTranslator { @NotNull private static JsExpression translateExclExclOperator(@NotNull JetUnaryExpression expression, @NotNull TranslationContext context) { - TemporaryVariable cachedValue = context.declareTemporary(translateAsExpression(getBaseExpression(expression), context)); - return new JsConditional(isNotNullCheck(cachedValue.assignmentExpression()), cachedValue.reference(), context.namer().throwNPEFunctionCall()); + JsExpression translatedExpression = translateAsExpression(getBaseExpression(expression), context); + TemporaryConstVariable tempVar = context.getOrDeclareTemporaryConstVariable(translatedExpression); + + JsConditional ensureNotNull = new JsConditional(isNotNullCheck(tempVar.value()), tempVar.value(), context.namer().throwNPEFunctionCall()); + + // associate (cache) ensureNotNull expression to new LazyValue with same name. + context.associateExpressionToLazyValue(ensureNotNull, new TemporaryConstVariable(tempVar.name(), ensureNotNull)); + return ensureNotNull; } @NotNull diff --git a/js/js.translator/src/org/jetbrains/k2js/translate/reference/CallExpressionTranslator.java b/js/js.translator/src/org/jetbrains/k2js/translate/reference/CallExpressionTranslator.java index d1c9cb177f6..75940e5604c 100644 --- a/js/js.translator/src/org/jetbrains/k2js/translate/reference/CallExpressionTranslator.java +++ b/js/js.translator/src/org/jetbrains/k2js/translate/reference/CallExpressionTranslator.java @@ -31,7 +31,7 @@ import org.jetbrains.jet.lang.resolve.calls.model.ResolvedValueArgument; import org.jetbrains.jet.lang.resolve.calls.model.VarargValueArgument; import org.jetbrains.jet.lang.resolve.calls.model.VariableAsFunctionResolvedCall; import org.jetbrains.jet.lang.resolve.calls.util.ExpressionAsFunctionDescriptor; -import org.jetbrains.k2js.translate.context.TemporaryVariable; +import org.jetbrains.k2js.translate.context.TemporaryConstVariable; import org.jetbrains.k2js.translate.context.TranslationContext; import org.jetbrains.k2js.translate.general.Translation; import org.jetbrains.k2js.translate.utils.AnnotationsUtils; @@ -57,7 +57,7 @@ public final class CallExpressionTranslator extends AbstractCallExpressionTransl private final boolean isNativeFunctionCall; private boolean hasSpreadOperator = false; - private TemporaryVariable cachedReceiver = null; + private TemporaryConstVariable cachedReceiver = null; private List translatedArguments = null; private JsExpression translatedReceiver = null; private JsExpression translatedCallee = null; @@ -172,7 +172,7 @@ public final class CallExpressionTranslator extends AbstractCallExpressionTransl } if (receiver != null) { - cachedReceiver = context().declareTemporary(receiver); + cachedReceiver = context().getOrDeclareTemporaryConstVariable(receiver); result.add(0, cachedReceiver.reference()); } else { diff --git a/js/js.translator/src/org/jetbrains/k2js/translate/reference/CallType.java b/js/js.translator/src/org/jetbrains/k2js/translate/reference/CallType.java index 13b1849df95..893455b6d3c 100644 --- a/js/js.translator/src/org/jetbrains/k2js/translate/reference/CallType.java +++ b/js/js.translator/src/org/jetbrains/k2js/translate/reference/CallType.java @@ -24,7 +24,7 @@ import org.jetbrains.annotations.Nullable; import org.jetbrains.jet.lang.psi.JetDotQualifiedExpression; import org.jetbrains.jet.lang.psi.JetQualifiedExpression; import org.jetbrains.jet.lang.psi.JetSafeQualifiedExpression; -import org.jetbrains.k2js.translate.context.TemporaryVariable; +import org.jetbrains.k2js.translate.context.TemporaryConstVariable; import org.jetbrains.k2js.translate.context.TranslationContext; import static org.jetbrains.k2js.translate.utils.TranslationUtils.isNotNullCheck; @@ -36,8 +36,9 @@ public enum CallType { JsExpression constructCall(@Nullable JsExpression receiver, @NotNull CallConstructor constructor, @NotNull TranslationContext context) { assert receiver != null; - TemporaryVariable cachedValue = context.declareTemporary(receiver); - return new JsConditional(isNotNullCheck(cachedValue.assignmentExpression()), constructor.construct(cachedValue.reference()), JsLiteral.NULL); + + TemporaryConstVariable tempVar = context.getOrDeclareTemporaryConstVariable(receiver); + return new JsConditional(isNotNullCheck(tempVar.value()), constructor.construct(tempVar.value()), JsLiteral.NULL); } }, //TODO: bang qualifier is not implemented in frontend for now diff --git a/js/js.translator/testFiles/native/cases/vararg.kt b/js/js.translator/testFiles/native/cases/vararg.kt index f81532714e9..1486d25e137 100644 --- a/js/js.translator/testFiles/native/cases/vararg.kt +++ b/js/js.translator/testFiles/native/cases/vararg.kt @@ -85,5 +85,9 @@ fun box(): String { if (!(testCallOrder(1, 2, 3, 4))) return "failed when test calling order when using spread operator without args" + val baz: Bar? = Bar(1) + if (!(baz!!)?.test(0, 1, 1)) + return "failed when combined SureCall and SafeCall, maybe we lost cached expression" + return "OK" } \ No newline at end of file From 16d71eeeace4ede335eda0d3858d4c9423532f07 Mon Sep 17 00:00:00 2001 From: Zalim Bashorov Date: Sat, 15 Jun 2013 16:08:55 +0400 Subject: [PATCH 135/291] Added missing file (class). --- .../context/TemporaryConstVariable.java | 38 +++++++++++++++++++ 1 file changed, 38 insertions(+) create mode 100644 js/js.translator/src/org/jetbrains/k2js/translate/context/TemporaryConstVariable.java diff --git a/js/js.translator/src/org/jetbrains/k2js/translate/context/TemporaryConstVariable.java b/js/js.translator/src/org/jetbrains/k2js/translate/context/TemporaryConstVariable.java new file mode 100644 index 00000000000..46eb4af5838 --- /dev/null +++ b/js/js.translator/src/org/jetbrains/k2js/translate/context/TemporaryConstVariable.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.k2js.translate.context; + +import com.google.dart.compiler.backend.js.ast.JsExpression; +import com.google.dart.compiler.backend.js.ast.JsName; +import org.jetbrains.annotations.NotNull; + +public final class TemporaryConstVariable extends TemporaryVariable{ + private boolean initialized = false; + + public TemporaryConstVariable(@NotNull JsName variableName, @NotNull JsExpression assignmentExpression) { + super(variableName, assignmentExpression); + } + + @NotNull + public JsExpression value() { + if (initialized) { + return reference(); + } + initialized = true; + return assignmentExpression(); + } +} From 4ef2f997ed7b25b7a0f9bb65f336e2e34bb34643 Mon Sep 17 00:00:00 2001 From: Mikhael Bogdanov Date: Mon, 10 Jun 2013 15:56:14 +0400 Subject: [PATCH 136/291] Test for not reproduced KT-2700 #KT-2700 Can't Reproduce --- .../testData/codegen/box/localClasses/kt2700.kt | 17 +++++++++++++++++ .../generated/BlackBoxCodegenTestGenerated.java | 5 +++++ 2 files changed, 22 insertions(+) create mode 100644 compiler/testData/codegen/box/localClasses/kt2700.kt diff --git a/compiler/testData/codegen/box/localClasses/kt2700.kt b/compiler/testData/codegen/box/localClasses/kt2700.kt new file mode 100644 index 00000000000..f6964fb8e1e --- /dev/null +++ b/compiler/testData/codegen/box/localClasses/kt2700.kt @@ -0,0 +1,17 @@ +package a.b + +trait Test { + fun invoke(): String { + return "OK" + } +} + +private val a : Test = { + object : Test { + + } +}() + +fun box(): String { + return a.invoke(); +} \ 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 0996939a371..bcc33435963 100644 --- a/compiler/tests/org/jetbrains/jet/codegen/generated/BlackBoxCodegenTestGenerated.java +++ b/compiler/tests/org/jetbrains/jet/codegen/generated/BlackBoxCodegenTestGenerated.java @@ -2449,6 +2449,11 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest { doTest("compiler/testData/codegen/box/localClasses/innerClassInLocalClass.kt"); } + @TestMetadata("kt2700.kt") + public void testKt2700() throws Exception { + doTest("compiler/testData/codegen/box/localClasses/kt2700.kt"); + } + @TestMetadata("kt2873.kt") public void testKt2873() throws Exception { doTest("compiler/testData/codegen/box/localClasses/kt2873.kt"); From 47fe81471ab935bd83f399ff8edf1e381bbedd89 Mon Sep 17 00:00:00 2001 From: Mikhael Bogdanov Date: Mon, 10 Jun 2013 18:14:05 +0400 Subject: [PATCH 137/291] Synthetic accessors for class object private members #KT-3338 Fixed --- .../org/jetbrains/jet/codegen/AsmUtil.java | 8 +- .../jetbrains/jet/codegen/CallableMethod.java | 6 +- .../jet/codegen/ClassBodyCodegen.java | 24 ++- .../org/jetbrains/jet/codegen/CodeChunk.java | 4 +- .../jet/codegen/ExpressionCodegen.java | 59 ++----- .../jet/codegen/FunctionCodegen.java | 7 +- .../codegen/ImplementationBodyCodegen.java | 145 ++++++++++-------- .../jet/codegen/PropertyCodegen.java | 2 + .../org/jetbrains/jet/codegen/StackValue.java | 4 +- .../jet/codegen/context/ClassContext.java | 12 +- .../jet/codegen/context/CodegenContext.java | 129 +++++++++++++++- .../di/InjectorForTopDownAnalyzerForJvm.java | 4 + .../jet/di/InjectorForBodyResolve.java | 4 + .../jet/di/InjectorForLazyResolve.java | 4 + .../jetbrains/jet/di/InjectorForMacros.java | 4 + .../di/InjectorForTopDownAnalyzerBasic.java | 4 + .../jet/lang/resolve/BindingContext.java | 2 + .../jet/lang/resolve/DescriptorUtils.java | 18 ++- .../jet/lang/resolve/calls/CallResolver.java | 25 ++- .../resolve/calls/CallResolverExtension.java | 26 ++++ .../NeedSyntheticCallResolverExtension.java | 54 +++++++ .../function/classObjectPrivate/privateFun.kt | 14 ++ .../function/classObjectPrivate/privateVal.kt | 12 ++ .../function/classObjectPrivate/privateVar.kt | 12 ++ .../function/constructors/classObject.kt | 8 + .../function/constructors/objectInClass.kt | 8 + .../function/constructors/objectLiteral.kt | 9 ++ .../function/constructors/topLevelObject.kt | 7 + .../flags/WriteFlagsTestGenerated.java | 55 ++++++- .../jetbrains/jet/di/InjectorForTests.java | 4 + .../injectors/GenerateInjectors.java | 10 +- .../di/InjectorForTopDownAnalyzerForJs.java | 4 + 32 files changed, 542 insertions(+), 146 deletions(-) create mode 100644 compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/CallResolverExtension.java create mode 100644 compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/NeedSyntheticCallResolverExtension.java create mode 100644 compiler/testData/writeFlags/function/classObjectPrivate/privateFun.kt create mode 100644 compiler/testData/writeFlags/function/classObjectPrivate/privateVal.kt create mode 100644 compiler/testData/writeFlags/function/classObjectPrivate/privateVar.kt create mode 100644 compiler/testData/writeFlags/function/constructors/classObject.kt create mode 100644 compiler/testData/writeFlags/function/constructors/objectInClass.kt create mode 100644 compiler/testData/writeFlags/function/constructors/objectLiteral.kt create mode 100644 compiler/testData/writeFlags/function/constructors/topLevelObject.kt diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/AsmUtil.java b/compiler/backend/src/org/jetbrains/jet/codegen/AsmUtil.java index 8a818ac3f6d..fbe222a069f 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/AsmUtil.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/AsmUtil.java @@ -30,6 +30,7 @@ import org.jetbrains.jet.codegen.binding.CalculatedClosure; import org.jetbrains.jet.codegen.state.GenerationState; import org.jetbrains.jet.codegen.state.JetTypeMapper; import org.jetbrains.jet.lang.descriptors.*; +import org.jetbrains.jet.lang.psi.JetPsiUtil; import org.jetbrains.jet.lang.resolve.BindingContext; import org.jetbrains.jet.lang.resolve.DescriptorUtils; import org.jetbrains.jet.lang.resolve.calls.model.ResolvedCall; @@ -48,6 +49,7 @@ import java.util.Set; import static org.jetbrains.asm4.Opcodes.*; import static org.jetbrains.jet.codegen.CodegenUtil.*; import static org.jetbrains.jet.lang.resolve.DescriptorUtils.isClassObject; +import static org.jetbrains.jet.lang.resolve.DescriptorUtils.isEnumEntry; import static org.jetbrains.jet.lang.resolve.java.AsmTypeConstants.JAVA_STRING_TYPE; public class AsmUtil { @@ -239,15 +241,13 @@ public class AsmUtil { return null; } // the following code is only for PRIVATE visibility of member - if (isClassObject(containingDeclaration)) { + if (isEnumEntry(memberDescriptor)) { return NO_FLAG_PACKAGE_PRIVATE; } if (memberDescriptor instanceof ConstructorDescriptor) { ClassKind kind = ((ClassDescriptor) containingDeclaration).getKind(); if (kind == ClassKind.OBJECT) { - //TODO: should be NO_FLAG_PACKAGE_PRIVATE - // see http://youtrack.jetbrains.com/issue/KT-2700 - return ACC_PUBLIC; + return NO_FLAG_PACKAGE_PRIVATE; } else if (kind == ClassKind.ENUM_ENTRY) { return NO_FLAG_PACKAGE_PRIVATE; diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/CallableMethod.java b/compiler/backend/src/org/jetbrains/jet/codegen/CallableMethod.java index e56d5ed6834..ca47be38717 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/CallableMethod.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/CallableMethod.java @@ -105,10 +105,14 @@ public class CallableMethod implements Callable { @NotNull GenerationState state, @NotNull ResolvedCall resolvedCall ) { - invoke(v); + invokeWithoutAssertions(v); AsmUtil.genNotNullAssertionForMethod(v, state, resolvedCall); } + public void invokeWithoutAssertions(@NotNull InstructionAdapter v) { + invoke(v); + } + @Nullable public Type getGenerateCalleeType() { return generateCalleeType; diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/ClassBodyCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/ClassBodyCodegen.java index bfbf4597349..8ef88ae3fdf 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/ClassBodyCodegen.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/ClassBodyCodegen.java @@ -19,7 +19,6 @@ package org.jetbrains.jet.codegen; import org.jetbrains.annotations.NotNull; import org.jetbrains.asm4.MethodVisitor; import org.jetbrains.asm4.Type; -import org.jetbrains.asm4.commons.InstructionAdapter; import org.jetbrains.jet.codegen.context.CodegenContext; import org.jetbrains.jet.codegen.state.GenerationState; import org.jetbrains.jet.lang.descriptors.ClassDescriptor; @@ -76,12 +75,25 @@ public abstract class ClassBodyCodegen extends MemberCodegen { PropertyCodegen propertyCodegen = new PropertyCodegen(context, v, functionCodegen); for (JetDeclaration declaration : myClass.getDeclarations()) { - generateDeclaration(propertyCodegen, declaration, functionCodegen); + //generate nested classes first and only then generate class body. It necessary to access to nested CodegenContexts + if (shouldProcessFirst(declaration)) { + generateDeclaration(propertyCodegen, declaration, functionCodegen); + } + } + + for (JetDeclaration declaration : myClass.getDeclarations()) { + if (!shouldProcessFirst(declaration)) { + generateDeclaration(propertyCodegen, declaration, functionCodegen); + } } generatePrimaryConstructorProperties(propertyCodegen, myClass); } + private boolean shouldProcessFirst(JetDeclaration declaration) { + return false == (declaration instanceof JetProperty || declaration instanceof JetNamedFunction); + } + protected void generateDeclaration(PropertyCodegen propertyCodegen, JetDeclaration declaration, FunctionCodegen functionCodegen) { if (declaration instanceof JetProperty || declaration instanceof JetNamedFunction) { genFunctionOrProperty(context, (JetTypeParameterListOwner) declaration, v); @@ -126,18 +138,18 @@ public abstract class ClassBodyCodegen extends MemberCodegen { private void generateStaticInitializer() { if (staticInitializerChunks.size() > 0) { - MethodVisitor mv = v.newMethod(null, ACC_PUBLIC | ACC_STATIC, "", "()V", null, null); + MethodVisitor mv = v.newMethod(null, ACC_STATIC, "", "()V", null, null); if (state.getClassBuilderMode() == ClassBuilderMode.FULL) { mv.visitCode(); - InstructionAdapter v = new InstructionAdapter(mv); + ExpressionCodegen codegen = new ExpressionCodegen(mv, new FrameMap(), Type.VOID_TYPE, context, state); for (CodeChunk chunk : staticInitializerChunks) { - chunk.generate(v); + chunk.generate(codegen); } mv.visitInsn(RETURN); - FunctionCodegen.endVisit(v, "static initializer", myClass); + FunctionCodegen.endVisit(codegen.v, "static initializer", myClass); } } } diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/CodeChunk.java b/compiler/backend/src/org/jetbrains/jet/codegen/CodeChunk.java index 9aa1cb2ca30..293a3fdbfe6 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/CodeChunk.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/CodeChunk.java @@ -16,8 +16,6 @@ package org.jetbrains.jet.codegen; -import org.jetbrains.asm4.commons.InstructionAdapter; - public interface CodeChunk { - void generate(InstructionAdapter v); + void generate(ExpressionCodegen codegen); } diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java index 46b869544f4..295167f4a53 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java @@ -1562,7 +1562,7 @@ public class ExpressionCodegen extends JetVisitor implem expression.getReferencedNameElementType() == JetTokens.FIELD_IDENTIFIER && contextKind() != OwnerKind.TRAIT_IMPL; JetExpression r = getReceiverForSelector(expression); boolean isSuper = r instanceof JetSuperExpression; - propertyDescriptor = accessablePropertyDescriptor(context, propertyDescriptor); + propertyDescriptor = accessablePropertyDescriptor(propertyDescriptor); StackValue.Property iValue = intermediateValueForProperty(propertyDescriptor, directToField, isSuper ? (JetSuperExpression) r : null); if (directToField) { @@ -1677,16 +1677,14 @@ public class ExpressionCodegen extends JetVisitor implem boolean forceField, @Nullable JetSuperExpression superExpression ) { - return intermediateValueForProperty(propertyDescriptor, forceField, superExpression, state, context, false); + return intermediateValueForProperty(propertyDescriptor, forceField, superExpression, false); } @NotNull - public static StackValue.Property intermediateValueForProperty( + public StackValue.Property intermediateValueForProperty( PropertyDescriptor propertyDescriptor, boolean forceField, @Nullable JetSuperExpression superExpression, - @NotNull GenerationState state, - @NotNull CodegenContext context, @NotNull boolean forceSpecialFlag ) { JetTypeMapper typeMapper = state.getTypeMapper(); @@ -1720,7 +1718,7 @@ public class ExpressionCodegen extends JetVisitor implem } } - propertyDescriptor = accessablePropertyDescriptor(context, propertyDescriptor); + propertyDescriptor = accessablePropertyDescriptor(propertyDescriptor); if (propertyDescriptor.getGetter() != null) { callableGetter = typeMapper.mapToCallableMethod(propertyDescriptor.getGetter(), isSuper || forceSpecialFlag, isInsideClass, isInsideModule, OwnerKind.IMPLEMENTATION); @@ -1854,47 +1852,17 @@ public class ExpressionCodegen extends JetVisitor implem } } - private static PropertyDescriptor accessablePropertyDescriptor(CodegenContext context, PropertyDescriptor propertyDescriptor) { - PropertySetterDescriptor setter = propertyDescriptor.getSetter(); - PropertyGetterDescriptor getter = propertyDescriptor.getGetter(); - - int flag = getVisibilityAccessFlag(propertyDescriptor) | - (getter == null ? 0 : getVisibilityAccessFlag(getter)) | - (setter == null ? 0 : getVisibilityAccessFlag(setter)); - - if ((flag & ACC_PRIVATE) == 0) { - return propertyDescriptor; - } - - return (PropertyDescriptor) accessibleDescriptor(context, propertyDescriptor); + @NotNull + private PropertyDescriptor accessablePropertyDescriptor(PropertyDescriptor propertyDescriptor) { + return context.accessablePropertyDescriptor(propertyDescriptor); } - private FunctionDescriptor accessableFunctionDescriptor(FunctionDescriptor fd) { - int flag = getVisibilityAccessFlag(fd); - if ((flag & ACC_PRIVATE) == 0) { - return fd; - } - - return (FunctionDescriptor) accessibleDescriptor(context, fd); - } - - private static MemberDescriptor accessibleDescriptor(CodegenContext context, DeclarationDescriptor descriptor) { - if (context.getClassOrNamespaceDescriptor() != descriptor.getContainingDeclaration()) { - DeclarationDescriptor enclosed = descriptor.getContainingDeclaration(); - if (context.hasThisDescriptor() && enclosed != context.getThisDescriptor()) { - CodegenContext c = context; - while (c.getContextDescriptor() != enclosed) { - c = c.getParentContext(); - if (c == null) { - return (MemberDescriptor) descriptor; - } - } - return (MemberDescriptor) c.getAccessor(descriptor); - } - } - return (MemberDescriptor) descriptor; + @NotNull + protected FunctionDescriptor accessableFunctionDescriptor(FunctionDescriptor fd) { + return context.accessableFunctionDescriptor(fd); } + @NotNull public StackValue invokeFunction( Call call, StackValue receiver, @@ -1943,7 +1911,7 @@ public class ExpressionCodegen extends JetVisitor implem } @Nullable - private static JetSuperExpression getSuperCallExpression(Call call) { + private static JetSuperExpression getSuperCallExpression(@NotNull Call call) { ReceiverValue explicitReceiver = call.getExplicitReceiver(); if (explicitReceiver instanceof ExpressionReceiver) { JetExpression receiverExpression = ((ExpressionReceiver) explicitReceiver).getExpression(); @@ -1954,7 +1922,7 @@ public class ExpressionCodegen extends JetVisitor implem return null; } - private static boolean isSuperCall(Call call) { + private static boolean isSuperCall(@NotNull Call call) { return getSuperCallExpression(call) != null; } @@ -1972,6 +1940,7 @@ public class ExpressionCodegen extends JetVisitor implem } } + @NotNull private StackValue returnValueAsStackValue(FunctionDescriptor fd, Type callReturnType) { if (callReturnType != Type.VOID_TYPE) { JetType type = fd.getReturnType(); diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/FunctionCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/FunctionCodegen.java index ccbff63900f..697c37b290f 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/FunctionCodegen.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/FunctionCodegen.java @@ -37,6 +37,7 @@ import org.jetbrains.jet.codegen.signature.kotlin.JetMethodAnnotationWriter; import org.jetbrains.jet.codegen.signature.kotlin.JetValueParameterAnnotationWriter; import org.jetbrains.jet.codegen.state.GenerationState; import org.jetbrains.jet.codegen.state.GenerationStateAware; +import org.jetbrains.jet.codegen.state.JetTypeMapper; import org.jetbrains.jet.codegen.state.JetTypeMapperMode; import org.jetbrains.jet.lang.descriptors.*; import org.jetbrains.jet.lang.psi.JetNamedFunction; @@ -132,6 +133,8 @@ public class FunctionCodegen extends GenerationStateAware { endVisit(mv, null, origin); generateBridgeIfNeeded(owner, state, v, jvmSignature.getAsmMethod(), functionDescriptor); + + methodContext.recordSyntheticAccessorIfNeeded(functionDescriptor, typeMapper); } @Nullable @@ -180,7 +183,9 @@ public class FunctionCodegen extends GenerationStateAware { labelsForSharedVars.putAll(createSharedVarsForParameters(mv, functionDescriptor, frameMap)); - genNotNullAssertionsForParameters(new InstructionAdapter(mv), state, functionDescriptor, frameMap); + if (!JetTypeMapper.isAccessor(functionDescriptor)) { + genNotNullAssertionsForParameters(new InstructionAdapter(mv), state, functionDescriptor, frameMap); + } strategy.generateBody(mv, signature, context); diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/ImplementationBodyCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/ImplementationBodyCodegen.java index 785d3a0913e..05668955841 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/ImplementationBodyCodegen.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/ImplementationBodyCodegen.java @@ -750,22 +750,25 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { MethodContext functionContext = context.intoFunction(function); FunctionCodegen.generateDefaultIfNeeded(functionContext, state, v, methodSignature, function, OwnerKind.IMPLEMENTATION, - new DefaultParameterValueLoader() { - @Override - public void putValueOnStack( - ValueParameterDescriptor descriptor, - ExpressionCodegen codegen - ) { - assert (KotlinBuiltIns.getInstance().isData((ClassDescriptor) function.getContainingDeclaration())) - : "Trying to create function with default arguments for function that isn't presented in code for class without data annotation"; - PropertyDescriptor propertyDescriptor = codegen.getBindingContext().get( - BindingContext.VALUE_PARAMETER_AS_PROPERTY, descriptor); - assert propertyDescriptor != null : "Trying to generate default value for parameter of copy function that doesn't correspond to any property"; - codegen.v.load(0, thisDescriptorType); - Type propertyType = codegen.typeMapper.mapType(propertyDescriptor.getType()); - codegen.intermediateValueForProperty(propertyDescriptor, false, null).put(propertyType, codegen.v); - } - }); + new DefaultParameterValueLoader() { + @Override + public void putValueOnStack( + ValueParameterDescriptor descriptor, + ExpressionCodegen codegen + ) { + assert (KotlinBuiltIns.getInstance() + .isData((ClassDescriptor) function.getContainingDeclaration())) + : "Trying to create function with default arguments for function that isn't presented in code for class without data annotation"; + PropertyDescriptor propertyDescriptor = codegen.getBindingContext().get( + BindingContext.VALUE_PARAMETER_AS_PROPERTY, descriptor); + assert propertyDescriptor != + null : "Trying to generate default value for parameter of copy function that doesn't correspond to any property"; + codegen.v.load(0, thisDescriptorType); + Type propertyType = codegen.typeMapper.mapType(propertyDescriptor.getType()); + codegen.intermediateValueForProperty(propertyDescriptor, false, null) + .put(propertyType, codegen.v); + } + }); } private void generateEnumMethods() { @@ -802,8 +805,9 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { } } - private void generateSyntheticAccessors() { - for (Map.Entry entry : context.getAccessors().entrySet()) { + protected void generateSyntheticAccessors() { + Map accessors = context.getAccessors(); + for (Map.Entry entry : accessors.entrySet()) { generateSyntheticAccessor(entry); } } @@ -811,51 +815,21 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { private void generateSyntheticAccessor(Map.Entry entry) { if (entry.getValue() instanceof FunctionDescriptor) { FunctionDescriptor bridge = (FunctionDescriptor) entry.getValue(); - FunctionDescriptor original = (FunctionDescriptor) entry.getKey(); + final FunctionDescriptor original = (FunctionDescriptor) entry.getKey(); + functionCodegen.generateMethod(null, typeMapper.mapSignature(bridge), false, bridge, + new FunctionGenerationStrategy.CodegenBased(state, bridge) { + @Override + public void doGenerateBody(ExpressionCodegen codegen, JvmMethodSignature signature) { + generateMethodCallTo(original, codegen.v); - Method method = typeMapper.mapSignature(bridge).getAsmMethod(); - boolean isConstructor = original instanceof ConstructorDescriptor; - Method originalMethod = isConstructor ? - typeMapper.mapConstructorSignature((ConstructorDescriptor) original).getAsmMethod() : - typeMapper.mapSignature(original).getAsmMethod(); - 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().asString(), - method.getDescriptor(), null, null); - if (state.getClassBuilderMode() == ClassBuilderMode.STUBS) { - genStubCode(mv); - } - else if (state.getClassBuilderMode() == ClassBuilderMode.FULL) { - mv.visitCode(); - - InstructionAdapter iv = new InstructionAdapter(mv); - - if (isConstructor) { - iv.anew(method.getReturnType()); - iv.dup(); - } - else { - // todo: note that for now we never have access bridges for namespace methods, if at some point we do... - iv.load(0, OBJECT_TYPE); - } - - for (int i = isConstructor ? 0 : 1, reg = isConstructor ? 0 : 1; i < argTypes.length; i++) { - Type argType = argTypes[i]; - iv.load(reg, argType); - //noinspection AssignmentToForLoopParameter - reg += argType.getSize(); - } - iv.invokespecial(owner, originalMethod.getName(), originalMethod.getDescriptor()); - - iv.areturn(method.getReturnType()); - FunctionCodegen.endVisit(iv, "accessor", null); - } + codegen.v.areturn(signature.getAsmMethod().getReturnType()); + } + }); } else if (entry.getValue() instanceof PropertyDescriptor) { PropertyDescriptor bridge = (PropertyDescriptor) entry.getValue(); final PropertyDescriptor original = (PropertyDescriptor) entry.getKey(); - final StackValue.Property property = ExpressionCodegen.intermediateValueForProperty(original, false, null, state, context, true); + PropertyGetterDescriptor getter = bridge.getGetter(); assert getter != null; @@ -863,6 +837,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { new FunctionGenerationStrategy.CodegenBased(state, getter) { @Override public void doGenerateBody(ExpressionCodegen codegen, JvmMethodSignature signature) { + StackValue.Property property = codegen.intermediateValueForProperty(original, false, null, true); InstructionAdapter iv = codegen.v; iv.load(0, OBJECT_TYPE); property.put(property.type, iv); @@ -879,6 +854,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { new FunctionGenerationStrategy.CodegenBased(state, setter) { @Override public void doGenerateBody(ExpressionCodegen codegen, JvmMethodSignature signature) { + StackValue.Property property = codegen.intermediateValueForProperty(original, false, null, true); InstructionAdapter iv = codegen.v; iv.load(0, OBJECT_TYPE); @@ -901,23 +877,58 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { } } + private void generateMethodCallTo(FunctionDescriptor functionDescriptor, InstructionAdapter iv) { + boolean isConstructor = functionDescriptor instanceof ConstructorDescriptor; + boolean callFromAccessor = !JetTypeMapper.isAccessor(functionDescriptor); + CallableMethod callableMethod = isConstructor ? + typeMapper.mapToCallableMethod((ConstructorDescriptor) functionDescriptor) : + typeMapper.mapToCallableMethod(functionDescriptor, callFromAccessor, + isCallInsideSameClassAsDeclared(functionDescriptor, context), + isCallInsideSameModuleAsDeclared(functionDescriptor, context), + context.getContextKind()); + + Method method = callableMethod.getSignature().getAsmMethod(); + Type[] argTypes = method.getArgumentTypes(); + + int reg = 1; + if (isConstructor) { + iv.anew(callableMethod.getOwner().getAsmType()); + iv.dup(); + reg = 0; + } + else if (callFromAccessor) { + iv.load(0, OBJECT_TYPE); + } + + for (int paramIndex = 0; paramIndex < argTypes.length; paramIndex++) { + Type argType = argTypes[paramIndex]; + iv.load(reg, argType); + //noinspection AssignmentToForLoopParameter + reg += argType.getSize(); + } + callableMethod.invokeWithoutAssertions(iv); + } + private void generateFieldForSingleton() { boolean hasClassObject = descriptor.getClassObjectDescriptor() != null; boolean isEnumClass = DescriptorUtils.isEnumClass(descriptor); if (!(isNonLiteralObject(myClass) || hasClassObject) || isEnumClass) return; - ClassDescriptor fieldTypeDescriptor = hasClassObject ? descriptor.getClassObjectDescriptor() : descriptor; + final ClassDescriptor fieldTypeDescriptor = hasClassObject ? descriptor.getClassObjectDescriptor() : descriptor; assert fieldTypeDescriptor != null; - final FieldInfo info = FieldInfo.createForSingleton(fieldTypeDescriptor, typeMapper); + final StackValue.Field field = StackValue.singleton(fieldTypeDescriptor, typeMapper); JetClassOrObject original = hasClassObject ? ((JetClass) myClass).getClassObject().getObjectDeclaration() : myClass; - v.newField(original, ACC_PUBLIC | ACC_STATIC | ACC_FINAL, info.getFieldName(), info.getFieldType().getDescriptor(), null, null); + v.newField(original, ACC_PUBLIC | ACC_STATIC | ACC_FINAL, field.name, field.type.getDescriptor(), null, null); staticInitializerChunks.add(new CodeChunk() { @Override - public void generate(InstructionAdapter iv) { - genInitSingletonField(info, iv); + public void generate(ExpressionCodegen codegen) { + ConstructorDescriptor constructorDescriptor = DescriptorUtils.getConstructorOfSingletonObject(fieldTypeDescriptor); + FunctionDescriptor fd = codegen.accessableFunctionDescriptor(constructorDescriptor); + generateMethodCallTo(fd, codegen.v); + field.store(field.type, codegen.v); } }); } @@ -963,6 +974,10 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { CallableMethod callableMethod = typeMapper.mapToCallableMethod(constructorDescriptor, closure); FunctionCodegen.generateConstructorWithoutParametersIfNeeded(state, callableMethod, constructorDescriptor, v); + + if (isClassObject(descriptor)) { + context.recordSyntheticAccessorIfNeeded(constructorDescriptor, typeMapper); + } } private void generatePrimaryConstructorImpl( @@ -1418,8 +1433,8 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { if (myEnumConstants.isEmpty()) { staticInitializerChunks.add(new CodeChunk() { @Override - public void generate(InstructionAdapter v) { - initializeEnumConstants(v); + public void generate(ExpressionCodegen codegen) { + initializeEnumConstants(codegen.v); } }); } diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/PropertyCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/PropertyCodegen.java index 34c71c9655b..493de79443b 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/PropertyCodegen.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/PropertyCodegen.java @@ -77,6 +77,8 @@ public class PropertyCodegen extends GenerationStateAware { } generateGetter(p, propertyDescriptor, p.getGetter()); generateSetter(p, propertyDescriptor, p.getSetter()); + + context.recordSyntheticAccessorIfNeeded(propertyDescriptor, typeMapper); } public void generatePrimaryConstructorProperty(JetParameter p, PropertyDescriptor descriptor) { diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/StackValue.java b/compiler/backend/src/org/jetbrains/jet/codegen/StackValue.java index b7f8d673b7d..55b37b180b6 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/StackValue.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/StackValue.java @@ -131,7 +131,7 @@ public abstract class StackValue { } @NotNull - public static StackValue field(@NotNull Type type, @NotNull JvmClassName owner, @NotNull String name, boolean isStatic) { + public static Field field(@NotNull Type type, @NotNull JvmClassName owner, @NotNull String name, boolean isStatic) { return new Field(type, owner, name, isStatic); } @@ -338,7 +338,7 @@ public abstract class StackValue { return receiverWithParameter; } - public static StackValue singleton(ClassDescriptor classDescriptor, JetTypeMapper typeMapper) { + public static Field singleton(ClassDescriptor classDescriptor, JetTypeMapper typeMapper) { FieldInfo info = FieldInfo.createForSingleton(classDescriptor, typeMapper); return field(info.getFieldType(), JvmClassName.byInternalName(info.getOwnerInternalName()), info.getFieldName(), true); } diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/context/ClassContext.java b/compiler/backend/src/org/jetbrains/jet/codegen/context/ClassContext.java index 2dac8bb2e83..6b99c7baaf5 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/context/ClassContext.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/context/ClassContext.java @@ -24,7 +24,8 @@ import org.jetbrains.jet.lang.descriptors.ClassDescriptor; import static org.jetbrains.jet.codegen.binding.CodegenBinding.CLOSURE; -public class ClassContext extends CodegenContext { +public class ClassContext extends CodegenContext { + public ClassContext( @NotNull JetTypeMapper typeMapper, @NotNull ClassDescriptor contextDescriptor, @@ -38,6 +39,15 @@ public class ClassContext extends CodegenContext { initOuterExpression(typeMapper, contextDescriptor); } + + @Nullable + public CodegenContext getClassObjectContext() { + if (getContextDescriptor().getClassObjectDescriptor() != null) { + return findChildContext(getContextDescriptor().getClassObjectDescriptor()); + } + return null; + } + @Override public boolean isStatic() { return false; diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/context/CodegenContext.java b/compiler/backend/src/org/jetbrains/jet/codegen/context/CodegenContext.java index f78261f5c6c..14a55244cbc 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/context/CodegenContext.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/context/CodegenContext.java @@ -27,21 +27,25 @@ import org.jetbrains.jet.codegen.state.JetTypeMapper; import org.jetbrains.jet.lang.descriptors.*; import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor; import org.jetbrains.jet.lang.descriptors.impl.ConstructorDescriptorImpl; +import org.jetbrains.jet.lang.resolve.BindingContext; +import org.jetbrains.jet.lang.resolve.DescriptorUtils; import java.util.Collections; import java.util.HashMap; import java.util.Map; +import static org.jetbrains.asm4.Opcodes.ACC_PRIVATE; import static org.jetbrains.jet.codegen.AsmUtil.CAPTURED_THIS_FIELD; +import static org.jetbrains.jet.codegen.AsmUtil.getVisibilityAccessFlag; import static org.jetbrains.jet.codegen.binding.CodegenBinding.*; import static org.jetbrains.jet.lang.resolve.java.AsmTypeConstants.OBJECT_TYPE; -public abstract class CodegenContext { +public abstract class CodegenContext { public static final CodegenContext STATIC = new RootContext(); @NotNull - private final DeclarationDescriptor contextDescriptor; + private final T contextDescriptor; @NotNull private final OwnerKind contextKind; @@ -52,13 +56,16 @@ public abstract class CodegenContext { public final MutableClosure closure; - HashMap accessors; + private HashMap accessors; + + private Map childContexts; protected StackValue outerExpression; + private final LocalLookup enclosingLocalLookup; public CodegenContext( - @NotNull DeclarationDescriptor contextDescriptor, + @NotNull T contextDescriptor, @NotNull OwnerKind contextKind, @Nullable CodegenContext parentContext, @Nullable MutableClosure closure, @@ -71,6 +78,10 @@ public abstract class CodegenContext { this.closure = closure; this.thisDescriptor = thisDescriptor; this.enclosingLocalLookup = expressionCodegen; + + if (parentContext != null) { + parentContext.addChild(this); + } } @NotNull @@ -126,7 +137,7 @@ public abstract class CodegenContext { } @NotNull - public DeclarationDescriptor getContextDescriptor() { + public T getContextDescriptor() { return contextDescriptor; } @@ -143,7 +154,7 @@ public abstract class CodegenContext { return new NamespaceContext(descriptor, this, new OwnerKind.StaticDelegateKind(delegateTo)); } - public CodegenContext intoClass(ClassDescriptor descriptor, OwnerKind kind, GenerationState state) { + public ClassContext intoClass(ClassDescriptor descriptor, OwnerKind kind, GenerationState state) { return new ClassContext(state.getTypeMapper(), descriptor, kind, this, null); } @@ -297,4 +308,110 @@ public abstract class CodegenContext { public Map getAccessors() { return accessors == null ? Collections.emptyMap() : accessors; } + + @NotNull + public PropertyDescriptor accessablePropertyDescriptor(PropertyDescriptor propertyDescriptor) { + return (PropertyDescriptor) accessibleDescriptorIfNeeded(propertyDescriptor, true); + } + + @NotNull + public FunctionDescriptor accessableFunctionDescriptor(FunctionDescriptor fd) { + return (FunctionDescriptor) accessibleDescriptorIfNeeded(fd, true); + } + + @NotNull + public void recordSyntheticAccessorIfNeeded(@NotNull FunctionDescriptor fd, @NotNull JetTypeMapper typeMapper) { + if (fd instanceof ConstructorDescriptor || needSyntheticAccessorInBindingTrace(fd, typeMapper)) { + accessibleDescriptorIfNeeded(fd, false); + } + } + + @NotNull + public void recordSyntheticAccessorIfNeeded(PropertyDescriptor propertyDescriptor, JetTypeMapper typeMapper) { + if (needSyntheticAccessorInBindingTrace(propertyDescriptor, typeMapper)) { + accessibleDescriptorIfNeeded(propertyDescriptor, false); + } + } + + private boolean needSyntheticAccessorInBindingTrace(@NotNull CallableMemberDescriptor descriptor, @NotNull JetTypeMapper typeMapper) { + Boolean result = typeMapper.getBindingContext().get(BindingContext.NEED_SYNTHETIC_ACCESSOR, descriptor); + return result == null ? false : result.booleanValue(); + } + + @NotNull + private int getAccessFlags(CallableMemberDescriptor descriptor) { + int flag = getVisibilityAccessFlag(descriptor); + if (descriptor instanceof PropertyDescriptor) { + PropertyDescriptor propertyDescriptor = (PropertyDescriptor) descriptor; + + PropertySetterDescriptor setter = propertyDescriptor.getSetter(); + PropertyGetterDescriptor getter = propertyDescriptor.getGetter(); + + flag |= (getter == null ? 0 : getVisibilityAccessFlag(getter)) | + (setter == null ? 0 : getVisibilityAccessFlag(setter)); + } + return flag; + } + + @NotNull + private MemberDescriptor accessibleDescriptorIfNeeded(CallableMemberDescriptor descriptor, boolean fromOutsideContext) { + int flag = getAccessFlags(descriptor); + if ((flag & ACC_PRIVATE) == 0) { + return descriptor; + } + + CodegenContext descriptorContext = null; + if (!fromOutsideContext || getClassOrNamespaceDescriptor() != descriptor.getContainingDeclaration()) { + DeclarationDescriptor enclosed = descriptor.getContainingDeclaration(); + boolean isClassObjectMember = DescriptorUtils.isClassObject(enclosed); + //go upper + if (hasThisDescriptor() && (enclosed != getThisDescriptor() || !fromOutsideContext)) { + CodegenContext currentContext = this; + while (currentContext != null) { + if (currentContext.getContextDescriptor() == enclosed) { + descriptorContext = currentContext; + break; + } + + //accessors for private members in class object for call from class + if (isClassObjectMember && currentContext instanceof ClassContext) { + ClassContext classContext = (ClassContext) currentContext; + CodegenContext classObject = classContext.getClassObjectContext(); + if (classObject != null && classObject.getContextDescriptor() == enclosed) { + descriptorContext = classObject; + break; + } + } + + currentContext = currentContext.getParentContext(); + } + } + } + + return (MemberDescriptor) (descriptorContext != null ? descriptorContext.getAccessor(descriptor) : descriptor); + } + + private void addChild(@NotNull CodegenContext child) { + if (shouldAddChild(child)) { + if (childContexts == null) { + childContexts = new HashMap(); + } + DeclarationDescriptor childContextDescriptor = child.getContextDescriptor(); + childContexts.put(childContextDescriptor, child); + } + } + + protected boolean shouldAddChild(@NotNull CodegenContext child) { + DeclarationDescriptor childContextDescriptor = child.contextDescriptor; + if (childContextDescriptor instanceof ClassDescriptor) { + ClassKind kind = ((ClassDescriptor) childContextDescriptor).getKind(); + return kind == ClassKind.CLASS_OBJECT; + } + return false; + } + + @Nullable + public CodegenContext findChildContext(@NotNull DeclarationDescriptor child) { + return childContexts == null ? null : childContexts.get(child); + } } 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 f39ccfdc0bc..7bd46ce35e7 100644 --- a/compiler/frontend.java/src/org/jetbrains/jet/di/InjectorForTopDownAnalyzerForJvm.java +++ b/compiler/frontend.java/src/org/jetbrains/jet/di/InjectorForTopDownAnalyzerForJvm.java @@ -22,6 +22,7 @@ import org.jetbrains.jet.lang.resolve.BodyResolver; import org.jetbrains.jet.lang.resolve.ControlFlowAnalyzer; import org.jetbrains.jet.lang.resolve.DeclarationsChecker; import org.jetbrains.jet.lang.resolve.DescriptorResolver; +import org.jetbrains.jet.lang.resolve.calls.NeedSyntheticCallResolverExtension; import com.intellij.openapi.project.Project; import org.jetbrains.jet.lang.resolve.TopDownAnalysisParameters; import org.jetbrains.jet.lang.resolve.BindingTrace; @@ -73,6 +74,7 @@ public class InjectorForTopDownAnalyzerForJvm implements InjectorForTopDownAnaly private ControlFlowAnalyzer controlFlowAnalyzer; private DeclarationsChecker declarationsChecker; private DescriptorResolver descriptorResolver; + private NeedSyntheticCallResolverExtension needSyntheticCallResolverExtension; private final Project project; private final TopDownAnalysisParameters topDownAnalysisParameters; private final BindingTrace bindingTrace; @@ -125,6 +127,7 @@ public class InjectorForTopDownAnalyzerForJvm implements InjectorForTopDownAnaly this.controlFlowAnalyzer = new ControlFlowAnalyzer(); this.declarationsChecker = new DeclarationsChecker(); this.descriptorResolver = new DescriptorResolver(); + this.needSyntheticCallResolverExtension = new NeedSyntheticCallResolverExtension(); this.project = project; this.topDownAnalysisParameters = topDownAnalysisParameters; this.bindingTrace = bindingTrace; @@ -224,6 +227,7 @@ public class InjectorForTopDownAnalyzerForJvm implements InjectorForTopDownAnaly callResolver.setArgumentTypeResolver(argumentTypeResolver); callResolver.setCandidateResolver(candidateResolver); callResolver.setExpressionTypingServices(expressionTypingServices); + callResolver.setExtension(needSyntheticCallResolverExtension); callResolver.setTypeResolver(typeResolver); argumentTypeResolver.setExpressionTypingServices(expressionTypingServices); diff --git a/compiler/frontend/src/org/jetbrains/jet/di/InjectorForBodyResolve.java b/compiler/frontend/src/org/jetbrains/jet/di/InjectorForBodyResolve.java index 2e403ff5caa..9926b81519a 100644 --- a/compiler/frontend/src/org/jetbrains/jet/di/InjectorForBodyResolve.java +++ b/compiler/frontend/src/org/jetbrains/jet/di/InjectorForBodyResolve.java @@ -17,6 +17,7 @@ package org.jetbrains.jet.di; import org.jetbrains.jet.lang.resolve.BodyResolver; +import org.jetbrains.jet.lang.resolve.calls.NeedSyntheticCallResolverExtension; import com.intellij.openapi.project.Project; import org.jetbrains.jet.lang.resolve.TopDownAnalysisParameters; import org.jetbrains.jet.lang.resolve.BindingTrace; @@ -42,6 +43,7 @@ import javax.annotation.PreDestroy; public class InjectorForBodyResolve { private BodyResolver bodyResolver; + private NeedSyntheticCallResolverExtension needSyntheticCallResolverExtension; private final Project project; private final TopDownAnalysisParameters topDownAnalysisParameters; private final BindingTrace bindingTrace; @@ -69,6 +71,7 @@ public class InjectorForBodyResolve { @NotNull ModuleDescriptor moduleDescriptor ) { this.bodyResolver = new BodyResolver(); + this.needSyntheticCallResolverExtension = new NeedSyntheticCallResolverExtension(); this.project = project; this.topDownAnalysisParameters = topDownAnalysisParameters; this.bindingTrace = bindingTrace; @@ -101,6 +104,7 @@ public class InjectorForBodyResolve { callResolver.setArgumentTypeResolver(argumentTypeResolver); callResolver.setCandidateResolver(candidateResolver); callResolver.setExpressionTypingServices(expressionTypingServices); + callResolver.setExtension(needSyntheticCallResolverExtension); callResolver.setTypeResolver(typeResolver); argumentTypeResolver.setExpressionTypingServices(expressionTypingServices); diff --git a/compiler/frontend/src/org/jetbrains/jet/di/InjectorForLazyResolve.java b/compiler/frontend/src/org/jetbrains/jet/di/InjectorForLazyResolve.java index 75abc36457b..845263ea0ca 100644 --- a/compiler/frontend/src/org/jetbrains/jet/di/InjectorForLazyResolve.java +++ b/compiler/frontend/src/org/jetbrains/jet/di/InjectorForLazyResolve.java @@ -26,6 +26,7 @@ import org.jetbrains.jet.lang.resolve.lazy.ScopeProvider; import org.jetbrains.jet.lang.resolve.AnnotationResolver; import org.jetbrains.jet.lang.resolve.QualifiedExpressionResolver; import org.jetbrains.jet.lang.psi.JetImportsFactory; +import org.jetbrains.jet.lang.resolve.calls.NeedSyntheticCallResolverExtension; import org.jetbrains.jet.lang.resolve.calls.CallExpressionResolver; import org.jetbrains.jet.lang.resolve.calls.CallResolver; import org.jetbrains.jet.lang.resolve.calls.ArgumentTypeResolver; @@ -46,6 +47,7 @@ public class InjectorForLazyResolve { private AnnotationResolver annotationResolver; private QualifiedExpressionResolver qualifiedExpressionResolver; private JetImportsFactory jetImportsFactory; + private NeedSyntheticCallResolverExtension needSyntheticCallResolverExtension; private CallExpressionResolver callExpressionResolver; private CallResolver callResolver; private ArgumentTypeResolver argumentTypeResolver; @@ -66,6 +68,7 @@ public class InjectorForLazyResolve { this.annotationResolver = new AnnotationResolver(); this.qualifiedExpressionResolver = new QualifiedExpressionResolver(); this.jetImportsFactory = new JetImportsFactory(); + this.needSyntheticCallResolverExtension = new NeedSyntheticCallResolverExtension(); this.callExpressionResolver = new CallExpressionResolver(); this.callResolver = new CallResolver(); this.argumentTypeResolver = new ArgumentTypeResolver(); @@ -96,6 +99,7 @@ public class InjectorForLazyResolve { callResolver.setArgumentTypeResolver(argumentTypeResolver); callResolver.setCandidateResolver(candidateResolver); callResolver.setExpressionTypingServices(expressionTypingServices); + callResolver.setExtension(needSyntheticCallResolverExtension); callResolver.setTypeResolver(typeResolver); argumentTypeResolver.setExpressionTypingServices(expressionTypingServices); diff --git a/compiler/frontend/src/org/jetbrains/jet/di/InjectorForMacros.java b/compiler/frontend/src/org/jetbrains/jet/di/InjectorForMacros.java index 72b331eb103..b4625f5ba1f 100644 --- a/compiler/frontend/src/org/jetbrains/jet/di/InjectorForMacros.java +++ b/compiler/frontend/src/org/jetbrains/jet/di/InjectorForMacros.java @@ -17,6 +17,7 @@ package org.jetbrains.jet.di; import org.jetbrains.jet.lang.types.expressions.ExpressionTypingServices; +import org.jetbrains.jet.lang.resolve.calls.NeedSyntheticCallResolverExtension; import com.intellij.openapi.project.Project; import org.jetbrains.jet.lang.descriptors.ModuleDescriptor; import org.jetbrains.jet.lang.resolve.calls.CallExpressionResolver; @@ -34,6 +35,7 @@ import javax.annotation.PreDestroy; public class InjectorForMacros { private ExpressionTypingServices expressionTypingServices; + private NeedSyntheticCallResolverExtension needSyntheticCallResolverExtension; private final Project project; private final ModuleDescriptor moduleDescriptor; private CallExpressionResolver callExpressionResolver; @@ -50,6 +52,7 @@ public class InjectorForMacros { @NotNull ModuleDescriptor moduleDescriptor ) { this.expressionTypingServices = new ExpressionTypingServices(); + this.needSyntheticCallResolverExtension = new NeedSyntheticCallResolverExtension(); this.project = project; this.moduleDescriptor = moduleDescriptor; this.callExpressionResolver = new CallExpressionResolver(); @@ -72,6 +75,7 @@ public class InjectorForMacros { callResolver.setArgumentTypeResolver(argumentTypeResolver); callResolver.setCandidateResolver(candidateResolver); callResolver.setExpressionTypingServices(expressionTypingServices); + callResolver.setExtension(needSyntheticCallResolverExtension); callResolver.setTypeResolver(typeResolver); argumentTypeResolver.setExpressionTypingServices(expressionTypingServices); diff --git a/compiler/frontend/src/org/jetbrains/jet/di/InjectorForTopDownAnalyzerBasic.java b/compiler/frontend/src/org/jetbrains/jet/di/InjectorForTopDownAnalyzerBasic.java index c79fe48893c..966d52b828c 100644 --- a/compiler/frontend/src/org/jetbrains/jet/di/InjectorForTopDownAnalyzerBasic.java +++ b/compiler/frontend/src/org/jetbrains/jet/di/InjectorForTopDownAnalyzerBasic.java @@ -22,6 +22,7 @@ import org.jetbrains.jet.lang.resolve.BodyResolver; import org.jetbrains.jet.lang.resolve.ControlFlowAnalyzer; import org.jetbrains.jet.lang.resolve.DeclarationsChecker; import org.jetbrains.jet.lang.resolve.DescriptorResolver; +import org.jetbrains.jet.lang.resolve.calls.NeedSyntheticCallResolverExtension; import com.intellij.openapi.project.Project; import org.jetbrains.jet.lang.resolve.TopDownAnalysisParameters; import org.jetbrains.jet.lang.resolve.BindingTrace; @@ -56,6 +57,7 @@ public class InjectorForTopDownAnalyzerBasic { private ControlFlowAnalyzer controlFlowAnalyzer; private DeclarationsChecker declarationsChecker; private DescriptorResolver descriptorResolver; + private NeedSyntheticCallResolverExtension needSyntheticCallResolverExtension; private final Project project; private final TopDownAnalysisParameters topDownAnalysisParameters; private final BindingTrace bindingTrace; @@ -91,6 +93,7 @@ public class InjectorForTopDownAnalyzerBasic { this.controlFlowAnalyzer = new ControlFlowAnalyzer(); this.declarationsChecker = new DeclarationsChecker(); this.descriptorResolver = new DescriptorResolver(); + this.needSyntheticCallResolverExtension = new NeedSyntheticCallResolverExtension(); this.project = project; this.topDownAnalysisParameters = topDownAnalysisParameters; this.bindingTrace = bindingTrace; @@ -162,6 +165,7 @@ public class InjectorForTopDownAnalyzerBasic { callResolver.setArgumentTypeResolver(argumentTypeResolver); callResolver.setCandidateResolver(candidateResolver); callResolver.setExpressionTypingServices(expressionTypingServices); + callResolver.setExtension(needSyntheticCallResolverExtension); callResolver.setTypeResolver(typeResolver); argumentTypeResolver.setExpressionTypingServices(expressionTypingServices); 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 6b4980374a0..b84fa9060f8 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/BindingContext.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/BindingContext.java @@ -133,6 +133,8 @@ public interface BindingContext { WritableSlice CAPTURED_IN_CLOSURE = new BasicWritableSlice(DO_NOTHING); + WritableSlice NEED_SYNTHETIC_ACCESSOR = new BasicWritableSlice(DO_NOTHING); + // enum DeferredTypeKey {DEFERRED_TYPE_KEY} // WritableSlice> DEFERRED_TYPES = Slices.createSimpleSlice(); 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 5a48b391d44..84dd2283356 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/DescriptorUtils.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/DescriptorUtils.java @@ -420,10 +420,24 @@ public class DescriptorUtils { return (ClassDescriptor) classifier; } + @NotNull public static ConstructorDescriptor getConstructorOfDataClass(ClassDescriptor classDescriptor) { + ConstructorDescriptor descriptor = getConstructorDescriptorIfOnlyOne(classDescriptor); + assert descriptor != null : "Data class must have only one constructor: " + classDescriptor.getConstructors(); + return descriptor; + } + + @NotNull + public static ConstructorDescriptor getConstructorOfSingletonObject(ClassDescriptor classDescriptor) { + ConstructorDescriptor descriptor = getConstructorDescriptorIfOnlyOne(classDescriptor); + assert descriptor != null : "Class of singleton object must have only one constructor: " + classDescriptor.getConstructors(); + return descriptor; + } + + @Nullable + private static ConstructorDescriptor getConstructorDescriptorIfOnlyOne(ClassDescriptor classDescriptor) { Collection constructors = classDescriptor.getConstructors(); - assert constructors.size() == 1 : "Data class must have only one constructor: " + constructors; - return constructors.iterator().next(); + return constructors.size() != 1 ? null : constructors.iterator().next(); } @Nullable 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 5a1b5923a77..f5bb8302e8f 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 @@ -21,6 +21,7 @@ import com.google.common.collect.Lists; import com.intellij.openapi.progress.ProgressIndicatorProvider; import com.intellij.psi.PsiElement; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import org.jetbrains.jet.lang.descriptors.*; import org.jetbrains.jet.lang.descriptors.impl.FunctionDescriptorImpl; import org.jetbrains.jet.lang.descriptors.impl.FunctionDescriptorUtil; @@ -70,6 +71,8 @@ public class CallResolver { private CandidateResolver candidateResolver; @NotNull private ArgumentTypeResolver argumentTypeResolver; + @Nullable + private CallResolverExtension extension; @Inject public void setExpressionTypingServices(@NotNull ExpressionTypingServices expressionTypingServices) { @@ -91,6 +94,11 @@ public class CallResolver { this.argumentTypeResolver = argumentTypeResolver; } + @Inject + public void setExtension(@NotNull CallResolverExtension extension) { + this.extension = extension; + } + @NotNull public OverloadResolutionResults resolveSimpleProperty(@NotNull BasicCallResolutionContext context) { JetExpression calleeExpression = context.call.getCalleeExpression(); @@ -142,7 +150,7 @@ public class CallResolver { ProgressIndicatorProvider.checkCanceled(); List> prioritizedTasks; - + JetExpression calleeExpression = context.call.getCalleeExpression(); JetReferenceExpression functionReference; if (calleeExpression instanceof JetSimpleNameExpression) { @@ -239,7 +247,7 @@ public class CallResolver { } return checkArgumentTypesAndFail(context); } - + FunctionDescriptorImpl functionDescriptor = new ExpressionAsFunctionDescriptor(context.scope.getContainingDeclaration(), Name.special("")); FunctionDescriptorUtil.initializeFromFunctionType(functionDescriptor, calleeType, NO_RECEIVER_PARAMETER, Modality.FINAL, Visibilities.LOCAL); @@ -296,12 +304,17 @@ public class CallResolver { } traceToResolveCall.commit(); - if (prioritizedTasks.isEmpty()) { - return results; + if (prioritizedTasks.isEmpty() || context.resolveMode == ResolveMode.NESTED_CALL) { + //do nothing + } else { + results = completeTypeInferenceDependentOnExpectedType(context, results, tracing); } - if (context.resolveMode == ResolveMode.NESTED_CALL) return results; - return completeTypeInferenceDependentOnExpectedType(context, results, tracing); + if (extension != null) { + extension.run(results, context); + } + + return results; } private void completeTypeInferenceDependentOnFunctionLiterals( diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/CallResolverExtension.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/CallResolverExtension.java new file mode 100644 index 00000000000..d6ddb7ac4a6 --- /dev/null +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/CallResolverExtension.java @@ -0,0 +1,26 @@ +/* + * 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; + +import org.jetbrains.annotations.NotNull; +import org.jetbrains.jet.lang.descriptors.CallableDescriptor; +import org.jetbrains.jet.lang.resolve.calls.context.BasicCallResolutionContext; +import org.jetbrains.jet.lang.resolve.calls.results.OverloadResolutionResultsImpl; + +public interface CallResolverExtension { + void run(@NotNull OverloadResolutionResultsImpl results, @NotNull BasicCallResolutionContext context); +} diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/NeedSyntheticCallResolverExtension.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/NeedSyntheticCallResolverExtension.java new file mode 100644 index 00000000000..bebcce131aa --- /dev/null +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/NeedSyntheticCallResolverExtension.java @@ -0,0 +1,54 @@ +/* + * 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; + +import org.jetbrains.annotations.NotNull; +import org.jetbrains.jet.lang.descriptors.CallableDescriptor; +import org.jetbrains.jet.lang.descriptors.CallableMemberDescriptor; +import org.jetbrains.jet.lang.descriptors.Visibilities; +import org.jetbrains.jet.lang.resolve.calls.context.BasicCallResolutionContext; +import org.jetbrains.jet.lang.resolve.calls.model.ResolvedCallWithTrace; +import org.jetbrains.jet.lang.resolve.calls.results.OverloadResolutionResultsImpl; +import org.jetbrains.jet.lang.resolve.scopes.JetScope; + +import static org.jetbrains.jet.lang.resolve.BindingContext.NEED_SYNTHETIC_ACCESSOR; + +public class NeedSyntheticCallResolverExtension implements CallResolverExtension { + + @Override + public void run( + @NotNull OverloadResolutionResultsImpl results, + @NotNull BasicCallResolutionContext context + ) { + if (results.isSingleResult()) { + ResolvedCallWithTrace resolvedCall = results.getResultingCall(); + CallableDescriptor targetDescriptor = resolvedCall.getResultingDescriptor(); + if (needSyntheticAccessor(context.scope, targetDescriptor)) { + context.trace.record(NEED_SYNTHETIC_ACCESSOR, (CallableMemberDescriptor) targetDescriptor, Boolean.TRUE); + } + } + } + + //Necessary synthetic accessors in outer classes generated via old logic: CodegenContext.getAccessor + //Generation of accessors in nested classes (to invoke from outer, + // e.g.: from class to classobject) controlled via NEED_SYNTHETIC_ACCESSOR slice + private boolean needSyntheticAccessor(JetScope invokationScope, CallableDescriptor targetDescriptor) { + return targetDescriptor instanceof CallableMemberDescriptor && + targetDescriptor.getVisibility() == Visibilities.PRIVATE && + targetDescriptor.getContainingDeclaration() != invokationScope.getContainingDeclaration().getContainingDeclaration(); + } +} diff --git a/compiler/testData/writeFlags/function/classObjectPrivate/privateFun.kt b/compiler/testData/writeFlags/function/classObjectPrivate/privateFun.kt new file mode 100644 index 00000000000..6d4b5eac24d --- /dev/null +++ b/compiler/testData/writeFlags/function/classObjectPrivate/privateFun.kt @@ -0,0 +1,14 @@ +class Foo { + + {Foo.test()} + + class object { + private fun test() { + + } + } +} + +// TESTED_OBJECT_KIND: function +// TESTED_OBJECTS: Foo$object, test +// FLAGS: ACC_PRIVATE, ACC_FINAL \ No newline at end of file diff --git a/compiler/testData/writeFlags/function/classObjectPrivate/privateVal.kt b/compiler/testData/writeFlags/function/classObjectPrivate/privateVal.kt new file mode 100644 index 00000000000..25438523a72 --- /dev/null +++ b/compiler/testData/writeFlags/function/classObjectPrivate/privateVal.kt @@ -0,0 +1,12 @@ +class Foo { + + {Foo.test} + + class object { + private val test = "String" + } +} + +// TESTED_OBJECT_KIND: function +// TESTED_OBJECTS: Foo$object, getTest +// FLAGS: ACC_PRIVATE, ACC_FINAL \ No newline at end of file diff --git a/compiler/testData/writeFlags/function/classObjectPrivate/privateVar.kt b/compiler/testData/writeFlags/function/classObjectPrivate/privateVar.kt new file mode 100644 index 00000000000..03cb784f676 --- /dev/null +++ b/compiler/testData/writeFlags/function/classObjectPrivate/privateVar.kt @@ -0,0 +1,12 @@ +class Foo { + + {Foo.test} + + class object { + private var test = "String" + } +} + +// TESTED_OBJECT_KIND: function +// TESTED_OBJECTS: Foo$object, setTest +// FLAGS: ACC_PRIVATE, ACC_FINAL \ No newline at end of file diff --git a/compiler/testData/writeFlags/function/constructors/classObject.kt b/compiler/testData/writeFlags/function/constructors/classObject.kt new file mode 100644 index 00000000000..d0c6e867203 --- /dev/null +++ b/compiler/testData/writeFlags/function/constructors/classObject.kt @@ -0,0 +1,8 @@ +class Foo { + class object { + } +} + +// TESTED_OBJECT_KIND: function +// TESTED_OBJECTS: Foo$object, +// FLAGS: ACC_PRIVATE diff --git a/compiler/testData/writeFlags/function/constructors/objectInClass.kt b/compiler/testData/writeFlags/function/constructors/objectInClass.kt new file mode 100644 index 00000000000..bf61f402f18 --- /dev/null +++ b/compiler/testData/writeFlags/function/constructors/objectInClass.kt @@ -0,0 +1,8 @@ +class Foo { + object Test { + } +} + +// TESTED_OBJECT_KIND: function +// TESTED_OBJECTS: Foo$Test, +// FLAGS: \ No newline at end of file diff --git a/compiler/testData/writeFlags/function/constructors/objectLiteral.kt b/compiler/testData/writeFlags/function/constructors/objectLiteral.kt new file mode 100644 index 00000000000..57ccd6b8d9d --- /dev/null +++ b/compiler/testData/writeFlags/function/constructors/objectLiteral.kt @@ -0,0 +1,9 @@ +class Foo { + fun a() { + val s = object { } + } +} + +// TESTED_OBJECT_KIND: function +// TESTED_OBJECTS: Foo$a$s$1, +// FLAGS: \ No newline at end of file diff --git a/compiler/testData/writeFlags/function/constructors/topLevelObject.kt b/compiler/testData/writeFlags/function/constructors/topLevelObject.kt new file mode 100644 index 00000000000..65bc75b1560 --- /dev/null +++ b/compiler/testData/writeFlags/function/constructors/topLevelObject.kt @@ -0,0 +1,7 @@ +object Foo { + +} + +// TESTED_OBJECT_KIND: function +// TESTED_OBJECTS: Foo, +// FLAGS: \ No newline at end of file diff --git a/compiler/tests/org/jetbrains/jet/codegen/flags/WriteFlagsTestGenerated.java b/compiler/tests/org/jetbrains/jet/codegen/flags/WriteFlagsTestGenerated.java index 0ef9a9a1feb..a71dae112dc 100644 --- a/compiler/tests/org/jetbrains/jet/codegen/flags/WriteFlagsTestGenerated.java +++ b/compiler/tests/org/jetbrains/jet/codegen/flags/WriteFlagsTestGenerated.java @@ -277,12 +277,63 @@ public class WriteFlagsTestGenerated extends AbstractWriteFlagsTest { } @TestMetadata("compiler/testData/writeFlags/function") - @InnerTestClasses({Function.DeprecatedFlag.class}) + @InnerTestClasses({Function.ClassObjectPrivate.class, Function.Constructors.class, Function.DeprecatedFlag.class}) public static class Function extends AbstractWriteFlagsTest { public void testAllFilesPresentInFunction() throws Exception { JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.GenerateTests", new File("compiler/testData/writeFlags/function"), Pattern.compile("^(.+)\\.kt$"), true); } + @TestMetadata("compiler/testData/writeFlags/function/classObjectPrivate") + public static class ClassObjectPrivate extends AbstractWriteFlagsTest { + public void testAllFilesPresentInClassObjectPrivate() throws Exception { + JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.GenerateTests", new File("compiler/testData/writeFlags/function/classObjectPrivate"), Pattern.compile("^(.+)\\.kt$"), true); + } + + @TestMetadata("privateFun.kt") + public void testPrivateFun() throws Exception { + doTest("compiler/testData/writeFlags/function/classObjectPrivate/privateFun.kt"); + } + + @TestMetadata("privateVal.kt") + public void testPrivateVal() throws Exception { + doTest("compiler/testData/writeFlags/function/classObjectPrivate/privateVal.kt"); + } + + @TestMetadata("privateVar.kt") + public void testPrivateVar() throws Exception { + doTest("compiler/testData/writeFlags/function/classObjectPrivate/privateVar.kt"); + } + + } + + @TestMetadata("compiler/testData/writeFlags/function/constructors") + public static class Constructors extends AbstractWriteFlagsTest { + public void testAllFilesPresentInConstructors() throws Exception { + JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.GenerateTests", new File("compiler/testData/writeFlags/function/constructors"), Pattern.compile("^(.+)\\.kt$"), true); + } + + @TestMetadata("classObject.kt") + public void testClassObject() throws Exception { + doTest("compiler/testData/writeFlags/function/constructors/classObject.kt"); + } + + @TestMetadata("objectInClass.kt") + public void testObjectInClass() throws Exception { + doTest("compiler/testData/writeFlags/function/constructors/objectInClass.kt"); + } + + @TestMetadata("objectLiteral.kt") + public void testObjectLiteral() throws Exception { + doTest("compiler/testData/writeFlags/function/constructors/objectLiteral.kt"); + } + + @TestMetadata("topLevelObject.kt") + public void testTopLevelObject() throws Exception { + doTest("compiler/testData/writeFlags/function/constructors/topLevelObject.kt"); + } + + } + @TestMetadata("compiler/testData/writeFlags/function/deprecatedFlag") public static class DeprecatedFlag extends AbstractWriteFlagsTest { public void testAllFilesPresentInDeprecatedFlag() throws Exception { @@ -354,6 +405,8 @@ public class WriteFlagsTestGenerated extends AbstractWriteFlagsTest { public static Test innerSuite() { TestSuite suite = new TestSuite("Function"); suite.addTestSuite(Function.class); + suite.addTestSuite(ClassObjectPrivate.class); + suite.addTestSuite(Constructors.class); suite.addTestSuite(DeprecatedFlag.class); return suite; } diff --git a/compiler/tests/org/jetbrains/jet/di/InjectorForTests.java b/compiler/tests/org/jetbrains/jet/di/InjectorForTests.java index 80be3fe32cd..0692ca721cc 100644 --- a/compiler/tests/org/jetbrains/jet/di/InjectorForTests.java +++ b/compiler/tests/org/jetbrains/jet/di/InjectorForTests.java @@ -20,6 +20,7 @@ import org.jetbrains.jet.lang.resolve.DescriptorResolver; import org.jetbrains.jet.lang.types.expressions.ExpressionTypingServices; import org.jetbrains.jet.lang.resolve.TypeResolver; import org.jetbrains.jet.lang.resolve.calls.CallResolver; +import org.jetbrains.jet.lang.resolve.calls.NeedSyntheticCallResolverExtension; import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns; import com.intellij.openapi.project.Project; import org.jetbrains.jet.lang.descriptors.ModuleDescriptor; @@ -38,6 +39,7 @@ public class InjectorForTests { private ExpressionTypingServices expressionTypingServices; private TypeResolver typeResolver; private CallResolver callResolver; + private NeedSyntheticCallResolverExtension needSyntheticCallResolverExtension; private KotlinBuiltIns kotlinBuiltIns; private final Project project; private final ModuleDescriptor moduleDescriptor; @@ -55,6 +57,7 @@ public class InjectorForTests { this.expressionTypingServices = new ExpressionTypingServices(); this.typeResolver = new TypeResolver(); this.callResolver = new CallResolver(); + this.needSyntheticCallResolverExtension = new NeedSyntheticCallResolverExtension(); this.kotlinBuiltIns = KotlinBuiltIns.getInstance(); this.project = project; this.moduleDescriptor = moduleDescriptor; @@ -82,6 +85,7 @@ public class InjectorForTests { this.callResolver.setArgumentTypeResolver(argumentTypeResolver); this.callResolver.setCandidateResolver(candidateResolver); this.callResolver.setExpressionTypingServices(expressionTypingServices); + this.callResolver.setExtension(needSyntheticCallResolverExtension); this.callResolver.setTypeResolver(typeResolver); annotationResolver.setCallResolver(callResolver); diff --git a/generators/org/jetbrains/jet/generators/injectors/GenerateInjectors.java b/generators/org/jetbrains/jet/generators/injectors/GenerateInjectors.java index 0ff749f5b92..4b685395a26 100644 --- a/generators/org/jetbrains/jet/generators/injectors/GenerateInjectors.java +++ b/generators/org/jetbrains/jet/generators/injectors/GenerateInjectors.java @@ -24,14 +24,13 @@ import org.jetbrains.jet.codegen.ScriptCodegen; import org.jetbrains.jet.codegen.intrinsics.IntrinsicMethods; import org.jetbrains.jet.codegen.state.GenerationState; import org.jetbrains.jet.codegen.state.JetTypeMapper; -import org.jetbrains.jet.di.DependencyInjectorGenerator; -import org.jetbrains.jet.di.GivenExpression; -import org.jetbrains.jet.di.InjectorForTopDownAnalyzer; +import org.jetbrains.jet.di.*; import org.jetbrains.jet.lang.descriptors.ModuleDescriptor; import org.jetbrains.jet.lang.descriptors.ModuleDescriptorImpl; import org.jetbrains.jet.lang.psi.JetImportsFactory; import org.jetbrains.jet.lang.resolve.*; import org.jetbrains.jet.lang.resolve.calls.CallResolver; +import org.jetbrains.jet.lang.resolve.calls.NeedSyntheticCallResolverExtension; import org.jetbrains.jet.lang.resolve.java.*; import org.jetbrains.jet.lang.resolve.lazy.ResolveSession; import org.jetbrains.jet.lang.resolve.lazy.ScopeProvider; @@ -74,6 +73,7 @@ public class GenerateInjectors { generator.addPublicField(AnnotationResolver.class); generator.addPublicField(QualifiedExpressionResolver.class); generator.addPublicField(JetImportsFactory.class); + generator.addField(NeedSyntheticCallResolverExtension.class); generator.generate("compiler/frontend/src", "org.jetbrains.jet.di", "InjectorForLazyResolve", GenerateInjectors.class); } @@ -131,6 +131,7 @@ public class GenerateInjectors { generator.addPublicField(ControlFlowAnalyzer.class); generator.addPublicField(DeclarationsChecker.class); generator.addPublicField(DescriptorResolver.class); + generator.addField(NeedSyntheticCallResolverExtension.class); // Parameters generator.addPublicParameter(Project.class); @@ -144,6 +145,7 @@ public class GenerateInjectors { // Fields generator.addPublicField(ExpressionTypingServices.class); + generator.addField(NeedSyntheticCallResolverExtension.class); // Parameters generator.addPublicParameter(Project.class); @@ -160,6 +162,7 @@ public class GenerateInjectors { generator.addPublicField(ExpressionTypingServices.class); generator.addPublicField(TypeResolver.class); generator.addPublicField(CallResolver.class); + generator.addField(NeedSyntheticCallResolverExtension.class); generator.addField(true, KotlinBuiltIns.class, null, new GivenExpression("KotlinBuiltIns.getInstance()")); // Parameters @@ -219,6 +222,7 @@ public class GenerateInjectors { DependencyInjectorGenerator generator = new DependencyInjectorGenerator(); // Fields generator.addPublicField(BodyResolver.class); + generator.addField(NeedSyntheticCallResolverExtension.class); // Parameters generator.addPublicParameter(Project.class); diff --git a/js/js.translator/src/org/jetbrains/jet/di/InjectorForTopDownAnalyzerForJs.java b/js/js.translator/src/org/jetbrains/jet/di/InjectorForTopDownAnalyzerForJs.java index 3d823a2b021..14976718021 100644 --- a/js/js.translator/src/org/jetbrains/jet/di/InjectorForTopDownAnalyzerForJs.java +++ b/js/js.translator/src/org/jetbrains/jet/di/InjectorForTopDownAnalyzerForJs.java @@ -22,6 +22,7 @@ import org.jetbrains.jet.lang.resolve.BodyResolver; import org.jetbrains.jet.lang.resolve.ControlFlowAnalyzer; import org.jetbrains.jet.lang.resolve.DeclarationsChecker; import org.jetbrains.jet.lang.resolve.DescriptorResolver; +import org.jetbrains.jet.lang.resolve.calls.NeedSyntheticCallResolverExtension; import com.intellij.openapi.project.Project; import org.jetbrains.jet.lang.resolve.TopDownAnalysisParameters; import org.jetbrains.jet.lang.resolve.BindingTrace; @@ -56,6 +57,7 @@ public class InjectorForTopDownAnalyzerForJs { private ControlFlowAnalyzer controlFlowAnalyzer; private DeclarationsChecker declarationsChecker; private DescriptorResolver descriptorResolver; + private NeedSyntheticCallResolverExtension needSyntheticCallResolverExtension; private final Project project; private final TopDownAnalysisParameters topDownAnalysisParameters; private final BindingTrace bindingTrace; @@ -91,6 +93,7 @@ public class InjectorForTopDownAnalyzerForJs { this.controlFlowAnalyzer = new ControlFlowAnalyzer(); this.declarationsChecker = new DeclarationsChecker(); this.descriptorResolver = new DescriptorResolver(); + this.needSyntheticCallResolverExtension = new NeedSyntheticCallResolverExtension(); this.project = project; this.topDownAnalysisParameters = topDownAnalysisParameters; this.bindingTrace = bindingTrace; @@ -162,6 +165,7 @@ public class InjectorForTopDownAnalyzerForJs { callResolver.setArgumentTypeResolver(argumentTypeResolver); callResolver.setCandidateResolver(candidateResolver); callResolver.setExpressionTypingServices(expressionTypingServices); + callResolver.setExtension(needSyntheticCallResolverExtension); callResolver.setTypeResolver(typeResolver); argumentTypeResolver.setExpressionTypingServices(expressionTypingServices); From be72e096ef8e5501afe99971bb2b7b6a14571463 Mon Sep 17 00:00:00 2001 From: Mikhael Bogdanov Date: Tue, 21 May 2013 14:23:38 +0400 Subject: [PATCH 138/291] Realization of class object fields as static fields of outer class #KT-2213 Fixed --- .../AccessorForPropertyDescriptor.java | 8 +- .../org/jetbrains/jet/codegen/AsmUtil.java | 49 +++- .../jet/codegen/ClassBodyCodegen.java | 72 ++++-- .../jetbrains/jet/codegen/CodegenUtil.java | 19 +- .../jet/codegen/ExpressionCodegen.java | 62 +++-- .../codegen/FunctionGenerationStrategy.java | 2 +- .../codegen/ImplementationBodyCodegen.java | 211 ++++++++++++------ .../jetbrains/jet/codegen/MemberCodegen.java | 24 +- .../org/jetbrains/jet/codegen/MethodKind.java | 23 ++ .../jet/codegen/NamespaceCodegen.java | 6 +- .../jet/codegen/PropertyCodegen.java | 187 +++++++++------- .../jetbrains/jet/codegen/ScriptCodegen.java | 3 +- .../jet/codegen/TraitImplBodyCodegen.java | 6 +- .../context/AnonymousClassContext.java | 12 +- .../jet/codegen/context/CodegenContext.java | 13 +- .../jet/codegen/state/JetTypeMapper.java | 12 + .../jetbrains/jet/lang/psi/JetPsiUtil.java | 4 + .../jet/lang/resolve/DescriptorUtils.java | 14 ++ 18 files changed, 501 insertions(+), 226 deletions(-) create mode 100644 compiler/backend/src/org/jetbrains/jet/codegen/MethodKind.java diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/AccessorForPropertyDescriptor.java b/compiler/backend/src/org/jetbrains/jet/codegen/AccessorForPropertyDescriptor.java index 97df1657f93..35a9193ff75 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/AccessorForPropertyDescriptor.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/AccessorForPropertyDescriptor.java @@ -34,8 +34,12 @@ public class AccessorForPropertyDescriptor extends PropertyDescriptorImpl { pd.isVar(), Name.identifier(pd.getName() + "$b$" + index), Kind.DECLARATION); - JetType receiverType = DescriptorUtils.getReceiverParameterType(pd.getReceiverParameter()); - setType(pd.getType(), Collections.emptyList(), pd.getExpectedThisObject(), receiverType); + boolean isStaticProperty = AsmUtil.isPropertyWithBackingFieldInOuterClass(pd) + && !AsmUtil.isClassObjectWithBackingFieldsInOuter(containingDeclaration); + JetType receiverType = !isStaticProperty ? DescriptorUtils.getReceiverParameterType(pd.getReceiverParameter()) : null; + + setType(pd.getType(), Collections.emptyList(), isStaticProperty ? null : pd.getExpectedThisObject(), + receiverType); initialize(new Getter(this), new Setter(this)); } diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/AsmUtil.java b/compiler/backend/src/org/jetbrains/jet/codegen/AsmUtil.java index fbe222a069f..a2c63c40d4f 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/AsmUtil.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/AsmUtil.java @@ -30,7 +30,6 @@ import org.jetbrains.jet.codegen.binding.CalculatedClosure; import org.jetbrains.jet.codegen.state.GenerationState; import org.jetbrains.jet.codegen.state.JetTypeMapper; import org.jetbrains.jet.lang.descriptors.*; -import org.jetbrains.jet.lang.psi.JetPsiUtil; import org.jetbrains.jet.lang.resolve.BindingContext; import org.jetbrains.jet.lang.resolve.DescriptorUtils; import org.jetbrains.jet.lang.resolve.calls.model.ResolvedCall; @@ -50,6 +49,7 @@ import static org.jetbrains.asm4.Opcodes.*; import static org.jetbrains.jet.codegen.CodegenUtil.*; import static org.jetbrains.jet.lang.resolve.DescriptorUtils.isClassObject; import static org.jetbrains.jet.lang.resolve.DescriptorUtils.isEnumEntry; +import static org.jetbrains.jet.lang.resolve.DescriptorUtils.isKindOf; import static org.jetbrains.jet.lang.resolve.java.AsmTypeConstants.JAVA_STRING_TYPE; public class AsmUtil { @@ -589,10 +589,57 @@ public class AsmUtil { } } + public static boolean isPropertyWithBackingFieldInOuterClass(@NotNull PropertyDescriptor propertyDescriptor) { + return isPropertyWithSpecialBackingField(propertyDescriptor.getContainingDeclaration(), ClassKind.CLASS); + } + + public static int getVisibilityForSpecialPropertyBackingField(@NotNull PropertyDescriptor propertyDescriptor, boolean isDelegate) { + boolean isExtensionProperty = propertyDescriptor.getReceiverParameter() != null; + if (isDelegate || isExtensionProperty) { + return ACC_PRIVATE; + } else { + return areBothAccessorDefault(propertyDescriptor) ? getVisibilityAccessFlag(descriptorForVisibility(propertyDescriptor)) : ACC_PRIVATE; + } + } + + private static MemberDescriptor descriptorForVisibility(@NotNull PropertyDescriptor propertyDescriptor) { + if (!propertyDescriptor.isVar() ) { + return propertyDescriptor; + } else { + return propertyDescriptor.getSetter() != null ? propertyDescriptor.getSetter() : propertyDescriptor; + } + } + + public static boolean isPropertyWithBackingFieldCopyInOuterClass(@NotNull PropertyDescriptor propertyDescriptor) { + boolean isExtensionProperty = propertyDescriptor.getReceiverParameter() != null; + return !propertyDescriptor.isVar() && !isExtensionProperty + && isPropertyWithSpecialBackingField(propertyDescriptor.getContainingDeclaration(), ClassKind.TRAIT) + && areBothAccessorDefault(propertyDescriptor) + && getVisibilityForSpecialPropertyBackingField(propertyDescriptor, false) == ACC_PUBLIC; + } + + public static boolean isClassObjectWithBackingFieldsInOuter(@NotNull DeclarationDescriptor classObject) { + return isPropertyWithSpecialBackingField(classObject, ClassKind.CLASS); + } + + private static boolean areBothAccessorDefault(@NotNull PropertyDescriptor propertyDescriptor) { + return isAccessorWithEmptyBody(propertyDescriptor.getGetter()) + && (!propertyDescriptor.isVar() || isAccessorWithEmptyBody(propertyDescriptor.getSetter())); + } + + private static boolean isAccessorWithEmptyBody(@Nullable PropertyAccessorDescriptor accessorDescriptor) { + return accessorDescriptor == null || !accessorDescriptor.hasBody(); + } + + private static boolean isPropertyWithSpecialBackingField(@NotNull DeclarationDescriptor classObject, ClassKind kind) { + return isClassObject(classObject) && isKindOf(classObject.getContainingDeclaration(), kind); + } + public static Type comparisonOperandType(Type left, Type right) { if (left == Type.DOUBLE_TYPE || right == Type.DOUBLE_TYPE) return Type.DOUBLE_TYPE; if (left == Type.FLOAT_TYPE || right == Type.FLOAT_TYPE) return Type.FLOAT_TYPE; if (left == Type.LONG_TYPE || right == Type.LONG_TYPE) return Type.LONG_TYPE; return Type.INT_TYPE; } + } diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/ClassBodyCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/ClassBodyCodegen.java index 8ef88ae3fdf..0a0fea7de56 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/ClassBodyCodegen.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/ClassBodyCodegen.java @@ -17,9 +17,10 @@ package org.jetbrains.jet.codegen; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import org.jetbrains.asm4.MethodVisitor; import org.jetbrains.asm4.Type; -import org.jetbrains.jet.codegen.context.CodegenContext; +import org.jetbrains.jet.codegen.context.ClassContext; import org.jetbrains.jet.codegen.state.GenerationState; import org.jetbrains.jet.lang.descriptors.ClassDescriptor; import org.jetbrains.jet.lang.descriptors.PropertyDescriptor; @@ -40,12 +41,20 @@ public abstract class ClassBodyCodegen extends MemberCodegen { protected final OwnerKind kind; protected final ClassDescriptor descriptor; protected final ClassBuilder v; - protected final CodegenContext context; + protected final ClassContext context; - protected final List staticInitializerChunks = new ArrayList(); + private MethodVisitor clInitMethod; - protected ClassBodyCodegen(JetClassOrObject aClass, CodegenContext context, ClassBuilder v, GenerationState state) { - super(state); + private ExpressionCodegen clInitCodegen; + + protected ClassBodyCodegen( + @NotNull JetClassOrObject aClass, + @NotNull ClassContext context, + @NotNull ClassBuilder v, + @NotNull GenerationState state, + @Nullable MemberCodegen parentCodegen + ) { + super(state, parentCodegen); descriptor = state.getBindingContext().get(BindingContext.CLASS, aClass); myClass = aClass; this.context = context; @@ -53,7 +62,7 @@ public abstract class ClassBodyCodegen extends MemberCodegen { this.v = v; } - public final void generate() { + public void generate() { generateDeclaration(); generateClassBody(); @@ -72,18 +81,20 @@ public abstract class ClassBodyCodegen extends MemberCodegen { private void generateClassBody() { FunctionCodegen functionCodegen = new FunctionCodegen(context, v, state); - PropertyCodegen propertyCodegen = new PropertyCodegen(context, v, functionCodegen); + PropertyCodegen propertyCodegen = new PropertyCodegen(context, v, functionCodegen, this); - for (JetDeclaration declaration : myClass.getDeclarations()) { + if (kind != OwnerKind.TRAIT_IMPL) { //generate nested classes first and only then generate class body. It necessary to access to nested CodegenContexts - if (shouldProcessFirst(declaration)) { - generateDeclaration(propertyCodegen, declaration, functionCodegen); + for (JetDeclaration declaration : myClass.getDeclarations()) { + if (shouldProcessFirst(declaration)) { + generateDeclaration(propertyCodegen, declaration); + } } } for (JetDeclaration declaration : myClass.getDeclarations()) { if (!shouldProcessFirst(declaration)) { - generateDeclaration(propertyCodegen, declaration, functionCodegen); + generateDeclaration(propertyCodegen, declaration); } } @@ -94,7 +105,8 @@ public abstract class ClassBodyCodegen extends MemberCodegen { return false == (declaration instanceof JetProperty || declaration instanceof JetNamedFunction); } - protected void generateDeclaration(PropertyCodegen propertyCodegen, JetDeclaration declaration, FunctionCodegen functionCodegen) { + + protected void generateDeclaration(PropertyCodegen propertyCodegen, JetDeclaration declaration) { if (declaration instanceof JetProperty || declaration instanceof JetNamedFunction) { genFunctionOrProperty(context, (JetTypeParameterListOwner) declaration, v); } @@ -137,23 +149,39 @@ public abstract class ClassBodyCodegen extends MemberCodegen { } private void generateStaticInitializer() { - if (staticInitializerChunks.size() > 0) { - MethodVisitor mv = v.newMethod(null, ACC_STATIC, "", "()V", null, null); + if (clInitMethod != null) { + createOrGetClInitMethod(); + if (state.getClassBuilderMode() == ClassBuilderMode.FULL) { - mv.visitCode(); + ExpressionCodegen codegen = createOrGetClInitCodegen(); - ExpressionCodegen codegen = new ExpressionCodegen(mv, new FrameMap(), Type.VOID_TYPE, context, state); - - for (CodeChunk chunk : staticInitializerChunks) { - chunk.generate(codegen); - } - - mv.visitInsn(RETURN); + createOrGetClInitMethod().visitInsn(RETURN); FunctionCodegen.endVisit(codegen.v, "static initializer", myClass); } } } + @Nullable + protected MethodVisitor createOrGetClInitMethod() { + if (clInitMethod == null) { + clInitMethod = v.newMethod(null, ACC_STATIC, "", "()V", null, null); + } + return clInitMethod; + } + + @Nullable + protected ExpressionCodegen createOrGetClInitCodegen() { + assert state.getClassBuilderMode() == ClassBuilderMode.FULL; + if (state.getClassBuilderMode() == ClassBuilderMode.FULL) { + if (clInitCodegen == null) { + MethodVisitor method = createOrGetClInitMethod(); + method.visitCode(); + clInitCodegen = new ExpressionCodegen(method, new FrameMap(), Type.VOID_TYPE, context, state); + } + } + return clInitCodegen; + } + private void generateRemoveInIterator() { // generates stub 'remove' function for subclasses of Iterator to be compatible with java.util.Iterator if (DescriptorUtils.isIteratorWithoutRemoveImpl(descriptor)) { diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/CodegenUtil.java b/compiler/backend/src/org/jetbrains/jet/codegen/CodegenUtil.java index f0cfb552f19..57605e9648f 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/CodegenUtil.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/CodegenUtil.java @@ -27,6 +27,7 @@ import org.jetbrains.jet.codegen.context.NamespaceContext; import org.jetbrains.jet.codegen.signature.BothSignatureWriter; import org.jetbrains.jet.codegen.signature.JvmMethodParameterKind; import org.jetbrains.jet.codegen.signature.JvmMethodSignature; +import org.jetbrains.jet.codegen.state.JetTypeMapper; import org.jetbrains.jet.lang.descriptors.*; import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor; import org.jetbrains.jet.lang.descriptors.impl.SimpleFunctionDescriptorImpl; @@ -263,14 +264,26 @@ public class CodegenUtil { return false; } - public static boolean couldUseDirectAccessToProperty(PropertyDescriptor propertyDescriptor, boolean forGetter, boolean isInsideClass, boolean isDelegated) { + public static boolean couldUseDirectAccessToProperty(@NotNull PropertyDescriptor propertyDescriptor, boolean forGetter, boolean isInsideClass, boolean isDelegated) { PropertyAccessorDescriptor accessorDescriptor = forGetter ? propertyDescriptor.getGetter() : propertyDescriptor.getSetter(); boolean isExtensionProperty = propertyDescriptor.getReceiverParameter() != null; + boolean specialTypeProperty = isDelegated || + isExtensionProperty || + DescriptorUtils.isClassObject(propertyDescriptor.getContainingDeclaration()) || + JetTypeMapper.isAccessor(propertyDescriptor); return isInsideClass && - !isDelegated && - !isExtensionProperty && + !specialTypeProperty && (accessorDescriptor == null || accessorDescriptor.isDefault() && (!DescriptorUtils.isExternallyAccessible(propertyDescriptor) || accessorDescriptor.getModality() == Modality.FINAL)); } + + @NotNull + public static ImplementationBodyCodegen getParentBodyCodegen(@Nullable MemberCodegen classBodyCodegen) { + assert classBodyCodegen != null && + classBodyCodegen + .getParentCodegen() instanceof ImplementationBodyCodegen : "Class object should have appropriate parent BodyCodegen"; + + return ((ImplementationBodyCodegen) classBodyCodegen.getParentCodegen()); + } } diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java index 295167f4a53..0f69bb1dbbd 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java @@ -87,6 +87,7 @@ public class ExpressionCodegen extends JetVisitor implem private int myLastLineNumber = -1; final InstructionAdapter v; + final MethodVisitor methodVisitor; final FrameMap myFrameMap; final JetTypeMapper typeMapper; @@ -121,8 +122,8 @@ public class ExpressionCodegen extends JetVisitor implem //noinspection SuspiciousMethodCalls CalculatedClosure closure = bindingContext.get(CLOSURE, classDescriptor); - CodegenContext objectContext = context.intoAnonymousClass(classDescriptor, this); - ImplementationBodyCodegen implementationBodyCodegen = new ImplementationBodyCodegen(objectDeclaration, objectContext, classBuilder, state); + ClassContext objectContext = context.intoAnonymousClass(classDescriptor, this); + ImplementationBodyCodegen implementationBodyCodegen = new ImplementationBodyCodegen(objectDeclaration, objectContext, classBuilder, state, null); implementationBodyCodegen.generate(); @@ -164,7 +165,15 @@ public class ExpressionCodegen extends JetVisitor implem this.typeMapper = state.getTypeMapper(); this.returnType = returnType; this.state = state; - this.v = new InstructionAdapter(v) { + this.methodVisitor = v; + this.v = createInstructionAdapter(methodVisitor); + this.bindingContext = state.getBindingContext(); + this.context = context; + this.statementVisitor = new CodegenStatementVisitor(this); + } + + protected InstructionAdapter createInstructionAdapter(MethodVisitor mv) { + return new InstructionAdapter(methodVisitor) { @Override public void visitLocalVariable(String name, String desc, String signature, Label start, Label end, int index) { super.visitLocalVariable(name, desc, signature, start, end, @@ -172,9 +181,6 @@ public class ExpressionCodegen extends JetVisitor implem localVariableNames.add(name); } }; - this.bindingContext = state.getBindingContext(); - this.context = context; - this.statementVisitor = new CodegenStatementVisitor(this); } public GenerationState getState() { @@ -275,9 +281,9 @@ public class ExpressionCodegen extends JetVisitor implem ClassBuilder classBuilder = state.getFactory().newVisitor(className.getInternalName(), declaration.getContainingFile() ); - CodegenContext objectContext = context.intoAnonymousClass(descriptor, this); + ClassContext objectContext = context.intoAnonymousClass(descriptor, this); - new ImplementationBodyCodegen(declaration, objectContext, classBuilder, state).generate(); + new ImplementationBodyCodegen(declaration, objectContext, classBuilder, state, null).generate(); return StackValue.none(); } @@ -1673,26 +1679,26 @@ public class ExpressionCodegen extends JetVisitor implem @NotNull public StackValue.Property intermediateValueForProperty( - PropertyDescriptor propertyDescriptor, + @NotNull PropertyDescriptor propertyDescriptor, boolean forceField, @Nullable JetSuperExpression superExpression ) { - return intermediateValueForProperty(propertyDescriptor, forceField, superExpression, false); + return intermediateValueForProperty(propertyDescriptor, forceField, superExpression, MethodKind.GENERAL); } - @NotNull public StackValue.Property intermediateValueForProperty( - PropertyDescriptor propertyDescriptor, + @NotNull PropertyDescriptor propertyDescriptor, boolean forceField, @Nullable JetSuperExpression superExpression, - @NotNull boolean forceSpecialFlag + @NotNull MethodKind methodKind ) { JetTypeMapper typeMapper = state.getTypeMapper(); DeclarationDescriptor containingDeclaration = propertyDescriptor.getContainingDeclaration(); assert containingDeclaration != null; - boolean isStatic = containingDeclaration instanceof NamespaceDescriptor; + boolean isBackingFieldInAnotherClass = AsmUtil.isPropertyWithBackingFieldInOuterClass(propertyDescriptor); + boolean isStatic = containingDeclaration instanceof NamespaceDescriptor || isBackingFieldInAnotherClass; boolean isSuper = superExpression != null; boolean isInsideClass = isCallInsideSameClassAsDeclared(propertyDescriptor, context); boolean isInsideModule = isCallInsideSameModuleAsDeclared(propertyDescriptor, context); @@ -1700,10 +1706,25 @@ public class ExpressionCodegen extends JetVisitor implem JetType delegateType = getPropertyDelegateType(propertyDescriptor, state.getBindingContext()); boolean isDelegatedProperty = delegateType != null; + CallableMethod callableGetter = null; CallableMethod callableSetter = null; - if (!forceField) { + boolean skipPropertyAccessors = forceField && !isBackingFieldInAnotherClass; + + CodegenContext backingFieldContext = context.getParentContext(); + + if (isBackingFieldInAnotherClass && forceField) { + //delegate call to classObject owner : OWNER + backingFieldContext = context.findParentContextWithDescriptor(containingDeclaration.getContainingDeclaration()); + int flags = AsmUtil.getVisibilityForSpecialPropertyBackingField(propertyDescriptor, isDelegatedProperty); + skipPropertyAccessors = (flags & ACC_PRIVATE) == 0 || methodKind == MethodKind.SYNTHETIC_ACCESSOR || methodKind == MethodKind.INITIALIZER; + if (!skipPropertyAccessors) { + propertyDescriptor = (PropertyDescriptor) backingFieldContext.getAccessor(propertyDescriptor); + } + } + + if (!skipPropertyAccessors) { //noinspection ConstantConditions if (couldUseDirectAccessToProperty(propertyDescriptor, true, isInsideClass, isDelegatedProperty)) { callableGetter = null; @@ -1721,7 +1742,9 @@ public class ExpressionCodegen extends JetVisitor implem propertyDescriptor = accessablePropertyDescriptor(propertyDescriptor); if (propertyDescriptor.getGetter() != null) { - callableGetter = typeMapper.mapToCallableMethod(propertyDescriptor.getGetter(), isSuper || forceSpecialFlag, isInsideClass, isInsideModule, OwnerKind.IMPLEMENTATION); + callableGetter = typeMapper + .mapToCallableMethod(propertyDescriptor.getGetter(), isSuper || MethodKind.SYNTHETIC_ACCESSOR == methodKind, + isInsideClass, isInsideModule, OwnerKind.IMPLEMENTATION); } } @@ -1731,7 +1754,7 @@ public class ExpressionCodegen extends JetVisitor implem callableSetter = null; } else { - callableSetter = typeMapper.mapToCallableMethod(propertyDescriptor.getSetter(), isSuper || forceSpecialFlag, isInsideClass, isInsideModule, OwnerKind.IMPLEMENTATION); + callableSetter = typeMapper.mapToCallableMethod(propertyDescriptor.getSetter(), isSuper || MethodKind.SYNTHETIC_ACCESSOR == methodKind, isInsideClass, isInsideModule, OwnerKind.IMPLEMENTATION); } } } @@ -1742,7 +1765,7 @@ public class ExpressionCodegen extends JetVisitor implem propertyDescriptor = unwrapFakeOverride(propertyDescriptor); if (callableMethod == null) { - owner = typeMapper.getOwner(propertyDescriptor, context.getContextKind(), isInsideModule); + owner = typeMapper.getOwner(isBackingFieldInAnotherClass ? propertyDescriptor.getContainingDeclaration() : propertyDescriptor, context.getContextKind(), isInsideModule); } else { owner = callableMethod.getOwner(); @@ -2316,8 +2339,7 @@ public class ExpressionCodegen extends JetVisitor implem @NotNull public Type expressionType(JetExpression expr) { - JetType type = bindingContext.get(BindingContext.EXPRESSION_TYPE, expr); - return asmTypeOrVoid(type); + return typeMapper.expressionType(expr); } public int indexOfLocal(JetReferenceExpression lhs) { diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/FunctionGenerationStrategy.java b/compiler/backend/src/org/jetbrains/jet/codegen/FunctionGenerationStrategy.java index 6a7f7426e47..204786833c4 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/FunctionGenerationStrategy.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/FunctionGenerationStrategy.java @@ -85,7 +85,7 @@ public abstract class FunctionGenerationStrategy { public abstract static class CodegenBased extends FunctionGenerationStrategy { - private final GenerationState state; + protected final GenerationState state; protected final T callableDescriptor; diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/ImplementationBodyCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/ImplementationBodyCodegen.java index 05668955841..d32993d3d71 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/ImplementationBodyCodegen.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/ImplementationBodyCodegen.java @@ -31,7 +31,7 @@ import org.jetbrains.asm4.commons.Method; import org.jetbrains.jet.codegen.binding.CalculatedClosure; import org.jetbrains.jet.codegen.binding.CodegenBinding; import org.jetbrains.jet.codegen.binding.MutableClosure; -import org.jetbrains.jet.codegen.context.CodegenContext; +import org.jetbrains.jet.codegen.context.ClassContext; import org.jetbrains.jet.codegen.context.ConstructorContext; import org.jetbrains.jet.codegen.context.MethodContext; import org.jetbrains.jet.codegen.signature.*; @@ -67,6 +67,7 @@ import static org.jetbrains.jet.codegen.CodegenUtil.*; import static org.jetbrains.jet.codegen.binding.CodegenBinding.*; import static org.jetbrains.jet.lang.resolve.BindingContextUtils.callableDescriptorToDeclaration; import static org.jetbrains.jet.lang.resolve.DescriptorUtils.*; +import static org.jetbrains.jet.lang.resolve.DescriptorUtils.isKindOf; import static org.jetbrains.jet.lang.resolve.java.AsmTypeConstants.JAVA_STRING_TYPE; import static org.jetbrains.jet.lang.resolve.java.AsmTypeConstants.OBJECT_TYPE; @@ -79,13 +80,21 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { private final Type classAsmType; private final FunctionCodegen functionCodegen; - private final PropertyCodegen propertyCodegen; + private final PropertyCodegen propertyCodegen; - public ImplementationBodyCodegen(JetClassOrObject aClass, CodegenContext context, ClassBuilder v, GenerationState state) { - super(aClass, context, v, state); + private List classObjectPropertiesToCopy; + + public ImplementationBodyCodegen( + @NotNull JetClassOrObject aClass, + @NotNull ClassContext context, + @NotNull ClassBuilder v, + @NotNull GenerationState state, + @Nullable MemberCodegen parentCodegen + ) { + super(aClass, context, v, state, parentCodegen); this.classAsmType = typeMapper.mapType(descriptor.getDefaultType(), JetTypeMapperMode.IMPL); this.functionCodegen = new FunctionCodegen(context, v, state); - this.propertyCodegen = new PropertyCodegen(context, v, this.functionCodegen); + this.propertyCodegen = new PropertyCodegen(context, v, this.functionCodegen, this); } @Override @@ -429,6 +438,8 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { protected void generateSyntheticParts() { generateFieldForSingleton(); + generateClassObjectBackingFieldCopies(); + try { generatePrimaryConstructor(); } @@ -446,7 +457,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { generateSyntheticAccessors(); - generateEnumMethods(); + generateEnumMethodsAndConstInitializers(); generateFunctionsForDataClasses(); @@ -750,25 +761,33 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { MethodContext functionContext = context.intoFunction(function); FunctionCodegen.generateDefaultIfNeeded(functionContext, state, v, methodSignature, function, OwnerKind.IMPLEMENTATION, - new DefaultParameterValueLoader() { - @Override - public void putValueOnStack( - ValueParameterDescriptor descriptor, - ExpressionCodegen codegen - ) { - assert (KotlinBuiltIns.getInstance() - .isData((ClassDescriptor) function.getContainingDeclaration())) - : "Trying to create function with default arguments for function that isn't presented in code for class without data annotation"; - PropertyDescriptor propertyDescriptor = codegen.getBindingContext().get( - BindingContext.VALUE_PARAMETER_AS_PROPERTY, descriptor); - assert propertyDescriptor != - null : "Trying to generate default value for parameter of copy function that doesn't correspond to any property"; - codegen.v.load(0, thisDescriptorType); - Type propertyType = codegen.typeMapper.mapType(propertyDescriptor.getType()); - codegen.intermediateValueForProperty(propertyDescriptor, false, null) - .put(propertyType, codegen.v); - } - }); + new DefaultParameterValueLoader() { + @Override + public void putValueOnStack( + ValueParameterDescriptor descriptor, + ExpressionCodegen codegen + ) { + assert (KotlinBuiltIns.getInstance().isData((ClassDescriptor) function.getContainingDeclaration())) + : "Trying to create function with default arguments for function that isn't presented in code for class without data annotation"; + PropertyDescriptor propertyDescriptor = codegen.getBindingContext().get( + BindingContext.VALUE_PARAMETER_AS_PROPERTY, descriptor); + assert propertyDescriptor != null + : "Trying to generate default value for parameter of copy function that doesn't correspond to any property"; + codegen.v.load(0, thisDescriptorType); + Type propertyType = codegen.typeMapper.mapType(propertyDescriptor.getType()); + codegen.intermediateValueForProperty(propertyDescriptor, false, null).put(propertyType, codegen.v); + } + }); +} + + private void generateEnumMethodsAndConstInitializers() { + if (!myEnumConstants.isEmpty()) { + generateEnumMethods(); + + if (state.getClassBuilderMode() == ClassBuilderMode.FULL) { + initializeEnumConstants(createOrGetClInitCodegen()); + } + } } private void generateEnumMethods() { @@ -827,7 +846,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { }); } else if (entry.getValue() instanceof PropertyDescriptor) { - PropertyDescriptor bridge = (PropertyDescriptor) entry.getValue(); + final PropertyDescriptor bridge = (PropertyDescriptor) entry.getValue(); final PropertyDescriptor original = (PropertyDescriptor) entry.getKey(); @@ -837,9 +856,12 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { new FunctionGenerationStrategy.CodegenBased(state, getter) { @Override public void doGenerateBody(ExpressionCodegen codegen, JvmMethodSignature signature) { - StackValue.Property property = codegen.intermediateValueForProperty(original, false, null, true); InstructionAdapter iv = codegen.v; - iv.load(0, OBJECT_TYPE); + boolean forceField = AsmUtil.isPropertyWithBackingFieldInOuterClass(original) && !isClassObject(bridge.getContainingDeclaration()); + StackValue.Property property = codegen.intermediateValueForProperty(original, forceField, null, MethodKind.SYNTHETIC_ACCESSOR); + if (!forceField) { + iv.load(0, OBJECT_TYPE); + } property.put(property.type, iv); iv.areturn(signature.getAsmMethod().getReturnType()); } @@ -854,12 +876,12 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { new FunctionGenerationStrategy.CodegenBased(state, setter) { @Override public void doGenerateBody(ExpressionCodegen codegen, JvmMethodSignature signature) { - StackValue.Property property = codegen.intermediateValueForProperty(original, false, null, true); + boolean forceField = AsmUtil.isPropertyWithBackingFieldInOuterClass(original) && !isClassObject(bridge.getContainingDeclaration()); + StackValue.Property property = codegen.intermediateValueForProperty(original, forceField, null, MethodKind.SYNTHETIC_ACCESSOR); InstructionAdapter iv = codegen.v; - iv.load(0, OBJECT_TYPE); Type[] argTypes = signature.getAsmMethod().getArgumentTypes(); - for (int i = 1, reg = 1; i < argTypes.length; i++) { + for (int i = 0, reg = 0; i < argTypes.length; i++) { Type argType = argTypes[i]; iv.load(reg, argType); //noinspection AssignmentToForLoopParameter @@ -915,22 +937,64 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { if (!(isNonLiteralObject(myClass) || hasClassObject) || isEnumClass) return; - final ClassDescriptor fieldTypeDescriptor = hasClassObject ? descriptor.getClassObjectDescriptor() : descriptor; + ClassDescriptor fieldTypeDescriptor = hasClassObject ? descriptor.getClassObjectDescriptor() : descriptor; assert fieldTypeDescriptor != null; - final StackValue.Field field = StackValue.singleton(fieldTypeDescriptor, typeMapper); + StackValue.Field field = StackValue.singleton(fieldTypeDescriptor, typeMapper); JetClassOrObject original = hasClassObject ? ((JetClass) myClass).getClassObject().getObjectDeclaration() : myClass; v.newField(original, ACC_PUBLIC | ACC_STATIC | ACC_FINAL, field.name, field.type.getDescriptor(), null, null); - staticInitializerChunks.add(new CodeChunk() { - @Override - public void generate(ExpressionCodegen codegen) { - ConstructorDescriptor constructorDescriptor = DescriptorUtils.getConstructorOfSingletonObject(fieldTypeDescriptor); - FunctionDescriptor fd = codegen.accessableFunctionDescriptor(constructorDescriptor); - generateMethodCallTo(fd, codegen.v); - field.store(field.type, codegen.v); + if (!AsmUtil.isClassObjectWithBackingFieldsInOuter(fieldTypeDescriptor)) { + genInitSingleton(fieldTypeDescriptor, field); + } + } + + private void generateClassObjectBackingFieldCopies() { + if (classObjectPropertiesToCopy != null) { + for (PropertyDescriptor propertyDescriptor : classObjectPropertiesToCopy) { + + v.newField(null, ACC_STATIC | ACC_FINAL | ACC_PUBLIC, propertyDescriptor.getName().asString(), typeMapper.mapType(propertyDescriptor).getDescriptor(), null, null); + + if (state.getClassBuilderMode() == ClassBuilderMode.FULL) { + ExpressionCodegen codegen = createOrGetClInitCodegen(); + int classObjectIndex = putClassObjectInLocalVar(codegen); + StackValue.local(classObjectIndex, OBJECT_TYPE).put(OBJECT_TYPE, codegen.v); + copyFieldFromClassObject(propertyDescriptor); + } } - }); + } + } + + private int putClassObjectInLocalVar(ExpressionCodegen codegen) { + FrameMap frameMap = codegen.myFrameMap; + ClassDescriptor classObjectDescriptor = descriptor.getClassObjectDescriptor(); + int classObjectIndex = frameMap.getIndex(classObjectDescriptor); + if (classObjectIndex == -1) { + classObjectIndex = frameMap.enter(classObjectDescriptor, OBJECT_TYPE); + StackValue classObject = StackValue.singleton(classObjectDescriptor, typeMapper); + classObject.put(classObject.type, codegen.v); + StackValue.local(classObjectIndex, classObject.type).store(classObject.type, codegen.v); + } + return classObjectIndex; + } + + private void copyFieldFromClassObject(PropertyDescriptor propertyDescriptor) { + ExpressionCodegen codegen = createOrGetClInitCodegen(); + StackValue property = codegen.intermediateValueForProperty(propertyDescriptor, false, null); + property.put(property.type, codegen.v); + StackValue.Field field = StackValue.field(property.type, JvmClassName.byClassDescriptor(descriptor), + propertyDescriptor.getName().asString(), true); + field.store(field.type, codegen.v); + } + + protected void genInitSingleton(ClassDescriptor fieldTypeDescriptor, StackValue.Field field) { + if (state.getClassBuilderMode() == ClassBuilderMode.FULL) { + ConstructorDescriptor constructorDescriptor = DescriptorUtils.getConstructorOfSingletonObject(fieldTypeDescriptor); + ExpressionCodegen codegen = createOrGetClInitCodegen(); + FunctionDescriptor fd = codegen.accessableFunctionDescriptor(constructorDescriptor); + generateMethodCallTo(fd, codegen.v); + field.store(field.type, codegen.v); + } } protected void generatePrimaryConstructor() { @@ -981,9 +1045,9 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { } private void generatePrimaryConstructorImpl( - ConstructorDescriptor constructorDescriptor, - ExpressionCodegen codegen, - MutableClosure closure + @Nullable ConstructorDescriptor constructorDescriptor, + @NotNull final ExpressionCodegen codegen, + @Nullable MutableClosure closure ) { List paramDescrs = constructorDescriptor != null ? constructorDescriptor.getValueParameters() @@ -1035,7 +1099,17 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { curParam++; } - generateInitializers(codegen, iv, myClass.getDeclarations(), bindingContext, state); + boolean generateInitializerInOuter = isClassObjectWithBackingFieldsInOuter(descriptor); + if (generateInitializerInOuter) { + ImplementationBodyCodegen parentCodegen = getParentBodyCodegen(this); + //generate object$ + parentCodegen.genInitSingleton(descriptor, StackValue.singleton(descriptor, typeMapper)); + parentCodegen.generateInitializers(parentCodegen.createOrGetClInitCodegen(), + myClass.getDeclarations(), bindingContext, state); + } else { + generateInitializers(codegen, myClass.getDeclarations(), bindingContext, state); + } + iv.visitInsn(RETURN); } @@ -1225,7 +1299,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { } private void generateTraitMethods() { - if (myClass instanceof JetClass && ((JetClass) myClass).isTrait()) { + if (JetPsiUtil.isTrait(myClass)) { return; } @@ -1425,29 +1499,21 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { } @Override - protected void generateDeclaration(PropertyCodegen propertyCodegen, JetDeclaration declaration, FunctionCodegen functionCodegen) { + protected void generateDeclaration(PropertyCodegen propertyCodegen, JetDeclaration declaration) { if (declaration instanceof JetEnumEntry) { String name = declaration.getName(); String desc = "L" + classAsmType.getInternalName() + ";"; v.newField(declaration, ACC_PUBLIC | ACC_ENUM | ACC_STATIC | ACC_FINAL, name, desc, null, null); - if (myEnumConstants.isEmpty()) { - staticInitializerChunks.add(new CodeChunk() { - @Override - public void generate(ExpressionCodegen codegen) { - initializeEnumConstants(codegen.v); - } - }); - } myEnumConstants.add((JetEnumEntry) declaration); } - super.generateDeclaration(propertyCodegen, declaration, functionCodegen); + super.generateDeclaration(propertyCodegen, declaration); } private final List myEnumConstants = new ArrayList(); - private void initializeEnumConstants(InstructionAdapter iv) { - ExpressionCodegen codegen = new ExpressionCodegen(iv, new FrameMap(), Type.VOID_TYPE, context, state); + private void initializeEnumConstants(ExpressionCodegen codegen) { + InstructionAdapter iv = codegen.v; int ordinal = -1; JetType myType = descriptor.getDefaultType(); Type myAsmType = typeMapper.mapType(myType, JetTypeMapperMode.IMPL); @@ -1509,14 +1575,14 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { } public static void generateInitializers( - @NotNull ExpressionCodegen codegen, @NotNull InstructionAdapter iv, @NotNull List declarations, + @NotNull ExpressionCodegen codegen, @NotNull List declarations, @NotNull BindingContext bindingContext, @NotNull GenerationState state ) { JetTypeMapper typeMapper = state.getTypeMapper(); for (JetDeclaration declaration : declarations) { if (declaration instanceof JetProperty) { if (shouldInitializeProperty((JetProperty) declaration, typeMapper)) { - initializeProperty(codegen, bindingContext, iv, (JetProperty) declaration, false); + initializeProperty(codegen, bindingContext, (JetProperty) declaration); } } else if (declaration instanceof JetClassInitializer) { @@ -1525,16 +1591,12 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { } } + public static void initializeProperty( @NotNull ExpressionCodegen codegen, @NotNull BindingContext bindingContext, - @NotNull InstructionAdapter iv, - @NotNull JetProperty property, - boolean isStatic + @NotNull JetProperty property ) { - if (!isStatic) { - iv.load(0, OBJECT_TYPE); - } PropertyDescriptor propertyDescriptor = (PropertyDescriptor) bindingContext.get(BindingContext.VARIABLE, property); assert propertyDescriptor != null; @@ -1543,14 +1605,20 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { assert initializer != null : "shouldInitializeProperty must return false if initializer is null"; JetType jetType = getPropertyOrDelegateType(bindingContext, property, propertyDescriptor); + + StackValue.Property propValue = codegen.intermediateValueForProperty(propertyDescriptor, true, null, MethodKind.INITIALIZER); + + if (!propValue.isStatic) { + codegen.v.load(0, OBJECT_TYPE); + } + Type type = codegen.expressionType(initializer); if (jetType.isNullable()) { type = boxType(type); } codegen.gen(initializer, type); - StackValue.Property propValue = codegen.intermediateValueForProperty(propertyDescriptor, true, null); - propValue.store(type, iv); + propValue.store(type, codegen.v); } public static boolean shouldInitializeProperty( @@ -1699,4 +1767,11 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { return r; } + public void addClassObjectPropertyToCopy(PropertyDescriptor descriptor) { + if (classObjectPropertiesToCopy == null) { + classObjectPropertiesToCopy = new ArrayList(); + } + classObjectPropertiesToCopy.add(descriptor); + } + } diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/MemberCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/MemberCodegen.java index 89627161c90..41ecee8aaed 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/MemberCodegen.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/MemberCodegen.java @@ -17,22 +17,32 @@ package org.jetbrains.jet.codegen; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import org.jetbrains.jet.codegen.context.ClassContext; import org.jetbrains.jet.codegen.context.CodegenContext; import org.jetbrains.jet.codegen.state.GenerationState; import org.jetbrains.jet.codegen.state.GenerationStateAware; import org.jetbrains.jet.lang.descriptors.ClassDescriptor; -import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor; import org.jetbrains.jet.lang.psi.*; import org.jetbrains.jet.lang.resolve.BindingContext; import org.jetbrains.jet.lang.types.ErrorUtils; -import java.util.Map; +import java.util.List; -import static org.jetbrains.jet.codegen.binding.CodegenBinding.enumEntryNeedSubclass; public class MemberCodegen extends GenerationStateAware { - public MemberCodegen(@NotNull GenerationState state) { + + @Nullable + private MemberCodegen parentCodegen; + + public MemberCodegen(@NotNull GenerationState state, @Nullable MemberCodegen parentCodegen) { super(state); + this.parentCodegen = parentCodegen; + } + + @Nullable + public MemberCodegen getParentCodegen() { + return parentCodegen; } public void genFunctionOrProperty( @@ -54,7 +64,7 @@ public class MemberCodegen extends GenerationStateAware { } else if (functionOrProperty instanceof JetProperty) { try { - new PropertyCodegen(context, classBuilder, functionCodegen).gen((JetProperty) functionOrProperty); + new PropertyCodegen(context, classBuilder, functionCodegen, this).gen((JetProperty) functionOrProperty); } catch (CompilationException e) { throw e; @@ -80,8 +90,8 @@ public class MemberCodegen extends GenerationStateAware { } ClassBuilder classBuilder = state.getFactory().forClassImplementation(descriptor, aClass.getContainingFile()); - CodegenContext classContext = parentContext.intoClass(descriptor, OwnerKind.IMPLEMENTATION, state); - new ImplementationBodyCodegen(aClass, classContext, classBuilder, state).generate(); + ClassContext classContext = parentContext.intoClass(descriptor, OwnerKind.IMPLEMENTATION, state); + new ImplementationBodyCodegen(aClass, classContext, classBuilder, state, this).generate(); classBuilder.done(); if (aClass instanceof JetClass && ((JetClass) aClass).isTrait()) { diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/MethodKind.java b/compiler/backend/src/org/jetbrains/jet/codegen/MethodKind.java new file mode 100644 index 00000000000..e0d1634880a --- /dev/null +++ b/compiler/backend/src/org/jetbrains/jet/codegen/MethodKind.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.codegen; + +public enum MethodKind { + GENERAL, + INITIALIZER, + SYNTHETIC_ACCESSOR +} diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/NamespaceCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/NamespaceCodegen.java index 7c3e2e34336..08f7f5a6a92 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/NamespaceCodegen.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/NamespaceCodegen.java @@ -26,11 +26,9 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.asm4.AnnotationVisitor; import org.jetbrains.asm4.MethodVisitor; import org.jetbrains.asm4.Type; -import org.jetbrains.asm4.commons.InstructionAdapter; import org.jetbrains.jet.codegen.context.CodegenContext; import org.jetbrains.jet.codegen.state.GenerationState; import org.jetbrains.jet.lang.descriptors.NamespaceDescriptor; -import org.jetbrains.jet.lang.descriptors.PropertyDescriptor; import org.jetbrains.jet.lang.diagnostics.DiagnosticUtils; import org.jetbrains.jet.lang.psi.*; import org.jetbrains.jet.lang.resolve.BindingContext; @@ -56,7 +54,7 @@ public class NamespaceCodegen extends MemberCodegen { GenerationState state, Collection namespaceFiles ) { - super(state); + super(state, null); checkAllFilesHaveSameNamespace(namespaceFiles); this.v = v; @@ -218,7 +216,7 @@ public class NamespaceCodegen extends MemberCodegen { for (JetDeclaration declaration : properties) { ImplementationBodyCodegen. - initializeProperty(codegen, state.getBindingContext(), new InstructionAdapter(mv), (JetProperty) declaration, true); + initializeProperty(codegen, state.getBindingContext(), (JetProperty) declaration); } mv.visitInsn(RETURN); diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/PropertyCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/PropertyCodegen.java index 493de79443b..46b6820effd 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/PropertyCodegen.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/PropertyCodegen.java @@ -19,24 +19,29 @@ package org.jetbrains.jet.codegen; import com.intellij.openapi.util.text.StringUtil; import com.intellij.psi.PsiElement; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; import org.jetbrains.asm4.FieldVisitor; import org.jetbrains.asm4.MethodVisitor; import org.jetbrains.asm4.Type; import org.jetbrains.asm4.commons.InstructionAdapter; +import org.jetbrains.jet.codegen.context.ClassContext; import org.jetbrains.jet.codegen.context.CodegenContext; import org.jetbrains.jet.codegen.context.MethodContext; import org.jetbrains.jet.codegen.signature.JvmMethodSignature; import org.jetbrains.jet.codegen.signature.JvmPropertyAccessorSignature; import org.jetbrains.jet.codegen.signature.kotlin.JetMethodAnnotationWriter; +import org.jetbrains.jet.codegen.state.GenerationState; import org.jetbrains.jet.codegen.state.GenerationStateAware; import org.jetbrains.jet.codegen.state.JetTypeMapper; 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.DescriptorResolver; +import org.jetbrains.jet.lang.resolve.DescriptorUtils; import org.jetbrains.jet.lang.resolve.calls.model.ResolvedCall; import org.jetbrains.jet.lang.resolve.constants.CompileTimeConstant; import org.jetbrains.jet.lang.resolve.java.JvmAbi; +import org.jetbrains.jet.lang.resolve.java.JvmClassName; 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; @@ -46,31 +51,44 @@ import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns; import static org.jetbrains.asm4.Opcodes.*; import static org.jetbrains.jet.codegen.AsmUtil.getDeprecatedAccessFlag; +import static org.jetbrains.jet.codegen.AsmUtil.getVisibilityForSpecialPropertyBackingField; import static org.jetbrains.jet.codegen.CodegenUtil.*; import static org.jetbrains.jet.lang.resolve.java.AsmTypeConstants.OBJECT_TYPE; public class PropertyCodegen extends GenerationStateAware { + @NotNull private final FunctionCodegen functionCodegen; + + @NotNull private final ClassBuilder v; + + @NotNull private final CodegenContext context; + + @Nullable + private MemberCodegen classBodyCodegen; + + @NotNull private final OwnerKind kind; - public PropertyCodegen(CodegenContext context, ClassBuilder v, FunctionCodegen functionCodegen) { + public PropertyCodegen( + @NotNull CodegenContext context, + @NotNull ClassBuilder v, + @NotNull FunctionCodegen functionCodegen, + @Nullable MemberCodegen classBodyCodegen + ) { super(functionCodegen.getState()); this.v = v; this.functionCodegen = functionCodegen; this.context = context; + this.classBodyCodegen = classBodyCodegen; this.kind = context.getContextKind(); } public void gen(JetProperty p) { - VariableDescriptor descriptor = bindingContext.get(BindingContext.VARIABLE, p); - if (!(descriptor instanceof PropertyDescriptor)) { - throw new UnsupportedOperationException("expect a property to have a property descriptor"); - } - PropertyDescriptor propertyDescriptor = (PropertyDescriptor) descriptor; + PropertyDescriptor propertyDescriptor = DescriptorUtils.getPropertyDescriptor(p, bindingContext); assert kind instanceof OwnerKind.StaticDelegateKind || kind == OwnerKind.NAMESPACE || kind == OwnerKind.IMPLEMENTATION || kind == OwnerKind.TRAIT_IMPL - : "Generating property with a wrong kind (" + kind + "): " + descriptor; + : "Generating property with a wrong kind (" + kind + "): " + propertyDescriptor; if (kind != OwnerKind.TRAIT_IMPL && !(kind instanceof OwnerKind.StaticDelegateKind)) { generateBackingField(p, propertyDescriptor); @@ -89,7 +107,7 @@ public class PropertyCodegen extends GenerationStateAware { } } - private void generateBackingField(PsiElement p, PropertyDescriptor propertyDescriptor) { + private void generateBackingField(JetNamedDeclaration p, PropertyDescriptor propertyDescriptor) { //noinspection ConstantConditions boolean hasBackingField = bindingContext.get(BindingContext.BACKING_FIELD_REQUIRED, propertyDescriptor); boolean isDelegated = p instanceof JetProperty && ((JetProperty) p).getDelegateExpression() != null; @@ -108,25 +126,56 @@ public class PropertyCodegen extends GenerationStateAware { } - private FieldVisitor generatePropertyDelegateAccess(JetProperty p, PropertyDescriptor propertyDescriptor) { - int modifiers = ACC_PRIVATE | ACC_FINAL | getDeprecatedAccessFlag(propertyDescriptor); - if (kind == OwnerKind.NAMESPACE) { - modifiers |= ACC_STATIC; - } + private FieldVisitor generateBackingField(JetNamedDeclaration element, PropertyDescriptor propertyDescriptor, boolean isDelegate, JetType jetType, Object defaultValue) { + int modifiers = getDeprecatedAccessFlag(propertyDescriptor); + if (KotlinBuiltIns.getInstance().isVolatile(propertyDescriptor)) { modifiers |= ACC_VOLATILE; } + + if (kind == OwnerKind.NAMESPACE) { + modifiers |= ACC_STATIC; + } + + if (!propertyDescriptor.isVar() || isDelegate) { + modifiers |= ACC_FINAL; + } + + Type type = typeMapper.mapType(jetType); + + ClassBuilder builder = v; + + if (AsmUtil.isPropertyWithBackingFieldInOuterClass(propertyDescriptor)) { + modifiers |= ACC_STATIC | getVisibilityForSpecialPropertyBackingField(propertyDescriptor, isDelegate); + builder = getParentBodyCodegen(classBodyCodegen).v; + } else { + if (kind != OwnerKind.NAMESPACE || isDelegate) { + modifiers |= ACC_PRIVATE; + } + } + + if (AsmUtil.isPropertyWithBackingFieldCopyInOuterClass(propertyDescriptor)) { + ImplementationBodyCodegen parentBodyCodegen = getParentBodyCodegen(classBodyCodegen); + parentBodyCodegen.addClassObjectPropertyToCopy(propertyDescriptor); + } + + String name = isDelegate ? JvmAbi.getPropertyDelegateName(propertyDescriptor.getName()) : propertyDescriptor.getName().asString(); + + return builder.newField(element, modifiers, name, type.getDescriptor(), + null, defaultValue); + } + + private FieldVisitor generatePropertyDelegateAccess(JetProperty p, PropertyDescriptor propertyDescriptor) { JetType delegateType = bindingContext.get(BindingContext.EXPRESSION_TYPE, p.getDelegateExpression()); 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); + + return generateBackingField(p, propertyDescriptor, true, delegateType, null); } - private FieldVisitor generateBackingFieldAccess(PsiElement p, PropertyDescriptor propertyDescriptor) { + private FieldVisitor generateBackingFieldAccess(JetNamedDeclaration p, PropertyDescriptor propertyDescriptor) { Object value = null; if (p instanceof JetProperty && !ImplementationBodyCodegen.shouldInitializeProperty((JetProperty) p, typeMapper)) { JetExpression initializer = ((JetProperty) p).getInitializer(); @@ -135,22 +184,8 @@ public class PropertyCodegen extends GenerationStateAware { value = compileTimeValue != null ? compileTimeValue.getValue() : null; } } - int modifiers; - if (kind == OwnerKind.NAMESPACE) { - modifiers = ACC_STATIC; - } - else { - modifiers = ACC_PRIVATE; - } - if (!propertyDescriptor.isVar()) { - modifiers |= ACC_FINAL; - } - modifiers |= getDeprecatedAccessFlag(propertyDescriptor); - if (KotlinBuiltIns.getInstance().isVolatile(propertyDescriptor)) { - modifiers |= ACC_VOLATILE; - } - Type type = typeMapper.mapType(propertyDescriptor); - return v.newField(p, modifiers, propertyDescriptor.getName().asString(), type.getDescriptor(), null, value); + + return generateBackingField(p, propertyDescriptor, false, propertyDescriptor.getType(), value); } private void generateGetter(JetNamedDeclaration p, PropertyDescriptor propertyDescriptor, JetPropertyAccessor getter) { @@ -166,10 +201,10 @@ public class PropertyCodegen extends GenerationStateAware { FunctionGenerationStrategy strategy; if (defaultGetter) { if (p instanceof JetProperty && ((JetProperty) p).getDelegateExpression() != null) { - strategy = new DefaultPropertyWithDelegateAccessorStrategy(getterDescriptor); + strategy = new DefaultPropertyWithDelegateAccessorStrategy(state, getterDescriptor); } else { - strategy = new DefaultPropertyAccessorStrategy(getterDescriptor); + strategy = new DefaultPropertyAccessorStrategy(state, getterDescriptor); } } else { @@ -197,10 +232,10 @@ public class PropertyCodegen extends GenerationStateAware { FunctionGenerationStrategy strategy; if (defaultSetter) { if (p instanceof JetProperty && ((JetProperty) p).getDelegateExpression() != null) { - strategy = new DefaultPropertyWithDelegateAccessorStrategy(setterDescriptor); + strategy = new DefaultPropertyWithDelegateAccessorStrategy(state, setterDescriptor); } else { - strategy = new DefaultPropertyAccessorStrategy(setterDescriptor); + strategy = new DefaultPropertyAccessorStrategy(state, setterDescriptor); } } else { @@ -216,90 +251,82 @@ public class PropertyCodegen extends GenerationStateAware { } - private class DefaultPropertyAccessorStrategy extends FunctionGenerationStrategy { - private final PropertyAccessorDescriptor descriptor; + private static class DefaultPropertyAccessorStrategy extends FunctionGenerationStrategy.CodegenBased { - public DefaultPropertyAccessorStrategy(@NotNull PropertyAccessorDescriptor descriptor) { - this.descriptor = descriptor; + public DefaultPropertyAccessorStrategy( + @NotNull GenerationState state, + @NotNull PropertyAccessorDescriptor callableDescriptor + ) { + super(state, callableDescriptor); } @Override - public void generateBody( - @NotNull MethodVisitor mv, - @NotNull JvmMethodSignature signature, - @NotNull MethodContext context + public void doGenerateBody( + ExpressionCodegen codegen, JvmMethodSignature signature ) { - generateDefaultAccessor(descriptor, new InstructionAdapter(mv), typeMapper, context); + generateDefaultAccessor(callableDescriptor, codegen.v, codegen); } } private static void generateDefaultAccessor( @NotNull PropertyAccessorDescriptor accessorDescriptor, @NotNull InstructionAdapter iv, - @NotNull JetTypeMapper typeMapper, - @NotNull CodegenContext context + @NotNull ExpressionCodegen codegen ) { + JetTypeMapper typeMapper = codegen.typeMapper; + CodegenContext context = codegen.context; OwnerKind kind = context.getContextKind(); PropertyDescriptor propertyDescriptor = accessorDescriptor.getCorrespondingProperty(); Type type = typeMapper.mapType(propertyDescriptor); + + int paramCode = 0; + if (kind != OwnerKind.NAMESPACE) { + iv.load(0, OBJECT_TYPE); + paramCode = 1; + } + + StackValue property = codegen.intermediateValueForProperty(accessorDescriptor.getCorrespondingProperty(), true, null); + if (accessorDescriptor instanceof PropertyGetterDescriptor) { - if (kind != OwnerKind.NAMESPACE) { - iv.load(0, OBJECT_TYPE); - } - iv.visitFieldInsn( - kind == OwnerKind.NAMESPACE ? GETSTATIC : GETFIELD, - typeMapper.getOwner(propertyDescriptor, kind, isCallInsideSameModuleAsDeclared(propertyDescriptor, context)).getInternalName(), - propertyDescriptor.getName().asString(), - type.getDescriptor()); + property.put(type, iv); iv.areturn(type); } else if (accessorDescriptor instanceof PropertySetterDescriptor) { - int paramCode = 0; - if (kind != OwnerKind.NAMESPACE) { - iv.load(0, OBJECT_TYPE); - paramCode = 1; - } ReceiverParameterDescriptor receiverParameter = propertyDescriptor.getReceiverParameter(); if (receiverParameter != null) { paramCode += typeMapper.mapType(receiverParameter.getType()).getSize(); } iv.load(paramCode, type); - iv.visitFieldInsn(kind == OwnerKind.NAMESPACE ? PUTSTATIC : PUTFIELD, - typeMapper.getOwner(propertyDescriptor, kind, isCallInsideSameModuleAsDeclared(propertyDescriptor, context)).getInternalName(), - propertyDescriptor.getName().asString(), - type.getDescriptor()); + property.store(type, iv); iv.visitInsn(RETURN); } else { assert false : "Unreachable state"; } } - private class DefaultPropertyWithDelegateAccessorStrategy extends FunctionGenerationStrategy { - private final PropertyAccessorDescriptor descriptor; - - public DefaultPropertyWithDelegateAccessorStrategy(@NotNull PropertyAccessorDescriptor descriptor) { - this.descriptor = descriptor; + private static class DefaultPropertyWithDelegateAccessorStrategy extends FunctionGenerationStrategy.CodegenBased { + public DefaultPropertyWithDelegateAccessorStrategy(@NotNull GenerationState state, @NotNull PropertyAccessorDescriptor descriptor) { + super(state, descriptor); } @Override - public void generateBody( - @NotNull MethodVisitor mv, - @NotNull JvmMethodSignature signature, - @NotNull MethodContext context + public void doGenerateBody( + @NotNull ExpressionCodegen codegen, @NotNull JvmMethodSignature signature ) { - InstructionAdapter iv = new InstructionAdapter(mv); - ExpressionCodegen codegen = new ExpressionCodegen( - mv, getFrameMap(typeMapper, context), signature.getAsmMethod().getReturnType(), context, state); + JetTypeMapper typeMapper = codegen.typeMapper; + OwnerKind kind = codegen.context.getContextKind(); + InstructionAdapter iv = codegen.v; + BindingContext bindingContext = state.getBindingContext(); ResolvedCall resolvedCall = - bindingContext.get(BindingContext.DELEGATED_PROPERTY_RESOLVED_CALL, descriptor); + bindingContext.get(BindingContext.DELEGATED_PROPERTY_RESOLVED_CALL, callableDescriptor); - Call call = bindingContext.get(BindingContext.DELEGATED_PROPERTY_CALL, descriptor); + Call call = bindingContext.get(BindingContext.DELEGATED_PROPERTY_CALL, callableDescriptor); assert call != null : "Call should be recorded for delegate call " + signature.toString(); - PropertyDescriptor property = descriptor.getCorrespondingProperty(); + PropertyDescriptor property = callableDescriptor.getCorrespondingProperty(); Type asmType = typeMapper.mapType(property); if (kind != OwnerKind.NAMESPACE) { diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/ScriptCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/ScriptCodegen.java index 5861fa2a645..e7323990991 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/ScriptCodegen.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/ScriptCodegen.java @@ -53,7 +53,7 @@ public class ScriptCodegen extends MemberCodegen { private Method scriptConstructorMethod; public ScriptCodegen(@NotNull GenerationState state) { - super(state); + super(state, null); } @Inject @@ -145,7 +145,6 @@ public class ScriptCodegen extends MemberCodegen { ImplementationBodyCodegen.generateInitializers( new ExpressionCodegen(instructionAdapter, frameMap, Type.VOID_TYPE, context, state), - instructionAdapter, scriptDeclaration.getDeclarations(), bindingContext, state); diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/TraitImplBodyCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/TraitImplBodyCodegen.java index 47042069858..1f04bcc9c5d 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/TraitImplBodyCodegen.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/TraitImplBodyCodegen.java @@ -16,7 +16,7 @@ package org.jetbrains.jet.codegen; -import org.jetbrains.jet.codegen.context.CodegenContext; +import org.jetbrains.jet.codegen.context.ClassContext; import org.jetbrains.jet.codegen.state.GenerationState; import org.jetbrains.jet.codegen.state.JetTypeMapperMode; import org.jetbrains.jet.lang.psi.JetClassOrObject; @@ -24,8 +24,8 @@ import org.jetbrains.jet.lang.psi.JetClassOrObject; import static org.jetbrains.asm4.Opcodes.*; public class TraitImplBodyCodegen extends ClassBodyCodegen { - public TraitImplBodyCodegen(JetClassOrObject aClass, CodegenContext context, ClassBuilder v, GenerationState state) { - super(aClass, context, v, state); + public TraitImplBodyCodegen(JetClassOrObject aClass, ClassContext context, ClassBuilder v, GenerationState state) { + super(aClass, context, v, state, null); } @Override diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/context/AnonymousClassContext.java b/compiler/backend/src/org/jetbrains/jet/codegen/context/AnonymousClassContext.java index f76eaf973ee..d3c5cbbb612 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/context/AnonymousClassContext.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/context/AnonymousClassContext.java @@ -22,9 +22,8 @@ import org.jetbrains.jet.codegen.OwnerKind; import org.jetbrains.jet.codegen.state.JetTypeMapper; import org.jetbrains.jet.lang.descriptors.ClassDescriptor; -import static org.jetbrains.jet.codegen.binding.CodegenBinding.CLOSURE; +public class AnonymousClassContext extends ClassContext { -public class AnonymousClassContext extends CodegenContext { public AnonymousClassContext( @NotNull JetTypeMapper typeMapper, @NotNull ClassDescriptor contextDescriptor, @@ -33,14 +32,7 @@ public class AnonymousClassContext extends CodegenContext { @Nullable LocalLookup localLookup ) { //noinspection SuspiciousMethodCalls - super(contextDescriptor, contextKind, parentContext, typeMapper.getBindingContext().get(CLOSURE, contextDescriptor), - contextDescriptor, localLookup); - initOuterExpression(typeMapper, contextDescriptor); - } - - @Override - public boolean isStatic() { - return false; + super(typeMapper, contextDescriptor, contextKind, parentContext, localLookup); } @Override diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/context/CodegenContext.java b/compiler/backend/src/org/jetbrains/jet/codegen/context/CodegenContext.java index 14a55244cbc..efd84a550fa 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/context/CodegenContext.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/context/CodegenContext.java @@ -146,31 +146,37 @@ public abstract class CodegenContext { return contextKind; } + @NotNull public CodegenContext intoNamespace(@NotNull NamespaceDescriptor descriptor) { return new NamespaceContext(descriptor, this, OwnerKind.NAMESPACE); } + @NotNull public CodegenContext intoNamespacePart(String delegateTo, NamespaceDescriptor descriptor) { return new NamespaceContext(descriptor, this, new OwnerKind.StaticDelegateKind(delegateTo)); } + @NotNull public ClassContext intoClass(ClassDescriptor descriptor, OwnerKind kind, GenerationState state) { return new ClassContext(state.getTypeMapper(), descriptor, kind, this, null); } - public CodegenContext intoAnonymousClass( - ClassDescriptor descriptor, - ExpressionCodegen expressionCodegen + @NotNull + public ClassContext intoAnonymousClass( + @NotNull ClassDescriptor descriptor, + @NotNull ExpressionCodegen expressionCodegen ) { JetTypeMapper typeMapper = expressionCodegen.getState().getTypeMapper(); return new AnonymousClassContext(typeMapper, descriptor, OwnerKind.IMPLEMENTATION, this, expressionCodegen); } + @NotNull public MethodContext intoFunction(FunctionDescriptor descriptor) { return new MethodContext(descriptor, getContextKind(), this); } + @NotNull public ConstructorContext intoConstructor(ConstructorDescriptor descriptor) { if (descriptor == null) { descriptor = new ConstructorDescriptorImpl(getThisDescriptor(), Collections.emptyList(), true) @@ -180,6 +186,7 @@ public abstract class CodegenContext { return new ConstructorContext(descriptor, getContextKind(), this); } + @NotNull public CodegenContext intoScript(@NotNull ScriptDescriptor script, @NotNull ClassDescriptor classDescriptor) { return new ScriptContext(script, classDescriptor, OwnerKind.IMPLEMENTATION, this, closure); } 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 d9606affaf0..119d1e12ce3 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/state/JetTypeMapper.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/state/JetTypeMapper.java @@ -28,6 +28,7 @@ import org.jetbrains.jet.codegen.context.EnclosedValueDescriptor; import org.jetbrains.jet.codegen.signature.*; import org.jetbrains.jet.lang.descriptors.*; import org.jetbrains.jet.lang.psi.JetDelegatorToSuperCall; +import org.jetbrains.jet.lang.psi.JetExpression; import org.jetbrains.jet.lang.psi.JetFile; import org.jetbrains.jet.lang.resolve.BindingContext; import org.jetbrains.jet.lang.resolve.BindingContextUtils; @@ -961,4 +962,15 @@ public class JetTypeMapper extends BindingTraceAware { } return new CallableMethod(owner, null, null, descriptor, INVOKEINTERFACE, owner, receiverParameterType, owner.getAsmType()); } + + @NotNull + public Type expressionType(JetExpression expr) { + JetType type = bindingContext.get(BindingContext.EXPRESSION_TYPE, expr); + return asmTypeOrVoid(type); + } + + @NotNull + private Type asmTypeOrVoid(@Nullable JetType type) { + return type == null ? Type.VOID_TYPE : mapType(type); + } } 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 d56b23b3cff..1aa0917c074 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetPsiUtil.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetPsiUtil.java @@ -553,6 +553,10 @@ public class JetPsiUtil { return getOutermostClassOrObject(classOrObject) == null; } + public static boolean isTrait(@NotNull JetClassOrObject classOrObject) { + return classOrObject instanceof JetClass && ((JetClass) classOrObject).isTrait(); + } + @Nullable public static JetClassOrObject getOutermostClassOrObject(@NotNull JetClassOrObject classOrObject) { JetClassOrObject current = classOrObject; 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 84dd2283356..ede955951da 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/DescriptorUtils.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/DescriptorUtils.java @@ -27,6 +27,7 @@ import org.jetbrains.jet.lang.descriptors.impl.AnonymousFunctionDescriptor; import org.jetbrains.jet.lang.descriptors.impl.NamespaceDescriptorParent; import org.jetbrains.jet.lang.psi.JetElement; import org.jetbrains.jet.lang.psi.JetFunction; +import org.jetbrains.jet.lang.psi.JetProperty; import org.jetbrains.jet.lang.resolve.constants.CompileTimeConstant; import org.jetbrains.jet.lang.resolve.name.FqName; import org.jetbrains.jet.lang.resolve.name.FqNameUnsafe; @@ -289,6 +290,10 @@ public class DescriptorUtils { return isKindOf(descriptor, ClassKind.ENUM_CLASS); } + public static boolean isClass(@NotNull DeclarationDescriptor descriptor) { + return isKindOf(descriptor, ClassKind.CLASS); + } + public static boolean isKindOf(@NotNull JetType jetType, @NotNull ClassKind classKind) { ClassifierDescriptor descriptor = jetType.getConstructor().getDeclarationDescriptor(); return isKindOf(descriptor, classKind); @@ -572,4 +577,13 @@ public class DescriptorUtils { } return allSuperclasses; } + + @NotNull + public static PropertyDescriptor getPropertyDescriptor(@NotNull JetProperty property, @NotNull BindingContext bindingContext) { + VariableDescriptor descriptor = bindingContext.get(BindingContext.VARIABLE, property); + if (!(descriptor instanceof PropertyDescriptor)) { + throw new UnsupportedOperationException("expect a property to have a property descriptor"); + } + return (PropertyDescriptor) descriptor; + } } From 4feb395dcc90bd1c154601d28d567c237588930b Mon Sep 17 00:00:00 2001 From: Mikhael Bogdanov Date: Mon, 3 Jun 2013 16:21:04 +0400 Subject: [PATCH 139/291] Test for static --- .../box/properties/classObjectProperties.kt | 58 +++++ .../staticFields/staticClassProperty.java | 8 + .../staticFields/staticClassProperty.kt | 9 + .../staticFields/staticTraitProperty.java | 8 + .../staticFields/staticTraitProperty.kt | 9 + .../classObjectInClassStaticFields.kt | 30 +++ .../classObjectInClassStaticFields.txt | 26 ++ .../classObjectInTraitStaticFields.kt | 30 +++ .../classObjectInTraitStaticFields.txt | 25 ++ .../class/delegatedProtectedVar.kt | 32 +++ .../classObject/class/delegatedPublicVal.kt | 27 +++ .../classObject/class/extensionPublicVal.kt | 13 + .../classObject/class/extensionPublicVar.kt | 13 + .../property/classObject/class/internalVal.kt | 13 + .../property/classObject/class/internalVar.kt | 13 + .../class/internalVarPrivateSet.kt | 14 ++ .../classObject/class/noBackingField.kt | 19 ++ .../property/classObject/class/privateVal.kt | 13 + .../property/classObject/class/privateVar.kt | 13 + .../classObject/class/protectedVal.kt | 13 + .../class/protectedVarPrivateSet.kt | 14 ++ .../property/classObject/class/publicVal.kt | 13 + .../classObject/class/publicValNonDefault.kt | 16 ++ .../property/classObject/class/publicVar.kt | 13 + .../classObject/class/publicVarNonDefault.kt | 16 ++ .../classObject/class/publicVarPrivateSet.kt | 14 ++ .../class/publicVarProtectedSet.kt | 14 ++ .../classObject/class/publicVarPublicSet.kt | 14 ++ .../trait/delegatedProtectedVar.kt | 32 +++ .../classObject/trait/delegatedPublicVal.kt | 27 +++ .../classObject/trait/extensionPublicVal.kt | 13 + .../classObject/trait/extensionPublicVar.kt | 13 + .../property/classObject/trait/internalVal.kt | 13 + .../property/classObject/trait/internalVar.kt | 13 + .../trait/internalVarPrivateSet.kt | 14 ++ .../classObject/trait/noBackingField.kt | 19 ++ .../property/classObject/trait/privateVal.kt | 13 + .../property/classObject/trait/privateVar.kt | 13 + .../classObject/trait/protectedVal.kt | 13 + .../trait/protectedVarPrivateSet.kt | 14 ++ .../property/classObject/trait/publicVal.kt | 13 + .../classObject/trait/publicValNonDefault.kt | 16 ++ .../property/classObject/trait/publicVar.kt | 13 + .../classObject/trait/publicVarNonDefault.kt | 16 ++ .../classObject/trait/publicVarPrivateSet.kt | 14 ++ .../trait/publicVarProtectedSet.kt | 14 ++ .../classObject/trait/publicVarPublicSet.kt | 14 ++ .../codegen/flags/AbstractWriteFlagsTest.java | 130 ++++++---- .../flags/WriteFlagsTestGenerated.java | 225 +++++++++++++++++- .../BlackBoxCodegenTestGenerated.java | 5 + ...CompileJavaAgainstKotlinTestGenerated.java | 21 +- .../LoadCompiledKotlinTestGenerated.java | 10 + ...esolveNamespaceComparingTestGenerated.java | 10 + 53 files changed, 1155 insertions(+), 43 deletions(-) create mode 100644 compiler/testData/codegen/box/properties/classObjectProperties.kt create mode 100644 compiler/testData/compileJavaAgainstKotlin/staticFields/staticClassProperty.java create mode 100644 compiler/testData/compileJavaAgainstKotlin/staticFields/staticClassProperty.kt create mode 100644 compiler/testData/compileJavaAgainstKotlin/staticFields/staticTraitProperty.java create mode 100644 compiler/testData/compileJavaAgainstKotlin/staticFields/staticTraitProperty.kt create mode 100644 compiler/testData/loadKotlin/classObject/classObjectInClassStaticFields.kt create mode 100644 compiler/testData/loadKotlin/classObject/classObjectInClassStaticFields.txt create mode 100644 compiler/testData/loadKotlin/classObject/classObjectInTraitStaticFields.kt create mode 100644 compiler/testData/loadKotlin/classObject/classObjectInTraitStaticFields.txt create mode 100644 compiler/testData/writeFlags/property/classObject/class/delegatedProtectedVar.kt create mode 100644 compiler/testData/writeFlags/property/classObject/class/delegatedPublicVal.kt create mode 100644 compiler/testData/writeFlags/property/classObject/class/extensionPublicVal.kt create mode 100644 compiler/testData/writeFlags/property/classObject/class/extensionPublicVar.kt create mode 100644 compiler/testData/writeFlags/property/classObject/class/internalVal.kt create mode 100644 compiler/testData/writeFlags/property/classObject/class/internalVar.kt create mode 100644 compiler/testData/writeFlags/property/classObject/class/internalVarPrivateSet.kt create mode 100644 compiler/testData/writeFlags/property/classObject/class/noBackingField.kt create mode 100644 compiler/testData/writeFlags/property/classObject/class/privateVal.kt create mode 100644 compiler/testData/writeFlags/property/classObject/class/privateVar.kt create mode 100644 compiler/testData/writeFlags/property/classObject/class/protectedVal.kt create mode 100644 compiler/testData/writeFlags/property/classObject/class/protectedVarPrivateSet.kt create mode 100644 compiler/testData/writeFlags/property/classObject/class/publicVal.kt create mode 100644 compiler/testData/writeFlags/property/classObject/class/publicValNonDefault.kt create mode 100644 compiler/testData/writeFlags/property/classObject/class/publicVar.kt create mode 100644 compiler/testData/writeFlags/property/classObject/class/publicVarNonDefault.kt create mode 100644 compiler/testData/writeFlags/property/classObject/class/publicVarPrivateSet.kt create mode 100644 compiler/testData/writeFlags/property/classObject/class/publicVarProtectedSet.kt create mode 100644 compiler/testData/writeFlags/property/classObject/class/publicVarPublicSet.kt create mode 100644 compiler/testData/writeFlags/property/classObject/trait/delegatedProtectedVar.kt create mode 100644 compiler/testData/writeFlags/property/classObject/trait/delegatedPublicVal.kt create mode 100644 compiler/testData/writeFlags/property/classObject/trait/extensionPublicVal.kt create mode 100644 compiler/testData/writeFlags/property/classObject/trait/extensionPublicVar.kt create mode 100644 compiler/testData/writeFlags/property/classObject/trait/internalVal.kt create mode 100644 compiler/testData/writeFlags/property/classObject/trait/internalVar.kt create mode 100644 compiler/testData/writeFlags/property/classObject/trait/internalVarPrivateSet.kt create mode 100644 compiler/testData/writeFlags/property/classObject/trait/noBackingField.kt create mode 100644 compiler/testData/writeFlags/property/classObject/trait/privateVal.kt create mode 100644 compiler/testData/writeFlags/property/classObject/trait/privateVar.kt create mode 100644 compiler/testData/writeFlags/property/classObject/trait/protectedVal.kt create mode 100644 compiler/testData/writeFlags/property/classObject/trait/protectedVarPrivateSet.kt create mode 100644 compiler/testData/writeFlags/property/classObject/trait/publicVal.kt create mode 100644 compiler/testData/writeFlags/property/classObject/trait/publicValNonDefault.kt create mode 100644 compiler/testData/writeFlags/property/classObject/trait/publicVar.kt create mode 100644 compiler/testData/writeFlags/property/classObject/trait/publicVarNonDefault.kt create mode 100644 compiler/testData/writeFlags/property/classObject/trait/publicVarPrivateSet.kt create mode 100644 compiler/testData/writeFlags/property/classObject/trait/publicVarProtectedSet.kt create mode 100644 compiler/testData/writeFlags/property/classObject/trait/publicVarPublicSet.kt diff --git a/compiler/testData/codegen/box/properties/classObjectProperties.kt b/compiler/testData/codegen/box/properties/classObjectProperties.kt new file mode 100644 index 00000000000..17afac79eb2 --- /dev/null +++ b/compiler/testData/codegen/box/properties/classObjectProperties.kt @@ -0,0 +1,58 @@ +class Test { + + class object { + + public val prop1 : Int = 10 + + public var prop2 : Int = 11 + protected set + + public val prop3: Int = 12 + get() { + return $prop3 + } + + var prop4 : Int = 13 + + fun incProp4() { + $prop4++ + } + + + public var prop5 : Int = 14 + + public var prop7 : Int = 20 + set(i: Int) { + $prop7++ + } + } + +} + + +fun box(): String { + val t = Test; + + if (t.prop1 != 10) return "fail1"; + + if (t.prop2 != 11) return "fail2"; + + if (t.prop3 != 12) return "fail3"; + + if (t.prop4 != 13) return "fail4"; + + t.incProp4() + if (t.prop4 != 14) return "fail4.inc"; + + if (t.prop5 != 14) return "fail5"; + + t.prop5 = 1414 + if (t.prop5 != 1414) return "fail6"; + + if (t.prop7 != 20) return "fail7"; + + t.prop7 = 1000000 + if (t.prop7 != 21) return "fail8"; + + return "OK" +} \ No newline at end of file diff --git a/compiler/testData/compileJavaAgainstKotlin/staticFields/staticClassProperty.java b/compiler/testData/compileJavaAgainstKotlin/staticFields/staticClassProperty.java new file mode 100644 index 00000000000..7b4a231ad93 --- /dev/null +++ b/compiler/testData/compileJavaAgainstKotlin/staticFields/staticClassProperty.java @@ -0,0 +1,8 @@ +class staticProperty { + + public static void main(String[] args) { + int i = Test.valProp; + int j = Test.varProp; + Test.varProp = 100; + } +} \ No newline at end of file diff --git a/compiler/testData/compileJavaAgainstKotlin/staticFields/staticClassProperty.kt b/compiler/testData/compileJavaAgainstKotlin/staticFields/staticClassProperty.kt new file mode 100644 index 00000000000..30261421a54 --- /dev/null +++ b/compiler/testData/compileJavaAgainstKotlin/staticFields/staticClassProperty.kt @@ -0,0 +1,9 @@ +class Test { + + class object { + public val valProp: Int = 10 + + public var varProp: Int = 10 + } + +} \ No newline at end of file diff --git a/compiler/testData/compileJavaAgainstKotlin/staticFields/staticTraitProperty.java b/compiler/testData/compileJavaAgainstKotlin/staticFields/staticTraitProperty.java new file mode 100644 index 00000000000..7b4a231ad93 --- /dev/null +++ b/compiler/testData/compileJavaAgainstKotlin/staticFields/staticTraitProperty.java @@ -0,0 +1,8 @@ +class staticProperty { + + public static void main(String[] args) { + int i = Test.valProp; + int j = Test.varProp; + Test.varProp = 100; + } +} \ No newline at end of file diff --git a/compiler/testData/compileJavaAgainstKotlin/staticFields/staticTraitProperty.kt b/compiler/testData/compileJavaAgainstKotlin/staticFields/staticTraitProperty.kt new file mode 100644 index 00000000000..19d8e7c1fa2 --- /dev/null +++ b/compiler/testData/compileJavaAgainstKotlin/staticFields/staticTraitProperty.kt @@ -0,0 +1,9 @@ +trait Test { + + class object { + public val valProp: Int = 10 + + public var varProp: Int = 10 + } + +} \ No newline at end of file diff --git a/compiler/testData/loadKotlin/classObject/classObjectInClassStaticFields.kt b/compiler/testData/loadKotlin/classObject/classObjectInClassStaticFields.kt new file mode 100644 index 00000000000..70b2b81f04c --- /dev/null +++ b/compiler/testData/loadKotlin/classObject/classObjectInClassStaticFields.kt @@ -0,0 +1,30 @@ +package test + +class Test { + + class object { + + public val prop1 : Int = 10 + + public var prop2 : Int = 11 + protected set + + public val prop3: Int = 12 + get() { + return $prop3 + } + + var prop4 : Int = 13 + + fun incProp4() { + $prop4++ + } + + public var prop5 : Int = 14 + + public var prop7 : Int = 20 + set(i: Int) { + $prop7++ + } + } +} \ No newline at end of file diff --git a/compiler/testData/loadKotlin/classObject/classObjectInClassStaticFields.txt b/compiler/testData/loadKotlin/classObject/classObjectInClassStaticFields.txt new file mode 100644 index 00000000000..d75e4b1e99c --- /dev/null +++ b/compiler/testData/loadKotlin/classObject/classObjectInClassStaticFields.txt @@ -0,0 +1,26 @@ +package test + +internal final class Test { + /*primary*/ public constructor Test() + + internal class object { + /*primary*/ private constructor () + public final val prop1: jet.Int + public final fun (): jet.Int + public final var prop2: jet.Int + public final fun (): jet.Int + protected final fun (/*0*/ : jet.Int): jet.Unit + public final val prop3: jet.Int + public final fun (): jet.Int + internal final var prop4: jet.Int + internal final fun (): jet.Int + internal final fun (/*0*/ : jet.Int): jet.Unit + public final var prop5: jet.Int + public final fun (): jet.Int + public final fun (/*0*/ : jet.Int): jet.Unit + public final var prop7: jet.Int + public final fun (): jet.Int + public final fun (/*0*/ i: jet.Int): jet.Unit + internal final fun incProp4(): jet.Unit + } +} diff --git a/compiler/testData/loadKotlin/classObject/classObjectInTraitStaticFields.kt b/compiler/testData/loadKotlin/classObject/classObjectInTraitStaticFields.kt new file mode 100644 index 00000000000..395d216fc20 --- /dev/null +++ b/compiler/testData/loadKotlin/classObject/classObjectInTraitStaticFields.kt @@ -0,0 +1,30 @@ +package test + +trait Test { + + class object { + + public val prop1 : Int = 10 + + public var prop2 : Int = 11 + protected set + + public val prop3: Int = 12 + get() { + return $prop3 + } + + var prop4 : Int = 13 + + fun incProp4() { + $prop4++ + } + + public var prop5 : Int = 14 + + public var prop7 : Int = 20 + set(i: Int) { + $prop7++ + } + } +} \ No newline at end of file diff --git a/compiler/testData/loadKotlin/classObject/classObjectInTraitStaticFields.txt b/compiler/testData/loadKotlin/classObject/classObjectInTraitStaticFields.txt new file mode 100644 index 00000000000..e4687a6dc33 --- /dev/null +++ b/compiler/testData/loadKotlin/classObject/classObjectInTraitStaticFields.txt @@ -0,0 +1,25 @@ +package test + +internal trait Test { + + internal class object { + /*primary*/ private constructor () + public final val prop1: jet.Int + public final fun (): jet.Int + public final var prop2: jet.Int + public final fun (): jet.Int + protected final fun (/*0*/ : jet.Int): jet.Unit + public final val prop3: jet.Int + public final fun (): jet.Int + internal final var prop4: jet.Int + internal final fun (): jet.Int + internal final fun (/*0*/ : jet.Int): jet.Unit + public final var prop5: jet.Int + public final fun (): jet.Int + public final fun (/*0*/ : jet.Int): jet.Unit + public final var prop7: jet.Int + public final fun (): jet.Int + public final fun (/*0*/ i: jet.Int): jet.Unit + internal final fun incProp4(): jet.Unit + } +} diff --git a/compiler/testData/writeFlags/property/classObject/class/delegatedProtectedVar.kt b/compiler/testData/writeFlags/property/classObject/class/delegatedProtectedVar.kt new file mode 100644 index 00000000000..8d0fa5bb006 --- /dev/null +++ b/compiler/testData/writeFlags/property/classObject/class/delegatedProtectedVar.kt @@ -0,0 +1,32 @@ +class TestDelegate() { + fun get(thisRef: Any?, desc: PropertyMetadata): Int { + return 10 + } + + public open fun set(thisRef: Any?, desc: PropertyMetadata, svalue : Int) { + + } +} + + +class Test { + class object { + protected var prop: Int by TestDelegate() + } +} + +// TESTED_OBJECT_KIND: property +// TESTED_OBJECTS: Test, prop +// ABSENT: TRUE + +// TESTED_OBJECT_KIND: property +// TESTED_OBJECTS: Test$object, prop +// ABSENT: TRUE + +// TESTED_OBJECT_KIND: property +// TESTED_OBJECTS: Test$object, prop$delegate +// ABSENT: TRUE + +// TESTED_OBJECT_KIND: property +// TESTED_OBJECTS: Test, prop$delegate +// FLAGS: ACC_STATIC, ACC_FINAL, ACC_PRIVATE diff --git a/compiler/testData/writeFlags/property/classObject/class/delegatedPublicVal.kt b/compiler/testData/writeFlags/property/classObject/class/delegatedPublicVal.kt new file mode 100644 index 00000000000..bf44cb09219 --- /dev/null +++ b/compiler/testData/writeFlags/property/classObject/class/delegatedPublicVal.kt @@ -0,0 +1,27 @@ +class TestDelegate() { + fun get(thisRef: Any?, desc: PropertyMetadata): Int { + return 10 + } +} + +class Test { + class object { + public val prop: Int by TestDelegate() + } +} + +// TESTED_OBJECT_KIND: property +// TESTED_OBJECTS: Test, prop +// ABSENT: TRUE + +// TESTED_OBJECT_KIND: property +// TESTED_OBJECTS: Test$object, prop +// ABSENT: TRUE + +// TESTED_OBJECT_KIND: property +// TESTED_OBJECTS: Test$object, prop$delegate +// ABSENT: TRUE + +// TESTED_OBJECT_KIND: property +// TESTED_OBJECTS: Test, prop$delegate +// FLAGS: ACC_STATIC, ACC_FINAL, ACC_PRIVATE diff --git a/compiler/testData/writeFlags/property/classObject/class/extensionPublicVal.kt b/compiler/testData/writeFlags/property/classObject/class/extensionPublicVal.kt new file mode 100644 index 00000000000..ade829c8e40 --- /dev/null +++ b/compiler/testData/writeFlags/property/classObject/class/extensionPublicVal.kt @@ -0,0 +1,13 @@ +class Test { + class object { + public val Test.prop: Int = 0; + } +} + +// TESTED_OBJECT_KIND: property +// TESTED_OBJECTS: Test, prop +// FLAGS: ACC_FINAL, ACC_STATIC, ACC_PRIVATE + +// TESTED_OBJECT_KIND: property +// TESTED_OBJECTS: Test$object, prop +// ABSENT: TRUE \ No newline at end of file diff --git a/compiler/testData/writeFlags/property/classObject/class/extensionPublicVar.kt b/compiler/testData/writeFlags/property/classObject/class/extensionPublicVar.kt new file mode 100644 index 00000000000..a7ce2e266ee --- /dev/null +++ b/compiler/testData/writeFlags/property/classObject/class/extensionPublicVar.kt @@ -0,0 +1,13 @@ +class Test { + class object { + public var Test.prop: Int = 0; + } +} + +// TESTED_OBJECT_KIND: property +// TESTED_OBJECTS: Test, prop +// FLAGS: ACC_STATIC, ACC_PRIVATE + +// TESTED_OBJECT_KIND: property +// TESTED_OBJECTS: Test$object, prop +// ABSENT: TRUE \ No newline at end of file diff --git a/compiler/testData/writeFlags/property/classObject/class/internalVal.kt b/compiler/testData/writeFlags/property/classObject/class/internalVal.kt new file mode 100644 index 00000000000..b9165253dca --- /dev/null +++ b/compiler/testData/writeFlags/property/classObject/class/internalVal.kt @@ -0,0 +1,13 @@ +class Test { + class object { + var prop: Int = 0; + } +} + +// TESTED_OBJECT_KIND: property +// TESTED_OBJECTS: Test, prop +// FLAGS: ACC_STATIC, ACC_PUBLIC + +// TESTED_OBJECT_KIND: property +// TESTED_OBJECTS: Test$object, prop +// ABSENT: TRUE diff --git a/compiler/testData/writeFlags/property/classObject/class/internalVar.kt b/compiler/testData/writeFlags/property/classObject/class/internalVar.kt new file mode 100644 index 00000000000..b9165253dca --- /dev/null +++ b/compiler/testData/writeFlags/property/classObject/class/internalVar.kt @@ -0,0 +1,13 @@ +class Test { + class object { + var prop: Int = 0; + } +} + +// TESTED_OBJECT_KIND: property +// TESTED_OBJECTS: Test, prop +// FLAGS: ACC_STATIC, ACC_PUBLIC + +// TESTED_OBJECT_KIND: property +// TESTED_OBJECTS: Test$object, prop +// ABSENT: TRUE diff --git a/compiler/testData/writeFlags/property/classObject/class/internalVarPrivateSet.kt b/compiler/testData/writeFlags/property/classObject/class/internalVarPrivateSet.kt new file mode 100644 index 00000000000..f55b91a1102 --- /dev/null +++ b/compiler/testData/writeFlags/property/classObject/class/internalVarPrivateSet.kt @@ -0,0 +1,14 @@ +class Test { + class object { + var prop: Int = 0 + private set + } +} + +// TESTED_OBJECT_KIND: property +// TESTED_OBJECTS: Test, prop +// FLAGS: ACC_STATIC, ACC_PRIVATE + +// TESTED_OBJECT_KIND: property +// TESTED_OBJECTS: Test$object, prop +// ABSENT: TRUE \ No newline at end of file diff --git a/compiler/testData/writeFlags/property/classObject/class/noBackingField.kt b/compiler/testData/writeFlags/property/classObject/class/noBackingField.kt new file mode 100644 index 00000000000..44287db4f69 --- /dev/null +++ b/compiler/testData/writeFlags/property/classObject/class/noBackingField.kt @@ -0,0 +1,19 @@ +class Test { + class object { + var prop: Int + get() { + return 10 + } + set(i : Int) { + + } + } +} + +// TESTED_OBJECT_KIND: property +// TESTED_OBJECTS: Test, prop +// ABSENT: TRUE + +// TESTED_OBJECT_KIND: property +// TESTED_OBJECTS: Test$object, prop +// ABSENT: TRUE diff --git a/compiler/testData/writeFlags/property/classObject/class/privateVal.kt b/compiler/testData/writeFlags/property/classObject/class/privateVal.kt new file mode 100644 index 00000000000..a38e09beba5 --- /dev/null +++ b/compiler/testData/writeFlags/property/classObject/class/privateVal.kt @@ -0,0 +1,13 @@ +class Test { + class object { + private val prop = 0; + } +} + +// TESTED_OBJECT_KIND: property +// TESTED_OBJECTS: Test, prop +// FLAGS: ACC_STATIC, ACC_PRIVATE, ACC_FINAL + +// TESTED_OBJECT_KIND: property +// TESTED_OBJECTS: Test$object, prop +// ABSENT: TRUE \ No newline at end of file diff --git a/compiler/testData/writeFlags/property/classObject/class/privateVar.kt b/compiler/testData/writeFlags/property/classObject/class/privateVar.kt new file mode 100644 index 00000000000..9c5aea21403 --- /dev/null +++ b/compiler/testData/writeFlags/property/classObject/class/privateVar.kt @@ -0,0 +1,13 @@ +class Test { + class object { + private var prop = 0; + } +} + +// TESTED_OBJECT_KIND: property +// TESTED_OBJECTS: Test, prop +// FLAGS: ACC_STATIC, ACC_PRIVATE + +// TESTED_OBJECT_KIND: property +// TESTED_OBJECTS: Test$object, prop +// ABSENT: TRUE \ No newline at end of file diff --git a/compiler/testData/writeFlags/property/classObject/class/protectedVal.kt b/compiler/testData/writeFlags/property/classObject/class/protectedVal.kt new file mode 100644 index 00000000000..974c2c68d72 --- /dev/null +++ b/compiler/testData/writeFlags/property/classObject/class/protectedVal.kt @@ -0,0 +1,13 @@ +class Test { + class object { + protected val prop: Int = 0; + } +} + +// TESTED_OBJECT_KIND: property +// TESTED_OBJECTS: Test, prop +// FLAGS: ACC_STATIC, ACC_PROTECTED, ACC_FINAL + +// TESTED_OBJECT_KIND: property +// TESTED_OBJECTS: Test$object, prop +// ABSENT: TRUE \ No newline at end of file diff --git a/compiler/testData/writeFlags/property/classObject/class/protectedVarPrivateSet.kt b/compiler/testData/writeFlags/property/classObject/class/protectedVarPrivateSet.kt new file mode 100644 index 00000000000..65e5efddbf8 --- /dev/null +++ b/compiler/testData/writeFlags/property/classObject/class/protectedVarPrivateSet.kt @@ -0,0 +1,14 @@ +class Test { + class object { + protected var prop: Int = 0 + private set + } +} + +// TESTED_OBJECT_KIND: property +// TESTED_OBJECTS: Test, prop +// FLAGS: ACC_STATIC, ACC_PRIVATE + +// TESTED_OBJECT_KIND: property +// TESTED_OBJECTS: Test$object, prop +// ABSENT: TRUE diff --git a/compiler/testData/writeFlags/property/classObject/class/publicVal.kt b/compiler/testData/writeFlags/property/classObject/class/publicVal.kt new file mode 100644 index 00000000000..3b8abf2797d --- /dev/null +++ b/compiler/testData/writeFlags/property/classObject/class/publicVal.kt @@ -0,0 +1,13 @@ +class Test { + class object { + public val prop: Int = 0; + } +} + +// TESTED_OBJECT_KIND: property +// TESTED_OBJECTS: Test, prop +// FLAGS: ACC_STATIC, ACC_PUBLIC, ACC_FINAL + +// TESTED_OBJECT_KIND: property +// TESTED_OBJECTS: Test$object, prop +// ABSENT: TRUE \ No newline at end of file diff --git a/compiler/testData/writeFlags/property/classObject/class/publicValNonDefault.kt b/compiler/testData/writeFlags/property/classObject/class/publicValNonDefault.kt new file mode 100644 index 00000000000..d25a4c26e20 --- /dev/null +++ b/compiler/testData/writeFlags/property/classObject/class/publicValNonDefault.kt @@ -0,0 +1,16 @@ +class Test { + class object { + public val prop: Int = 0 + get() { + return $prop + } + } +} + +// TESTED_OBJECT_KIND: property +// TESTED_OBJECTS: Test, prop +// FLAGS: ACC_STATIC, ACC_PRIVATE, ACC_FINAL + +// TESTED_OBJECT_KIND: property +// TESTED_OBJECTS: Test$object, prop +// ABSENT: TRUE \ No newline at end of file diff --git a/compiler/testData/writeFlags/property/classObject/class/publicVar.kt b/compiler/testData/writeFlags/property/classObject/class/publicVar.kt new file mode 100644 index 00000000000..a487d869eb4 --- /dev/null +++ b/compiler/testData/writeFlags/property/classObject/class/publicVar.kt @@ -0,0 +1,13 @@ +class Test { + class object { + public var prop: Int = 0; + } +} + +// TESTED_OBJECT_KIND: property +// TESTED_OBJECTS: Test, prop +// FLAGS: ACC_STATIC, ACC_PUBLIC + +// TESTED_OBJECT_KIND: property +// TESTED_OBJECTS: Test$object, prop +// ABSENT: TRUE \ No newline at end of file diff --git a/compiler/testData/writeFlags/property/classObject/class/publicVarNonDefault.kt b/compiler/testData/writeFlags/property/classObject/class/publicVarNonDefault.kt new file mode 100644 index 00000000000..704581972b3 --- /dev/null +++ b/compiler/testData/writeFlags/property/classObject/class/publicVarNonDefault.kt @@ -0,0 +1,16 @@ +class Test { + class object { + public var prop: Int = 0 + set(i : Int) { + $prop = i + } + } +} + +// TESTED_OBJECT_KIND: property +// TESTED_OBJECTS: Test, prop +// FLAGS: ACC_STATIC, ACC_PRIVATE + +// TESTED_OBJECT_KIND: property +// TESTED_OBJECTS: Test$object, prop +// ABSENT: TRUE \ No newline at end of file diff --git a/compiler/testData/writeFlags/property/classObject/class/publicVarPrivateSet.kt b/compiler/testData/writeFlags/property/classObject/class/publicVarPrivateSet.kt new file mode 100644 index 00000000000..83f4a5c3a0f --- /dev/null +++ b/compiler/testData/writeFlags/property/classObject/class/publicVarPrivateSet.kt @@ -0,0 +1,14 @@ +class Test { + class object { + public var prop: Int = 0 + private set + } +} + +// TESTED_OBJECT_KIND: property +// TESTED_OBJECTS: Test, prop +// FLAGS: ACC_STATIC, ACC_PRIVATE + +// TESTED_OBJECT_KIND: property +// TESTED_OBJECTS: Test$object, prop +// ABSENT: TRUE \ No newline at end of file diff --git a/compiler/testData/writeFlags/property/classObject/class/publicVarProtectedSet.kt b/compiler/testData/writeFlags/property/classObject/class/publicVarProtectedSet.kt new file mode 100644 index 00000000000..a06c623f919 --- /dev/null +++ b/compiler/testData/writeFlags/property/classObject/class/publicVarProtectedSet.kt @@ -0,0 +1,14 @@ +class Test { + class object { + public var prop: Int = 0 + protected set + } +} + +// TESTED_OBJECT_KIND: property +// TESTED_OBJECTS: Test, prop +// FLAGS: ACC_STATIC, ACC_PROTECTED + +// TESTED_OBJECT_KIND: property +// TESTED_OBJECTS: Test$object, prop +// ABSENT: TRUE \ No newline at end of file diff --git a/compiler/testData/writeFlags/property/classObject/class/publicVarPublicSet.kt b/compiler/testData/writeFlags/property/classObject/class/publicVarPublicSet.kt new file mode 100644 index 00000000000..b068834c168 --- /dev/null +++ b/compiler/testData/writeFlags/property/classObject/class/publicVarPublicSet.kt @@ -0,0 +1,14 @@ +class Test { + class object { + public var prop: Int = 0 + public set + } +} + +// TESTED_OBJECT_KIND: property +// TESTED_OBJECTS: Test, prop +// FLAGS: ACC_STATIC, ACC_PUBLIC + +// TESTED_OBJECT_KIND: property +// TESTED_OBJECTS: Test$object, prop +// ABSENT: TRUE diff --git a/compiler/testData/writeFlags/property/classObject/trait/delegatedProtectedVar.kt b/compiler/testData/writeFlags/property/classObject/trait/delegatedProtectedVar.kt new file mode 100644 index 00000000000..2d2940c852a --- /dev/null +++ b/compiler/testData/writeFlags/property/classObject/trait/delegatedProtectedVar.kt @@ -0,0 +1,32 @@ +class TestDelegate() { + fun get(thisRef: Any?, desc: PropertyMetadata): Int { + return 10 + } + + public open fun set(thisRef: Any?, desc: PropertyMetadata, svalue : Int) { + + } +} + +trait Test { + class object { + protected var prop: Int by TestDelegate() + } +} + +// TESTED_OBJECT_KIND: property +// TESTED_OBJECTS: Test, prop +// ABSENT: TRUE + +// TESTED_OBJECT_KIND: property +// TESTED_OBJECTS: Test$object, prop +// ABSENT: TRUE + +// TESTED_OBJECT_KIND: property +// TESTED_OBJECTS: Test$object, prop$delegate +// FLAGS: ACC_FINAL, ACC_PRIVATE + +// TESTED_OBJECT_KIND: property +// TESTED_OBJECTS: Test, prop$delegate +// FLAGS: ACC_FINAL, ACC_PRIVATE +// ABSENT: TRUE \ No newline at end of file diff --git a/compiler/testData/writeFlags/property/classObject/trait/delegatedPublicVal.kt b/compiler/testData/writeFlags/property/classObject/trait/delegatedPublicVal.kt new file mode 100644 index 00000000000..67ebd828754 --- /dev/null +++ b/compiler/testData/writeFlags/property/classObject/trait/delegatedPublicVal.kt @@ -0,0 +1,27 @@ +class TestDelegate() { + fun get(thisRef: Any?, desc: PropertyMetadata): Int { + return 10 + } +} + +trait Test { + class object { + public val prop: Int by TestDelegate() + } +} + +// TESTED_OBJECT_KIND: property +// TESTED_OBJECTS: Test, prop +// ABSENT: TRUE + +// TESTED_OBJECT_KIND: property +// TESTED_OBJECTS: Test$object, prop +// ABSENT: TRUE + +// TESTED_OBJECT_KIND: property +// TESTED_OBJECTS: Test$object, prop$delegate +// FLAGS: ACC_FINAL, ACC_PRIVATE + +// TESTED_OBJECT_KIND: property +// TESTED_OBJECTS: Test, prop$delegate +// ABSENT: TRUE \ No newline at end of file diff --git a/compiler/testData/writeFlags/property/classObject/trait/extensionPublicVal.kt b/compiler/testData/writeFlags/property/classObject/trait/extensionPublicVal.kt new file mode 100644 index 00000000000..0f9fd18d933 --- /dev/null +++ b/compiler/testData/writeFlags/property/classObject/trait/extensionPublicVal.kt @@ -0,0 +1,13 @@ +trait Test { + class object { + public val Test.prop: Int = 0; + } +} + +// TESTED_OBJECT_KIND: property +// TESTED_OBJECTS: Test, prop +// ABSENT: TRUE + +// TESTED_OBJECT_KIND: property +// TESTED_OBJECTS: Test$object, prop +// FLAGS: ACC_FINAL, ACC_PRIVATE \ No newline at end of file diff --git a/compiler/testData/writeFlags/property/classObject/trait/extensionPublicVar.kt b/compiler/testData/writeFlags/property/classObject/trait/extensionPublicVar.kt new file mode 100644 index 00000000000..4fd4b033c49 --- /dev/null +++ b/compiler/testData/writeFlags/property/classObject/trait/extensionPublicVar.kt @@ -0,0 +1,13 @@ +trait Test { + class object { + public var Test.prop: Int = 0; + } +} + +// TESTED_OBJECT_KIND: property +// TESTED_OBJECTS: Test, prop +// ABSENT: TRUE + +// TESTED_OBJECT_KIND: property +// TESTED_OBJECTS: Test$object, prop +// FLAGS: ACC_PRIVATE \ No newline at end of file diff --git a/compiler/testData/writeFlags/property/classObject/trait/internalVal.kt b/compiler/testData/writeFlags/property/classObject/trait/internalVal.kt new file mode 100644 index 00000000000..f5b6ae2fd41 --- /dev/null +++ b/compiler/testData/writeFlags/property/classObject/trait/internalVal.kt @@ -0,0 +1,13 @@ +trait Test { + class object { + val prop: Int = 0; + } +} + +// TESTED_OBJECT_KIND: property +// TESTED_OBJECTS: Test, prop +// FLAGS: ACC_STATIC, ACC_PUBLIC, ACC_FINAL + +// TESTED_OBJECT_KIND: property +// TESTED_OBJECTS: Test$object, prop +// FLAGS: ACC_PRIVATE, ACC_FINAL \ No newline at end of file diff --git a/compiler/testData/writeFlags/property/classObject/trait/internalVar.kt b/compiler/testData/writeFlags/property/classObject/trait/internalVar.kt new file mode 100644 index 00000000000..d292799f925 --- /dev/null +++ b/compiler/testData/writeFlags/property/classObject/trait/internalVar.kt @@ -0,0 +1,13 @@ +trait Test { + class object { + var prop: Int = 0; + } +} + +// TESTED_OBJECT_KIND: property +// TESTED_OBJECTS: Test, prop +// ABSENT: TRUE + +// TESTED_OBJECT_KIND: property +// TESTED_OBJECTS: Test$object, prop +// FLAGS: ACC_PRIVATE diff --git a/compiler/testData/writeFlags/property/classObject/trait/internalVarPrivateSet.kt b/compiler/testData/writeFlags/property/classObject/trait/internalVarPrivateSet.kt new file mode 100644 index 00000000000..0264cad45c5 --- /dev/null +++ b/compiler/testData/writeFlags/property/classObject/trait/internalVarPrivateSet.kt @@ -0,0 +1,14 @@ +trait Test { + class object { + var prop: Int = 0 + private set + } +} + +// TESTED_OBJECT_KIND: property +// TESTED_OBJECTS: Test, prop +// ABSENT: TRUE + +// TESTED_OBJECT_KIND: property +// TESTED_OBJECTS: Test$object, prop +// FLAGS: ACC_PRIVATE \ No newline at end of file diff --git a/compiler/testData/writeFlags/property/classObject/trait/noBackingField.kt b/compiler/testData/writeFlags/property/classObject/trait/noBackingField.kt new file mode 100644 index 00000000000..34a12ca105b --- /dev/null +++ b/compiler/testData/writeFlags/property/classObject/trait/noBackingField.kt @@ -0,0 +1,19 @@ +trait Test { + class object { + var prop: Int + get() { + return 10 + } + set(i : Int) { + + } + } +} + +// TESTED_OBJECT_KIND: property +// TESTED_OBJECTS: Test, prop +// ABSENT: TRUE + +// TESTED_OBJECT_KIND: property +// TESTED_OBJECTS: Test$object, prop +// ABSENT: TRUE diff --git a/compiler/testData/writeFlags/property/classObject/trait/privateVal.kt b/compiler/testData/writeFlags/property/classObject/trait/privateVal.kt new file mode 100644 index 00000000000..f751ecb6822 --- /dev/null +++ b/compiler/testData/writeFlags/property/classObject/trait/privateVal.kt @@ -0,0 +1,13 @@ +trait Test { + class object { + private val prop = 0; + } +} + +// TESTED_OBJECT_KIND: property +// TESTED_OBJECTS: Test, prop +// ABSENT: TRUE + +// TESTED_OBJECT_KIND: property +// TESTED_OBJECTS: Test$object, prop +// FLAGS: ACC_PRIVATE, ACC_FINAL \ No newline at end of file diff --git a/compiler/testData/writeFlags/property/classObject/trait/privateVar.kt b/compiler/testData/writeFlags/property/classObject/trait/privateVar.kt new file mode 100644 index 00000000000..8f02ea9198e --- /dev/null +++ b/compiler/testData/writeFlags/property/classObject/trait/privateVar.kt @@ -0,0 +1,13 @@ +trait Test { + class object { + private var prop = 0; + } +} + +// TESTED_OBJECT_KIND: property +// TESTED_OBJECTS: Test, prop +// ABSENT: TRUE + +// TESTED_OBJECT_KIND: property +// TESTED_OBJECTS: Test$object, prop +// FLAGS: ACC_PRIVATE \ No newline at end of file diff --git a/compiler/testData/writeFlags/property/classObject/trait/protectedVal.kt b/compiler/testData/writeFlags/property/classObject/trait/protectedVal.kt new file mode 100644 index 00000000000..1a83c26b481 --- /dev/null +++ b/compiler/testData/writeFlags/property/classObject/trait/protectedVal.kt @@ -0,0 +1,13 @@ +trait Test { + class object { + protected val prop: Int = 0 + } +} + +// TESTED_OBJECT_KIND: property +// TESTED_OBJECTS: Test, prop +// ABSENT: TRUE + +// TESTED_OBJECT_KIND: property +// TESTED_OBJECTS: Test$object, prop +// FLAGS: ACC_PRIVATE, ACC_FINAL \ No newline at end of file diff --git a/compiler/testData/writeFlags/property/classObject/trait/protectedVarPrivateSet.kt b/compiler/testData/writeFlags/property/classObject/trait/protectedVarPrivateSet.kt new file mode 100644 index 00000000000..6baa56b9ba1 --- /dev/null +++ b/compiler/testData/writeFlags/property/classObject/trait/protectedVarPrivateSet.kt @@ -0,0 +1,14 @@ +trait Test { + class object { + protected var prop: Int = 0 + private set + } +} + +// TESTED_OBJECT_KIND: property +// TESTED_OBJECTS: Test, prop +// ABSENT: TRUE + +// TESTED_OBJECT_KIND: property +// TESTED_OBJECTS: Test$object, prop +// FLAGS: ACC_PRIVATE \ No newline at end of file diff --git a/compiler/testData/writeFlags/property/classObject/trait/publicVal.kt b/compiler/testData/writeFlags/property/classObject/trait/publicVal.kt new file mode 100644 index 00000000000..1a7541e66ca --- /dev/null +++ b/compiler/testData/writeFlags/property/classObject/trait/publicVal.kt @@ -0,0 +1,13 @@ +trait Test { + class object { + public val prop: Int = 0; + } +} + +// TESTED_OBJECT_KIND: property +// TESTED_OBJECTS: Test, prop +// FLAGS: ACC_STATIC, ACC_PUBLIC, ACC_FINAL + +// TESTED_OBJECT_KIND: property +// TESTED_OBJECTS: Test$object, prop +// FLAGS: ACC_PRIVATE, ACC_FINAL \ No newline at end of file diff --git a/compiler/testData/writeFlags/property/classObject/trait/publicValNonDefault.kt b/compiler/testData/writeFlags/property/classObject/trait/publicValNonDefault.kt new file mode 100644 index 00000000000..4fcca650f7d --- /dev/null +++ b/compiler/testData/writeFlags/property/classObject/trait/publicValNonDefault.kt @@ -0,0 +1,16 @@ +trait Test { + class object { + public val prop: Int = 0 + get() { + return $prop + } + } +} + +// TESTED_OBJECT_KIND: property +// TESTED_OBJECTS: Test, prop +// ABSENT: TRUE + +// TESTED_OBJECT_KIND: property +// TESTED_OBJECTS: Test$object, prop +// FLAGS: ACC_PRIVATE, ACC_FINAL \ No newline at end of file diff --git a/compiler/testData/writeFlags/property/classObject/trait/publicVar.kt b/compiler/testData/writeFlags/property/classObject/trait/publicVar.kt new file mode 100644 index 00000000000..02b1f3195f1 --- /dev/null +++ b/compiler/testData/writeFlags/property/classObject/trait/publicVar.kt @@ -0,0 +1,13 @@ +trait Test { + class object { + public var prop: Int = 0 + } +} + +// TESTED_OBJECT_KIND: property +// TESTED_OBJECTS: Test, prop +// ABSENT: TRUE + +// TESTED_OBJECT_KIND: property +// TESTED_OBJECTS: Test$object, prop +// FLAGS: ACC_PRIVATE \ No newline at end of file diff --git a/compiler/testData/writeFlags/property/classObject/trait/publicVarNonDefault.kt b/compiler/testData/writeFlags/property/classObject/trait/publicVarNonDefault.kt new file mode 100644 index 00000000000..d7a6267d384 --- /dev/null +++ b/compiler/testData/writeFlags/property/classObject/trait/publicVarNonDefault.kt @@ -0,0 +1,16 @@ +trait Test { + class object { + public var prop: Int = 0 + set(i : Int) { + $prop = i + } + } +} + +// TESTED_OBJECT_KIND: property +// TESTED_OBJECTS: Test, prop +// ABSENT: TRUE + +// TESTED_OBJECT_KIND: property +// TESTED_OBJECTS: Test$object, prop +// FLAGS: ACC_PRIVATE \ No newline at end of file diff --git a/compiler/testData/writeFlags/property/classObject/trait/publicVarPrivateSet.kt b/compiler/testData/writeFlags/property/classObject/trait/publicVarPrivateSet.kt new file mode 100644 index 00000000000..0d099680e5c --- /dev/null +++ b/compiler/testData/writeFlags/property/classObject/trait/publicVarPrivateSet.kt @@ -0,0 +1,14 @@ +trait Test { + class object { + public var prop: Int = 0 + private set + } +} + +// TESTED_OBJECT_KIND: property +// TESTED_OBJECTS: Test, prop +// ABSENT: TRUE + +// TESTED_OBJECT_KIND: property +// TESTED_OBJECTS: Test$object, prop +// FLAGS: ACC_PRIVATE \ No newline at end of file diff --git a/compiler/testData/writeFlags/property/classObject/trait/publicVarProtectedSet.kt b/compiler/testData/writeFlags/property/classObject/trait/publicVarProtectedSet.kt new file mode 100644 index 00000000000..765e9a3c1a8 --- /dev/null +++ b/compiler/testData/writeFlags/property/classObject/trait/publicVarProtectedSet.kt @@ -0,0 +1,14 @@ +trait Test { + class object { + public var prop: Int = 0 + protected set + } +} + +// TESTED_OBJECT_KIND: property +// TESTED_OBJECTS: Test, prop +// ABSENT: TRUE + +// TESTED_OBJECT_KIND: property +// TESTED_OBJECTS: Test$object, prop +// FLAGS: ACC_PRIVATE diff --git a/compiler/testData/writeFlags/property/classObject/trait/publicVarPublicSet.kt b/compiler/testData/writeFlags/property/classObject/trait/publicVarPublicSet.kt new file mode 100644 index 00000000000..d753c5bbae6 --- /dev/null +++ b/compiler/testData/writeFlags/property/classObject/trait/publicVarPublicSet.kt @@ -0,0 +1,14 @@ +trait Test { + class object { + public var prop: Int = 0 + public set + } +} + +// TESTED_OBJECT_KIND: property +// TESTED_OBJECTS: Test, prop +// ABSENT: TRUE + +// TESTED_OBJECT_KIND: property +// TESTED_OBJECTS: Test$object, prop +// FLAGS: ACC_PRIVATE diff --git a/compiler/tests/org/jetbrains/jet/codegen/flags/AbstractWriteFlagsTest.java b/compiler/tests/org/jetbrains/jet/codegen/flags/AbstractWriteFlagsTest.java index f18d9ca666b..cad9423b32d 100644 --- a/compiler/tests/org/jetbrains/jet/codegen/flags/AbstractWriteFlagsTest.java +++ b/compiler/tests/org/jetbrains/jet/codegen/flags/AbstractWriteFlagsTest.java @@ -29,6 +29,7 @@ import org.jetbrains.jet.lang.psi.JetFile; import java.io.File; import java.io.IOException; import java.lang.reflect.Field; +import java.util.ArrayList; import java.util.List; import static org.jetbrains.jet.InTextDirectivesUtils.findListWithPrefixes; @@ -39,7 +40,17 @@ import static org.jetbrains.jet.InTextDirectivesUtils.findStringWithPrefixes; * * TESTED_OBJECT_KIND - maybe class, function or property * TESTED_OBJECTS - className, [function/property name] - * FLAGS - only flags which must be true + * FLAGS - only flags which must be true (could be skipped if ABSENT is TRUE) + * ABSENT - true or false, optional (false by default) + * + * There is could be specified several tested objects separated by empty line, e.g: + * TESTED_OBJECT_KIND: property + * TESTED_OBJECTS: Test$object, prop + * ABSENT: TRUE + * + * TESTED_OBJECT_KIND: property + * TESTED_OBJECTS: Test, prop$delegate + * FLAGS: ACC_STATIC, ACC_FINAL, ACC_PRIVATE */ public abstract class AbstractWriteFlagsTest extends UsefulTestCase { @@ -61,59 +72,78 @@ public abstract class AbstractWriteFlagsTest extends UsefulTestCase { File ktFile = new File(path); assertTrue("Cannot find a file " + ktFile.getAbsolutePath(), ktFile.exists()); - String fileText = FileUtil.loadFile(ktFile); + String fileText = FileUtil.loadFile(ktFile, true); JetFile psiFile = JetTestUtils.createFile(ktFile.getName(), fileText, jetCoreEnvironment.getProject()); assertTrue("Cannot create JetFile from text", psiFile != null); ClassFileFactory factory = GenerationUtils.compileFileGetClassFileFactoryForTest(psiFile); - TestedObject testedObject = parseExpectedTestedObject(fileText); - - String className = null; - for (String filename : factory.files()) { - if (testedObject.isFullContainingClassName && filename.equals(testedObject.containingClass + ".class")) { - className = filename; + List testedObjects = parseExpectedTestedObject(fileText); + for (TestedObject testedObject : testedObjects) { + String className = null; + for (String filename : factory.files()) { + if (testedObject.isFullContainingClassName && filename.equals(testedObject.containingClass + ".class")) { + className = filename; + } + else if (!testedObject.isFullContainingClassName && filename.startsWith(testedObject.containingClass)) { + className = filename; + } } - else if (!testedObject.isFullContainingClassName && filename.startsWith(testedObject.containingClass)) { - className = filename; + + if (className == null) { + throw new AssertionError("Couldn't find a class file with name " + testedObject.containingClass); + } + + ClassReader cr = new ClassReader(factory.asBytes(className)); + TestClassVisitor classVisitor; + classVisitor = getClassVisitor(testedObject.kind, testedObject.name); + cr.accept(classVisitor, ClassReader.SKIP_CODE); + + boolean isObjectExists = false == Boolean.valueOf(findStringWithPrefixes(testedObject.textData, "// ABSENT: ")); + assertEquals( "Wrong object existence state: " + testedObject, isObjectExists, classVisitor.isExists()); + int expectedAccess = getExpectedFlags(testedObject.textData); + + if (isObjectExists) { + assertEquals("Wrong access flag \n" + factory.asText(className), expectedAccess, classVisitor.getAccess()); } } - - if (className == null) { - throw new AssertionError("Couldn't find a class file with name " + testedObject.containingClass); - } - - ClassReader cr = new ClassReader(factory.asBytes(className)); - TestClassVisitor classVisitor; - classVisitor = getClassVisitor(testedObject.kind, testedObject.name); - cr.accept(classVisitor, ClassReader.SKIP_CODE); - int expectedAccess = getExpectedFlags(fileText); - assertEquals("Wrong access flag \n" + factory.asText(className), expectedAccess, classVisitor.getAccess()); } - private static TestedObject parseExpectedTestedObject(String fileText) { - TestedObject result = new TestedObject(); - List testedObjects = findListWithPrefixes(fileText, "// TESTED_OBJECTS: "); - assertTrue("Cannot find TESTED_OBJECTS instruction", !testedObjects.isEmpty()); - result.containingClass = testedObjects.get(0); - if (testedObjects.size() == 1) { - result.name = testedObjects.get(0); - } - else if (testedObjects.size() == 2) { - result.name = testedObjects.get(1); - } - else { - throw new IllegalArgumentException( - "TESTED_OBJECTS instruction must contains one (for class) or two (for function and property) values"); - } + private static List parseExpectedTestedObject(String testDescription) { + testDescription = testDescription.substring(testDescription.indexOf("// TESTED_OBJECT_KIND")); + String [] testObjectData = testDescription.split("\n\n"); + ArrayList objects = new ArrayList(); - result.kind = findStringWithPrefixes(fileText, "// TESTED_OBJECT_KIND: "); - List isFullName = findListWithPrefixes(fileText, "// IS_FULL_CONTAINING_CLASS_NAME: "); - if (isFullName.size() == 1) { - result.isFullContainingClassName = Boolean.parseBoolean(isFullName.get(0)); + for (int i = 0; i < testObjectData.length; i++) { + String testData = testObjectData[i]; + if (!testData.isEmpty()) { + TestedObject testObject = new TestedObject(); + testObject.textData = testData; + List testedObjects = findListWithPrefixes(testData, "// TESTED_OBJECTS: "); + assertTrue("Cannot find TESTED_OBJECTS instruction", !testedObjects.isEmpty()); + testObject.containingClass = testedObjects.get(0); + if (testedObjects.size() == 1) { + testObject.name = testedObjects.get(0); + } + else if (testedObjects.size() == 2) { + testObject.name = testedObjects.get(1); + } + else { + throw new IllegalArgumentException( + "TESTED_OBJECTS instruction must contains one (for class) or two (for function and property) values"); + } + + testObject.kind = findStringWithPrefixes(testData, "// TESTED_OBJECT_KIND: "); + List isFullName = findListWithPrefixes(testData, "// IS_FULL_CONTAINING_CLASS_NAME: "); + if (isFullName.size() == 1) { + testObject.isFullContainingClassName = Boolean.parseBoolean(isFullName.get(0)); + } + objects.add(testObject); + } } - return result; + assertTrue("Test description not present!", !objects.isEmpty()); + return objects; } private static class TestedObject { @@ -121,6 +151,12 @@ public abstract class AbstractWriteFlagsTest extends UsefulTestCase { public String containingClass = ""; public boolean isFullContainingClassName = true; public String kind; + public String textData; + + @Override + public String toString() { + return "Class = " + containingClass + ", name = " + name + ", kind = " + kind; + } } private static TestClassVisitor getClassVisitor(String visitorKind, String testedObjectName) { @@ -136,15 +172,23 @@ public abstract class AbstractWriteFlagsTest extends UsefulTestCase { else if (visitorKind.equals("innerClass")) { return new InnerClassFlagsVisitor(testedObjectName); } + throw new IllegalArgumentException("Value of TESTED_OBJECT_KIND is incorrect: " + visitorKind); } protected static abstract class TestClassVisitor extends ClassVisitor { + + protected boolean isExists; + public TestClassVisitor() { super(Opcodes.ASM4); } abstract public int getAccess(); + + public boolean isExists() { + return isExists; + } } private static int getExpectedFlags(String text) { @@ -172,6 +216,7 @@ public abstract class AbstractWriteFlagsTest extends UsefulTestCase { @Override public void visit(int version, int access, String name, String signature, String superName, String[] interfaces) { this.access = access; + isExists = true; } @Override @@ -192,6 +237,7 @@ public abstract class AbstractWriteFlagsTest extends UsefulTestCase { public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) { if (name.equals(funName)) { this.access = access; + isExists = true; } return null; } @@ -214,6 +260,7 @@ public abstract class AbstractWriteFlagsTest extends UsefulTestCase { public FieldVisitor visitField(int access, String name, String desc, String signature, Object value) { if (name.equals(propertyName)) { this.access = access; + isExists = true; } return null; } @@ -236,6 +283,7 @@ public abstract class AbstractWriteFlagsTest extends UsefulTestCase { public void visitInnerClass(String innerClassInternalName, String outerClassInternalName, String name, int access) { if (name.equals(innerClassName)) { this.access = access; + isExists = true; } } diff --git a/compiler/tests/org/jetbrains/jet/codegen/flags/WriteFlagsTestGenerated.java b/compiler/tests/org/jetbrains/jet/codegen/flags/WriteFlagsTestGenerated.java index a71dae112dc..245663a34e8 100644 --- a/compiler/tests/org/jetbrains/jet/codegen/flags/WriteFlagsTestGenerated.java +++ b/compiler/tests/org/jetbrains/jet/codegen/flags/WriteFlagsTestGenerated.java @@ -466,12 +466,234 @@ public class WriteFlagsTestGenerated extends AbstractWriteFlagsTest { } @TestMetadata("compiler/testData/writeFlags/property") - @InnerTestClasses({Property.DeprecatedFlag.class, Property.Visibility.class}) + @InnerTestClasses({Property.ClassObject.class, Property.DeprecatedFlag.class, Property.Visibility.class}) public static class Property extends AbstractWriteFlagsTest { public void testAllFilesPresentInProperty() throws Exception { JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.GenerateTests", new File("compiler/testData/writeFlags/property"), Pattern.compile("^(.+)\\.kt$"), true); } + @TestMetadata("compiler/testData/writeFlags/property/classObject") + @InnerTestClasses({ClassObject.Class.class, ClassObject.Trait.class}) + public static class ClassObject extends AbstractWriteFlagsTest { + public void testAllFilesPresentInClassObject() throws Exception { + JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.GenerateTests", new File("compiler/testData/writeFlags/property/classObject"), Pattern.compile("^(.+)\\.kt$"), true); + } + + @TestMetadata("compiler/testData/writeFlags/property/classObject/class") + public static class Class extends AbstractWriteFlagsTest { + public void testAllFilesPresentInClass() throws Exception { + JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.GenerateTests", new File("compiler/testData/writeFlags/property/classObject/class"), Pattern.compile("^(.+)\\.kt$"), true); + } + + @TestMetadata("delegatedProtectedVar.kt") + public void testDelegatedProtectedVar() throws Exception { + doTest("compiler/testData/writeFlags/property/classObject/class/delegatedProtectedVar.kt"); + } + + @TestMetadata("delegatedPublicVal.kt") + public void testDelegatedPublicVal() throws Exception { + doTest("compiler/testData/writeFlags/property/classObject/class/delegatedPublicVal.kt"); + } + + @TestMetadata("extensionPublicVal.kt") + public void testExtensionPublicVal() throws Exception { + doTest("compiler/testData/writeFlags/property/classObject/class/extensionPublicVal.kt"); + } + + @TestMetadata("extensionPublicVar.kt") + public void testExtensionPublicVar() throws Exception { + doTest("compiler/testData/writeFlags/property/classObject/class/extensionPublicVar.kt"); + } + + @TestMetadata("internalVal.kt") + public void testInternalVal() throws Exception { + doTest("compiler/testData/writeFlags/property/classObject/class/internalVal.kt"); + } + + @TestMetadata("internalVar.kt") + public void testInternalVar() throws Exception { + doTest("compiler/testData/writeFlags/property/classObject/class/internalVar.kt"); + } + + @TestMetadata("internalVarPrivateSet.kt") + public void testInternalVarPrivateSet() throws Exception { + doTest("compiler/testData/writeFlags/property/classObject/class/internalVarPrivateSet.kt"); + } + + @TestMetadata("noBackingField.kt") + public void testNoBackingField() throws Exception { + doTest("compiler/testData/writeFlags/property/classObject/class/noBackingField.kt"); + } + + @TestMetadata("privateVal.kt") + public void testPrivateVal() throws Exception { + doTest("compiler/testData/writeFlags/property/classObject/class/privateVal.kt"); + } + + @TestMetadata("privateVar.kt") + public void testPrivateVar() throws Exception { + doTest("compiler/testData/writeFlags/property/classObject/class/privateVar.kt"); + } + + @TestMetadata("protectedVal.kt") + public void testProtectedVal() throws Exception { + doTest("compiler/testData/writeFlags/property/classObject/class/protectedVal.kt"); + } + + @TestMetadata("protectedVarPrivateSet.kt") + public void testProtectedVarPrivateSet() throws Exception { + doTest("compiler/testData/writeFlags/property/classObject/class/protectedVarPrivateSet.kt"); + } + + @TestMetadata("publicVal.kt") + public void testPublicVal() throws Exception { + doTest("compiler/testData/writeFlags/property/classObject/class/publicVal.kt"); + } + + @TestMetadata("publicValNonDefault.kt") + public void testPublicValNonDefault() throws Exception { + doTest("compiler/testData/writeFlags/property/classObject/class/publicValNonDefault.kt"); + } + + @TestMetadata("publicVar.kt") + public void testPublicVar() throws Exception { + doTest("compiler/testData/writeFlags/property/classObject/class/publicVar.kt"); + } + + @TestMetadata("publicVarNonDefault.kt") + public void testPublicVarNonDefault() throws Exception { + doTest("compiler/testData/writeFlags/property/classObject/class/publicVarNonDefault.kt"); + } + + @TestMetadata("publicVarPrivateSet.kt") + public void testPublicVarPrivateSet() throws Exception { + doTest("compiler/testData/writeFlags/property/classObject/class/publicVarPrivateSet.kt"); + } + + @TestMetadata("publicVarProtectedSet.kt") + public void testPublicVarProtectedSet() throws Exception { + doTest("compiler/testData/writeFlags/property/classObject/class/publicVarProtectedSet.kt"); + } + + @TestMetadata("publicVarPublicSet.kt") + public void testPublicVarPublicSet() throws Exception { + doTest("compiler/testData/writeFlags/property/classObject/class/publicVarPublicSet.kt"); + } + + } + + @TestMetadata("compiler/testData/writeFlags/property/classObject/trait") + public static class Trait extends AbstractWriteFlagsTest { + public void testAllFilesPresentInTrait() throws Exception { + JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.GenerateTests", new File("compiler/testData/writeFlags/property/classObject/trait"), Pattern.compile("^(.+)\\.kt$"), true); + } + + @TestMetadata("delegatedProtectedVar.kt") + public void testDelegatedProtectedVar() throws Exception { + doTest("compiler/testData/writeFlags/property/classObject/trait/delegatedProtectedVar.kt"); + } + + @TestMetadata("delegatedPublicVal.kt") + public void testDelegatedPublicVal() throws Exception { + doTest("compiler/testData/writeFlags/property/classObject/trait/delegatedPublicVal.kt"); + } + + @TestMetadata("extensionPublicVal.kt") + public void testExtensionPublicVal() throws Exception { + doTest("compiler/testData/writeFlags/property/classObject/trait/extensionPublicVal.kt"); + } + + @TestMetadata("extensionPublicVar.kt") + public void testExtensionPublicVar() throws Exception { + doTest("compiler/testData/writeFlags/property/classObject/trait/extensionPublicVar.kt"); + } + + @TestMetadata("internalVal.kt") + public void testInternalVal() throws Exception { + doTest("compiler/testData/writeFlags/property/classObject/trait/internalVal.kt"); + } + + @TestMetadata("internalVar.kt") + public void testInternalVar() throws Exception { + doTest("compiler/testData/writeFlags/property/classObject/trait/internalVar.kt"); + } + + @TestMetadata("internalVarPrivateSet.kt") + public void testInternalVarPrivateSet() throws Exception { + doTest("compiler/testData/writeFlags/property/classObject/trait/internalVarPrivateSet.kt"); + } + + @TestMetadata("noBackingField.kt") + public void testNoBackingField() throws Exception { + doTest("compiler/testData/writeFlags/property/classObject/trait/noBackingField.kt"); + } + + @TestMetadata("privateVal.kt") + public void testPrivateVal() throws Exception { + doTest("compiler/testData/writeFlags/property/classObject/trait/privateVal.kt"); + } + + @TestMetadata("privateVar.kt") + public void testPrivateVar() throws Exception { + doTest("compiler/testData/writeFlags/property/classObject/trait/privateVar.kt"); + } + + @TestMetadata("protectedVal.kt") + public void testProtectedVal() throws Exception { + doTest("compiler/testData/writeFlags/property/classObject/trait/protectedVal.kt"); + } + + @TestMetadata("protectedVarPrivateSet.kt") + public void testProtectedVarPrivateSet() throws Exception { + doTest("compiler/testData/writeFlags/property/classObject/trait/protectedVarPrivateSet.kt"); + } + + @TestMetadata("publicVal.kt") + public void testPublicVal() throws Exception { + doTest("compiler/testData/writeFlags/property/classObject/trait/publicVal.kt"); + } + + @TestMetadata("publicValNonDefault.kt") + public void testPublicValNonDefault() throws Exception { + doTest("compiler/testData/writeFlags/property/classObject/trait/publicValNonDefault.kt"); + } + + @TestMetadata("publicVar.kt") + public void testPublicVar() throws Exception { + doTest("compiler/testData/writeFlags/property/classObject/trait/publicVar.kt"); + } + + @TestMetadata("publicVarNonDefault.kt") + public void testPublicVarNonDefault() throws Exception { + doTest("compiler/testData/writeFlags/property/classObject/trait/publicVarNonDefault.kt"); + } + + @TestMetadata("publicVarPrivateSet.kt") + public void testPublicVarPrivateSet() throws Exception { + doTest("compiler/testData/writeFlags/property/classObject/trait/publicVarPrivateSet.kt"); + } + + @TestMetadata("publicVarProtectedSet.kt") + public void testPublicVarProtectedSet() throws Exception { + doTest("compiler/testData/writeFlags/property/classObject/trait/publicVarProtectedSet.kt"); + } + + @TestMetadata("publicVarPublicSet.kt") + public void testPublicVarPublicSet() throws Exception { + doTest("compiler/testData/writeFlags/property/classObject/trait/publicVarPublicSet.kt"); + } + + } + + public static Test innerSuite() { + TestSuite suite = new TestSuite("ClassObject"); + suite.addTestSuite(ClassObject.class); + suite.addTestSuite(Class.class); + suite.addTestSuite(Trait.class); + return suite; + } + } + @TestMetadata("compiler/testData/writeFlags/property/deprecatedFlag") public static class DeprecatedFlag extends AbstractWriteFlagsTest { public void testAllFilesPresentInDeprecatedFlag() throws Exception { @@ -516,6 +738,7 @@ public class WriteFlagsTestGenerated extends AbstractWriteFlagsTest { public static Test innerSuite() { TestSuite suite = new TestSuite("Property"); suite.addTestSuite(Property.class); + suite.addTest(ClassObject.innerSuite()); suite.addTestSuite(DeprecatedFlag.class); suite.addTestSuite(Visibility.class); return suite; diff --git a/compiler/tests/org/jetbrains/jet/codegen/generated/BlackBoxCodegenTestGenerated.java b/compiler/tests/org/jetbrains/jet/codegen/generated/BlackBoxCodegenTestGenerated.java index bcc33435963..d874af8313d 100644 --- a/compiler/tests/org/jetbrains/jet/codegen/generated/BlackBoxCodegenTestGenerated.java +++ b/compiler/tests/org/jetbrains/jet/codegen/generated/BlackBoxCodegenTestGenerated.java @@ -3459,6 +3459,11 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest { JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.GenerateTests", new File("compiler/testData/codegen/box/properties"), Pattern.compile("^(.+)\\.kt$"), true); } + @TestMetadata("classObjectProperties.kt") + public void testClassObjectProperties() throws Exception { + doTest("compiler/testData/codegen/box/properties/classObjectProperties.kt"); + } + @TestMetadata("generalAccess.kt") public void testGeneralAccess() throws Exception { doTest("compiler/testData/codegen/box/properties/generalAccess.kt"); diff --git a/compiler/tests/org/jetbrains/jet/jvm/compiler/CompileJavaAgainstKotlinTestGenerated.java b/compiler/tests/org/jetbrains/jet/jvm/compiler/CompileJavaAgainstKotlinTestGenerated.java index c6f6c63623f..107b0044382 100644 --- a/compiler/tests/org/jetbrains/jet/jvm/compiler/CompileJavaAgainstKotlinTestGenerated.java +++ b/compiler/tests/org/jetbrains/jet/jvm/compiler/CompileJavaAgainstKotlinTestGenerated.java @@ -31,7 +31,7 @@ import org.jetbrains.jet.jvm.compiler.AbstractCompileJavaAgainstKotlinTest; /** This class is generated by {@link org.jetbrains.jet.generators.tests.GenerateTests}. DO NOT MODIFY MANUALLY */ @SuppressWarnings("all") @TestMetadata("compiler/testData/compileJavaAgainstKotlin") -@InnerTestClasses({CompileJavaAgainstKotlinTestGenerated.Class.class, CompileJavaAgainstKotlinTestGenerated.Method.class}) +@InnerTestClasses({CompileJavaAgainstKotlinTestGenerated.Class.class, CompileJavaAgainstKotlinTestGenerated.Method.class, CompileJavaAgainstKotlinTestGenerated.StaticFields.class}) public class CompileJavaAgainstKotlinTestGenerated extends AbstractCompileJavaAgainstKotlinTest { public void testAllFilesPresentInCompileJavaAgainstKotlin() throws Exception { JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.GenerateTests", new File("compiler/testData/compileJavaAgainstKotlin"), Pattern.compile("^(.+)\\.kt$"), true); @@ -183,11 +183,30 @@ public class CompileJavaAgainstKotlinTestGenerated extends AbstractCompileJavaAg } + @TestMetadata("compiler/testData/compileJavaAgainstKotlin/staticFields") + public static class StaticFields extends AbstractCompileJavaAgainstKotlinTest { + public void testAllFilesPresentInStaticFields() throws Exception { + JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.GenerateTests", new File("compiler/testData/compileJavaAgainstKotlin/staticFields"), Pattern.compile("^(.+)\\.kt$"), true); + } + + @TestMetadata("staticClassProperty.kt") + public void testStaticClassProperty() throws Exception { + doTest("compiler/testData/compileJavaAgainstKotlin/staticFields/staticClassProperty.kt"); + } + + @TestMetadata("staticTraitProperty.kt") + public void testStaticTraitProperty() throws Exception { + doTest("compiler/testData/compileJavaAgainstKotlin/staticFields/staticTraitProperty.kt"); + } + + } + public static Test suite() { TestSuite suite = new TestSuite("CompileJavaAgainstKotlinTestGenerated"); suite.addTestSuite(CompileJavaAgainstKotlinTestGenerated.class); suite.addTestSuite(Class.class); suite.addTestSuite(Method.class); + suite.addTestSuite(StaticFields.class); return suite; } } diff --git a/compiler/tests/org/jetbrains/jet/jvm/compiler/LoadCompiledKotlinTestGenerated.java b/compiler/tests/org/jetbrains/jet/jvm/compiler/LoadCompiledKotlinTestGenerated.java index 036177825ea..5a3b33e8e68 100644 --- a/compiler/tests/org/jetbrains/jet/jvm/compiler/LoadCompiledKotlinTestGenerated.java +++ b/compiler/tests/org/jetbrains/jet/jvm/compiler/LoadCompiledKotlinTestGenerated.java @@ -269,6 +269,16 @@ public class LoadCompiledKotlinTestGenerated extends AbstractLoadCompiledKotlinT doTestWithAccessors("compiler/testData/loadKotlin/classObject/ClassObjectExtendsTraitWithTP.kt"); } + @TestMetadata("classObjectInClassStaticFields.kt") + public void testClassObjectInClassStaticFields() throws Exception { + doTestWithAccessors("compiler/testData/loadKotlin/classObject/classObjectInClassStaticFields.kt"); + } + + @TestMetadata("classObjectInTraitStaticFields.kt") + public void testClassObjectInTraitStaticFields() throws Exception { + doTestWithAccessors("compiler/testData/loadKotlin/classObject/classObjectInTraitStaticFields.kt"); + } + @TestMetadata("ClassObjectPropertyInClass.kt") public void testClassObjectPropertyInClass() throws Exception { doTestWithAccessors("compiler/testData/loadKotlin/classObject/ClassObjectPropertyInClass.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 f6e5a1cdd7f..4e5a10b0deb 100644 --- a/compiler/tests/org/jetbrains/jet/lang/resolve/lazy/LazyResolveNamespaceComparingTestGenerated.java +++ b/compiler/tests/org/jetbrains/jet/lang/resolve/lazy/LazyResolveNamespaceComparingTestGenerated.java @@ -271,6 +271,16 @@ public class LazyResolveNamespaceComparingTestGenerated extends AbstractLazyReso doTestCheckingPrimaryConstructorsAndAccessors("compiler/testData/loadKotlin/classObject/ClassObjectExtendsTraitWithTP.kt"); } + @TestMetadata("classObjectInClassStaticFields.kt") + public void testClassObjectInClassStaticFields() throws Exception { + doTestCheckingPrimaryConstructorsAndAccessors("compiler/testData/loadKotlin/classObject/classObjectInClassStaticFields.kt"); + } + + @TestMetadata("classObjectInTraitStaticFields.kt") + public void testClassObjectInTraitStaticFields() throws Exception { + doTestCheckingPrimaryConstructorsAndAccessors("compiler/testData/loadKotlin/classObject/classObjectInTraitStaticFields.kt"); + } + @TestMetadata("ClassObjectPropertyInClass.kt") public void testClassObjectPropertyInClass() throws Exception { doTestCheckingPrimaryConstructorsAndAccessors("compiler/testData/loadKotlin/classObject/ClassObjectPropertyInClass.kt"); From 406f90badf589aac103f9c750855a055de281b70 Mon Sep 17 00:00:00 2001 From: Mikhael Bogdanov Date: Thu, 13 Jun 2013 15:14:59 +0400 Subject: [PATCH 140/291] CodegenContext replaced with MethodContext in ExpressionCodegen --- .../jet/codegen/ClassBodyCodegen.java | 18 +++++++++++----- .../jet/codegen/ExpressionCodegen.java | 12 +++++------ .../codegen/FunctionGenerationStrategy.java | 1 - .../codegen/ImplementationBodyCodegen.java | 13 +++++++----- .../jet/codegen/NamespaceCodegen.java | 21 ++++++++++++++----- 5 files changed, 43 insertions(+), 22 deletions(-) diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/ClassBodyCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/ClassBodyCodegen.java index 0a0fea7de56..806867b843b 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/ClassBodyCodegen.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/ClassBodyCodegen.java @@ -22,13 +22,14 @@ import org.jetbrains.asm4.MethodVisitor; import org.jetbrains.asm4.Type; import org.jetbrains.jet.codegen.context.ClassContext; import org.jetbrains.jet.codegen.state.GenerationState; -import org.jetbrains.jet.lang.descriptors.ClassDescriptor; -import org.jetbrains.jet.lang.descriptors.PropertyDescriptor; +import org.jetbrains.jet.lang.descriptors.*; +import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor; +import org.jetbrains.jet.lang.descriptors.impl.SimpleFunctionDescriptorImpl; import org.jetbrains.jet.lang.psi.*; import org.jetbrains.jet.lang.resolve.BindingContext; import org.jetbrains.jet.lang.resolve.DescriptorUtils; +import org.jetbrains.jet.lang.resolve.name.Name; -import java.util.ArrayList; import java.util.Collections; import java.util.List; @@ -45,7 +46,7 @@ public abstract class ClassBodyCodegen extends MemberCodegen { private MethodVisitor clInitMethod; - private ExpressionCodegen clInitCodegen; + private ExpressionCodegen clInitCodegen; protected ClassBodyCodegen( @NotNull JetClassOrObject aClass, @@ -176,7 +177,14 @@ public abstract class ClassBodyCodegen extends MemberCodegen { if (clInitCodegen == null) { MethodVisitor method = createOrGetClInitMethod(); method.visitCode(); - clInitCodegen = new ExpressionCodegen(method, new FrameMap(), Type.VOID_TYPE, context, state); + SimpleFunctionDescriptorImpl clInit = + new SimpleFunctionDescriptorImpl(descriptor, Collections.emptyList(), + Name.special(""), + CallableMemberDescriptor.Kind.SYNTHESIZED); + clInit.initialize(null, null, Collections.emptyList(), + Collections.emptyList(), null, null, Visibilities.PRIVATE, false); + + clInitCodegen = new ExpressionCodegen(method, new FrameMap(), Type.VOID_TYPE, context.intoFunction(clInit), state); } } return clInitCodegen; diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java index 0f69bb1dbbd..490a6ce26f1 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java @@ -95,7 +95,7 @@ public class ExpressionCodegen extends JetVisitor implem private final Type returnType; private final BindingContext bindingContext; - final CodegenContext context; + final MethodContext context; private final CodegenStatementVisitor statementVisitor; private final Stack blockStackElements = new Stack(); @@ -155,11 +155,11 @@ public class ExpressionCodegen extends JetVisitor implem public ExpressionCodegen( - MethodVisitor v, - FrameMap myMap, - Type returnType, - CodegenContext context, - GenerationState state + @NotNull MethodVisitor v, + @NotNull FrameMap myMap, + @NotNull Type returnType, + @NotNull MethodContext context, + @NotNull GenerationState state ) { this.myFrameMap = myMap; this.typeMapper = state.getTypeMapper(); diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/FunctionGenerationStrategy.java b/compiler/backend/src/org/jetbrains/jet/codegen/FunctionGenerationStrategy.java index 204786833c4..7f3c4f5384e 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/FunctionGenerationStrategy.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/FunctionGenerationStrategy.java @@ -19,7 +19,6 @@ package org.jetbrains.jet.codegen; import org.jetbrains.annotations.NotNull; import org.jetbrains.asm4.MethodVisitor; import org.jetbrains.asm4.Type; -import org.jetbrains.jet.codegen.context.CodegenContext; import org.jetbrains.jet.codegen.context.MethodContext; import org.jetbrains.jet.codegen.signature.JvmMethodSignature; import org.jetbrains.jet.codegen.state.GenerationState; diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/ImplementationBodyCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/ImplementationBodyCodegen.java index d32993d3d71..388592e71d4 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/ImplementationBodyCodegen.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/ImplementationBodyCodegen.java @@ -20,6 +20,7 @@ import com.google.common.collect.Lists; import com.google.common.collect.Sets; import com.intellij.openapi.progress.ProcessCanceledException; import com.intellij.openapi.util.Pair; +import com.intellij.psi.PsiElement; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.asm4.AnnotationVisitor; @@ -66,6 +67,7 @@ import static org.jetbrains.jet.codegen.AsmUtil.*; import static org.jetbrains.jet.codegen.CodegenUtil.*; import static org.jetbrains.jet.codegen.binding.CodegenBinding.*; import static org.jetbrains.jet.lang.resolve.BindingContextUtils.callableDescriptorToDeclaration; +import static org.jetbrains.jet.lang.resolve.BindingContextUtils.descriptorToDeclaration; import static org.jetbrains.jet.lang.resolve.DescriptorUtils.*; import static org.jetbrains.jet.lang.resolve.DescriptorUtils.isKindOf; import static org.jetbrains.jet.lang.resolve.java.AsmTypeConstants.JAVA_STRING_TYPE; @@ -1322,7 +1324,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { } - private void generateDelegationToTraitImpl(@NotNull FunctionDescriptor fun, @NotNull FunctionDescriptor inheritedFun) { + private void generateDelegationToTraitImpl(final @NotNull FunctionDescriptor fun, @NotNull FunctionDescriptor inheritedFun) { DeclarationDescriptor containingDeclaration = fun.getContainingDeclaration(); if (!(containingDeclaration instanceof ClassDescriptor)) { return; @@ -1339,20 +1341,21 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { Method methodToGenerate = delegateInfo.methodToGenerate; Method methodInTrait = delegateInfo.methodInTrait; - MethodVisitor mv = v.newMethod(myClass, flags, methodToGenerate.getName(), methodToGenerate.getDescriptor(), null, null); + PsiElement origin = descriptorToDeclaration(bindingContext, fun); + MethodVisitor mv = v.newMethod(origin, flags, methodToGenerate.getName(), methodToGenerate.getDescriptor(), null, null); AnnotationCodegen.forMethod(mv, typeMapper).genAnnotations(fun); - writeAnnotationForDelegateToTraitImpl(fun, inheritedFun, mv); - if (state.getClassBuilderMode() == ClassBuilderMode.STUBS) { genStubCode(mv); } else if (state.getClassBuilderMode() == ClassBuilderMode.FULL) { + writeAnnotationForDelegateToTraitImpl(fun, inheritedFun, mv); + Type returnType = methodToGenerate.getReturnType(); mv.visitCode(); FrameMap frameMap = context.prepareFrame(typeMapper); - ExpressionCodegen codegen = new ExpressionCodegen(mv, frameMap, returnType, context, state); + ExpressionCodegen codegen = new ExpressionCodegen(mv, frameMap, returnType, context.intoFunction(inheritedFun), state); codegen.generateThisOrOuter(descriptor, false); // ??? wouldn't it be addClosureToConstructorParameters good idea to put it? Type[] argTypes = methodToGenerate.getArgumentTypes(); diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/NamespaceCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/NamespaceCodegen.java index 08f7f5a6a92..f8c59f92bc9 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/NamespaceCodegen.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/NamespaceCodegen.java @@ -28,7 +28,9 @@ import org.jetbrains.asm4.MethodVisitor; import org.jetbrains.asm4.Type; import org.jetbrains.jet.codegen.context.CodegenContext; import org.jetbrains.jet.codegen.state.GenerationState; -import org.jetbrains.jet.lang.descriptors.NamespaceDescriptor; +import org.jetbrains.jet.lang.descriptors.*; +import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor; +import org.jetbrains.jet.lang.descriptors.impl.SimpleFunctionDescriptorImpl; import org.jetbrains.jet.lang.diagnostics.DiagnosticUtils; import org.jetbrains.jet.lang.psi.*; import org.jetbrains.jet.lang.resolve.BindingContext; @@ -38,6 +40,7 @@ import org.jetbrains.jet.lang.resolve.name.Name; import java.io.File; import java.util.Collection; +import java.util.Collections; import java.util.List; import static org.jetbrains.asm4.Opcodes.*; @@ -159,7 +162,7 @@ public class NamespaceCodegen extends MemberCodegen { } } - generateStaticInitializers(builder, file); + generateStaticInitializers(descriptor, builder, file); builder.done(); } @@ -203,16 +206,24 @@ public class NamespaceCodegen extends MemberCodegen { } } - private void generateStaticInitializers(@NotNull ClassBuilder builder, @NotNull JetFile file) { + private void generateStaticInitializers(NamespaceDescriptor descriptor, @NotNull ClassBuilder builder, @NotNull JetFile file) { List properties = collectPropertiesToInitialize(file); if (properties.isEmpty()) return; - MethodVisitor mv = builder.newMethod(file, ACC_PUBLIC | ACC_STATIC, "", "()V", null, null); + MethodVisitor mv = builder.newMethod(file, ACC_STATIC, "", "()V", null, null); if (state.getClassBuilderMode() == ClassBuilderMode.FULL) { mv.visitCode(); FrameMap frameMap = new FrameMap(); - ExpressionCodegen codegen = new ExpressionCodegen(mv, frameMap, Type.VOID_TYPE, CodegenContext.STATIC, state); + + SimpleFunctionDescriptorImpl clInit = + new SimpleFunctionDescriptorImpl(descriptor, Collections.emptyList(), + Name.special(""), + CallableMemberDescriptor.Kind.SYNTHESIZED); + clInit.initialize(null, null, Collections.emptyList(), + Collections.emptyList(), null, null, Visibilities.PRIVATE, false); + + ExpressionCodegen codegen = new ExpressionCodegen(mv, frameMap, Type.VOID_TYPE, CodegenContext.STATIC.intoFunction(clInit), state); for (JetDeclaration declaration : properties) { ImplementationBodyCodegen. From aec6deae9f0369d62c6dd451d712d6264cb5335b Mon Sep 17 00:00:00 2001 From: Mikhael Bogdanov Date: Thu, 13 Jun 2013 13:48:08 +0400 Subject: [PATCH 141/291] Rename fields on name clashing #KT-3663 Fixed #KT-3664 Fixed --- .../jet/codegen/ExpressionCodegen.java | 32 +++++--- .../codegen/ImplementationBodyCodegen.java | 17 +++-- .../jetbrains/jet/codegen/MemberCodegen.java | 5 +- .../jet/codegen/NamespaceCodegen.java | 30 ++++---- .../jet/codegen/PropertyCodegen.java | 17 +++-- .../jetbrains/jet/codegen/ScriptCodegen.java | 3 +- .../org/jetbrains/jet/codegen/StackValue.java | 25 ++++--- .../jet/codegen/context/ClassContext.java | 2 +- .../jet/codegen/context/CodegenContext.java | 4 +- .../codegen/context/FieldOwnerContext.java | 73 +++++++++++++++++++ .../jet/codegen/context/NamespaceContext.java | 2 +- .../jet/codegen/context/ScriptContext.java | 2 +- .../jet/lang/resolve/java/JvmAbi.java | 15 ++++ .../jet/lang/resolve/DescriptorUtils.java | 10 +++ 14 files changed, 177 insertions(+), 60 deletions(-) create mode 100644 compiler/backend/src/org/jetbrains/jet/codegen/context/FieldOwnerContext.java diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java index 490a6ce26f1..41d1dd24b84 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java @@ -51,6 +51,7 @@ import org.jetbrains.jet.lang.resolve.calls.util.CallMaker; import org.jetbrains.jet.lang.resolve.calls.util.ExpressionAsFunctionDescriptor; import org.jetbrains.jet.lang.resolve.constants.CompileTimeConstant; import org.jetbrains.jet.lang.resolve.java.AsmTypeConstants; +import org.jetbrains.jet.lang.resolve.java.JvmAbi; import org.jetbrains.jet.lang.resolve.java.JvmClassName; import org.jetbrains.jet.lang.resolve.java.JvmPrimitiveType; import org.jetbrains.jet.lang.resolve.java.sam.SingleAbstractMethodUtils; @@ -1569,7 +1570,7 @@ public class ExpressionCodegen extends JetVisitor implem JetExpression r = getReceiverForSelector(expression); boolean isSuper = r instanceof JetSuperExpression; propertyDescriptor = accessablePropertyDescriptor(propertyDescriptor); - StackValue.Property iValue = + StackValue iValue = intermediateValueForProperty(propertyDescriptor, directToField, isSuper ? (JetSuperExpression) r : null); if (directToField) { receiver = StackValue.receiverWithoutReceiverArgument(receiver); @@ -1678,7 +1679,7 @@ public class ExpressionCodegen extends JetVisitor implem } @NotNull - public StackValue.Property intermediateValueForProperty( + public StackValue intermediateValueForProperty( @NotNull PropertyDescriptor propertyDescriptor, boolean forceField, @Nullable JetSuperExpression superExpression @@ -1686,7 +1687,7 @@ public class ExpressionCodegen extends JetVisitor implem return intermediateValueForProperty(propertyDescriptor, forceField, superExpression, MethodKind.GENERAL); } - public StackValue.Property intermediateValueForProperty( + public StackValue.StackValueWithSimpleReceiver intermediateValueForProperty( @NotNull PropertyDescriptor propertyDescriptor, boolean forceField, @Nullable JetSuperExpression superExpression, @@ -1754,7 +1755,9 @@ public class ExpressionCodegen extends JetVisitor implem callableSetter = null; } else { - callableSetter = typeMapper.mapToCallableMethod(propertyDescriptor.getSetter(), isSuper || MethodKind.SYNTHETIC_ACCESSOR == methodKind, isInsideClass, isInsideModule, OwnerKind.IMPLEMENTATION); + callableSetter = typeMapper + .mapToCallableMethod(propertyDescriptor.getSetter(), isSuper || MethodKind.SYNTHETIC_ACCESSOR == methodKind, + isInsideClass, isInsideModule, OwnerKind.IMPLEMENTATION); } } } @@ -1765,20 +1768,25 @@ public class ExpressionCodegen extends JetVisitor implem propertyDescriptor = unwrapFakeOverride(propertyDescriptor); if (callableMethod == null) { - owner = typeMapper.getOwner(isBackingFieldInAnotherClass ? propertyDescriptor.getContainingDeclaration() : propertyDescriptor, context.getContextKind(), isInsideModule); + owner = typeMapper.getOwner(isBackingFieldInAnotherClass ? propertyDescriptor.getContainingDeclaration() : propertyDescriptor, + context.getContextKind(), isInsideModule); } else { owner = callableMethod.getOwner(); } - if (isDelegatedProperty && forceField) { - return StackValue.property(propertyDescriptor, owner, typeMapper.mapType(delegateType), - isStatic, true, callableGetter, callableSetter, state); - } - else { - return StackValue.property(propertyDescriptor, owner, typeMapper.mapType(propertyDescriptor.getOriginal().getType()), - isStatic, false, callableGetter, callableSetter, state); + String name; + if (propertyDescriptor.getContainingDeclaration() == backingFieldContext.getContextDescriptor()) { + assert backingFieldContext instanceof FieldOwnerContext : "Actual context is " + backingFieldContext + " but should be instance of FieldOwnerContext" ; + name = ((FieldOwnerContext) backingFieldContext).getFieldName(propertyDescriptor, isDelegatedProperty); + } else { + name = JvmAbi.getDefaultPropertyName(propertyDescriptor.getName(), isDelegatedProperty, propertyDescriptor.getReceiverParameter() != null); } + + return StackValue.property(propertyDescriptor, owner, + typeMapper.mapType(isDelegatedProperty && forceField ? delegateType : propertyDescriptor.getOriginal().getType()), + isStatic, name, callableGetter, callableSetter, state); + } @Override diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/ImplementationBodyCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/ImplementationBodyCodegen.java index 388592e71d4..952a8768944 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/ImplementationBodyCodegen.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/ImplementationBodyCodegen.java @@ -471,8 +471,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { for (JetParameter parameter : getPrimaryConstructorParameters()) { if (parameter.getValOrVarNode() == null) continue; - PropertyDescriptor propertyDescriptor = state.getBindingContext().get(BindingContext.PRIMARY_CONSTRUCTOR_PARAMETER, parameter); - assert propertyDescriptor != null; + PropertyDescriptor propertyDescriptor = DescriptorUtils.getPropertyDescriptor(parameter, bindingContext); result.add(propertyDescriptor); } @@ -860,7 +859,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { public void doGenerateBody(ExpressionCodegen codegen, JvmMethodSignature signature) { InstructionAdapter iv = codegen.v; boolean forceField = AsmUtil.isPropertyWithBackingFieldInOuterClass(original) && !isClassObject(bridge.getContainingDeclaration()); - StackValue.Property property = codegen.intermediateValueForProperty(original, forceField, null, MethodKind.SYNTHETIC_ACCESSOR); + StackValue property = codegen.intermediateValueForProperty(original, forceField, null, MethodKind.SYNTHETIC_ACCESSOR); if (!forceField) { iv.load(0, OBJECT_TYPE); } @@ -879,7 +878,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { @Override public void doGenerateBody(ExpressionCodegen codegen, JvmMethodSignature signature) { boolean forceField = AsmUtil.isPropertyWithBackingFieldInOuterClass(original) && !isClassObject(bridge.getContainingDeclaration()); - StackValue.Property property = codegen.intermediateValueForProperty(original, forceField, null, MethodKind.SYNTHETIC_ACCESSOR); + StackValue property = codegen.intermediateValueForProperty(original, forceField, null, MethodKind.SYNTHETIC_ACCESSOR); InstructionAdapter iv = codegen.v; Type[] argTypes = signature.getAsmMethod().getArgumentTypes(); @@ -955,7 +954,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { if (classObjectPropertiesToCopy != null) { for (PropertyDescriptor propertyDescriptor : classObjectPropertiesToCopy) { - v.newField(null, ACC_STATIC | ACC_FINAL | ACC_PUBLIC, propertyDescriptor.getName().asString(), typeMapper.mapType(propertyDescriptor).getDescriptor(), null, null); + v.newField(null, ACC_STATIC | ACC_FINAL | ACC_PUBLIC, context.getFieldName(propertyDescriptor), typeMapper.mapType(propertyDescriptor).getDescriptor(), null, null); if (state.getClassBuilderMode() == ClassBuilderMode.FULL) { ExpressionCodegen codegen = createOrGetClInitCodegen(); @@ -1048,7 +1047,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { private void generatePrimaryConstructorImpl( @Nullable ConstructorDescriptor constructorDescriptor, - @NotNull final ExpressionCodegen codegen, + @NotNull ExpressionCodegen codegen, @Nullable MutableClosure closure ) { List paramDescrs = constructorDescriptor != null @@ -1096,7 +1095,9 @@ 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().asString(), type.getDescriptor()); + iv.putfield(classAsmType.getInternalName(), + context.getFieldName(DescriptorUtils.getPropertyDescriptor(parameter, bindingContext)), + type.getDescriptor()); } curParam++; } @@ -1609,7 +1610,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { JetType jetType = getPropertyOrDelegateType(bindingContext, property, propertyDescriptor); - StackValue.Property propValue = codegen.intermediateValueForProperty(propertyDescriptor, true, null, MethodKind.INITIALIZER); + StackValue.StackValueWithSimpleReceiver propValue = codegen.intermediateValueForProperty(propertyDescriptor, true, null, MethodKind.INITIALIZER); if (!propValue.isStatic) { codegen.v.load(0, OBJECT_TYPE); diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/MemberCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/MemberCodegen.java index 41ecee8aaed..255b476a9de 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/MemberCodegen.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/MemberCodegen.java @@ -20,6 +20,7 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.jet.codegen.context.ClassContext; import org.jetbrains.jet.codegen.context.CodegenContext; +import org.jetbrains.jet.codegen.context.FieldOwnerContext; import org.jetbrains.jet.codegen.state.GenerationState; import org.jetbrains.jet.codegen.state.GenerationStateAware; import org.jetbrains.jet.lang.descriptors.ClassDescriptor; @@ -27,8 +28,6 @@ import org.jetbrains.jet.lang.psi.*; import org.jetbrains.jet.lang.resolve.BindingContext; import org.jetbrains.jet.lang.types.ErrorUtils; -import java.util.List; - public class MemberCodegen extends GenerationStateAware { @@ -46,7 +45,7 @@ public class MemberCodegen extends GenerationStateAware { } public void genFunctionOrProperty( - CodegenContext context, + @NotNull FieldOwnerContext context, @NotNull JetTypeParameterListOwner functionOrProperty, @NotNull ClassBuilder classBuilder ) { diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/NamespaceCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/NamespaceCodegen.java index f8c59f92bc9..2a47158c56b 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/NamespaceCodegen.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/NamespaceCodegen.java @@ -27,6 +27,7 @@ import org.jetbrains.asm4.AnnotationVisitor; import org.jetbrains.asm4.MethodVisitor; import org.jetbrains.asm4.Type; import org.jetbrains.jet.codegen.context.CodegenContext; +import org.jetbrains.jet.codegen.context.FieldOwnerContext; import org.jetbrains.jet.codegen.state.GenerationState; import org.jetbrains.jet.lang.descriptors.*; import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor; @@ -147,22 +148,20 @@ public class NamespaceCodegen extends MemberCodegen { ); builder.visitSource(file.getName(), null); + FieldOwnerContext nameSpaceContext = + CodegenContext.STATIC.intoNamespace(descriptor); + + FieldOwnerContext nameSpacePart = + CodegenContext.STATIC.intoNamespacePart(className, descriptor); + for (JetDeclaration declaration : file.getDeclarations()) { if (declaration instanceof JetNamedFunction || declaration instanceof JetProperty) { - { - CodegenContext context = - CodegenContext.STATIC.intoNamespace(descriptor); - genFunctionOrProperty(context, (JetTypeParameterListOwner) declaration, builder); - } - { - CodegenContext context = - CodegenContext.STATIC.intoNamespacePart(className, descriptor); - genFunctionOrProperty(context, (JetTypeParameterListOwner) declaration, v.getClassBuilder()); - } + genFunctionOrProperty(nameSpaceContext, (JetTypeParameterListOwner) declaration, builder); + genFunctionOrProperty(nameSpacePart, (JetTypeParameterListOwner) declaration, v.getClassBuilder()); } } - generateStaticInitializers(descriptor, builder, file); + generateStaticInitializers(descriptor, builder, file, nameSpaceContext); builder.done(); } @@ -206,7 +205,12 @@ public class NamespaceCodegen extends MemberCodegen { } } - private void generateStaticInitializers(NamespaceDescriptor descriptor, @NotNull ClassBuilder builder, @NotNull JetFile file) { + private void generateStaticInitializers( + NamespaceDescriptor descriptor, + @NotNull ClassBuilder builder, + @NotNull JetFile file, + @NotNull FieldOwnerContext context + ) { List properties = collectPropertiesToInitialize(file); if (properties.isEmpty()) return; @@ -223,7 +227,7 @@ public class NamespaceCodegen extends MemberCodegen { clInit.initialize(null, null, Collections.emptyList(), Collections.emptyList(), null, null, Visibilities.PRIVATE, false); - ExpressionCodegen codegen = new ExpressionCodegen(mv, frameMap, Type.VOID_TYPE, CodegenContext.STATIC.intoFunction(clInit), state); + ExpressionCodegen codegen = new ExpressionCodegen(mv, frameMap, Type.VOID_TYPE, context.intoFunction(clInit), state); for (JetDeclaration declaration : properties) { ImplementationBodyCodegen. diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/PropertyCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/PropertyCodegen.java index 46b6820effd..60b33ddbeb4 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/PropertyCodegen.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/PropertyCodegen.java @@ -17,15 +17,14 @@ package org.jetbrains.jet.codegen; import com.intellij.openapi.util.text.StringUtil; -import com.intellij.psi.PsiElement; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.asm4.FieldVisitor; import org.jetbrains.asm4.MethodVisitor; import org.jetbrains.asm4.Type; import org.jetbrains.asm4.commons.InstructionAdapter; -import org.jetbrains.jet.codegen.context.ClassContext; import org.jetbrains.jet.codegen.context.CodegenContext; +import org.jetbrains.jet.codegen.context.FieldOwnerContext; import org.jetbrains.jet.codegen.context.MethodContext; import org.jetbrains.jet.codegen.signature.JvmMethodSignature; import org.jetbrains.jet.codegen.signature.JvmPropertyAccessorSignature; @@ -41,7 +40,6 @@ import org.jetbrains.jet.lang.resolve.DescriptorUtils; import org.jetbrains.jet.lang.resolve.calls.model.ResolvedCall; import org.jetbrains.jet.lang.resolve.constants.CompileTimeConstant; import org.jetbrains.jet.lang.resolve.java.JvmAbi; -import org.jetbrains.jet.lang.resolve.java.JvmClassName; 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; @@ -63,7 +61,7 @@ public class PropertyCodegen extends GenerationStateAware { private final ClassBuilder v; @NotNull - private final CodegenContext context; + private final FieldOwnerContext context; @Nullable private MemberCodegen classBodyCodegen; @@ -72,7 +70,7 @@ public class PropertyCodegen extends GenerationStateAware { private final OwnerKind kind; public PropertyCodegen( - @NotNull CodegenContext context, + @NotNull FieldOwnerContext context, @NotNull ClassBuilder v, @NotNull FunctionCodegen functionCodegen, @Nullable MemberCodegen classBodyCodegen @@ -145,9 +143,12 @@ public class PropertyCodegen extends GenerationStateAware { ClassBuilder builder = v; + FieldOwnerContext backingFieldContext = context; if (AsmUtil.isPropertyWithBackingFieldInOuterClass(propertyDescriptor)) { modifiers |= ACC_STATIC | getVisibilityForSpecialPropertyBackingField(propertyDescriptor, isDelegate); - builder = getParentBodyCodegen(classBodyCodegen).v; + ImplementationBodyCodegen codegen = getParentBodyCodegen(classBodyCodegen); + builder = codegen.v; + backingFieldContext = codegen.context; } else { if (kind != OwnerKind.NAMESPACE || isDelegate) { modifiers |= ACC_PRIVATE; @@ -159,7 +160,7 @@ public class PropertyCodegen extends GenerationStateAware { parentBodyCodegen.addClassObjectPropertyToCopy(propertyDescriptor); } - String name = isDelegate ? JvmAbi.getPropertyDelegateName(propertyDescriptor.getName()) : propertyDescriptor.getName().asString(); + String name = backingFieldContext.getFieldName(propertyDescriptor, isDelegate); return builder.newField(element, modifiers, name, type.getDescriptor(), null, defaultValue); @@ -333,7 +334,7 @@ public class PropertyCodegen extends GenerationStateAware { iv.load(0, OBJECT_TYPE); } - StackValue.Property delegatedProperty = codegen.intermediateValueForProperty(property, true, null); + StackValue delegatedProperty = codegen.intermediateValueForProperty(property, true, null); StackValue lastValue = codegen.invokeFunction(call, delegatedProperty, resolvedCall); if (lastValue.type != Type.VOID_TYPE) { diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/ScriptCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/ScriptCodegen.java index e7323990991..8d18cb286b1 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/ScriptCodegen.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/ScriptCodegen.java @@ -24,6 +24,7 @@ import org.jetbrains.asm4.Type; import org.jetbrains.asm4.commons.InstructionAdapter; import org.jetbrains.asm4.commons.Method; import org.jetbrains.jet.codegen.context.CodegenContext; +import org.jetbrains.jet.codegen.context.FieldOwnerContext; import org.jetbrains.jet.codegen.context.MethodContext; import org.jetbrains.jet.codegen.context.ScriptContext; import org.jetbrains.jet.codegen.signature.JvmMethodSignature; @@ -196,7 +197,7 @@ public class ScriptCodegen extends MemberCodegen { } } - private void genMembers(@NotNull JetScript scriptDeclaration, @NotNull CodegenContext context, @NotNull ClassBuilder classBuilder) { + private void genMembers(@NotNull JetScript scriptDeclaration, @NotNull FieldOwnerContext context, @NotNull ClassBuilder classBuilder) { for (JetDeclaration decl : scriptDeclaration.getDeclarations()) { genFunctionOrProperty(context, (JetTypeParameterListOwner) decl, classBuilder); } diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/StackValue.java b/compiler/backend/src/org/jetbrains/jet/codegen/StackValue.java index 55b37b180b6..db0639e04af 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/StackValue.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/StackValue.java @@ -116,10 +116,12 @@ public abstract class StackValue { return new Invert(stackValue); } + @NotNull public static StackValue arrayElement(Type type, boolean unbox) { return new ArrayElement(type, unbox); } + @NotNull public static StackValue collectionElement( Type type, ResolvedCall getter, @@ -135,19 +137,21 @@ public abstract class StackValue { return new Field(type, owner, name, isStatic); } + @NotNull public static Property property( - PropertyDescriptor descriptor, - JvmClassName methodOwner, - Type type, + @NotNull PropertyDescriptor descriptor, + @NotNull JvmClassName methodOwner, + @NotNull Type type, boolean isStatic, - boolean isDelegated, + @NotNull String name, @Nullable CallableMethod getter, @Nullable CallableMethod setter, GenerationState state ) { - return new Property(descriptor, methodOwner, getter, setter, isStatic, isDelegated, type, state); + return new Property(descriptor, methodOwner, getter, setter, isStatic, name, type, state); } + @NotNull public static StackValue expression(Type type, JetExpression expression, ExpressionCodegen generator) { return new Expression(type, expression, generator); } @@ -870,12 +874,13 @@ public abstract class StackValue { private final PropertyDescriptor descriptor; @NotNull private final GenerationState state; - private final boolean isDelegated; + + private final String name; public Property( @NotNull PropertyDescriptor descriptor, @NotNull JvmClassName methodOwner, @Nullable CallableMethod getter, @Nullable CallableMethod setter, boolean isStatic, - boolean isDelegated, @NotNull Type type, @NotNull GenerationState state + @NotNull String name, @NotNull Type type, @NotNull GenerationState state ) { super(type, isStatic); this.methodOwner = methodOwner; @@ -883,7 +888,7 @@ public abstract class StackValue { this.setter = setter; this.descriptor = descriptor; this.state = state; - this.isDelegated = isDelegated; + this.name = name; } @Override @@ -913,7 +918,7 @@ public abstract class StackValue { } private String getPropertyName() { - return isDelegated ? JvmAbi.getPropertyDelegateName(descriptor.getName()) : descriptor.getName().asString(); + return name; } } @@ -1244,7 +1249,7 @@ public abstract class StackValue { } } - private abstract static class StackValueWithSimpleReceiver extends StackValue { + public abstract static class StackValueWithSimpleReceiver extends StackValue { protected final boolean isStatic; diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/context/ClassContext.java b/compiler/backend/src/org/jetbrains/jet/codegen/context/ClassContext.java index 6b99c7baaf5..5116ca78745 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/context/ClassContext.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/context/ClassContext.java @@ -24,7 +24,7 @@ import org.jetbrains.jet.lang.descriptors.ClassDescriptor; import static org.jetbrains.jet.codegen.binding.CodegenBinding.CLOSURE; -public class ClassContext extends CodegenContext { +public class ClassContext extends FieldOwnerContext { public ClassContext( @NotNull JetTypeMapper typeMapper, diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/context/CodegenContext.java b/compiler/backend/src/org/jetbrains/jet/codegen/context/CodegenContext.java index efd84a550fa..32bd32ac879 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/context/CodegenContext.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/context/CodegenContext.java @@ -147,12 +147,12 @@ public abstract class CodegenContext { } @NotNull - public CodegenContext intoNamespace(@NotNull NamespaceDescriptor descriptor) { + public FieldOwnerContext intoNamespace(@NotNull NamespaceDescriptor descriptor) { return new NamespaceContext(descriptor, this, OwnerKind.NAMESPACE); } @NotNull - public CodegenContext intoNamespacePart(String delegateTo, NamespaceDescriptor descriptor) { + public FieldOwnerContext intoNamespacePart(String delegateTo, NamespaceDescriptor descriptor) { return new NamespaceContext(descriptor, this, new OwnerKind.StaticDelegateKind(delegateTo)); } diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/context/FieldOwnerContext.java b/compiler/backend/src/org/jetbrains/jet/codegen/context/FieldOwnerContext.java new file mode 100644 index 00000000000..ece881dda9e --- /dev/null +++ b/compiler/backend/src/org/jetbrains/jet/codegen/context/FieldOwnerContext.java @@ -0,0 +1,73 @@ +/* + * 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.codegen.context; + +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import org.jetbrains.jet.codegen.OwnerKind; +import org.jetbrains.jet.codegen.binding.MutableClosure; +import org.jetbrains.jet.lang.descriptors.*; +import org.jetbrains.jet.lang.resolve.java.JvmAbi; + +import java.util.HashMap; +import java.util.Map; + +public abstract class FieldOwnerContext extends CodegenContext { + + //default property name -> map bytecode name> + private Map> fieldNames = new HashMap>(); + + public FieldOwnerContext( + @NotNull T contextDescriptor, + @NotNull OwnerKind contextKind, + @Nullable CodegenContext parentContext, + @Nullable MutableClosure closure, + @Nullable ClassDescriptor thisDescriptor, + @Nullable LocalLookup expressionCodegen + ) { + super(contextDescriptor, contextKind, parentContext, closure, thisDescriptor, expressionCodegen); + } + + public String getFieldName(PropertyDescriptor descriptor) { + return getFieldName(descriptor, false); + } + + public String getFieldName(PropertyDescriptor descriptor, boolean isDelegated) { + assert descriptor.getKind() != CallableMemberDescriptor.Kind.FAKE_OVERRIDE; + boolean isExtension = descriptor.getReceiverParameter() != null; + + return getFieldName(descriptor, isDelegated, isExtension); + } + + private String getFieldName(PropertyDescriptor descriptor, boolean isDelegated, boolean isExtension) { + descriptor = descriptor.getOriginal(); + String defaultPropertyName = JvmAbi.getDefaultPropertyName(descriptor.getName(), isDelegated, isExtension); + + Map descriptor2Name = fieldNames.get(defaultPropertyName); + if (descriptor2Name == null) { + descriptor2Name = new HashMap(); + fieldNames.put(defaultPropertyName, descriptor2Name); + } + + String actualName = descriptor2Name.get(descriptor); + if (actualName == null) { + actualName = descriptor2Name.isEmpty() ? defaultPropertyName : defaultPropertyName + "$" + descriptor2Name.size(); + descriptor2Name.put(descriptor, actualName); + } + return actualName; + } +} diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/context/NamespaceContext.java b/compiler/backend/src/org/jetbrains/jet/codegen/context/NamespaceContext.java index cf4e893f093..f492af72ae5 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/context/NamespaceContext.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/context/NamespaceContext.java @@ -21,7 +21,7 @@ import org.jetbrains.annotations.Nullable; import org.jetbrains.jet.codegen.OwnerKind; import org.jetbrains.jet.lang.descriptors.NamespaceDescriptor; -public class NamespaceContext extends CodegenContext { +public class NamespaceContext extends FieldOwnerContext { public NamespaceContext(@NotNull NamespaceDescriptor contextDescriptor, @Nullable CodegenContext parent, @NotNull OwnerKind kind) { super(contextDescriptor, kind, parent, null, null, null); } diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/context/ScriptContext.java b/compiler/backend/src/org/jetbrains/jet/codegen/context/ScriptContext.java index 18ad481bf9b..e88efbf9556 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/context/ScriptContext.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/context/ScriptContext.java @@ -23,7 +23,7 @@ import org.jetbrains.jet.codegen.binding.MutableClosure; import org.jetbrains.jet.lang.descriptors.ClassDescriptor; import org.jetbrains.jet.lang.descriptors.ScriptDescriptor; -public class ScriptContext extends CodegenContext { +public class ScriptContext extends FieldOwnerContext { @NotNull private final ScriptDescriptor scriptDescriptor; 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 aa592f4dd02..35e1e2c48cb 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,6 +17,7 @@ package org.jetbrains.jet.lang.resolve.java; import org.jetbrains.annotations.NotNull; +import org.jetbrains.jet.lang.descriptors.PropertyDescriptor; import org.jetbrains.jet.lang.resolve.name.FqName; import org.jetbrains.jet.lang.resolve.name.Name; @@ -59,6 +60,20 @@ public class JvmAbi { return name.asString() + DELEGATED_PROPERTY_NAME_POSTFIX; } + + public static String getDefaultPropertyName(Name propertyName, boolean isDelegated, boolean isExtensionProperty) { + if (isDelegated) { + return getPropertyDelegateName(propertyName); + } + + String name = propertyName.asString(); + if (isExtensionProperty) { + name += "$ext"; + } + return name; + + } + private JvmAbi() { } } 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 ede955951da..fba14d1131c 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/DescriptorUtils.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/DescriptorUtils.java @@ -27,6 +27,7 @@ import org.jetbrains.jet.lang.descriptors.impl.AnonymousFunctionDescriptor; import org.jetbrains.jet.lang.descriptors.impl.NamespaceDescriptorParent; import org.jetbrains.jet.lang.psi.JetElement; import org.jetbrains.jet.lang.psi.JetFunction; +import org.jetbrains.jet.lang.psi.JetParameter; import org.jetbrains.jet.lang.psi.JetProperty; import org.jetbrains.jet.lang.resolve.constants.CompileTimeConstant; import org.jetbrains.jet.lang.resolve.name.FqName; @@ -586,4 +587,13 @@ public class DescriptorUtils { } return (PropertyDescriptor) descriptor; } + + + @NotNull + public static PropertyDescriptor getPropertyDescriptor(@NotNull JetParameter constructorParameter, @NotNull BindingContext bindingContext) { + assert constructorParameter.getValOrVarNode() != null; + PropertyDescriptor descriptor = bindingContext.get(BindingContext.PRIMARY_CONSTRUCTOR_PARAMETER, constructorParameter); + assert descriptor != null; + return descriptor; + } } From 76d4dcef7f2059b16902bbac091d4336add1fb71 Mon Sep 17 00:00:00 2001 From: Mikhael Bogdanov Date: Fri, 7 Jun 2013 14:54:07 +0400 Subject: [PATCH 142/291] Tests for renamed fields --- .../fieldRename/constructorAndClassObject.kt | 16 ++++++++ .../codegen/box/fieldRename/delegates.kt | 26 ++++++++++++ .../fieldRename/genericPropertyWithItself.kt | 14 +++++++ .../codegen/box/fieldRename/inNamespace.kt | 18 ++++++++ .../codegen/box/fieldRename/simple.kt | 22 ++++++++++ .../staticFields/staticClassProperty.java | 2 +- .../staticFields/staticTraitProperty.java | 4 +- .../staticFields/staticTraitProperty.kt | 2 - .../classObject/class/extensionPublicVal.kt | 4 +- .../classObject/class/extensionPublicVar.kt | 4 +- .../rename/constructorAndClassObject.kt | 16 ++++++++ .../rename/delegatedAndDelegated.kt | 31 ++++++++++++++ .../rename/delegatedAndProperty.kt | 31 ++++++++++++++ .../rename/extensionAndExtension.kt | 18 ++++++++ .../rename/extensionAndProperty.kt | 16 ++++++++ .../classObject/rename/propertyAndProperty.kt | 16 ++++++++ .../classObject/trait/extensionPublicVal.kt | 4 +- .../classObject/trait/extensionPublicVar.kt | 4 +- .../codegen/flags/AbstractWriteFlagsTest.java | 2 +- .../flags/WriteFlagsTestGenerated.java | 41 ++++++++++++++++++- .../BlackBoxCodegenTestGenerated.java | 40 ++++++++++++++++-- 21 files changed, 312 insertions(+), 19 deletions(-) create mode 100644 compiler/testData/codegen/box/fieldRename/constructorAndClassObject.kt create mode 100644 compiler/testData/codegen/box/fieldRename/delegates.kt create mode 100644 compiler/testData/codegen/box/fieldRename/genericPropertyWithItself.kt create mode 100644 compiler/testData/codegen/box/fieldRename/inNamespace.kt create mode 100644 compiler/testData/codegen/box/fieldRename/simple.kt create mode 100644 compiler/testData/writeFlags/property/classObject/rename/constructorAndClassObject.kt create mode 100644 compiler/testData/writeFlags/property/classObject/rename/delegatedAndDelegated.kt create mode 100644 compiler/testData/writeFlags/property/classObject/rename/delegatedAndProperty.kt create mode 100644 compiler/testData/writeFlags/property/classObject/rename/extensionAndExtension.kt create mode 100644 compiler/testData/writeFlags/property/classObject/rename/extensionAndProperty.kt create mode 100644 compiler/testData/writeFlags/property/classObject/rename/propertyAndProperty.kt diff --git a/compiler/testData/codegen/box/fieldRename/constructorAndClassObject.kt b/compiler/testData/codegen/box/fieldRename/constructorAndClassObject.kt new file mode 100644 index 00000000000..51997792442 --- /dev/null +++ b/compiler/testData/codegen/box/fieldRename/constructorAndClassObject.kt @@ -0,0 +1,16 @@ +class Test(val prop: String) { + + class object { + public val prop : String = "CO"; + } + +} + + +fun box() : String { + val obj = Test("OK"); + + if (Test.prop != "CO") return "fail1"; + + return obj.prop; +} diff --git a/compiler/testData/codegen/box/fieldRename/delegates.kt b/compiler/testData/codegen/box/fieldRename/delegates.kt new file mode 100644 index 00000000000..82253ca6ccb --- /dev/null +++ b/compiler/testData/codegen/box/fieldRename/delegates.kt @@ -0,0 +1,26 @@ +public open class TestDelegate(private val initializer: () -> T) { + private volatile var value: T? = null + + public open fun get(thisRef: Any?, desc: PropertyMetadata): T { + if (value == null) { + value = initializer() + } + return value!! + } + + public open fun set(thisRef: Any?, desc: PropertyMetadata, svalue : T) { + value = svalue + } +} + +class A {} +class B {} + +public val A.s: String by TestDelegate( {"OK2"}) +public val B.s: String by TestDelegate( {"OK"}) + +fun box() : String { + if (A().s != "OK2") return "fail1" + + return B().s +} diff --git a/compiler/testData/codegen/box/fieldRename/genericPropertyWithItself.kt b/compiler/testData/codegen/box/fieldRename/genericPropertyWithItself.kt new file mode 100644 index 00000000000..e9378c0210d --- /dev/null +++ b/compiler/testData/codegen/box/fieldRename/genericPropertyWithItself.kt @@ -0,0 +1,14 @@ +public class MPair ( + public val first: A +) { + fun equals(o: Any?): Boolean { + val t = o as MPair<*> + return first == t.first + } +} + +fun box(): String { + val a = MPair("O") + a.equals(a) + return "OK" +} \ No newline at end of file diff --git a/compiler/testData/codegen/box/fieldRename/inNamespace.kt b/compiler/testData/codegen/box/fieldRename/inNamespace.kt new file mode 100644 index 00000000000..2629c427876 --- /dev/null +++ b/compiler/testData/codegen/box/fieldRename/inNamespace.kt @@ -0,0 +1,18 @@ +class A { } +class B { } + +public val A.prop: Int = 0; +public val B.prop: String = "1111"; +public val prop: Double = 0.1; + +public fun doTest() : String { + if (A().prop != 0) return "fail1" + if (B().prop != "1111") return "fail2" + if (prop != 0.1) return "fail3" + + return "OK" +} + +fun box() : String { + return doTest() +} diff --git a/compiler/testData/codegen/box/fieldRename/simple.kt b/compiler/testData/codegen/box/fieldRename/simple.kt new file mode 100644 index 00000000000..e2b94b8a27f --- /dev/null +++ b/compiler/testData/codegen/box/fieldRename/simple.kt @@ -0,0 +1,22 @@ +class A { } +class B { } + +class Test { + + public val A.prop: Int = 0; + public val B.prop: String = "1111"; + public val prop: Double = 0.1; + + public fun doTest() : String { + if (A().prop != 0) return "fail1" + if (B().prop != "1111") return "fail2" + if (prop != 0.1) return "fail3" + + return "OK" + } +} + + +fun box() : String { + return Test().doTest() +} diff --git a/compiler/testData/compileJavaAgainstKotlin/staticFields/staticClassProperty.java b/compiler/testData/compileJavaAgainstKotlin/staticFields/staticClassProperty.java index 7b4a231ad93..454f8333471 100644 --- a/compiler/testData/compileJavaAgainstKotlin/staticFields/staticClassProperty.java +++ b/compiler/testData/compileJavaAgainstKotlin/staticFields/staticClassProperty.java @@ -1,4 +1,4 @@ -class staticProperty { +class staticClassProperty { public static void main(String[] args) { int i = Test.valProp; diff --git a/compiler/testData/compileJavaAgainstKotlin/staticFields/staticTraitProperty.java b/compiler/testData/compileJavaAgainstKotlin/staticFields/staticTraitProperty.java index 7b4a231ad93..0970136d3ba 100644 --- a/compiler/testData/compileJavaAgainstKotlin/staticFields/staticTraitProperty.java +++ b/compiler/testData/compileJavaAgainstKotlin/staticFields/staticTraitProperty.java @@ -1,8 +1,6 @@ -class staticProperty { +class staticTraitProperty { public static void main(String[] args) { int i = Test.valProp; - int j = Test.varProp; - Test.varProp = 100; } } \ No newline at end of file diff --git a/compiler/testData/compileJavaAgainstKotlin/staticFields/staticTraitProperty.kt b/compiler/testData/compileJavaAgainstKotlin/staticFields/staticTraitProperty.kt index 19d8e7c1fa2..ec78be164c0 100644 --- a/compiler/testData/compileJavaAgainstKotlin/staticFields/staticTraitProperty.kt +++ b/compiler/testData/compileJavaAgainstKotlin/staticFields/staticTraitProperty.kt @@ -2,8 +2,6 @@ trait Test { class object { public val valProp: Int = 10 - - public var varProp: Int = 10 } } \ No newline at end of file diff --git a/compiler/testData/writeFlags/property/classObject/class/extensionPublicVal.kt b/compiler/testData/writeFlags/property/classObject/class/extensionPublicVal.kt index ade829c8e40..96026758538 100644 --- a/compiler/testData/writeFlags/property/classObject/class/extensionPublicVal.kt +++ b/compiler/testData/writeFlags/property/classObject/class/extensionPublicVal.kt @@ -5,9 +5,9 @@ class Test { } // TESTED_OBJECT_KIND: property -// TESTED_OBJECTS: Test, prop +// TESTED_OBJECTS: Test, prop$ext // FLAGS: ACC_FINAL, ACC_STATIC, ACC_PRIVATE // TESTED_OBJECT_KIND: property -// TESTED_OBJECTS: Test$object, prop +// TESTED_OBJECTS: Test$object, prop$ext // ABSENT: TRUE \ No newline at end of file diff --git a/compiler/testData/writeFlags/property/classObject/class/extensionPublicVar.kt b/compiler/testData/writeFlags/property/classObject/class/extensionPublicVar.kt index a7ce2e266ee..2a7b58e901e 100644 --- a/compiler/testData/writeFlags/property/classObject/class/extensionPublicVar.kt +++ b/compiler/testData/writeFlags/property/classObject/class/extensionPublicVar.kt @@ -5,9 +5,9 @@ class Test { } // TESTED_OBJECT_KIND: property -// TESTED_OBJECTS: Test, prop +// TESTED_OBJECTS: Test, prop$ext // FLAGS: ACC_STATIC, ACC_PRIVATE // TESTED_OBJECT_KIND: property -// TESTED_OBJECTS: Test$object, prop +// TESTED_OBJECTS: Test$object, prop$ext // ABSENT: TRUE \ No newline at end of file diff --git a/compiler/testData/writeFlags/property/classObject/rename/constructorAndClassObject.kt b/compiler/testData/writeFlags/property/classObject/rename/constructorAndClassObject.kt new file mode 100644 index 00000000000..2e8655c2559 --- /dev/null +++ b/compiler/testData/writeFlags/property/classObject/rename/constructorAndClassObject.kt @@ -0,0 +1,16 @@ +class Test(val prop: String) { + + class object { + public val prop : String = "CO"; + } + +} + + +// TESTED_OBJECT_KIND: property +// TESTED_OBJECTS: Test, prop$1 +// FLAGS: ACC_PRIVATE, ACC_FINAL + +// TESTED_OBJECT_KIND: property +// TESTED_OBJECTS: Test, prop +// FLAGS: ACC_STATIC, ACC_PUBLIC, ACC_FINAL \ No newline at end of file diff --git a/compiler/testData/writeFlags/property/classObject/rename/delegatedAndDelegated.kt b/compiler/testData/writeFlags/property/classObject/rename/delegatedAndDelegated.kt new file mode 100644 index 00000000000..cadaf47e7a8 --- /dev/null +++ b/compiler/testData/writeFlags/property/classObject/rename/delegatedAndDelegated.kt @@ -0,0 +1,31 @@ +public open class TestDelegate(private val initializer: () -> T) { + private volatile var value: T? = null + + public open fun get(thisRef: Any?, desc: PropertyMetadata): T { + if (value == null) { + value = initializer() + } + return value!! + } + + public open fun set(thisRef: Any?, desc: PropertyMetadata, svalue : T) { + value = svalue + } +} + +class Test { + + public val prop: Int by TestDelegate({10}) + + class object { + public var prop: Int by TestDelegate({10}) + } +} + +// TESTED_OBJECT_KIND: property +// TESTED_OBJECTS: Test, prop$delegate$1 +// FLAGS: ACC_PRIVATE, ACC_FINAL + +// TESTED_OBJECT_KIND: property +// TESTED_OBJECTS: Test, prop$delegate +// FLAGS: ACC_STATIC, ACC_PRIVATE, ACC_FINAL \ No newline at end of file diff --git a/compiler/testData/writeFlags/property/classObject/rename/delegatedAndProperty.kt b/compiler/testData/writeFlags/property/classObject/rename/delegatedAndProperty.kt new file mode 100644 index 00000000000..f9d89660b04 --- /dev/null +++ b/compiler/testData/writeFlags/property/classObject/rename/delegatedAndProperty.kt @@ -0,0 +1,31 @@ +public open class TestDelegate(private val initializer: () -> T) { + private volatile var value: T? = null + + public open fun get(thisRef: Any?, desc: PropertyMetadata): T { + if (value == null) { + value = initializer() + } + return value!! + } + + public open fun set(thisRef: Any?, desc: PropertyMetadata, svalue : T) { + value = svalue + } +} + +class Test { + + public var prop: String = "" + + class object { + public var prop: Int by TestDelegate({10}) + } +} + +// TESTED_OBJECT_KIND: property +// TESTED_OBJECTS: Test, prop +// FLAGS: ACC_PRIVATE + +// TESTED_OBJECT_KIND: property +// TESTED_OBJECTS: Test, prop$delegate +// FLAGS: ACC_STATIC, ACC_PRIVATE, ACC_FINAL diff --git a/compiler/testData/writeFlags/property/classObject/rename/extensionAndExtension.kt b/compiler/testData/writeFlags/property/classObject/rename/extensionAndExtension.kt new file mode 100644 index 00000000000..a35f992a47a --- /dev/null +++ b/compiler/testData/writeFlags/property/classObject/rename/extensionAndExtension.kt @@ -0,0 +1,18 @@ +class A { } +class B { } + +class Test { + + class object { + public val A.prop: Int = 0; + public val B.prop: Int = 0; + } +} + +// TESTED_OBJECT_KIND: property +// TESTED_OBJECTS: Test, prop$ext +// FLAGS: ACC_PRIVATE, ACC_FINAL, ACC_STATIC + +// TESTED_OBJECT_KIND: property +// TESTED_OBJECTS: Test, prop$ext$1 +// FLAGS: ACC_PRIVATE, ACC_FINAL, ACC_STATIC diff --git a/compiler/testData/writeFlags/property/classObject/rename/extensionAndProperty.kt b/compiler/testData/writeFlags/property/classObject/rename/extensionAndProperty.kt new file mode 100644 index 00000000000..a8ad2764c6e --- /dev/null +++ b/compiler/testData/writeFlags/property/classObject/rename/extensionAndProperty.kt @@ -0,0 +1,16 @@ +class Test { + + public val prop: Int = 0; + + class object { + public var Test.prop: Int = 0; + } +} + +// TESTED_OBJECT_KIND: property +// TESTED_OBJECTS: Test, prop +// FLAGS: ACC_PRIVATE, ACC_FINAL + +// TESTED_OBJECT_KIND: property +// TESTED_OBJECTS: Test, prop$ext +// FLAGS: ACC_STATIC, ACC_PRIVATE diff --git a/compiler/testData/writeFlags/property/classObject/rename/propertyAndProperty.kt b/compiler/testData/writeFlags/property/classObject/rename/propertyAndProperty.kt new file mode 100644 index 00000000000..ad56dca52cb --- /dev/null +++ b/compiler/testData/writeFlags/property/classObject/rename/propertyAndProperty.kt @@ -0,0 +1,16 @@ +class Test { + + public var prop: Int = 0; + + class object { + public val prop: Int = 0; + } +} + +// TESTED_OBJECT_KIND: property +// TESTED_OBJECTS: Test, prop$1 +// FLAGS: ACC_PRIVATE + +// TESTED_OBJECT_KIND: property +// TESTED_OBJECTS: Test, prop +// FLAGS: ACC_STATIC, ACC_PUBLIC, ACC_FINAL \ No newline at end of file diff --git a/compiler/testData/writeFlags/property/classObject/trait/extensionPublicVal.kt b/compiler/testData/writeFlags/property/classObject/trait/extensionPublicVal.kt index 0f9fd18d933..0b05cf2ea99 100644 --- a/compiler/testData/writeFlags/property/classObject/trait/extensionPublicVal.kt +++ b/compiler/testData/writeFlags/property/classObject/trait/extensionPublicVal.kt @@ -5,9 +5,9 @@ trait Test { } // TESTED_OBJECT_KIND: property -// TESTED_OBJECTS: Test, prop +// TESTED_OBJECTS: Test, prop$ext // ABSENT: TRUE // TESTED_OBJECT_KIND: property -// TESTED_OBJECTS: Test$object, prop +// TESTED_OBJECTS: Test$object, prop$ext // FLAGS: ACC_FINAL, ACC_PRIVATE \ No newline at end of file diff --git a/compiler/testData/writeFlags/property/classObject/trait/extensionPublicVar.kt b/compiler/testData/writeFlags/property/classObject/trait/extensionPublicVar.kt index 4fd4b033c49..a6450f3cf6c 100644 --- a/compiler/testData/writeFlags/property/classObject/trait/extensionPublicVar.kt +++ b/compiler/testData/writeFlags/property/classObject/trait/extensionPublicVar.kt @@ -5,9 +5,9 @@ trait Test { } // TESTED_OBJECT_KIND: property -// TESTED_OBJECTS: Test, prop +// TESTED_OBJECTS: Test, prop$ext // ABSENT: TRUE // TESTED_OBJECT_KIND: property -// TESTED_OBJECTS: Test$object, prop +// TESTED_OBJECTS: Test$object, prop$ext // FLAGS: ACC_PRIVATE \ No newline at end of file diff --git a/compiler/tests/org/jetbrains/jet/codegen/flags/AbstractWriteFlagsTest.java b/compiler/tests/org/jetbrains/jet/codegen/flags/AbstractWriteFlagsTest.java index cad9423b32d..439d1486c2c 100644 --- a/compiler/tests/org/jetbrains/jet/codegen/flags/AbstractWriteFlagsTest.java +++ b/compiler/tests/org/jetbrains/jet/codegen/flags/AbstractWriteFlagsTest.java @@ -105,7 +105,7 @@ public abstract class AbstractWriteFlagsTest extends UsefulTestCase { int expectedAccess = getExpectedFlags(testedObject.textData); if (isObjectExists) { - assertEquals("Wrong access flag \n" + factory.asText(className), expectedAccess, classVisitor.getAccess()); + assertEquals("Wrong access flag for " + testedObject + " \n" + factory.asText(className), expectedAccess, classVisitor.getAccess()); } } } diff --git a/compiler/tests/org/jetbrains/jet/codegen/flags/WriteFlagsTestGenerated.java b/compiler/tests/org/jetbrains/jet/codegen/flags/WriteFlagsTestGenerated.java index 245663a34e8..3070770fdad 100644 --- a/compiler/tests/org/jetbrains/jet/codegen/flags/WriteFlagsTestGenerated.java +++ b/compiler/tests/org/jetbrains/jet/codegen/flags/WriteFlagsTestGenerated.java @@ -473,7 +473,7 @@ public class WriteFlagsTestGenerated extends AbstractWriteFlagsTest { } @TestMetadata("compiler/testData/writeFlags/property/classObject") - @InnerTestClasses({ClassObject.Class.class, ClassObject.Trait.class}) + @InnerTestClasses({ClassObject.Class.class, ClassObject.Rename.class, ClassObject.Trait.class}) public static class ClassObject extends AbstractWriteFlagsTest { public void testAllFilesPresentInClassObject() throws Exception { JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.GenerateTests", new File("compiler/testData/writeFlags/property/classObject"), Pattern.compile("^(.+)\\.kt$"), true); @@ -582,6 +582,44 @@ public class WriteFlagsTestGenerated extends AbstractWriteFlagsTest { } + @TestMetadata("compiler/testData/writeFlags/property/classObject/rename") + public static class Rename extends AbstractWriteFlagsTest { + public void testAllFilesPresentInRename() throws Exception { + JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.GenerateTests", new File("compiler/testData/writeFlags/property/classObject/rename"), Pattern.compile("^(.+)\\.kt$"), true); + } + + @TestMetadata("constructorAndClassObject.kt") + public void testConstructorAndClassObject() throws Exception { + doTest("compiler/testData/writeFlags/property/classObject/rename/constructorAndClassObject.kt"); + } + + @TestMetadata("delegatedAndDelegated.kt") + public void testDelegatedAndDelegated() throws Exception { + doTest("compiler/testData/writeFlags/property/classObject/rename/delegatedAndDelegated.kt"); + } + + @TestMetadata("delegatedAndProperty.kt") + public void testDelegatedAndProperty() throws Exception { + doTest("compiler/testData/writeFlags/property/classObject/rename/delegatedAndProperty.kt"); + } + + @TestMetadata("extensionAndExtension.kt") + public void testExtensionAndExtension() throws Exception { + doTest("compiler/testData/writeFlags/property/classObject/rename/extensionAndExtension.kt"); + } + + @TestMetadata("extensionAndProperty.kt") + public void testExtensionAndProperty() throws Exception { + doTest("compiler/testData/writeFlags/property/classObject/rename/extensionAndProperty.kt"); + } + + @TestMetadata("propertyAndProperty.kt") + public void testPropertyAndProperty() throws Exception { + doTest("compiler/testData/writeFlags/property/classObject/rename/propertyAndProperty.kt"); + } + + } + @TestMetadata("compiler/testData/writeFlags/property/classObject/trait") public static class Trait extends AbstractWriteFlagsTest { public void testAllFilesPresentInTrait() throws Exception { @@ -689,6 +727,7 @@ public class WriteFlagsTestGenerated extends AbstractWriteFlagsTest { TestSuite suite = new TestSuite("ClassObject"); suite.addTestSuite(ClassObject.class); suite.addTestSuite(Class.class); + suite.addTestSuite(Rename.class); suite.addTestSuite(Trait.class); return suite; } diff --git a/compiler/tests/org/jetbrains/jet/codegen/generated/BlackBoxCodegenTestGenerated.java b/compiler/tests/org/jetbrains/jet/codegen/generated/BlackBoxCodegenTestGenerated.java index d874af8313d..2d1b4df5978 100644 --- a/compiler/tests/org/jetbrains/jet/codegen/generated/BlackBoxCodegenTestGenerated.java +++ b/compiler/tests/org/jetbrains/jet/codegen/generated/BlackBoxCodegenTestGenerated.java @@ -31,7 +31,7 @@ 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/box") -@InnerTestClasses({BlackBoxCodegenTestGenerated.Arrays.class, BlackBoxCodegenTestGenerated.Bridges.class, BlackBoxCodegenTestGenerated.CallableReference.class, BlackBoxCodegenTestGenerated.Casts.class, BlackBoxCodegenTestGenerated.Classes.class, BlackBoxCodegenTestGenerated.Closures.class, BlackBoxCodegenTestGenerated.ControlStructures.class, BlackBoxCodegenTestGenerated.DefaultArguments.class, BlackBoxCodegenTestGenerated.DelegatedProperty.class, BlackBoxCodegenTestGenerated.Elvis.class, BlackBoxCodegenTestGenerated.Enum.class, BlackBoxCodegenTestGenerated.ExclExcl.class, BlackBoxCodegenTestGenerated.ExtensionFunctions.class, BlackBoxCodegenTestGenerated.ExtensionProperties.class, BlackBoxCodegenTestGenerated.Functions.class, BlackBoxCodegenTestGenerated.InnerNested.class, BlackBoxCodegenTestGenerated.Instructions.class, BlackBoxCodegenTestGenerated.Intrinsics.class, BlackBoxCodegenTestGenerated.Labels.class, BlackBoxCodegenTestGenerated.LocalClasses.class, BlackBoxCodegenTestGenerated.MultiDecl.class, BlackBoxCodegenTestGenerated.Namespace.class, BlackBoxCodegenTestGenerated.Objects.class, BlackBoxCodegenTestGenerated.OperatorConventions.class, BlackBoxCodegenTestGenerated.PrimitiveTypes.class, BlackBoxCodegenTestGenerated.Properties.class, BlackBoxCodegenTestGenerated.Reflection.class, BlackBoxCodegenTestGenerated.SafeCall.class, BlackBoxCodegenTestGenerated.Sam.class, BlackBoxCodegenTestGenerated.Strings.class, BlackBoxCodegenTestGenerated.Super.class, BlackBoxCodegenTestGenerated.Traits.class, BlackBoxCodegenTestGenerated.TypeInfo.class, BlackBoxCodegenTestGenerated.Unit.class, BlackBoxCodegenTestGenerated.Vararg.class, BlackBoxCodegenTestGenerated.When.class}) +@InnerTestClasses({BlackBoxCodegenTestGenerated.Arrays.class, BlackBoxCodegenTestGenerated.Bridges.class, BlackBoxCodegenTestGenerated.CallableReference.class, BlackBoxCodegenTestGenerated.Casts.class, BlackBoxCodegenTestGenerated.Classes.class, BlackBoxCodegenTestGenerated.Closures.class, BlackBoxCodegenTestGenerated.ControlStructures.class, BlackBoxCodegenTestGenerated.DefaultArguments.class, BlackBoxCodegenTestGenerated.DelegatedProperty.class, BlackBoxCodegenTestGenerated.Elvis.class, BlackBoxCodegenTestGenerated.Enum.class, BlackBoxCodegenTestGenerated.ExclExcl.class, BlackBoxCodegenTestGenerated.ExtensionFunctions.class, BlackBoxCodegenTestGenerated.ExtensionProperties.class, BlackBoxCodegenTestGenerated.FieldRename.class, BlackBoxCodegenTestGenerated.Functions.class, BlackBoxCodegenTestGenerated.InnerNested.class, BlackBoxCodegenTestGenerated.Instructions.class, BlackBoxCodegenTestGenerated.Intrinsics.class, BlackBoxCodegenTestGenerated.Labels.class, BlackBoxCodegenTestGenerated.LocalClasses.class, BlackBoxCodegenTestGenerated.MultiDecl.class, BlackBoxCodegenTestGenerated.Namespace.class, BlackBoxCodegenTestGenerated.Objects.class, BlackBoxCodegenTestGenerated.OperatorConventions.class, BlackBoxCodegenTestGenerated.PrimitiveTypes.class, BlackBoxCodegenTestGenerated.Properties.class, BlackBoxCodegenTestGenerated.Reflection.class, BlackBoxCodegenTestGenerated.SafeCall.class, BlackBoxCodegenTestGenerated.Sam.class, BlackBoxCodegenTestGenerated.Strings.class, BlackBoxCodegenTestGenerated.Super.class, BlackBoxCodegenTestGenerated.Traits.class, BlackBoxCodegenTestGenerated.TypeInfo.class, BlackBoxCodegenTestGenerated.Unit.class, BlackBoxCodegenTestGenerated.Vararg.class, BlackBoxCodegenTestGenerated.When.class}) public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest { public void testAllFilesPresentInBox() throws Exception { JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.GenerateTests", new File("compiler/testData/codegen/box"), Pattern.compile("^(.+)\\.kt$"), true); @@ -1551,8 +1551,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 { @@ -2038,6 +2038,39 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest { } + @TestMetadata("compiler/testData/codegen/box/fieldRename") + public static class FieldRename extends AbstractBlackBoxCodegenTest { + public void testAllFilesPresentInFieldRename() throws Exception { + JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.GenerateTests", new File("compiler/testData/codegen/box/fieldRename"), Pattern.compile("^(.+)\\.kt$"), true); + } + + @TestMetadata("constructorAndClassObject.kt") + public void testConstructorAndClassObject() throws Exception { + doTest("compiler/testData/codegen/box/fieldRename/constructorAndClassObject.kt"); + } + + @TestMetadata("delegates.kt") + public void testDelegates() throws Exception { + doTest("compiler/testData/codegen/box/fieldRename/delegates.kt"); + } + + @TestMetadata("genericPropertyWithItself.kt") + public void testGenericPropertyWithItself() throws Exception { + doTest("compiler/testData/codegen/box/fieldRename/genericPropertyWithItself.kt"); + } + + @TestMetadata("inNamespace.kt") + public void testInNamespace() throws Exception { + doTest("compiler/testData/codegen/box/fieldRename/inNamespace.kt"); + } + + @TestMetadata("simple.kt") + public void testSimple() throws Exception { + doTest("compiler/testData/codegen/box/fieldRename/simple.kt"); + } + + } + @TestMetadata("compiler/testData/codegen/box/functions") @InnerTestClasses({Functions.LocalFunctions.class}) public static class Functions extends AbstractBlackBoxCodegenTest { @@ -4093,6 +4126,7 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest { suite.addTestSuite(ExclExcl.class); suite.addTestSuite(ExtensionFunctions.class); suite.addTestSuite(ExtensionProperties.class); + suite.addTestSuite(FieldRename.class); suite.addTest(Functions.innerSuite()); suite.addTestSuite(InnerNested.class); suite.addTest(Instructions.innerSuite()); From 52ead7a35002886f4daf4281c539d7b69f6e50e9 Mon Sep 17 00:00:00 2001 From: Mikhael Bogdanov Date: Mon, 17 Jun 2013 17:25:19 +0400 Subject: [PATCH 143/291] Fix for static - write NEED_SYNTHETIC flag on original descriptor --- .../calls/NeedSyntheticCallResolverExtension.java | 2 +- .../classObjectWithPrivateGenericMember.kt | 15 +++++++++++++++ .../generated/BlackBoxCodegenTestGenerated.java | 5 +++++ 3 files changed, 21 insertions(+), 1 deletion(-) create mode 100644 compiler/testData/codegen/box/classes/classObjectWithPrivateGenericMember.kt diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/NeedSyntheticCallResolverExtension.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/NeedSyntheticCallResolverExtension.java index bebcce131aa..4fe67020909 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/NeedSyntheticCallResolverExtension.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/NeedSyntheticCallResolverExtension.java @@ -38,7 +38,7 @@ public class NeedSyntheticCallResolverExtension implements CallResolverExtension ResolvedCallWithTrace resolvedCall = results.getResultingCall(); CallableDescriptor targetDescriptor = resolvedCall.getResultingDescriptor(); if (needSyntheticAccessor(context.scope, targetDescriptor)) { - context.trace.record(NEED_SYNTHETIC_ACCESSOR, (CallableMemberDescriptor) targetDescriptor, Boolean.TRUE); + context.trace.record(NEED_SYNTHETIC_ACCESSOR, (CallableMemberDescriptor) targetDescriptor.getOriginal(), Boolean.TRUE); } } } diff --git a/compiler/testData/codegen/box/classes/classObjectWithPrivateGenericMember.kt b/compiler/testData/codegen/box/classes/classObjectWithPrivateGenericMember.kt new file mode 100644 index 00000000000..3e10c304bf0 --- /dev/null +++ b/compiler/testData/codegen/box/classes/classObjectWithPrivateGenericMember.kt @@ -0,0 +1,15 @@ +class C() { + class object { + private fun create() = C() + } + + class ZZZ { + val c = C.create() + } +} + +fun box(): String { + C.ZZZ().c + 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 2d1b4df5978..47093a14d48 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("classObjectWithPrivateGenericMember.kt") + public void testClassObjectWithPrivateGenericMember() throws Exception { + doTest("compiler/testData/codegen/box/classes/classObjectWithPrivateGenericMember.kt"); + } + @TestMetadata("classObjectsWithParentClasses.kt") public void testClassObjectsWithParentClasses() throws Exception { doTest("compiler/testData/codegen/box/classes/classObjectsWithParentClasses.kt"); From e803bcb3d9b304305ae407070ec628107b437477 Mon Sep 17 00:00:00 2001 From: Mikhael Bogdanov Date: Mon, 17 Jun 2013 17:31:07 +0400 Subject: [PATCH 144/291] Fix for KT-3687 #KT-3687 Fixed --- .../jvm/compiler/CompileEnvironmentUtil.java | 78 +++++-------------- 1 file changed, 19 insertions(+), 59 deletions(-) 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 e8ccfee3774..da704f6a59f 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 @@ -21,7 +21,6 @@ import com.intellij.openapi.util.Disposer; import com.intellij.openapi.util.io.FileUtil; import com.intellij.openapi.util.io.FileUtilRt; import com.intellij.util.Function; -import com.intellij.util.Processor; import com.intellij.util.containers.ContainerUtil; import jet.modules.AllModules; import jet.modules.Module; @@ -69,22 +68,9 @@ public class CompileEnvironmentUtil { } @Nullable - public static File getUnpackedRuntimePath() { - URL url = KotlinToJVMBytecodeCompiler.class.getClassLoader().getResource("jet/JetObject.class"); - if (url != null && url.getProtocol().equals("file")) { - return new File(url.getPath()).getParentFile().getParentFile(); - } - return null; - } - - @Nullable - public static File getRuntimeJarPath() { - URL url = KotlinToJVMBytecodeCompiler.class.getClassLoader().getResource("jet/JetObject.class"); - if (url != null && url.getProtocol().equals("jar")) { - String path = url.getPath(); - return new File(path.substring(path.indexOf(":") + 1, path.indexOf("!/"))); - } - return null; + private static File getRuntimeJarPath() { + File runtimePath = PathUtil.getKotlinPathsForCompiler().getRuntimePath(); + return runtimePath.exists() ? runtimePath : null; } @NotNull @@ -221,53 +207,27 @@ public class CompileEnvironmentUtil { } private static void writeRuntimeToJar(final JarOutputStream stream) throws IOException { - final File unpackedRuntimePath = getUnpackedRuntimePath(); - if (unpackedRuntimePath != null) { - FileUtil.processFilesRecursively(unpackedRuntimePath, new Processor() { - @Override - public boolean process(File file) { - if (file.isDirectory()) return true; - String relativePath = FileUtil.getRelativePath(unpackedRuntimePath, file); - try { - stream.putNextEntry(new JarEntry(FileUtil.toSystemIndependentName(relativePath))); - FileInputStream fis = new FileInputStream(file); - try { - FileUtil.copy(fis, stream); - } - finally { - fis.close(); - } + File runtimeJarPath = getRuntimeJarPath(); + if (runtimeJarPath != null) { + JarInputStream jis = new JarInputStream(new FileInputStream(runtimeJarPath)); + try { + while (true) { + JarEntry e = jis.getNextJarEntry(); + if (e == null) { + break; } - catch (IOException e) { - throw new RuntimeException(e); + if (FileUtilRt.extensionEquals(e.getName(), "class")) { + stream.putNextEntry(e); + FileUtil.copy(jis, stream); } - return true; } - }); + } + finally { + jis.close(); + } } else { - File runtimeJarPath = getRuntimeJarPath(); - if (runtimeJarPath != null) { - JarInputStream jis = new JarInputStream(new FileInputStream(runtimeJarPath)); - try { - while (true) { - JarEntry e = jis.getNextJarEntry(); - if (e == null) { - break; - } - if (FileUtil.getExtension(e.getName()).equals("class")) { - stream.putNextEntry(e); - FileUtil.copy(jis, stream); - } - } - } - finally { - jis.close(); - } - } - else { - throw new CompileEnvironmentException("Couldn't find runtime library"); - } + throw new CompileEnvironmentException("Couldn't find runtime library"); } } From 03a818f732897b42310843465724905953a2d306 Mon Sep 17 00:00:00 2001 From: Alexander Udalov Date: Mon, 17 Jun 2013 21:50:20 +0400 Subject: [PATCH 145/291] Regenerate tests --- .../jet/codegen/generated/BlackBoxCodegenTestGenerated.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/compiler/tests/org/jetbrains/jet/codegen/generated/BlackBoxCodegenTestGenerated.java b/compiler/tests/org/jetbrains/jet/codegen/generated/BlackBoxCodegenTestGenerated.java index 47093a14d48..a6e538735e7 100644 --- a/compiler/tests/org/jetbrains/jet/codegen/generated/BlackBoxCodegenTestGenerated.java +++ b/compiler/tests/org/jetbrains/jet/codegen/generated/BlackBoxCodegenTestGenerated.java @@ -1556,8 +1556,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 8ac879826607a9180c73cfaa0c61f47c8a30b53a Mon Sep 17 00:00:00 2001 From: Mikhael Bogdanov Date: Tue, 18 Jun 2013 10:55:53 +0400 Subject: [PATCH 146/291] Fix for KT-3684: IllegalAccess on a private property of the outer class #KT-3684 Fixed --- .../jet/lang/resolve/OverrideResolver.java | 7 ++++--- compiler/testData/codegen/box/objects/kt3684.kt | 16 ++++++++++++++++ .../generated/BlackBoxCodegenTestGenerated.java | 5 +++++ 3 files changed, 25 insertions(+), 3 deletions(-) create mode 100644 compiler/testData/codegen/box/objects/kt3684.kt 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 e1bca7991dd..c76866d56cf 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/OverrideResolver.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/OverrideResolver.java @@ -252,7 +252,7 @@ public class OverrideResolver { @NotNull ClassDescriptor current, @NotNull DescriptorSink sink ) { - Collection visibleOverridables = filterVisible(current, overridables); + Collection visibleOverridables = filterVisibleFakeOverrides(current, overridables); Modality modality = getMinimalModality(visibleOverridables); boolean allInvisible = visibleOverridables.isEmpty(); Collection effectiveOverridden = allInvisible ? overridables : visibleOverridables; @@ -277,14 +277,15 @@ public class OverrideResolver { } @NotNull - private static Collection filterVisible( + private static Collection filterVisibleFakeOverrides( @NotNull final ClassDescriptor current, @NotNull Collection toFilter ) { return Collections2.filter(toFilter, new Predicate() { @Override public boolean apply(@Nullable CallableMemberDescriptor descriptor) { - return Visibilities.isVisible(descriptor, current); + //nested class could capture private member, so check for private visibility added + return descriptor.getVisibility() != Visibilities.PRIVATE && Visibilities.isVisible(descriptor, current); } }); } diff --git a/compiler/testData/codegen/box/objects/kt3684.kt b/compiler/testData/codegen/box/objects/kt3684.kt new file mode 100644 index 00000000000..53e742f1764 --- /dev/null +++ b/compiler/testData/codegen/box/objects/kt3684.kt @@ -0,0 +1,16 @@ +open class X(private val n: String) { + + fun foo(): String { + return object : X("inner") { + fun print(): String { + return n; + } + }.print() + } +} + + +fun box() : String { + return X("OK").foo() +} + diff --git a/compiler/tests/org/jetbrains/jet/codegen/generated/BlackBoxCodegenTestGenerated.java b/compiler/tests/org/jetbrains/jet/codegen/generated/BlackBoxCodegenTestGenerated.java index a6e538735e7..5f3f94a2501 100644 --- a/compiler/tests/org/jetbrains/jet/codegen/generated/BlackBoxCodegenTestGenerated.java +++ b/compiler/tests/org/jetbrains/jet/codegen/generated/BlackBoxCodegenTestGenerated.java @@ -3168,6 +3168,11 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest { doTest("compiler/testData/codegen/box/objects/kt3238.kt"); } + @TestMetadata("kt3684.kt") + public void testKt3684() throws Exception { + doTest("compiler/testData/codegen/box/objects/kt3684.kt"); + } + @TestMetadata("kt535.kt") public void testKt535() throws Exception { doTest("compiler/testData/codegen/box/objects/kt535.kt"); From 79cf02ffb9c4908f09481bdb4219403240af7305 Mon Sep 17 00:00:00 2001 From: Mikhael Bogdanov Date: Tue, 18 Jun 2013 12:59:48 +0400 Subject: [PATCH 147/291] Fix for KT-3546: Exception when delegating to ArrayList #KT-3546 Fixed --- .../jet/codegen/FunctionCodegen.java | 3 ++- .../jet/lang/resolve/BindingContextUtils.java | 7 +++--- .../testData/codegen/box/classes/kt3546.kt | 25 +++++++++++++++++++ .../BlackBoxCodegenTestGenerated.java | 5 ++++ 4 files changed, 35 insertions(+), 5 deletions(-) create mode 100644 compiler/testData/codegen/box/classes/kt3546.kt diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/FunctionCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/FunctionCodegen.java index 697c37b290f..d0e6525faeb 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/FunctionCodegen.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/FunctionCodegen.java @@ -817,7 +817,8 @@ public class FunctionCodegen extends GenerationStateAware { StackValue.onStack(overriddenMethod.getReturnType()).put(delegateMethod.getReturnType(), iv); iv.areturn(delegateMethod.getReturnType()); - endVisit(mv, "delegate method", descriptorToDeclaration(bindingContext, functionDescriptor)); + endVisit(mv, "Delegate method " + functionDescriptor + " to " + jvmOverriddenMethodSignature, + descriptorToDeclaration(bindingContext, functionDescriptor.getContainingDeclaration())); generateBridgeIfNeeded(owner, state, v, jvmDelegateMethodSignature.getAsmMethod(), functionDescriptor); } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/BindingContextUtils.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/BindingContextUtils.java index 9ed613a5664..432abc27819 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/BindingContextUtils.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/BindingContextUtils.java @@ -17,6 +17,7 @@ package org.jetbrains.jet.lang.resolve; import com.google.common.collect.Lists; +import com.intellij.openapi.util.text.StringUtil; import com.intellij.psi.PsiElement; import com.intellij.psi.PsiFile; import com.intellij.psi.util.PsiTreeUtil; @@ -25,8 +26,6 @@ import org.jetbrains.annotations.Nullable; import org.jetbrains.jet.lang.descriptors.*; import org.jetbrains.jet.lang.psi.*; import org.jetbrains.jet.lang.resolve.calls.autocasts.DataFlowInfo; -import org.jetbrains.jet.lang.resolve.calls.context.ResolutionContext; -import org.jetbrains.jet.lang.resolve.calls.context.ResolutionResultsCache; import org.jetbrains.jet.lang.resolve.calls.model.ResolvedCall; import org.jetbrains.jet.lang.resolve.calls.model.VariableAsFunctionResolvedCall; import org.jetbrains.jet.lang.resolve.scopes.JetScope; @@ -34,7 +33,6 @@ import org.jetbrains.jet.lang.types.JetType; import org.jetbrains.jet.lang.types.JetTypeInfo; import org.jetbrains.jet.util.slicedmap.ReadOnlySlice; import org.jetbrains.jet.util.slicedmap.Slices; -import org.jetbrains.jet.util.slicedmap.WritableSlice; import java.util.*; @@ -188,7 +186,8 @@ public class BindingContextUtils { Set overriddenDescriptors = callable.getOverriddenDescriptors(); if (overriddenDescriptors.size() != 1) { throw new IllegalStateException( - "cannot find declaration: fake descriptor has more than one overridden descriptor: " + callable); + "Cannot find declaration: fake descriptor " + callable + " has more than one overridden descriptor:\n" + + StringUtil.join(overriddenDescriptors, ",\n")); } return callableDescriptorToDeclaration(context, overriddenDescriptors.iterator().next()); diff --git a/compiler/testData/codegen/box/classes/kt3546.kt b/compiler/testData/codegen/box/classes/kt3546.kt new file mode 100644 index 00000000000..4fb5ce41dd3 --- /dev/null +++ b/compiler/testData/codegen/box/classes/kt3546.kt @@ -0,0 +1,25 @@ +trait A { + fun test(): String +} + +trait B { + fun test(): String +} + +trait C: A, B + +class Z(val param: String): C { + + override fun test(): String { + return param + } +} + +public class MyClass(val value : C) : C by value { + +} + +fun box(): String { + val s = MyClass(Z("OK")) + return s.test() +} \ 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 5f3f94a2501..240dbad08db 100644 --- a/compiler/tests/org/jetbrains/jet/codegen/generated/BlackBoxCodegenTestGenerated.java +++ b/compiler/tests/org/jetbrains/jet/codegen/generated/BlackBoxCodegenTestGenerated.java @@ -970,6 +970,11 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest { doTest("compiler/testData/codegen/box/classes/kt343.kt"); } + @TestMetadata("kt3546.kt") + public void testKt3546() throws Exception { + doTest("compiler/testData/codegen/box/classes/kt3546.kt"); + } + @TestMetadata("kt454.kt") public void testKt454() throws Exception { doTest("compiler/testData/codegen/box/classes/kt454.kt"); From 86f2a6dc69492cb5f96e1b64d17e00fd29cedb13 Mon Sep 17 00:00:00 2001 From: Mikhael Bogdanov Date: Tue, 18 Jun 2013 14:46:14 +0400 Subject: [PATCH 148/291] Tests for not reproduced KT-1770, KT-3001 and KT-3414 #KT-3414 Can't Reproduced #KT-3001 Can't Reproduced #KT-1770 Can't Reproduced --- .../testData/codegen/box/classes/kt3001.kt | 11 +++++++++++ .../testData/codegen/box/classes/kt3414.kt | 18 ++++++++++++++++++ .../boxWithStdlib/regressions/kt1770.kt | 17 +++++++++++++++++ .../BlackBoxCodegenTestGenerated.java | 10 ++++++++++ ...BlackBoxWithStdlibCodegenTestGenerated.java | 5 +++++ 5 files changed, 61 insertions(+) create mode 100644 compiler/testData/codegen/box/classes/kt3001.kt create mode 100644 compiler/testData/codegen/box/classes/kt3414.kt create mode 100644 compiler/testData/codegen/boxWithStdlib/regressions/kt1770.kt diff --git a/compiler/testData/codegen/box/classes/kt3001.kt b/compiler/testData/codegen/box/classes/kt3001.kt new file mode 100644 index 00000000000..35925eade05 --- /dev/null +++ b/compiler/testData/codegen/box/classes/kt3001.kt @@ -0,0 +1,11 @@ +trait A { + val result: String +} + +class Base(override val result: String) : A + +open class Derived : A by Base("OK") + +class Z : Derived() + +fun box() = Z().result diff --git a/compiler/testData/codegen/box/classes/kt3414.kt b/compiler/testData/codegen/box/classes/kt3414.kt new file mode 100644 index 00000000000..6770d466086 --- /dev/null +++ b/compiler/testData/codegen/box/classes/kt3414.kt @@ -0,0 +1,18 @@ +trait A { + fun foo(): Int +} + +trait B { + fun foo(): Int +} + +class Z(val a: A) : A by a, B + +fun box(): String { + val s = Z(object : A { + override fun foo(): Int { + return 1; + } + }); + return if (s.foo() == 1) "OK" else "fail" +} \ No newline at end of file diff --git a/compiler/testData/codegen/boxWithStdlib/regressions/kt1770.kt b/compiler/testData/codegen/boxWithStdlib/regressions/kt1770.kt new file mode 100644 index 00000000000..db7ca78eb28 --- /dev/null +++ b/compiler/testData/codegen/boxWithStdlib/regressions/kt1770.kt @@ -0,0 +1,17 @@ +import org.w3c.dom.Element +import org.xml.sax.InputSource +import javax.xml.parsers.DocumentBuilderFactory +import java.io.StringReader + +class MyElement(e: Element): Element by e { + fun bar() = "OK" +} + +fun box() : String { + val factory = DocumentBuilderFactory.newInstance()!!; + val builder = factory.newDocumentBuilder()!!; + val source = InputSource(StringReader("")); + val doc = builder.parse(source)!!; + val myElement = MyElement(doc.getDocumentElement()!!) + return myElement.getTagName()!! +} \ 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 240dbad08db..544069b7f3a 100644 --- a/compiler/tests/org/jetbrains/jet/codegen/generated/BlackBoxCodegenTestGenerated.java +++ b/compiler/tests/org/jetbrains/jet/codegen/generated/BlackBoxCodegenTestGenerated.java @@ -960,11 +960,21 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest { doTest("compiler/testData/codegen/box/classes/kt285.kt"); } + @TestMetadata("kt3001.kt") + public void testKt3001() throws Exception { + doTest("compiler/testData/codegen/box/classes/kt3001.kt"); + } + @TestMetadata("kt3114.kt") public void testKt3114() throws Exception { doTest("compiler/testData/codegen/box/classes/kt3114.kt"); } + @TestMetadata("kt3414.kt") + public void testKt3414() throws Exception { + doTest("compiler/testData/codegen/box/classes/kt3414.kt"); + } + @TestMetadata("kt343.kt") public void testKt343() throws Exception { doTest("compiler/testData/codegen/box/classes/kt343.kt"); diff --git a/compiler/tests/org/jetbrains/jet/codegen/generated/BlackBoxWithStdlibCodegenTestGenerated.java b/compiler/tests/org/jetbrains/jet/codegen/generated/BlackBoxWithStdlibCodegenTestGenerated.java index 6543439e5eb..96533c05d3e 100644 --- a/compiler/tests/org/jetbrains/jet/codegen/generated/BlackBoxWithStdlibCodegenTestGenerated.java +++ b/compiler/tests/org/jetbrains/jet/codegen/generated/BlackBoxWithStdlibCodegenTestGenerated.java @@ -654,6 +654,11 @@ public class BlackBoxWithStdlibCodegenTestGenerated extends AbstractBlackBoxCode doTestWithStdlib("compiler/testData/codegen/boxWithStdlib/regressions/kt1733.kt"); } + @TestMetadata("kt1770.kt") + public void testKt1770() throws Exception { + doTestWithStdlib("compiler/testData/codegen/boxWithStdlib/regressions/kt1770.kt"); + } + @TestMetadata("kt1779.kt") public void testKt1779() throws Exception { doTestWithStdlib("compiler/testData/codegen/boxWithStdlib/regressions/kt1779.kt"); From 9c604267f8c0b4563522995b5e49603026bb7d87 Mon Sep 17 00:00:00 2001 From: Nikolay Krasko Date: Mon, 17 Jun 2013 16:01:48 +0400 Subject: [PATCH 149/291] Extract setting configurator to utility class --- .../FormattingSettingsConfigurator.java | 91 ---------------- .../jet/formatter/JetFormatSettingsUtil.java | 43 ++++++++ .../jet/formatter/JetFormatterTest.java | 22 ++-- .../formatter/JetTypingIndentationTest.java | 11 +- .../jet/testing/SettingsConfigurator.java | 102 ++++++++++++++++++ 5 files changed, 160 insertions(+), 109 deletions(-) delete mode 100644 idea/tests/org/jetbrains/jet/formatter/FormattingSettingsConfigurator.java create mode 100644 idea/tests/org/jetbrains/jet/formatter/JetFormatSettingsUtil.java create mode 100644 idea/tests/org/jetbrains/jet/testing/SettingsConfigurator.java diff --git a/idea/tests/org/jetbrains/jet/formatter/FormattingSettingsConfigurator.java b/idea/tests/org/jetbrains/jet/formatter/FormattingSettingsConfigurator.java deleted file mode 100644 index b93cac3d827..00000000000 --- a/idea/tests/org/jetbrains/jet/formatter/FormattingSettingsConfigurator.java +++ /dev/null @@ -1,91 +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.formatter; - -import com.intellij.psi.codeStyle.CodeStyleSettings; -import com.intellij.psi.codeStyle.CommonCodeStyleSettings; -import org.jetbrains.jet.InTextDirectivesUtils; -import org.jetbrains.jet.plugin.JetLanguage; -import org.jetbrains.jet.plugin.formatter.JetCodeStyleSettings; -import org.junit.Assert; - -import java.lang.reflect.Field; - -public class FormattingSettingsConfigurator { - private final String[] settingsToTrue; - private final String[] settingsToFalse; - - public FormattingSettingsConfigurator(String fileText) { - settingsToTrue = InTextDirectivesUtils.findArrayWithPrefixes(fileText, "// SET_TRUE:"); - settingsToFalse = InTextDirectivesUtils.findArrayWithPrefixes(fileText, "// SET_FALSE:"); - } - - public void configureSettings(CodeStyleSettings settings) { - JetCodeStyleSettings jetSettings = settings.getCustomSettings(JetCodeStyleSettings.class); - CommonCodeStyleSettings jetCommonSettings = settings.getCommonSettings(JetLanguage.INSTANCE); - - for (String trueSetting : settingsToTrue) { - configureSetting(jetSettings, jetCommonSettings, trueSetting, true); - } - - for (String falseSetting : settingsToFalse) { - configureSetting(jetSettings, jetCommonSettings, falseSetting, false); - } - } - - public void configureInvertedSettings(CodeStyleSettings settings) { - JetCodeStyleSettings jetSettings = settings.getCustomSettings(JetCodeStyleSettings.class); - CommonCodeStyleSettings jetCommonSettings = settings.getCommonSettings(JetLanguage.INSTANCE); - - for (String trueSetting : settingsToTrue) { - configureSetting(jetSettings, jetCommonSettings, trueSetting, false); - } - - for (String falseSetting : settingsToFalse) { - configureSetting(jetSettings, jetCommonSettings, falseSetting, true); - } - } - - private static void configureSetting(JetCodeStyleSettings jetSettings, - CommonCodeStyleSettings jetCommonSettings, - String settingName, - boolean value - ) { - try { - Field field = jetCommonSettings.getClass().getDeclaredField(settingName); - setSetting(field, jetCommonSettings, value); - } - catch (NoSuchFieldException e) { - try { - Field field = jetSettings.getClass().getDeclaredField(settingName); - setSetting(field, jetSettings, value); - } - catch (NoSuchFieldException e1) { - Assert.assertTrue(String.format("There's no property with name '%s' for kotlin language", settingName), false); - } - } - } - - private static void setSetting(Field settingField, Object settings, boolean value) { - try { - settingField.setBoolean(settings, value); - } - catch (IllegalAccessException e) { - Assert.assertTrue(String.format("Can't set property with the name %s", settingField.getName()), false); - } - } -} diff --git a/idea/tests/org/jetbrains/jet/formatter/JetFormatSettingsUtil.java b/idea/tests/org/jetbrains/jet/formatter/JetFormatSettingsUtil.java new file mode 100644 index 00000000000..bc948cf4c1c --- /dev/null +++ b/idea/tests/org/jetbrains/jet/formatter/JetFormatSettingsUtil.java @@ -0,0 +1,43 @@ +/* + * 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.formatter; + +import com.intellij.psi.codeStyle.CodeStyleSettings; +import com.intellij.psi.codeStyle.CodeStyleSettingsManager; +import com.intellij.testFramework.LightPlatformTestCase; +import org.jetbrains.jet.plugin.JetLanguage; +import org.jetbrains.jet.plugin.formatter.JetCodeStyleSettings; +import org.jetbrains.jet.testing.SettingsConfigurator; + +public class JetFormatSettingsUtil { + private JetFormatSettingsUtil() { + } + + public static CodeStyleSettings getSettings() { + return CodeStyleSettingsManager.getSettings(LightPlatformTestCase.getProject()); + } + + public static SettingsConfigurator createConfigurator(String fileText, CodeStyleSettings settings) { + return new SettingsConfigurator(fileText, + settings.getCustomSettings(JetCodeStyleSettings.class), + settings.getCommonSettings(JetLanguage.INSTANCE)); + } + + public static SettingsConfigurator createConfigurator(String fileText) { + return createConfigurator(fileText, getSettings()); + } +} diff --git a/idea/tests/org/jetbrains/jet/formatter/JetFormatterTest.java b/idea/tests/org/jetbrains/jet/formatter/JetFormatterTest.java index 85f31b0e319..dba2cdc827e 100644 --- a/idea/tests/org/jetbrains/jet/formatter/JetFormatterTest.java +++ b/idea/tests/org/jetbrains/jet/formatter/JetFormatterTest.java @@ -16,8 +16,7 @@ package org.jetbrains.jet.formatter; -import com.intellij.psi.codeStyle.CodeStyleSettings; -import com.intellij.psi.codeStyle.CodeStyleSettingsManager; +import org.jetbrains.jet.testing.SettingsConfigurator; /** * Based on com.intellij.psi.formatter.java.JavaFormatterTest @@ -132,10 +131,6 @@ public class JetFormatterTest extends AbstractJetFormatterTest { doTest(); } - public static CodeStyleSettings getSettings() { - return CodeStyleSettingsManager.getSettings(getProject()); - } - @Override public void doTest() throws Exception { String originalFileText = AbstractJetFormatterTest.loadFile(getTestName(false) + ".kt"); @@ -143,29 +138,28 @@ public class JetFormatterTest extends AbstractJetFormatterTest { String afterFileName = getTestName(false) + "_after.kt"; String afterText = AbstractJetFormatterTest.loadFile(afterFileName); - FormattingSettingsConfigurator configurator = new FormattingSettingsConfigurator(AbstractJetFormatterTest.loadFile( - getTestName(false) + ".kt")); - configurator.configureSettings(getSettings()); + SettingsConfigurator configurator = JetFormatSettingsUtil.createConfigurator(originalFileText); + configurator.configureSettings(); doTextTest(originalFileText, afterText, String.format("Failure in NORMAL file: %s", afterFileName)); - getSettings().clearCodeStyleSettings(); + JetFormatSettingsUtil.getSettings().clearCodeStyleSettings(); } public void doTestWithInvert() throws Exception { String originalFileText = AbstractJetFormatterTest.loadFile(getTestName(false) + ".kt"); - FormattingSettingsConfigurator configurator = new FormattingSettingsConfigurator(originalFileText); + SettingsConfigurator configurator = JetFormatSettingsUtil.createConfigurator(originalFileText, JetFormatSettingsUtil.getSettings()); String afterFileName = getTestName(false) + "_after.kt"; String afterText = AbstractJetFormatterTest.loadFile(afterFileName); - configurator.configureSettings(getSettings()); + configurator.configureSettings(); doTextTest(originalFileText, afterText, String.format("Failure in NORMAL file: %s", afterFileName)); String afterInvertedFileName = getTestName(false) + "_after_inv.kt"; String afterInvertedText = AbstractJetFormatterTest.loadFile(afterInvertedFileName); - configurator.configureInvertedSettings(getSettings()); + configurator.configureInvertedSettings(); doTextTest(originalFileText, afterInvertedText, String.format("Failure in INVERTED file: %s", afterInvertedFileName)); - getSettings().clearCodeStyleSettings(); + JetFormatSettingsUtil.getSettings().clearCodeStyleSettings(); } } diff --git a/idea/tests/org/jetbrains/jet/formatter/JetTypingIndentationTest.java b/idea/tests/org/jetbrains/jet/formatter/JetTypingIndentationTest.java index 22041d17aab..476f6b17d7c 100644 --- a/idea/tests/org/jetbrains/jet/formatter/JetTypingIndentationTest.java +++ b/idea/tests/org/jetbrains/jet/formatter/JetTypingIndentationTest.java @@ -20,7 +20,9 @@ import com.intellij.openapi.util.io.FileUtil; import com.intellij.psi.codeStyle.CodeStyleSettings; import com.intellij.psi.codeStyle.CodeStyleSettingsManager; import com.intellij.testFramework.LightCodeInsightTestCase; +import org.jetbrains.annotations.NotNull; import org.jetbrains.jet.plugin.PluginTestCaseBase; +import org.jetbrains.jet.testing.SettingsConfigurator; import java.io.File; @@ -104,12 +106,13 @@ public class JetTypingIndentationTest extends LightCodeInsightTestCase { public void doFileSettingNewLineTest() throws Exception { String originalFileText = FileUtil.loadFile(new File(getTestDataPath(), getBeforeFileName())); - FormattingSettingsConfigurator configurator = new FormattingSettingsConfigurator(originalFileText); - configurator.configureSettings(getSettings()); + SettingsConfigurator configurator = JetFormatSettingsUtil.createConfigurator(originalFileText); + + configurator.configureSettings(); doNewlineTest(getBeforeFileName(), getAfterFileName()); - configurator.configureInvertedSettings(getSettings()); + configurator.configureInvertedSettings(); doNewlineTest(getBeforeFileName(), getInvertedAfterFileName()); getSettings().clearCodeStyleSettings(); @@ -125,9 +128,9 @@ public class JetTypingIndentationTest extends LightCodeInsightTestCase { return CodeStyleSettingsManager.getSettings(getProject()); } + @NotNull @Override protected String getTestDataPath() { - String testRelativeDir = "formatter/IndentationOnNewline"; return new File(PluginTestCaseBase.getTestDataPathBase(), testRelativeDir).getPath() + File.separator; diff --git a/idea/tests/org/jetbrains/jet/testing/SettingsConfigurator.java b/idea/tests/org/jetbrains/jet/testing/SettingsConfigurator.java new file mode 100644 index 00000000000..b0b69f390e6 --- /dev/null +++ b/idea/tests/org/jetbrains/jet/testing/SettingsConfigurator.java @@ -0,0 +1,102 @@ +/* + * 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.testing; + +import org.jetbrains.jet.InTextDirectivesUtils; + +import java.lang.reflect.Field; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.util.Arrays; + +public class SettingsConfigurator { + private final String[] settingsToTrue; + private final String[] settingsToFalse; + private final Object[] objects; + + public SettingsConfigurator(String fileText, Object... objects) { + settingsToTrue = InTextDirectivesUtils.findArrayWithPrefixes(fileText, "// SET_TRUE:"); + settingsToFalse = InTextDirectivesUtils.findArrayWithPrefixes(fileText, "// SET_FALSE:"); + this.objects = objects; + } + + public static void setBooleanSetting(String settingName, boolean value, Object... objects) { + for (Object object : objects) { + if (setSettingWithField(settingName, object, value) || setSettingWithMethod(settingName, object, value)) { + return; + } + } + + throw new IllegalArgumentException(String.format( + "There's no property or method with name '%s' in given objects: %s", settingName, Arrays.toString(objects))); + } + + public void configureSettings() { + for (String trueSetting : settingsToTrue) { + setBooleanSetting(trueSetting, true, objects); + } + + for (String falseSetting : settingsToFalse) { + setBooleanSetting(falseSetting, false, objects); + } + } + + public void configureInvertedSettings() { + for (String trueSetting : settingsToTrue) { + setBooleanSetting(trueSetting, false, objects); + } + + for (String falseSetting : settingsToFalse) { + setBooleanSetting(falseSetting, true, objects); + } + } + + private static boolean setSettingWithField(String settingName, Object object, boolean value) { + try { + Field field = object.getClass().getDeclaredField(settingName); + field.setBoolean(object, value); + return true; + } + catch (IllegalAccessException e) { + throw new IllegalArgumentException(String.format("Can't set property with the name %s in object %s", settingName, object)); + } + catch (NoSuchFieldException e) { + // Do nothing - will try other variants + } + + return false; + } + + private static boolean setSettingWithMethod(String setterName, Object object, boolean value) { + try { + Method method = object.getClass().getMethod(setterName, boolean.class); + method.invoke(object, value); + return true; + } + catch (InvocationTargetException e) { + throw new IllegalArgumentException(String.format("Can't call method with name %s for object %s", setterName, object)); + } + catch (IllegalAccessException e) { + throw new IllegalArgumentException(String.format("Can't access to method with name %s for object %s", setterName, object)); + } + catch (NoSuchMethodException e) { + // Do nothing - will try other variants + } + + return false; + } +} From 935c5ec16d6c4ebff13fc3544de2fe4eb4581336 Mon Sep 17 00:00:00 2001 From: Nikolay Krasko Date: Tue, 18 Jun 2013 17:43:57 +0400 Subject: [PATCH 150/291] Add folding doc and multiline comments --- .../jet/generators/tests/GenerateTests.java | 7 +- .../jet/plugin/JetFoldingBuilder.java | 56 ++++++++--- .../folding/checkCollapse/headerKDoc.kt | 11 +++ .../checkCollapse/headerMultilineComment.kt | 12 +++ .../testData/folding/checkCollapse/imports.kt | 8 ++ .../folding/{ => noCollapse}/class.kt | 0 .../folding/{ => noCollapse}/function.kt | 0 .../folding/{ => noCollapse}/imports.kt | 0 .../folding/noCollapse/kdocComments.kt | 9 ++ .../folding/noCollapse/multilineComments.kt | 4 + .../folding/{ => noCollapse}/object.kt | 0 .../folding/{ => noCollapse}/oneImport.kt | 0 .../folding/AbstractKotlinFoldingTest.java | 76 ++++++++++++++- .../folding/KotlinFoldingTestGenerated.java | 93 ++++++++++++++----- .../jet/testing/SettingsConfigurator.java | 7 +- 15 files changed, 236 insertions(+), 47 deletions(-) create mode 100644 idea/testData/folding/checkCollapse/headerKDoc.kt create mode 100644 idea/testData/folding/checkCollapse/headerMultilineComment.kt create mode 100644 idea/testData/folding/checkCollapse/imports.kt rename idea/testData/folding/{ => noCollapse}/class.kt (100%) rename idea/testData/folding/{ => noCollapse}/function.kt (100%) rename idea/testData/folding/{ => noCollapse}/imports.kt (100%) create mode 100644 idea/testData/folding/noCollapse/kdocComments.kt create mode 100644 idea/testData/folding/noCollapse/multilineComments.kt rename idea/testData/folding/{ => noCollapse}/object.kt (100%) rename idea/testData/folding/{ => noCollapse}/oneImport.kt (100%) diff --git a/generators/org/jetbrains/jet/generators/tests/GenerateTests.java b/generators/org/jetbrains/jet/generators/tests/GenerateTests.java index 62a775547c2..6bfb8439a2c 100644 --- a/generators/org/jetbrains/jet/generators/tests/GenerateTests.java +++ b/generators/org/jetbrains/jet/generators/tests/GenerateTests.java @@ -32,13 +32,12 @@ 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; import org.jetbrains.jet.lang.resolve.lazy.AbstractLazyResolveTest; import org.jetbrains.jet.modules.xml.AbstractModuleXmlParserTest; import org.jetbrains.jet.plugin.intentions.AbstractCodeTransformationTest; +import org.jetbrains.jet.plugin.codeInsight.moveUpDown.AbstractCodeMoverTest; import org.jetbrains.jet.plugin.codeInsight.surroundWith.AbstractSurroundWithTest; import org.jetbrains.jet.plugin.folding.AbstractKotlinFoldingTest; import org.jetbrains.jet.plugin.hierarchy.AbstractHierarchyTest; @@ -46,6 +45,7 @@ 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.psi.AbstractJetPsiMatcherTest; import org.jetbrains.jet.resolve.AbstractResolveTest; import org.jetbrains.jet.test.generator.SimpleTestClassModel; import org.jetbrains.jet.test.generator.TestClassModel; @@ -307,7 +307,8 @@ public class GenerateTests { "idea/tests/", "KotlinFoldingTestGenerated", AbstractKotlinFoldingTest.class, - testModel("idea/testData/folding") + testModel("idea/testData/folding/noCollapse", "doTest"), + testModel("idea/testData/folding/checkCollapse", "doSettingsFoldingTest") ); generateTest( diff --git a/idea/src/org/jetbrains/jet/plugin/JetFoldingBuilder.java b/idea/src/org/jetbrains/jet/plugin/JetFoldingBuilder.java index 9e505bbccba..1517c92a1eb 100644 --- a/idea/src/org/jetbrains/jet/plugin/JetFoldingBuilder.java +++ b/idea/src/org/jetbrains/jet/plugin/JetFoldingBuilder.java @@ -16,6 +16,7 @@ package org.jetbrains.jet.plugin; +import com.intellij.codeInsight.folding.JavaCodeFoldingSettings; import com.intellij.lang.ASTNode; import com.intellij.lang.folding.FoldingBuilderEx; import com.intellij.lang.folding.FoldingDescriptor; @@ -23,9 +24,11 @@ import com.intellij.openapi.editor.Document; import com.intellij.openapi.project.DumbAware; import com.intellij.openapi.util.TextRange; import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiWhiteSpace; import com.intellij.psi.tree.IElementType; import org.jetbrains.annotations.NotNull; import org.jetbrains.jet.JetNodeTypes; +import org.jetbrains.jet.kdoc.lexer.KDocTokens; import org.jetbrains.jet.lang.psi.JetFile; import org.jetbrains.jet.lang.psi.JetImportDirective; import org.jetbrains.jet.lexer.JetTokens; @@ -61,8 +64,8 @@ public class JetFoldingBuilder extends FoldingBuilderEx implements DumbAware { private static void appendDescriptors(ASTNode node, Document document, List descriptors) { TextRange textRange = node.getTextRange(); IElementType type = node.getElementType(); - if ((type == JetNodeTypes.BLOCK || type == JetNodeTypes.CLASS_BODY) && - !isOneLine(textRange, document)) { + if ((type == JetNodeTypes.BLOCK || type == JetNodeTypes.CLASS_BODY || type == JetTokens.BLOCK_COMMENT || type == KDocTokens.KDOC) && + !isOneLine(textRange, document)) { descriptors.add(new FoldingDescriptor(node, textRange)); } else if (node.getElementType() == JetTokens.IDE_TEMPLATE_START) { @@ -87,29 +90,54 @@ public class JetFoldingBuilder extends FoldingBuilderEx implements DumbAware { } @Override - public String getPlaceholderText(@NotNull ASTNode astNode, @NotNull TextRange range) { - ASTNode prev = astNode.getTreePrev(); - ASTNode next = astNode.getTreeNext(); + public String getPlaceholderText(@NotNull ASTNode node) { + ASTNode prev = node.getTreePrev(); + ASTNode next = node.getTreeNext(); if (prev != null && next != null && prev.getElementType() == JetTokens.IDE_TEMPLATE_START - && next.getElementType() == JetTokens.IDE_TEMPLATE_END) { - return astNode.getText(); + && next.getElementType() == JetTokens.IDE_TEMPLATE_END) { + return node.getText(); } - if (astNode.getPsi() instanceof JetImportDirective) { + if (node.getElementType() == JetTokens.BLOCK_COMMENT) { + return "/.../"; + } + if (node.getElementType() == KDocTokens.KDOC) { + return "/**...*/"; + } + if (node.getPsi() instanceof JetImportDirective) { return "..."; } return "{...}"; } @Override - public String getPlaceholderText(@NotNull ASTNode node) { - return "{...}"; + public boolean isCollapsedByDefault(@NotNull ASTNode astNode) { + JavaCodeFoldingSettings settings = JavaCodeFoldingSettings.getInstance(); + + if (astNode.getPsi() instanceof JetImportDirective) { + return settings.isCollapseImports(); + } + + IElementType type = astNode.getElementType(); + if (type == JetTokens.BLOCK_COMMENT || type == KDocTokens.KDOC) { + if (isFirstElementInFile(astNode.getPsi())) { + return settings.isCollapseFileHeader(); + } + } + + return false; } - @Override - public boolean isCollapsedByDefault(@NotNull ASTNode astNode) { - if (astNode.getPsi() instanceof JetImportDirective) { - return true; + private static boolean isFirstElementInFile(PsiElement element) { + PsiElement parent = element.getParent(); + if (parent instanceof JetFile) { + PsiElement firstChild = parent.getFirstChild(); + if (firstChild instanceof PsiWhiteSpace) { + firstChild = firstChild.getNextSibling(); + } + + return element == firstChild; } + return false; } } diff --git a/idea/testData/folding/checkCollapse/headerKDoc.kt b/idea/testData/folding/checkCollapse/headerKDoc.kt new file mode 100644 index 00000000000..68730fd38c1 --- /dev/null +++ b/idea/testData/folding/checkCollapse/headerKDoc.kt @@ -0,0 +1,11 @@ +/** + * Some header kdoc + */ +package some + +/** + * Other + */ + +// SET_TRUE: setCollapseFileHeader + diff --git a/idea/testData/folding/checkCollapse/headerMultilineComment.kt b/idea/testData/folding/checkCollapse/headerMultilineComment.kt new file mode 100644 index 00000000000..b89b0cc9e3a --- /dev/null +++ b/idea/testData/folding/checkCollapse/headerMultilineComment.kt @@ -0,0 +1,12 @@ +/* + * Some header + */ + +val a = 12 + +/* + * Other + */ + +// SET_TRUE: setCollapseFileHeader + diff --git a/idea/testData/folding/checkCollapse/imports.kt b/idea/testData/folding/checkCollapse/imports.kt new file mode 100644 index 00000000000..6ea9d3cd13c --- /dev/null +++ b/idea/testData/folding/checkCollapse/imports.kt @@ -0,0 +1,8 @@ +package some + +import first +import second + +trait A + +// SET_TRUE: setCollapseImports \ No newline at end of file diff --git a/idea/testData/folding/class.kt b/idea/testData/folding/noCollapse/class.kt similarity index 100% rename from idea/testData/folding/class.kt rename to idea/testData/folding/noCollapse/class.kt diff --git a/idea/testData/folding/function.kt b/idea/testData/folding/noCollapse/function.kt similarity index 100% rename from idea/testData/folding/function.kt rename to idea/testData/folding/noCollapse/function.kt diff --git a/idea/testData/folding/imports.kt b/idea/testData/folding/noCollapse/imports.kt similarity index 100% rename from idea/testData/folding/imports.kt rename to idea/testData/folding/noCollapse/imports.kt diff --git a/idea/testData/folding/noCollapse/kdocComments.kt b/idea/testData/folding/noCollapse/kdocComments.kt new file mode 100644 index 00000000000..fa10d6117f7 --- /dev/null +++ b/idea/testData/folding/noCollapse/kdocComments.kt @@ -0,0 +1,9 @@ +/** + * Kdoc licence + */ +package some + +/** + * Some Kdoc comment + */ +class A \ No newline at end of file diff --git a/idea/testData/folding/noCollapse/multilineComments.kt b/idea/testData/folding/noCollapse/multilineComments.kt new file mode 100644 index 00000000000..846fb05f63d --- /dev/null +++ b/idea/testData/folding/noCollapse/multilineComments.kt @@ -0,0 +1,4 @@ +/* + * Some multiline comment + */ +class A \ No newline at end of file diff --git a/idea/testData/folding/object.kt b/idea/testData/folding/noCollapse/object.kt similarity index 100% rename from idea/testData/folding/object.kt rename to idea/testData/folding/noCollapse/object.kt diff --git a/idea/testData/folding/oneImport.kt b/idea/testData/folding/noCollapse/oneImport.kt similarity index 100% rename from idea/testData/folding/oneImport.kt rename to idea/testData/folding/noCollapse/oneImport.kt diff --git a/idea/tests/org/jetbrains/jet/plugin/folding/AbstractKotlinFoldingTest.java b/idea/tests/org/jetbrains/jet/plugin/folding/AbstractKotlinFoldingTest.java index 6fb9a60988a..9af2be9017d 100644 --- a/idea/tests/org/jetbrains/jet/plugin/folding/AbstractKotlinFoldingTest.java +++ b/idea/tests/org/jetbrains/jet/plugin/folding/AbstractKotlinFoldingTest.java @@ -16,22 +16,92 @@ package org.jetbrains.jet.plugin.folding; +import com.intellij.codeInsight.folding.JavaCodeFoldingSettings; +import com.intellij.codeInsight.folding.impl.JavaCodeFoldingSettingsImpl; +import com.intellij.openapi.editor.FoldRegion; +import com.intellij.openapi.editor.ex.FoldingModelEx; +import com.intellij.openapi.util.io.FileUtil; +import com.intellij.openapi.util.text.StringUtil; +import com.intellij.openapi.vfs.VirtualFile; import com.intellij.testFramework.LightProjectDescriptor; +import com.intellij.testFramework.PlatformTestCase; import com.intellij.testFramework.fixtures.LightCodeInsightFixtureTestCase; import org.jetbrains.annotations.NotNull; import org.jetbrains.jet.plugin.JetLightProjectDescriptor; +import org.jetbrains.jet.testing.SettingsConfigurator; + +import java.io.File; +import java.io.IOException; +import java.nio.charset.Charset; public abstract class AbstractKotlinFoldingTest extends LightCodeInsightFixtureTestCase { - protected void doTest(@NotNull String path) { myFixture.testFolding(path); } + protected void doSettingsFoldingTest(@NotNull String path) { + String fileText; + try { + fileText = StringUtil.convertLineSeparators(FileUtil.loadFile(new File(path))); + } + catch (IOException e) { + throw new RuntimeException(e); + } + + JavaCodeFoldingSettings settings = JavaCodeFoldingSettings.getInstance(); + JavaCodeFoldingSettingsImpl restoreSettings = new JavaCodeFoldingSettingsImpl(); + restoreSettings.loadState((JavaCodeFoldingSettingsImpl) settings); + + try { + String directText = fileText.replaceAll("~true~", "true").replaceAll("~false~", "false"); + directText += "\n\n// Generated from: " + path; + + doExpandSettingsTest(directText, settings); + + // Clean all regions in model to force IDEA treat all regions as new ones + cleanAllFoldedRegions(); + + String invertedText = fileText + .replaceAll("~false~", "true").replaceAll("~true~", "false") + .replaceAll(SettingsConfigurator.SET_TRUE_DIRECTIVE, "~TEMP_TRUE_DIRECTIVE~") + .replaceAll(SettingsConfigurator.SET_FALSE_DIRECTIVE, SettingsConfigurator.SET_TRUE_DIRECTIVE) + .replaceAll("~TEMP_TRUE_DIRECTIVE~", SettingsConfigurator.SET_FALSE_DIRECTIVE); + invertedText += "\n\n// Generated from: " + path + " with !INVERTED! settings"; + + doExpandSettingsTest(invertedText, settings); + } + catch (IOException e) { + throw new IllegalStateException(e); + } + finally { + ((JavaCodeFoldingSettingsImpl) JavaCodeFoldingSettings.getInstance()).loadState(restoreSettings); + } + } + + private void cleanAllFoldedRegions() { + final FoldingModelEx model = (FoldingModelEx) myFixture.getEditor().getFoldingModel(); + Runnable runnable = new Runnable() { + @Override + public void run() { + for (FoldRegion region : model.getAllFoldRegions()) { + model.removeFoldRegion(region); + } + } + }; + model.runBatchFoldingOperation(runnable); + } + + private void doExpandSettingsTest(String fileText, JavaCodeFoldingSettings settings) throws IOException { + SettingsConfigurator configurator = new SettingsConfigurator(fileText, settings); + configurator.configureSettings(); + + VirtualFile tempFile = PlatformTestCase.createTempFile("kt", null, fileText, Charset.defaultCharset()); + myFixture.testFoldingWithCollapseStatus(tempFile.getPath()); + } + @NotNull @Override protected LightProjectDescriptor getProjectDescriptor() { return JetLightProjectDescriptor.INSTANCE; } - - } diff --git a/idea/tests/org/jetbrains/jet/plugin/folding/KotlinFoldingTestGenerated.java b/idea/tests/org/jetbrains/jet/plugin/folding/KotlinFoldingTestGenerated.java index 3e430d49709..9d67a84b131 100644 --- a/idea/tests/org/jetbrains/jet/plugin/folding/KotlinFoldingTestGenerated.java +++ b/idea/tests/org/jetbrains/jet/plugin/folding/KotlinFoldingTestGenerated.java @@ -30,35 +30,78 @@ import org.jetbrains.jet.plugin.folding.AbstractKotlinFoldingTest; /** This class is generated by {@link org.jetbrains.jet.generators.tests.GenerateTests}. DO NOT MODIFY MANUALLY */ @SuppressWarnings("all") -@TestMetadata("idea/testData/folding") +@InnerTestClasses({KotlinFoldingTestGenerated.NoCollapse.class, KotlinFoldingTestGenerated.CheckCollapse.class}) public class KotlinFoldingTestGenerated extends AbstractKotlinFoldingTest { - public void testAllFilesPresentInFolding() throws Exception { - JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.GenerateTests", new File("idea/testData/folding"), Pattern.compile("^(.+)\\.kt$"), true); + @TestMetadata("idea/testData/folding/noCollapse") + public static class NoCollapse extends AbstractKotlinFoldingTest { + public void testAllFilesPresentInNoCollapse() throws Exception { + JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.GenerateTests", new File("idea/testData/folding/noCollapse"), Pattern.compile("^(.+)\\.kt$"), true); + } + + @TestMetadata("class.kt") + public void testClass() throws Exception { + doTest("idea/testData/folding/noCollapse/class.kt"); + } + + @TestMetadata("function.kt") + public void testFunction() throws Exception { + doTest("idea/testData/folding/noCollapse/function.kt"); + } + + @TestMetadata("imports.kt") + public void testImports() throws Exception { + doTest("idea/testData/folding/noCollapse/imports.kt"); + } + + @TestMetadata("kdocComments.kt") + public void testKdocComments() throws Exception { + doTest("idea/testData/folding/noCollapse/kdocComments.kt"); + } + + @TestMetadata("multilineComments.kt") + public void testMultilineComments() throws Exception { + doTest("idea/testData/folding/noCollapse/multilineComments.kt"); + } + + @TestMetadata("object.kt") + public void testObject() throws Exception { + doTest("idea/testData/folding/noCollapse/object.kt"); + } + + @TestMetadata("oneImport.kt") + public void testOneImport() throws Exception { + doTest("idea/testData/folding/noCollapse/oneImport.kt"); + } + } - @TestMetadata("class.kt") - public void testClass() throws Exception { - doTest("idea/testData/folding/class.kt"); + @TestMetadata("idea/testData/folding/checkCollapse") + public static class CheckCollapse extends AbstractKotlinFoldingTest { + public void testAllFilesPresentInCheckCollapse() throws Exception { + JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.GenerateTests", new File("idea/testData/folding/checkCollapse"), Pattern.compile("^(.+)\\.kt$"), true); + } + + @TestMetadata("headerKDoc.kt") + public void testHeaderKDoc() throws Exception { + doSettingsFoldingTest("idea/testData/folding/checkCollapse/headerKDoc.kt"); + } + + @TestMetadata("headerMultilineComment.kt") + public void testHeaderMultilineComment() throws Exception { + doSettingsFoldingTest("idea/testData/folding/checkCollapse/headerMultilineComment.kt"); + } + + @TestMetadata("imports.kt") + public void testImports() throws Exception { + doSettingsFoldingTest("idea/testData/folding/checkCollapse/imports.kt"); + } + } - @TestMetadata("function.kt") - public void testFunction() throws Exception { - doTest("idea/testData/folding/function.kt"); + public static Test suite() { + TestSuite suite = new TestSuite("KotlinFoldingTestGenerated"); + suite.addTestSuite(NoCollapse.class); + suite.addTestSuite(CheckCollapse.class); + return suite; } - - @TestMetadata("imports.kt") - public void testImports() throws Exception { - doTest("idea/testData/folding/imports.kt"); - } - - @TestMetadata("object.kt") - public void testObject() throws Exception { - doTest("idea/testData/folding/object.kt"); - } - - @TestMetadata("oneImport.kt") - public void testOneImport() throws Exception { - doTest("idea/testData/folding/oneImport.kt"); - } - } diff --git a/idea/tests/org/jetbrains/jet/testing/SettingsConfigurator.java b/idea/tests/org/jetbrains/jet/testing/SettingsConfigurator.java index b0b69f390e6..3e93e95461c 100644 --- a/idea/tests/org/jetbrains/jet/testing/SettingsConfigurator.java +++ b/idea/tests/org/jetbrains/jet/testing/SettingsConfigurator.java @@ -24,13 +24,16 @@ import java.lang.reflect.Method; import java.util.Arrays; public class SettingsConfigurator { + public static final String SET_TRUE_DIRECTIVE = "SET_TRUE:"; + public static final String SET_FALSE_DIRECTIVE = "SET_FALSE:"; + private final String[] settingsToTrue; private final String[] settingsToFalse; private final Object[] objects; public SettingsConfigurator(String fileText, Object... objects) { - settingsToTrue = InTextDirectivesUtils.findArrayWithPrefixes(fileText, "// SET_TRUE:"); - settingsToFalse = InTextDirectivesUtils.findArrayWithPrefixes(fileText, "// SET_FALSE:"); + settingsToTrue = InTextDirectivesUtils.findArrayWithPrefixes(fileText, SET_TRUE_DIRECTIVE); + settingsToFalse = InTextDirectivesUtils.findArrayWithPrefixes(fileText, SET_FALSE_DIRECTIVE); this.objects = objects; } From 132d74200b420ea642719b888cee431ecaa1cae4 Mon Sep 17 00:00:00 2001 From: Mikhael Bogdanov Date: Wed, 19 Jun 2013 15:27:11 +0400 Subject: [PATCH 151/291] Partial fix for KT-3698: properly write field initializer --- .../codegen/ImplementationBodyCodegen.java | 45 +++++++++++++++---- .../jet/codegen/PropertyCodegen.java | 8 ++-- .../nullablePrimitiveNoFieldInitializer.kt | 11 +++++ .../staticFields/AnnotationClass.java | 10 +++++ .../staticFields/AnnotationClass.kt | 23 ++++++++++ .../staticFields/AnnotationTrait.java | 10 +++++ .../staticFields/AnnotationTrait.kt | 23 ++++++++++ .../staticFields/kt3698.java | 11 +++++ .../staticFields/kt3698.kt | 5 +++ .../BlackBoxCodegenTestGenerated.java | 5 +++ ...CompileJavaAgainstKotlinTestGenerated.java | 15 +++++++ 11 files changed, 154 insertions(+), 12 deletions(-) create mode 100644 compiler/testData/codegen/box/namespace/nullablePrimitiveNoFieldInitializer.kt create mode 100644 compiler/testData/compileJavaAgainstKotlin/staticFields/AnnotationClass.java create mode 100644 compiler/testData/compileJavaAgainstKotlin/staticFields/AnnotationClass.kt create mode 100644 compiler/testData/compileJavaAgainstKotlin/staticFields/AnnotationTrait.java create mode 100644 compiler/testData/compileJavaAgainstKotlin/staticFields/AnnotationTrait.kt create mode 100644 compiler/testData/compileJavaAgainstKotlin/staticFields/kt3698.java create mode 100644 compiler/testData/compileJavaAgainstKotlin/staticFields/kt3698.kt diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/ImplementationBodyCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/ImplementationBodyCodegen.java index 952a8768944..bcdd7a43ffe 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/ImplementationBodyCodegen.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/ImplementationBodyCodegen.java @@ -84,7 +84,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { private final FunctionCodegen functionCodegen; private final PropertyCodegen propertyCodegen; - private List classObjectPropertiesToCopy; + private List classObjectPropertiesToCopy; public ImplementationBodyCodegen( @NotNull JetClassOrObject aClass, @@ -952,11 +952,15 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { private void generateClassObjectBackingFieldCopies() { if (classObjectPropertiesToCopy != null) { - for (PropertyDescriptor propertyDescriptor : classObjectPropertiesToCopy) { + for (PropertyAndDefaultValue propertyInfo : classObjectPropertiesToCopy) { + PropertyDescriptor propertyDescriptor = propertyInfo.propertyDescriptor; - v.newField(null, ACC_STATIC | ACC_FINAL | ACC_PUBLIC, context.getFieldName(propertyDescriptor), typeMapper.mapType(propertyDescriptor).getDescriptor(), null, null); + v.newField(null, ACC_STATIC | ACC_FINAL | ACC_PUBLIC, context.getFieldName(propertyDescriptor), + typeMapper.mapType(propertyDescriptor).getDescriptor(), null, propertyInfo.defaultValue); - if (state.getClassBuilderMode() == ClassBuilderMode.FULL) { + //This field are always static and final so if it has constant initializer don't do anything in clinit, + //field would be initialized via default value in v.newField(...) - see JVM SPEC Ch.4 + if (state.getClassBuilderMode() == ClassBuilderMode.FULL && propertyInfo.defaultValue == null) { ExpressionCodegen codegen = createOrGetClInitCodegen(); int classObjectIndex = putClassObjectInLocalVar(codegen); StackValue.local(classObjectIndex, OBJECT_TYPE).put(OBJECT_TYPE, codegen.v); @@ -1625,6 +1629,15 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { propValue.store(type, codegen.v); } + public static boolean shouldWriteFieldInitializer(PropertyDescriptor descriptor, JetTypeMapper mapper) { + //final field of primitive or String type + if (!descriptor.isVar()) { + Type type = mapper.mapType(descriptor.getType()); + return AsmUtil.isPrimitive(type) || "java.lang.String".equals(type.getClassName()); + } + return false; + } + public static boolean shouldInitializeProperty( @NotNull JetProperty property, @NotNull JetTypeMapper typeMapper @@ -1638,6 +1651,8 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { PropertyDescriptor propertyDescriptor = (PropertyDescriptor) typeMapper.getBindingContext().get(BindingContext.VARIABLE, property); assert propertyDescriptor != null; + //TODO: OPTIMIZATION: don't initialize static final fields + Object value = compileTimeValue.getValue(); JetType jetType = getPropertyOrDelegateType(typeMapper.getBindingContext(), property, propertyDescriptor); Type type = typeMapper.mapType(jetType); @@ -1655,7 +1670,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { return descriptor.getType(); } - private static boolean skipDefaultValue(PropertyDescriptor propertyDescriptor, Object value, Type type) { + private static boolean skipDefaultValue(@NotNull PropertyDescriptor propertyDescriptor, Object value, @NotNull Type type) { if (isPrimitive(type)) { if (!propertyDescriptor.getType().isNullable() && value instanceof Number) { if (type == Type.INT_TYPE && ((Number) value).intValue() == 0) { @@ -1771,11 +1786,25 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { return r; } - public void addClassObjectPropertyToCopy(PropertyDescriptor descriptor) { + public void addClassObjectPropertyToCopy(PropertyDescriptor descriptor, Object defaultValue) { if (classObjectPropertiesToCopy == null) { - classObjectPropertiesToCopy = new ArrayList(); + classObjectPropertiesToCopy = new ArrayList(); } - classObjectPropertiesToCopy.add(descriptor); + classObjectPropertiesToCopy.add(new PropertyAndDefaultValue(descriptor, defaultValue)); + } + + static class PropertyAndDefaultValue { + + PropertyAndDefaultValue(PropertyDescriptor propertyDescriptor, Object defaultValue) { + this.propertyDescriptor = propertyDescriptor; + this.defaultValue = defaultValue; + } + + private PropertyDescriptor propertyDescriptor; + + private Object defaultValue; + + } } diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/PropertyCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/PropertyCodegen.java index 60b33ddbeb4..c30a10423c6 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/PropertyCodegen.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/PropertyCodegen.java @@ -25,7 +25,6 @@ import org.jetbrains.asm4.Type; import org.jetbrains.asm4.commons.InstructionAdapter; import org.jetbrains.jet.codegen.context.CodegenContext; import org.jetbrains.jet.codegen.context.FieldOwnerContext; -import org.jetbrains.jet.codegen.context.MethodContext; import org.jetbrains.jet.codegen.signature.JvmMethodSignature; import org.jetbrains.jet.codegen.signature.JvmPropertyAccessorSignature; import org.jetbrains.jet.codegen.signature.kotlin.JetMethodAnnotationWriter; @@ -157,7 +156,7 @@ public class PropertyCodegen extends GenerationStateAware { if (AsmUtil.isPropertyWithBackingFieldCopyInOuterClass(propertyDescriptor)) { ImplementationBodyCodegen parentBodyCodegen = getParentBodyCodegen(classBodyCodegen); - parentBodyCodegen.addClassObjectPropertyToCopy(propertyDescriptor); + parentBodyCodegen.addClassObjectPropertyToCopy(propertyDescriptor, defaultValue); } String name = backingFieldContext.getFieldName(propertyDescriptor, isDelegate); @@ -178,8 +177,9 @@ public class PropertyCodegen extends GenerationStateAware { private FieldVisitor generateBackingFieldAccess(JetNamedDeclaration p, PropertyDescriptor propertyDescriptor) { Object value = null; - if (p instanceof JetProperty && !ImplementationBodyCodegen.shouldInitializeProperty((JetProperty) p, typeMapper)) { - JetExpression initializer = ((JetProperty) p).getInitializer(); + + if (ImplementationBodyCodegen.shouldWriteFieldInitializer(propertyDescriptor, typeMapper)) { + JetExpression initializer = p instanceof JetProperty ? ((JetProperty) p).getInitializer() : null; 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/namespace/nullablePrimitiveNoFieldInitializer.kt b/compiler/testData/codegen/box/namespace/nullablePrimitiveNoFieldInitializer.kt new file mode 100644 index 00000000000..8eef11e6156 --- /dev/null +++ b/compiler/testData/codegen/box/namespace/nullablePrimitiveNoFieldInitializer.kt @@ -0,0 +1,11 @@ +val zint : Int? = 1 +val zlong : Long? = 2 +val zbyte : Byte? = 3 +val zshort : Short? = 4 +val zchar : Char? = 'c' +val zdouble : Double? = 1.0 +val zfloat : Float? = 2.0 + +fun box(): String { + return "OK" +} \ No newline at end of file diff --git a/compiler/testData/compileJavaAgainstKotlin/staticFields/AnnotationClass.java b/compiler/testData/compileJavaAgainstKotlin/staticFields/AnnotationClass.java new file mode 100644 index 00000000000..ef003db815d --- /dev/null +++ b/compiler/testData/compileJavaAgainstKotlin/staticFields/AnnotationClass.java @@ -0,0 +1,10 @@ +@AString(value = Test.vstring) +@AStringNullable(value = Test.vstringNullable) +@AChar(value = Test.vchar) +@AInt(value = Test.vint) +@AByte(value = Test.vbyte) +@ALong(value = Test.vlong) +@ADouble(value = Test.vdouble) +@AFloat(value = Test.vfloat) +public class AnnotationClass { +} diff --git a/compiler/testData/compileJavaAgainstKotlin/staticFields/AnnotationClass.kt b/compiler/testData/compileJavaAgainstKotlin/staticFields/AnnotationClass.kt new file mode 100644 index 00000000000..0d2f88007c1 --- /dev/null +++ b/compiler/testData/compileJavaAgainstKotlin/staticFields/AnnotationClass.kt @@ -0,0 +1,23 @@ +annotation class AString(val value: String) +annotation class AStringNullable(val value: String?) +annotation class AChar(val value: Char) +annotation class AInt(val value: Int) +annotation class AByte(val value: Byte) +annotation class ALong(val value: Long) +annotation class ADouble(val value: Double) +annotation class AFloat(val value: Float) + +class Test { + + class object { + val vstring: String = "Test" + val vstringNullable: String? = "Test" + val vchar: Char = 'c' + val vint: Int = 10 + val vbyte: Byte = 11 + val vlong: Long = 12 + val vdouble: Double = 1.2 + val vfloat: Float = 1.3 + } + +} \ No newline at end of file diff --git a/compiler/testData/compileJavaAgainstKotlin/staticFields/AnnotationTrait.java b/compiler/testData/compileJavaAgainstKotlin/staticFields/AnnotationTrait.java new file mode 100644 index 00000000000..20cf3bb2061 --- /dev/null +++ b/compiler/testData/compileJavaAgainstKotlin/staticFields/AnnotationTrait.java @@ -0,0 +1,10 @@ +@AString(value = Test.vstring) +@AStringNullable(value = Test.vstringNullable) +@AChar(value = Test.vchar) +@AInt(value = Test.vint) +@AByte(value = Test.vbyte) +@ALong(value = Test.vlong) +@ADouble(value = Test.vdouble) +@AFloat(value = Test.vfloat) +public class AnnotationTrait { +} diff --git a/compiler/testData/compileJavaAgainstKotlin/staticFields/AnnotationTrait.kt b/compiler/testData/compileJavaAgainstKotlin/staticFields/AnnotationTrait.kt new file mode 100644 index 00000000000..d90d88de6f3 --- /dev/null +++ b/compiler/testData/compileJavaAgainstKotlin/staticFields/AnnotationTrait.kt @@ -0,0 +1,23 @@ +annotation class AString(val value: String) +annotation class AStringNullable(val value: String?) +annotation class AChar(val value: Char) +annotation class AInt(val value: Int) +annotation class AByte(val value: Byte) +annotation class ALong(val value: Long) +annotation class ADouble(val value: Double) +annotation class AFloat(val value: Float) + +trait Test { + + class object { + val vstring: String = "Test" + val vstringNullable: String? = "Test" + val vchar: Char = 'c' + val vint: Int = 10 + val vbyte: Byte = 11 + val vlong: Long = 12 + val vdouble: Double = 1.2 + val vfloat: Float = 1.3 + } + +} \ No newline at end of file diff --git a/compiler/testData/compileJavaAgainstKotlin/staticFields/kt3698.java b/compiler/testData/compileJavaAgainstKotlin/staticFields/kt3698.java new file mode 100644 index 00000000000..936d97acf31 --- /dev/null +++ b/compiler/testData/compileJavaAgainstKotlin/staticFields/kt3698.java @@ -0,0 +1,11 @@ +public class kt3698 { + + @interface Foo { + int value(); + } + + @Foo(KotlinClass.FOO) // Error here + public static void main(String[] args) { + System.out.println(KotlinClass.FOO); + } +} \ No newline at end of file diff --git a/compiler/testData/compileJavaAgainstKotlin/staticFields/kt3698.kt b/compiler/testData/compileJavaAgainstKotlin/staticFields/kt3698.kt new file mode 100644 index 00000000000..8e836926c81 --- /dev/null +++ b/compiler/testData/compileJavaAgainstKotlin/staticFields/kt3698.kt @@ -0,0 +1,5 @@ +class KotlinClass { + class object { + val FOO: Int = 10 + } +} diff --git a/compiler/tests/org/jetbrains/jet/codegen/generated/BlackBoxCodegenTestGenerated.java b/compiler/tests/org/jetbrains/jet/codegen/generated/BlackBoxCodegenTestGenerated.java index 544069b7f3a..42001930d01 100644 --- a/compiler/tests/org/jetbrains/jet/codegen/generated/BlackBoxCodegenTestGenerated.java +++ b/compiler/tests/org/jetbrains/jet/codegen/generated/BlackBoxCodegenTestGenerated.java @@ -3105,6 +3105,11 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest { doTest("compiler/testData/codegen/box/namespace/namespaceQualifiedMethod.kt"); } + @TestMetadata("nullablePrimitiveNoFieldInitializer.kt") + public void testNullablePrimitiveNoFieldInitializer() throws Exception { + doTest("compiler/testData/codegen/box/namespace/nullablePrimitiveNoFieldInitializer.kt"); + } + @TestMetadata("privateTopLevelPropAndVarInInner.kt") public void testPrivateTopLevelPropAndVarInInner() throws Exception { doTest("compiler/testData/codegen/box/namespace/privateTopLevelPropAndVarInInner.kt"); diff --git a/compiler/tests/org/jetbrains/jet/jvm/compiler/CompileJavaAgainstKotlinTestGenerated.java b/compiler/tests/org/jetbrains/jet/jvm/compiler/CompileJavaAgainstKotlinTestGenerated.java index 107b0044382..ff7efe887b7 100644 --- a/compiler/tests/org/jetbrains/jet/jvm/compiler/CompileJavaAgainstKotlinTestGenerated.java +++ b/compiler/tests/org/jetbrains/jet/jvm/compiler/CompileJavaAgainstKotlinTestGenerated.java @@ -189,6 +189,21 @@ public class CompileJavaAgainstKotlinTestGenerated extends AbstractCompileJavaAg JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.GenerateTests", new File("compiler/testData/compileJavaAgainstKotlin/staticFields"), Pattern.compile("^(.+)\\.kt$"), true); } + @TestMetadata("AnnotationClass.kt") + public void testAnnotationClass() throws Exception { + doTest("compiler/testData/compileJavaAgainstKotlin/staticFields/AnnotationClass.kt"); + } + + @TestMetadata("AnnotationTrait.kt") + public void testAnnotationTrait() throws Exception { + doTest("compiler/testData/compileJavaAgainstKotlin/staticFields/AnnotationTrait.kt"); + } + + @TestMetadata("kt3698.kt") + public void testKt3698() throws Exception { + doTest("compiler/testData/compileJavaAgainstKotlin/staticFields/kt3698.kt"); + } + @TestMetadata("staticClassProperty.kt") public void testStaticClassProperty() throws Exception { doTest("compiler/testData/compileJavaAgainstKotlin/staticFields/staticClassProperty.kt"); From 3cf133bff728807c33bc3bfda69b44abca43cb82 Mon Sep 17 00:00:00 2001 From: Svetlana Isakova Date: Fri, 7 Jun 2013 13:41:57 +0400 Subject: [PATCH 152/291] changed local extensions priority local extensions aren't longer chosen before members --- .../calls/tasks/ResolutionTaskHolder.java | 35 +-------- .../resolve/calls/tasks/TaskPrioritizer.java | 23 +++--- .../codegen/box/classes/resolveOrder.kt | 75 ------------------- .../closerReceiver1.resolve | 9 +++ .../closerReceiver2.resolve | 9 +++ .../closerReceiver3.resolve | 7 ++ .../candidatesPriority/closerScope.resolve | 8 ++ .../extensionToCloserReceiverVsMember.resolve | 16 ++++ ...solve => implicitThisVsNoReceiver.resolve} | 0 .../implicitThisVsNoReceiver2.resolve | 12 +++ .../localVsImplicitThis.resolve | 8 ++ .../memberVsExtension1.resolve | 9 +++ .../memberVsExtension2.resolve | 10 +++ .../memberVsExtension3.resolve | 13 ++++ .../memberVsLocalExtension.resolve | 8 ++ .../receiverVsThisObject.resolve | 9 +++ .../receiverVsThisObject2.resolve | 9 +++ .../BlackBoxCodegenTestGenerated.java | 5 -- .../jet/resolve/JetResolveTestGenerated.java | 73 +++++++++++++++++- .../additional/cases/resolveOrder.jet | 75 ------------------- 20 files changed, 210 insertions(+), 203 deletions(-) delete mode 100644 compiler/testData/codegen/box/classes/resolveOrder.kt create mode 100644 compiler/testData/resolve/candidatesPriority/closerReceiver1.resolve create mode 100644 compiler/testData/resolve/candidatesPriority/closerReceiver2.resolve create mode 100644 compiler/testData/resolve/candidatesPriority/closerReceiver3.resolve create mode 100644 compiler/testData/resolve/candidatesPriority/closerScope.resolve create mode 100644 compiler/testData/resolve/candidatesPriority/extensionToCloserReceiverVsMember.resolve rename compiler/testData/resolve/candidatesPriority/{preferImplicitThisToNoReceiver.resolve => implicitThisVsNoReceiver.resolve} (100%) create mode 100644 compiler/testData/resolve/candidatesPriority/implicitThisVsNoReceiver2.resolve create mode 100644 compiler/testData/resolve/candidatesPriority/localVsImplicitThis.resolve create mode 100644 compiler/testData/resolve/candidatesPriority/memberVsExtension1.resolve create mode 100644 compiler/testData/resolve/candidatesPriority/memberVsExtension2.resolve create mode 100644 compiler/testData/resolve/candidatesPriority/memberVsExtension3.resolve create mode 100644 compiler/testData/resolve/candidatesPriority/memberVsLocalExtension.resolve create mode 100644 compiler/testData/resolve/candidatesPriority/receiverVsThisObject.resolve create mode 100644 compiler/testData/resolve/candidatesPriority/receiverVsThisObject2.resolve delete mode 100644 js/js.translator/testFiles/additional/cases/resolveOrder.jet diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/tasks/ResolutionTaskHolder.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/tasks/ResolutionTaskHolder.java index ee25d9ef892..b9162fa9ff5 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/tasks/ResolutionTaskHolder.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/tasks/ResolutionTaskHolder.java @@ -36,9 +36,7 @@ public class ResolutionTaskHolder { private final PriorityProvider> priorityProvider; private final boolean isSafeCall; - private final Collection>> localExtensions = Sets.newLinkedHashSet(); - private final Collection>> members = Sets.newLinkedHashSet(); - private final Collection>> nonLocalExtensions = Sets.newLinkedHashSet(); + private final Collection>> candidatesList = Lists.newArrayList(); private List> tasks = null; @@ -59,44 +57,19 @@ public class ResolutionTaskHolder { return candidates; } - public void addLocalExtensions(@NotNull Collection> candidates) { + public void addCandidates(@NotNull Collection> candidates) { if (!candidates.isEmpty()) { - localExtensions.add(setIsSafeCall(candidates)); - } - } - - public void addMembers(@NotNull Collection> candidates) { - if (!candidates.isEmpty()) { - members.add(setIsSafeCall(candidates)); - } - } - - public void addNonLocalExtensions(@NotNull Collection> candidates) { - if (!candidates.isEmpty()) { - nonLocalExtensions.add(setIsSafeCall(candidates)); + candidatesList.add(setIsSafeCall(candidates)); } } public List> getTasks() { if (tasks == null) { tasks = Lists.newArrayList(); - List>> candidateList = Lists.newArrayList(); - // If the call is of the form super.foo(), it can actually be only a member - // But if there's no appropriate member, we would like to report that super cannot be a receiver for an extension - // Thus, put members first - if (TaskPrioritizer.getReceiverSuper(basicCallResolutionContext.call.getExplicitReceiver()) != null) { - candidateList.addAll(members); - candidateList.addAll(localExtensions); - } - else { - candidateList.addAll(localExtensions); - candidateList.addAll(members); - } - candidateList.addAll(nonLocalExtensions); for (int priority = priorityProvider.getMaxPriority(); priority >= 0; priority--) { final int finalPriority = priority; - for (Collection> candidates : candidateList) { + for (Collection> candidates : candidatesList) { Collection> filteredCandidates = Collections2.filter(candidates, new Predicate>() { @Override public boolean apply(@Nullable ResolutionCandidate input) { 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 20272763406..85db61fa34f 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 @@ -147,29 +147,26 @@ public class TaskPrioritizer { if (receiver.exists()) { List variantsForExplicitReceiver = autoCastService.getVariantsForReceiver(receiver); - Collection> extensionFunctions = convertWithImpliedThis(scope, variantsForExplicitReceiver, callableDescriptorCollector.getNonMembersByName(scope, name)); - List> nonlocals = Lists.newArrayList(); - List> locals = Lists.newArrayList(); - //noinspection unchecked,RedundantTypeArguments - TaskPrioritizer.splitLexicallyLocalDescriptors(extensionFunctions, scope.getContainingDeclaration(), locals, nonlocals); - Collection> members = Lists.newArrayList(); for (ReceiverValue variant : variantsForExplicitReceiver) { Collection membersForThisVariant = callableDescriptorCollector.getMembersByName(variant.getType(), name); - convertWithReceivers(membersForThisVariant, Collections.singletonList(variant), Collections.singletonList(NO_RECEIVER), members, hasExplicitThisObject); + convertWithReceivers(membersForThisVariant, Collections.singletonList(variant), + Collections.singletonList(NO_RECEIVER), members, hasExplicitThisObject); } - result.addLocalExtensions(locals); - result.addMembers(members); + result.addCandidates(members); for (ReceiverValue implicitReceiver : implicitReceivers) { Collection memberExtensions = callableDescriptorCollector.getNonMembersByName( implicitReceiver.getType().getMemberScope(), name); List variantsForImplicitReceiver = autoCastService.getVariantsForReceiver(implicitReceiver); - result.addNonLocalExtensions(convertWithReceivers(memberExtensions, variantsForImplicitReceiver, variantsForExplicitReceiver, hasExplicitThisObject)); + result.addCandidates(convertWithReceivers(memberExtensions, variantsForImplicitReceiver, + variantsForExplicitReceiver, hasExplicitThisObject)); } - result.addNonLocalExtensions(nonlocals); + Collection> extensionFunctions = convertWithImpliedThis( + scope, variantsForExplicitReceiver, callableDescriptorCollector.getNonMembersByName(scope, name)); + result.addCandidates(extensionFunctions); } else { Collection> functions = convertWithImpliedThis(scope, Collections.singletonList(receiver), callableDescriptorCollector @@ -180,12 +177,12 @@ public class TaskPrioritizer { //noinspection unchecked,RedundantTypeArguments TaskPrioritizer.splitLexicallyLocalDescriptors(functions, scope.getContainingDeclaration(), locals, nonlocals); - result.addLocalExtensions(locals); + result.addCandidates(locals); for (ReceiverValue implicitReceiver : implicitReceivers) { doComputeTasks(scope, implicitReceiver, name, result, context, callableDescriptorCollector); } - result.addNonLocalExtensions(nonlocals); + result.addCandidates(nonlocals); } } diff --git a/compiler/testData/codegen/box/classes/resolveOrder.kt b/compiler/testData/codegen/box/classes/resolveOrder.kt deleted file mode 100644 index 3770367675d..00000000000 --- a/compiler/testData/codegen/box/classes/resolveOrder.kt +++ /dev/null @@ -1,75 +0,0 @@ -fun box() : String { - if (!B().test()) return "fail 1"; - if (!D().test()) return "fail 2" - if (!F().test()) return "fail 3" - if (!L().test()) return "fail 4" - if (!H().test()) return "fail 5" - if (!N().test()) return "fail 6" - return "OK" -} - -class A { - fun foo() = 1 -} - -class B { - fun foo() = 2 - - fun A.bar() = foo() - - fun test() = A().bar() == 1 -} - - -class C { - fun D.foo() = 2 -} - -class D { - fun C.foo() = 1 - - fun C.bar() = foo() - - fun test() = C().bar() == 1 -} - -class E -fun E.foo() = 2 - -class F { - fun foo() = 1 - - fun E.bar() = foo() - - fun test() = E().bar() == 1 -} - -class G -fun G.foo() = 2 - -class H { - fun G.foo() = 1 - - fun G.bar() = foo() - - fun test() = G().bar() == 1 -} - -class K -class L { - fun K.bar() = foo() - - fun test() = K().bar() == 1 -} -fun K.foo() = 1 -fun L.foo() = 2 - -class M -class N { - fun foo() = 1 - fun M.foo() = 2 - - fun M.bar() = foo() - - fun test() = M().bar() == 1 -} diff --git a/compiler/testData/resolve/candidatesPriority/closerReceiver1.resolve b/compiler/testData/resolve/candidatesPriority/closerReceiver1.resolve new file mode 100644 index 00000000000..bcb86152e0c --- /dev/null +++ b/compiler/testData/resolve/candidatesPriority/closerReceiver1.resolve @@ -0,0 +1,9 @@ +class A { + fun B.foo() = 2 +} + +class B { + ~A.foo~fun A.foo() = 1 + + fun A.bar() = `A.foo`foo() +} diff --git a/compiler/testData/resolve/candidatesPriority/closerReceiver2.resolve b/compiler/testData/resolve/candidatesPriority/closerReceiver2.resolve new file mode 100644 index 00000000000..9d188e283a4 --- /dev/null +++ b/compiler/testData/resolve/candidatesPriority/closerReceiver2.resolve @@ -0,0 +1,9 @@ +class A + +class B { + fun A.bar() = `A.foo`foo() +} + +~A.foo~fun A.foo() = 1 + +fun B.foo() = 2 diff --git a/compiler/testData/resolve/candidatesPriority/closerReceiver3.resolve b/compiler/testData/resolve/candidatesPriority/closerReceiver3.resolve new file mode 100644 index 00000000000..d82516cf5f7 --- /dev/null +++ b/compiler/testData/resolve/candidatesPriority/closerReceiver3.resolve @@ -0,0 +1,7 @@ +class A +class B { + fun foo() = 1 + ~A.foo~fun A.foo() = 2 + + fun A.bar() = `A.foo`foo() +} diff --git a/compiler/testData/resolve/candidatesPriority/closerScope.resolve b/compiler/testData/resolve/candidatesPriority/closerScope.resolve new file mode 100644 index 00000000000..9741fc8bd11 --- /dev/null +++ b/compiler/testData/resolve/candidatesPriority/closerScope.resolve @@ -0,0 +1,8 @@ +class A +fun A.foo() = 2 + +class B { + ~foo~fun A.foo() = 1 + + fun A.bar() = `foo`foo() +} diff --git a/compiler/testData/resolve/candidatesPriority/extensionToCloserReceiverVsMember.resolve b/compiler/testData/resolve/candidatesPriority/extensionToCloserReceiverVsMember.resolve new file mode 100644 index 00000000000..bb339f7a3bc --- /dev/null +++ b/compiler/testData/resolve/candidatesPriority/extensionToCloserReceiverVsMember.resolve @@ -0,0 +1,16 @@ +class A { + fun foo() = 1 +} +class B { +} +~B.foo~fun B.foo() = 2 + +fun test(a: A, b: B) { + with (a) { + with (b) { + `B.foo`foo() + } + } +} + +fun with(receiver: T, f: T.() -> R) : R = receiver.f() \ No newline at end of file diff --git a/compiler/testData/resolve/candidatesPriority/preferImplicitThisToNoReceiver.resolve b/compiler/testData/resolve/candidatesPriority/implicitThisVsNoReceiver.resolve similarity index 100% rename from compiler/testData/resolve/candidatesPriority/preferImplicitThisToNoReceiver.resolve rename to compiler/testData/resolve/candidatesPriority/implicitThisVsNoReceiver.resolve diff --git a/compiler/testData/resolve/candidatesPriority/implicitThisVsNoReceiver2.resolve b/compiler/testData/resolve/candidatesPriority/implicitThisVsNoReceiver2.resolve new file mode 100644 index 00000000000..499b78dab00 --- /dev/null +++ b/compiler/testData/resolve/candidatesPriority/implicitThisVsNoReceiver2.resolve @@ -0,0 +1,12 @@ +class A { +} +~extension~fun A.foo() = 1 +fun foo() = 2 + +fun test(a: A) { + with (a) { + `extension`foo() + } +} + +fun with(receiver: T, f: T.() -> R) : R = receiver.f() \ No newline at end of file diff --git a/compiler/testData/resolve/candidatesPriority/localVsImplicitThis.resolve b/compiler/testData/resolve/candidatesPriority/localVsImplicitThis.resolve new file mode 100644 index 00000000000..894852280f5 --- /dev/null +++ b/compiler/testData/resolve/candidatesPriority/localVsImplicitThis.resolve @@ -0,0 +1,8 @@ +class A { + fun foo() = 1 + + fun test() { + fun ~local~foo() = 2 + `local`foo() + } +} \ No newline at end of file diff --git a/compiler/testData/resolve/candidatesPriority/memberVsExtension1.resolve b/compiler/testData/resolve/candidatesPriority/memberVsExtension1.resolve new file mode 100644 index 00000000000..2d5a8a04e2b --- /dev/null +++ b/compiler/testData/resolve/candidatesPriority/memberVsExtension1.resolve @@ -0,0 +1,9 @@ +class A { + fun ~member~foo() = 1 + + fun test() { + this.`member`foo() + } +} + +fun A.foo() = 2 \ No newline at end of file diff --git a/compiler/testData/resolve/candidatesPriority/memberVsExtension2.resolve b/compiler/testData/resolve/candidatesPriority/memberVsExtension2.resolve new file mode 100644 index 00000000000..1ad5c09c458 --- /dev/null +++ b/compiler/testData/resolve/candidatesPriority/memberVsExtension2.resolve @@ -0,0 +1,10 @@ +class A { + fun ~member~foo() = 1 + + fun test() { + this.`member`foo() + } + + fun A.foo() = 2 +} + diff --git a/compiler/testData/resolve/candidatesPriority/memberVsExtension3.resolve b/compiler/testData/resolve/candidatesPriority/memberVsExtension3.resolve new file mode 100644 index 00000000000..2750e411746 --- /dev/null +++ b/compiler/testData/resolve/candidatesPriority/memberVsExtension3.resolve @@ -0,0 +1,13 @@ +class A { + fun ~member~foo() = 1 +} + +fun A.foo() = 2 + +fun test(a: A) { + with (a) { + this.`member`foo() + } +} + +fun with(receiver: T, f: T.() -> R) : R = receiver.f() \ No newline at end of file diff --git a/compiler/testData/resolve/candidatesPriority/memberVsLocalExtension.resolve b/compiler/testData/resolve/candidatesPriority/memberVsLocalExtension.resolve new file mode 100644 index 00000000000..730ab9ad946 --- /dev/null +++ b/compiler/testData/resolve/candidatesPriority/memberVsLocalExtension.resolve @@ -0,0 +1,8 @@ +class A { + fun ~member~foo() = 1 + + fun test() { + fun A.foo() = 2 + this.`member`foo() + } +} \ No newline at end of file diff --git a/compiler/testData/resolve/candidatesPriority/receiverVsThisObject.resolve b/compiler/testData/resolve/candidatesPriority/receiverVsThisObject.resolve new file mode 100644 index 00000000000..74f1c30c928 --- /dev/null +++ b/compiler/testData/resolve/candidatesPriority/receiverVsThisObject.resolve @@ -0,0 +1,9 @@ +class A { + ~A.foo~fun foo() = 1 +} + +class B { + fun foo() = 2 + + fun A.bar() = `A.foo`foo() +} diff --git a/compiler/testData/resolve/candidatesPriority/receiverVsThisObject2.resolve b/compiler/testData/resolve/candidatesPriority/receiverVsThisObject2.resolve new file mode 100644 index 00000000000..3d79b298f28 --- /dev/null +++ b/compiler/testData/resolve/candidatesPriority/receiverVsThisObject2.resolve @@ -0,0 +1,9 @@ +class A + +class B { + fun foo() = 2 + + fun A.bar() = `A.foo`foo() +} + +~A.foo~fun A.foo() = 1 diff --git a/compiler/tests/org/jetbrains/jet/codegen/generated/BlackBoxCodegenTestGenerated.java b/compiler/tests/org/jetbrains/jet/codegen/generated/BlackBoxCodegenTestGenerated.java index 42001930d01..81f312778e2 100644 --- a/compiler/tests/org/jetbrains/jet/codegen/generated/BlackBoxCodegenTestGenerated.java +++ b/compiler/tests/org/jetbrains/jet/codegen/generated/BlackBoxCodegenTestGenerated.java @@ -1105,11 +1105,6 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest { doTest("compiler/testData/codegen/box/classes/propertyInInitializer.kt"); } - @TestMetadata("resolveOrder.kt") - public void testResolveOrder() throws Exception { - doTest("compiler/testData/codegen/box/classes/resolveOrder.kt"); - } - @TestMetadata("rightHandOverride.kt") public void testRightHandOverride() throws Exception { doTest("compiler/testData/codegen/box/classes/rightHandOverride.kt"); diff --git a/compiler/tests/org/jetbrains/jet/resolve/JetResolveTestGenerated.java b/compiler/tests/org/jetbrains/jet/resolve/JetResolveTestGenerated.java index 677f28521d0..3da417da3a5 100644 --- a/compiler/tests/org/jetbrains/jet/resolve/JetResolveTestGenerated.java +++ b/compiler/tests/org/jetbrains/jet/resolve/JetResolveTestGenerated.java @@ -162,15 +162,80 @@ public class JetResolveTestGenerated 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("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"); + @TestMetadata("closerReceiver1.resolve") + public void testCloserReceiver1() throws Exception { + doTest("compiler/testData/resolve/candidatesPriority/closerReceiver1.resolve"); + } + + @TestMetadata("closerReceiver2.resolve") + public void testCloserReceiver2() throws Exception { + doTest("compiler/testData/resolve/candidatesPriority/closerReceiver2.resolve"); + } + + @TestMetadata("closerReceiver3.resolve") + public void testCloserReceiver3() throws Exception { + doTest("compiler/testData/resolve/candidatesPriority/closerReceiver3.resolve"); + } + + @TestMetadata("closerScope.resolve") + public void testCloserScope() throws Exception { + doTest("compiler/testData/resolve/candidatesPriority/closerScope.resolve"); + } + + @TestMetadata("extensionToCloserReceiverVsMember.resolve") + public void testExtensionToCloserReceiverVsMember() throws Exception { + doTest("compiler/testData/resolve/candidatesPriority/extensionToCloserReceiverVsMember.resolve"); + } + + @TestMetadata("implicitThisVsNoReceiver.resolve") + public void testImplicitThisVsNoReceiver() throws Exception { + doTest("compiler/testData/resolve/candidatesPriority/implicitThisVsNoReceiver.resolve"); + } + + @TestMetadata("implicitThisVsNoReceiver2.resolve") + public void testImplicitThisVsNoReceiver2() throws Exception { + doTest("compiler/testData/resolve/candidatesPriority/implicitThisVsNoReceiver2.resolve"); + } + + @TestMetadata("localVsImplicitThis.resolve") + public void testLocalVsImplicitThis() throws Exception { + doTest("compiler/testData/resolve/candidatesPriority/localVsImplicitThis.resolve"); + } + + @TestMetadata("memberVsExtension1.resolve") + public void testMemberVsExtension1() throws Exception { + doTest("compiler/testData/resolve/candidatesPriority/memberVsExtension1.resolve"); + } + + @TestMetadata("memberVsExtension2.resolve") + public void testMemberVsExtension2() throws Exception { + doTest("compiler/testData/resolve/candidatesPriority/memberVsExtension2.resolve"); + } + + @TestMetadata("memberVsExtension3.resolve") + public void testMemberVsExtension3() throws Exception { + doTest("compiler/testData/resolve/candidatesPriority/memberVsExtension3.resolve"); + } + + @TestMetadata("memberVsLocalExtension.resolve") + public void testMemberVsLocalExtension() throws Exception { + doTest("compiler/testData/resolve/candidatesPriority/memberVsLocalExtension.resolve"); + } + + @TestMetadata("receiverVsThisObject.resolve") + public void testReceiverVsThisObject() throws Exception { + doTest("compiler/testData/resolve/candidatesPriority/receiverVsThisObject.resolve"); + } + + @TestMetadata("receiverVsThisObject2.resolve") + public void testReceiverVsThisObject2() throws Exception { + doTest("compiler/testData/resolve/candidatesPriority/receiverVsThisObject2.resolve"); } } diff --git a/js/js.translator/testFiles/additional/cases/resolveOrder.jet b/js/js.translator/testFiles/additional/cases/resolveOrder.jet deleted file mode 100644 index 3770367675d..00000000000 --- a/js/js.translator/testFiles/additional/cases/resolveOrder.jet +++ /dev/null @@ -1,75 +0,0 @@ -fun box() : String { - if (!B().test()) return "fail 1"; - if (!D().test()) return "fail 2" - if (!F().test()) return "fail 3" - if (!L().test()) return "fail 4" - if (!H().test()) return "fail 5" - if (!N().test()) return "fail 6" - return "OK" -} - -class A { - fun foo() = 1 -} - -class B { - fun foo() = 2 - - fun A.bar() = foo() - - fun test() = A().bar() == 1 -} - - -class C { - fun D.foo() = 2 -} - -class D { - fun C.foo() = 1 - - fun C.bar() = foo() - - fun test() = C().bar() == 1 -} - -class E -fun E.foo() = 2 - -class F { - fun foo() = 1 - - fun E.bar() = foo() - - fun test() = E().bar() == 1 -} - -class G -fun G.foo() = 2 - -class H { - fun G.foo() = 1 - - fun G.bar() = foo() - - fun test() = G().bar() == 1 -} - -class K -class L { - fun K.bar() = foo() - - fun test() = K().bar() == 1 -} -fun K.foo() = 1 -fun L.foo() = 2 - -class M -class N { - fun foo() = 1 - fun M.foo() = 2 - - fun M.bar() = foo() - - fun test() = M().bar() == 1 -} From 342e9ebe7ad7260280ad35083bca6a2f9998aac5 Mon Sep 17 00:00:00 2001 From: Svetlana Isakova Date: Thu, 13 Jun 2013 20:27:31 +0400 Subject: [PATCH 153/291] KT-3563 Compiler requiring java.io.File, and it's unclear why #KT-3563 fixed --- .../jet/lang/resolve/DescriptorUtils.java | 6 +- .../lang/resolve/calls/CallResolverUtil.java | 40 ++++++++++-- .../lang/resolve/calls/CandidateResolver.java | 61 ++++++++++--------- .../tests/extensions/ExtensionFunctions.kt | 2 +- .../diagnostics/tests/extensions/kt3563.kt | 17 ++++++ .../throwOutCandidatesByReceiver.kt | 49 +++++++++++++++ .../tests/inference/regressions/kt742.kt | 4 +- .../diagnostics/tests/regressions/kt557.kt | 2 +- .../resolve/ExtensionFunctions.resolve | 5 +- .../checkers/JetDiagnosticsTestGenerated.java | 10 +++ idea/testData/checker/ExtensionFunctions.kt | 2 +- 11 files changed, 156 insertions(+), 42 deletions(-) create mode 100644 compiler/testData/diagnostics/tests/extensions/kt3563.kt create mode 100644 compiler/testData/diagnostics/tests/extensions/throwOutCandidatesByReceiver.kt 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 fba14d1131c..03955144b36 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/DescriptorUtils.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/DescriptorUtils.java @@ -36,10 +36,7 @@ import org.jetbrains.jet.lang.resolve.name.Name; import org.jetbrains.jet.lang.resolve.scopes.FilteringScope; import org.jetbrains.jet.lang.resolve.scopes.JetScope; import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverValue; -import org.jetbrains.jet.lang.types.DescriptorSubstitutor; -import org.jetbrains.jet.lang.types.JetType; -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.checker.JetTypeChecker; import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns; import org.jetbrains.jet.renderer.DescriptorRenderer; @@ -47,6 +44,7 @@ import org.jetbrains.jet.renderer.DescriptorRenderer; import java.util.*; import static org.jetbrains.jet.lang.descriptors.ReceiverParameterDescriptor.NO_RECEIVER_PARAMETER; +import static org.jetbrains.jet.lang.resolve.calls.CallResolverUtil.DONT_CARE; public class DescriptorUtils { diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/CallResolverUtil.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/CallResolverUtil.java index d1dd55523af..44bb0618819 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/CallResolverUtil.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/CallResolverUtil.java @@ -20,10 +20,7 @@ import com.google.common.collect.Lists; import com.intellij.psi.PsiElement; 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.TypeParameterDescriptor; -import org.jetbrains.jet.lang.descriptors.ValueParameterDescriptor; +import org.jetbrains.jet.lang.descriptors.*; import org.jetbrains.jet.lang.psi.Call; import org.jetbrains.jet.lang.psi.CallKey; import org.jetbrains.jet.lang.psi.JetExpression; @@ -38,6 +35,7 @@ import org.jetbrains.jet.lang.resolve.calls.model.ResolvedCallWithTrace; import org.jetbrains.jet.lang.resolve.calls.model.ResolvedValueArgument; import org.jetbrains.jet.lang.resolve.calls.tasks.ResolutionCandidate; import org.jetbrains.jet.lang.types.*; +import org.jetbrains.jet.lang.types.checker.JetTypeChecker; import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns; import java.util.Collections; @@ -153,4 +151,38 @@ public class CallResolverUtil { if (!(callElement instanceof JetExpression)) return null; return CallKey.create(context.call.getCallType(), (JetExpression) callElement); } + + public static boolean checkArgumentCannotBeReceiver( + @NotNull JetType receiverArgumentType, + @NotNull CallableDescriptor descriptor + ) { + JetType effectiveReceiverArgumentType = TypeUtils.makeNotNullable(receiverArgumentType); + + JetType erasedReceiverType = getErasedReceiverType(descriptor); + if (erasedReceiverType == null) return true; + + return !JetTypeChecker.INSTANCE.isSubtypeOf(effectiveReceiverArgumentType, erasedReceiverType); + } + + @Nullable + private static JetType getErasedReceiverType(@NotNull CallableDescriptor descriptor) { + ReceiverParameterDescriptor receiverDescriptor = descriptor.getReceiverParameter(); + ReceiverParameterDescriptor expectedThisObjectDescriptor = descriptor.getExpectedThisObject(); + JetType receiverType = receiverDescriptor != null ? receiverDescriptor.getType() : + expectedThisObjectDescriptor != null ? expectedThisObjectDescriptor.getType() : null; + if (receiverType == null) return null; + + for (TypeParameterDescriptor typeParameter : descriptor.getTypeParameters()) { + if (typeParameter.getTypeConstructor().equals(receiverType.getConstructor())) { + return typeParameter.getUpperBoundsAsType(); + } + } + List fakeTypeArguments = Lists.newArrayList(); + for (TypeProjection typeProjection : receiverType.getArguments()) { + fakeTypeArguments.add(new TypeProjection(typeProjection.getProjectionKind(), DONT_CARE)); + } + return new JetTypeImpl( + receiverType.getAnnotations(), receiverType.getConstructor(), receiverType.isNullable(), + fakeTypeArguments, receiverType.getMemberScope()); + } } 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 8d15321b81d..9cb99b27291 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 @@ -41,6 +41,7 @@ import org.jetbrains.jet.lang.resolve.calls.results.ResolutionDebugInfo; import org.jetbrains.jet.lang.resolve.calls.results.ResolutionStatus; import org.jetbrains.jet.lang.resolve.calls.tasks.ResolutionTask; import org.jetbrains.jet.lang.resolve.calls.tasks.TaskPrioritizer; +import org.jetbrains.jet.lang.resolve.calls.util.ExpressionAsFunctionDescriptor; import org.jetbrains.jet.lang.resolve.scopes.receivers.ExpressionReceiver; import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverValue; import org.jetbrains.jet.lang.types.*; @@ -660,39 +661,43 @@ public class CandidateResolver { } private ResolutionStatus checkReceiver( - CallCandidateResolutionContext context, ResolvedCall candidateCall, BindingTrace trace, - ReceiverParameterDescriptor receiverParameter, ReceiverValue receiverArgument, - boolean isExplicitReceiver, boolean implicitInvokeCheck) { + @NotNull CallCandidateResolutionContext context, + @NotNull ResolvedCall candidateCall, + @NotNull BindingTrace trace, + @Nullable ReceiverParameterDescriptor receiverParameter, + @NotNull ReceiverValue receiverArgument, + boolean isExplicitReceiver, + boolean implicitInvokeCheck + ) { + if (receiverParameter == null || !receiverArgument.exists()) return SUCCESS; - BindingContext bindingContext = trace.getBindingContext(); + JetType receiverArgumentType = receiverArgument.getType(); + JetType effectiveReceiverArgumentType = TypeUtils.makeNotNullable(receiverArgumentType); + D candidateDescriptor = candidateCall.getCandidateDescriptor(); + if (!argumentTypeResolver.isSubtypeOfForArgumentType(effectiveReceiverArgumentType, receiverParameter.getType())) { - ResolutionStatus result = SUCCESS; - if (receiverParameter != null && receiverArgument.exists()) { - boolean safeAccess = isExplicitReceiver && !implicitInvokeCheck && candidateCall.isSafeCall(); - JetType receiverArgumentType = receiverArgument.getType(); - AutoCastServiceImpl autoCastService = new AutoCastServiceImpl(context.dataFlowInfo, bindingContext); - if (!safeAccess && !receiverParameter.getType().isNullable() && !autoCastService.isNotNull(receiverArgument)) { - - context.tracing.unsafeCall(trace, receiverArgumentType, implicitInvokeCheck); - result = UNSAFE_CALL_ERROR; + if (CallResolverUtil.checkArgumentCannotBeReceiver(effectiveReceiverArgumentType, candidateDescriptor) + && !(candidateDescriptor instanceof ExpressionAsFunctionDescriptor)) { + return STRONG_ERROR; } - else { - JetType effectiveReceiverArgumentType = safeAccess - ? TypeUtils.makeNotNullable(receiverArgumentType) - : receiverArgumentType; - if (!TypeUtils.dependsOnTypeParameters(receiverParameter.getType(), - candidateCall.getCandidateDescriptor().getTypeParameters()) && - !argumentTypeResolver.isSubtypeOfForArgumentType(effectiveReceiverArgumentType, receiverParameter.getType())) { - context.tracing.wrongReceiverType(trace, receiverParameter, receiverArgument); - result = OTHER_ERROR; - } - } - DataFlowValue receiverValue = DataFlowValueFactory.INSTANCE.createDataFlowValue(receiverArgument, bindingContext); - if (safeAccess && !context.dataFlowInfo.getNullability(receiverValue).canBeNull()) { - context.tracing.unnecessarySafeCall(trace, receiverArgumentType); + if (!TypeUtils.dependsOnTypeParameters(receiverParameter.getType(), candidateDescriptor.getTypeParameters())) { + context.tracing.wrongReceiverType(trace, receiverParameter, receiverArgument); + return OTHER_ERROR; } } - return result; + BindingContext bindingContext = trace.getBindingContext(); + boolean safeAccess = isExplicitReceiver && !implicitInvokeCheck && candidateCall.isSafeCall(); + AutoCastServiceImpl autoCastService = new AutoCastServiceImpl(context.dataFlowInfo, bindingContext); + if (!safeAccess && !receiverParameter.getType().isNullable() && !autoCastService.isNotNull(receiverArgument)) { + + context.tracing.unsafeCall(trace, receiverArgumentType, implicitInvokeCheck); + return UNSAFE_CALL_ERROR; + } + DataFlowValue receiverValue = DataFlowValueFactory.INSTANCE.createDataFlowValue(receiverArgument, bindingContext); + if (safeAccess && !context.dataFlowInfo.getNullability(receiverValue).canBeNull()) { + context.tracing.unnecessarySafeCall(trace, receiverArgumentType); + } + return SUCCESS; } private static class ValueArgumentsCheckingResult { diff --git a/compiler/testData/diagnostics/tests/extensions/ExtensionFunctions.kt b/compiler/testData/diagnostics/tests/extensions/ExtensionFunctions.kt index 9d11eb8bbc9..a2c5585ac31 100644 --- a/compiler/testData/diagnostics/tests/extensions/ExtensionFunctions.kt +++ b/compiler/testData/diagnostics/tests/extensions/ExtensionFunctions.kt @@ -19,7 +19,7 @@ class A fun A.plus(a : Any) { 1.foo() - true.foo() + true.foo() 1 } diff --git a/compiler/testData/diagnostics/tests/extensions/kt3563.kt b/compiler/testData/diagnostics/tests/extensions/kt3563.kt new file mode 100644 index 00000000000..e4401193846 --- /dev/null +++ b/compiler/testData/diagnostics/tests/extensions/kt3563.kt @@ -0,0 +1,17 @@ +// KT-3563 Compiler requiring java.io.File, and it's unclear why + +package bar + +import java.io.File + +class Customer(name: String) + +fun foo(f: File, c: Customer) { + f.name + + c.name // name should be unresolved here +} + +//from standard library +val File.name: String + get() = getName() diff --git a/compiler/testData/diagnostics/tests/extensions/throwOutCandidatesByReceiver.kt b/compiler/testData/diagnostics/tests/extensions/throwOutCandidatesByReceiver.kt new file mode 100644 index 00000000000..92a76c68f8b --- /dev/null +++ b/compiler/testData/diagnostics/tests/extensions/throwOutCandidatesByReceiver.kt @@ -0,0 +1,49 @@ +package bar + + +// should be thrown away + +fun List.a() {} + +fun test1(i: Int?) { + 1.a() + i.a() +} + +fun test2(c: Collection) { + c.a() +} + +fun Int.foo() {} + +fun test3(s: String?) { + "".foo() + s.foo() +} + +trait A +fun T.c() {} + +fun test4() { + 1.c() +} + + +// should be an error on receiver, shouldn't be thrown away + +fun test5() { + 1.{ String.(): String -> this}() +} + +fun R?.sure() : R = this!! + +fun test6(l: List?) { + l.sure() +} + + +fun List.b() {} + +fun test7(l: List) { + l.b() +} \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/inference/regressions/kt742.kt b/compiler/testData/diagnostics/tests/inference/regressions/kt742.kt index d8f1846148c..59c9090b75f 100644 --- a/compiler/testData/diagnostics/tests/inference/regressions/kt742.kt +++ b/compiler/testData/diagnostics/tests/inference/regressions/kt742.kt @@ -7,4 +7,6 @@ class List(val head: T, val tail: List? = null) fun List.map1(f: (T)-> Q): List? = tail!!.map1(f) -fun List.map2(f: (T)-> Q): List? = tail.sure().map2(f) \ No newline at end of file +fun List.map2(f: (T)-> Q): List? = tail.sure().map2(f) + +fun List.map3(f: (T)-> Q): List? = tail.sure().map3(f) \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/regressions/kt557.kt b/compiler/testData/diagnostics/tests/regressions/kt557.kt index 993d2703426..bd964a524ff 100644 --- a/compiler/testData/diagnostics/tests/regressions/kt557.kt +++ b/compiler/testData/diagnostics/tests/regressions/kt557.kt @@ -7,5 +7,5 @@ fun Array.length() : Int { } fun test(array : Array?) { - array?.sure>().length() + array?.sure>().length() } diff --git a/compiler/testData/resolve/ExtensionFunctions.resolve b/compiler/testData/resolve/ExtensionFunctions.resolve index 19f490db5c6..28de6f75ddc 100644 --- a/compiler/testData/resolve/ExtensionFunctions.resolve +++ b/compiler/testData/resolve/ExtensionFunctions.resolve @@ -1,4 +1,4 @@ -fun <~T~T, ~E~E> `T`T.foo(x : `E`E, y : `A`A) : `T`T { +~T.foo~fun <~T~T, ~E~E> `T`T.foo(x : `E`E, y : `A`A) : `T`T { y.`+`plus(1) y `+`plus 1 y `+1`+ 1.0 @@ -13,7 +13,8 @@ fun <~T~T, ~E~E> `T`T.foo(x : `E`E, y : `A`A) : `T`T { ~+1~fun `A`A.plus(a : Any) { 1.`foo`foo() - true.`!null`foo() + true.`T.foo`foo() + 3.`!null`foo(4) 1 } diff --git a/compiler/tests/org/jetbrains/jet/checkers/JetDiagnosticsTestGenerated.java b/compiler/tests/org/jetbrains/jet/checkers/JetDiagnosticsTestGenerated.java index 6da64048a60..247de11cbc4 100644 --- a/compiler/tests/org/jetbrains/jet/checkers/JetDiagnosticsTestGenerated.java +++ b/compiler/tests/org/jetbrains/jet/checkers/JetDiagnosticsTestGenerated.java @@ -2282,11 +2282,21 @@ public class JetDiagnosticsTestGenerated extends AbstractDiagnosticsTestWithEage doTest("compiler/testData/diagnostics/tests/extensions/kt2317.kt"); } + @TestMetadata("kt3563.kt") + public void testKt3563() throws Exception { + doTest("compiler/testData/diagnostics/tests/extensions/kt3563.kt"); + } + @TestMetadata("kt819ExtensionProperties.kt") public void testKt819ExtensionProperties() throws Exception { doTest("compiler/testData/diagnostics/tests/extensions/kt819ExtensionProperties.kt"); } + @TestMetadata("throwOutCandidatesByReceiver.kt") + public void testThrowOutCandidatesByReceiver() throws Exception { + doTest("compiler/testData/diagnostics/tests/extensions/throwOutCandidatesByReceiver.kt"); + } + } @TestMetadata("compiler/testData/diagnostics/tests/functionLiterals") diff --git a/idea/testData/checker/ExtensionFunctions.kt b/idea/testData/checker/ExtensionFunctions.kt index d52c79e886e..55c078ae6d3 100644 --- a/idea/testData/checker/ExtensionFunctions.kt +++ b/idea/testData/checker/ExtensionFunctions.kt @@ -16,7 +16,7 @@ class A fun A.plus(a : Any) { 1.foo() - true.foo() + true.foo() 1 } From 3340b94bd82e5ea72c1959314c04e796e652904a Mon Sep 17 00:00:00 2001 From: Svetlana Isakova Date: Thu, 13 Jun 2013 20:35:34 +0400 Subject: [PATCH 154/291] refactoring extracted methods --- .../results/ResolutionResultsHandler.java | 156 +++++++++--------- 1 file changed, 82 insertions(+), 74 deletions(-) diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/results/ResolutionResultsHandler.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/results/ResolutionResultsHandler.java index 6a539962ed8..a427b80640e 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/results/ResolutionResultsHandler.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/results/ResolutionResultsHandler.java @@ -57,85 +57,13 @@ public class ResolutionResultsHandler { failedCandidates.add(candidateCall); } } - return computeResultAndReportErrors(trace, tracing, successfulCandidates, failedCandidates, incompleteCandidates); - } - - @NotNull - private OverloadResolutionResultsImpl computeResultAndReportErrors( - @NotNull BindingTrace trace, - @NotNull TracingStrategy tracing, - @NotNull Set> successfulCandidates, - @NotNull Set> failedCandidates, - @NotNull Set> incompleteCandidates - ) { // TODO : maybe it's better to filter overrides out first, and only then look for the maximally specific if (!successfulCandidates.isEmpty() || !incompleteCandidates.isEmpty()) { - Set> successfulAndIncomplete = Sets.newLinkedHashSet(); - successfulAndIncomplete.addAll(successfulCandidates); - successfulAndIncomplete.addAll(incompleteCandidates); - OverloadResolutionResultsImpl results = chooseAndReportMaximallySpecific(successfulAndIncomplete, true); - if (results.isSingleResult()) { - ResolvedCallWithTrace resultingCall = results.getResultingCall(); - resultingCall.getTrace().moveAllMyDataTo(trace); - if (resultingCall.getStatus() == INCOMPLETE_TYPE_INFERENCE) { - return OverloadResolutionResultsImpl.incompleteTypeInference(resultingCall); - } - } - if (results.isAmbiguity()) { - tracing.recordAmbiguity(trace, results.getResultingCalls()); - if (allIncomplete(results.getResultingCalls())) { - tracing.cannotCompleteResolve(trace, results.getResultingCalls()); - return OverloadResolutionResultsImpl.incompleteTypeInference(results.getResultingCalls()); - } - // This check is needed for the following case: - // x.foo(unresolved) -- if there are multiple foo's, we'd report an ambiguity, and it does not make sense here - if (allClean(results.getResultingCalls())) { - tracing.ambiguity(trace, results.getResultingCalls()); - } - } - return results; + return computeSuccessfulResult(trace, tracing, successfulCandidates, incompleteCandidates); } else if (!failedCandidates.isEmpty()) { - if (failedCandidates.size() != 1) { - // This is needed when there are several overloads some of which are OK but for nullability of the receiver, - // and some are not OK at all. In this case we'd like to say "unsafe call" rather than "none applicable" - // Used to be: weak errors. Generalized for future extensions - for (EnumSet severityLevel : SEVERITY_LEVELS) { - Set> thisLevel = Sets.newLinkedHashSet(); - for (ResolvedCallWithTrace candidate : failedCandidates) { - if (severityLevel.contains(candidate.getStatus())) { - thisLevel.add(candidate); - } - } - if (!thisLevel.isEmpty()) { - OverloadResolutionResultsImpl results = chooseAndReportMaximallySpecific(thisLevel, false); - if (results.isSingleResult()) { - results.getResultingCall().getTrace().moveAllMyDataTo(trace); - return OverloadResolutionResultsImpl.singleFailedCandidate(results.getResultingCall()); - } - - tracing.noneApplicable(trace, results.getResultingCalls()); - tracing.recordAmbiguity(trace, results.getResultingCalls()); - return OverloadResolutionResultsImpl.manyFailedCandidates(results.getResultingCalls()); - } - } - - assert false : "Should not be reachable, cause every status must belong to some level"; - - Set> noOverrides = OverridingUtil.filterOverrides(failedCandidates, MAP_TO_CANDIDATE); - if (noOverrides.size() != 1) { - tracing.noneApplicable(trace, noOverrides); - tracing.recordAmbiguity(trace, noOverrides); - return OverloadResolutionResultsImpl.manyFailedCandidates(noOverrides); - } - - failedCandidates = noOverrides; - } - - ResolvedCallWithTrace failed = failedCandidates.iterator().next(); - failed.getTrace().moveAllMyDataTo(trace); - return OverloadResolutionResultsImpl.singleFailedCandidate(failed); + return computeFailedResult(trace, tracing, failedCandidates); } else { tracing.unresolvedReference(trace); @@ -143,6 +71,86 @@ public class ResolutionResultsHandler { } } + @NotNull + private OverloadResolutionResultsImpl computeSuccessfulResult( + BindingTrace trace, + TracingStrategy tracing, + Set> successfulCandidates, + Set> incompleteCandidates + ) { + Set> successfulAndIncomplete = Sets.newLinkedHashSet(); + successfulAndIncomplete.addAll(successfulCandidates); + successfulAndIncomplete.addAll(incompleteCandidates); + OverloadResolutionResultsImpl results = chooseAndReportMaximallySpecific(successfulAndIncomplete, true); + if (results.isSingleResult()) { + ResolvedCallWithTrace resultingCall = results.getResultingCall(); + resultingCall.getTrace().moveAllMyDataTo(trace); + if (resultingCall.getStatus() == INCOMPLETE_TYPE_INFERENCE) { + return OverloadResolutionResultsImpl.incompleteTypeInference(resultingCall); + } + } + if (results.isAmbiguity()) { + tracing.recordAmbiguity(trace, results.getResultingCalls()); + if (allIncomplete(results.getResultingCalls())) { + tracing.cannotCompleteResolve(trace, results.getResultingCalls()); + return OverloadResolutionResultsImpl.incompleteTypeInference(results.getResultingCalls()); + } + // This check is needed for the following case: + // x.foo(unresolved) -- if there are multiple foo's, we'd report an ambiguity, and it does not make sense here + if (allClean(results.getResultingCalls())) { + tracing.ambiguity(trace, results.getResultingCalls()); + } + } + return results; + } + + @NotNull + private OverloadResolutionResultsImpl computeFailedResult( + BindingTrace trace, + TracingStrategy tracing, + Set> failedCandidates + ) { + if (failedCandidates.size() != 1) { + // This is needed when there are several overloads some of which are OK but for nullability of the receiver, + // and some are not OK at all. In this case we'd like to say "unsafe call" rather than "none applicable" + // Used to be: weak errors. Generalized for future extensions + for (EnumSet severityLevel : SEVERITY_LEVELS) { + Set> thisLevel = Sets.newLinkedHashSet(); + for (ResolvedCallWithTrace candidate : failedCandidates) { + if (severityLevel.contains(candidate.getStatus())) { + thisLevel.add(candidate); + } + } + if (!thisLevel.isEmpty()) { + OverloadResolutionResultsImpl results = chooseAndReportMaximallySpecific(thisLevel, false); + if (results.isSingleResult()) { + results.getResultingCall().getTrace().moveAllMyDataTo(trace); + return OverloadResolutionResultsImpl.singleFailedCandidate(results.getResultingCall()); + } + + tracing.noneApplicable(trace, results.getResultingCalls()); + tracing.recordAmbiguity(trace, results.getResultingCalls()); + return OverloadResolutionResultsImpl.manyFailedCandidates(results.getResultingCalls()); + } + } + + assert false : "Should not be reachable, cause every status must belong to some level"; + + Set> noOverrides = OverridingUtil.filterOverrides(failedCandidates, MAP_TO_CANDIDATE); + if (noOverrides.size() != 1) { + tracing.noneApplicable(trace, noOverrides); + tracing.recordAmbiguity(trace, noOverrides); + return OverloadResolutionResultsImpl.manyFailedCandidates(noOverrides); + } + + failedCandidates = noOverrides; + } + + ResolvedCallWithTrace failed = failedCandidates.iterator().next(); + failed.getTrace().moveAllMyDataTo(trace); + return OverloadResolutionResultsImpl.singleFailedCandidate(failed); + } + private static boolean allClean(@NotNull Collection> results) { for (ResolvedCallWithTrace result : results) { if (result.isDirty()) return false; From 041505f5b8e3d913cd7491f948ab4dbe4e1240c0 Mon Sep 17 00:00:00 2001 From: Svetlana Isakova Date: Mon, 17 Jun 2013 19:05:54 +0400 Subject: [PATCH 155/291] report UNRESOLVED_REFERENCE_WRONG_RECEIVER mentioning candidates with wrong receiver --- .../jet/lang/diagnostics/Errors.java | 3 +- .../rendering/DefaultErrorMessages.java | 1 + .../resolve/calls/ArgumentTypeResolver.java | 6 +-- .../jet/lang/resolve/calls/CallResolver.java | 23 +++++----- .../lang/resolve/calls/CandidateResolver.java | 42 +++++++++++++------ .../results/OverloadResolutionResults.java | 1 + .../OverloadResolutionResultsImpl.java | 6 ++- .../results/ResolutionResultsHandler.java | 14 +++++-- .../calls/results/ResolutionStatus.java | 11 ++++- .../resolve/calls/tasks/TracingStrategy.java | 10 +++-- .../calls/tasks/TracingStrategyImpl.java | 7 +++- .../diagnostics/tests/extensions/kt3563.kt | 4 +- .../throwOutCandidatesByReceiver.kt | 18 +++++--- .../throwOutCandidatesByReceiver2.kt | 14 +++++++ .../tests/inference/regressions/kt742.kt | 2 +- .../wrongReceiverVsOtherError.resolve | 17 ++++++++ .../checkers/JetDiagnosticsTestGenerated.java | 5 +++ .../jet/resolve/JetResolveTestGenerated.java | 5 +++ .../plugin/highlighter/IdeErrorMessages.java | 2 +- 19 files changed, 142 insertions(+), 49 deletions(-) create mode 100644 compiler/testData/diagnostics/tests/extensions/throwOutCandidatesByReceiver2.kt create mode 100644 compiler/testData/resolve/candidatesPriority/wrongReceiverVsOtherError.resolve diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/diagnostics/Errors.java b/compiler/frontend/src/org/jetbrains/jet/lang/diagnostics/Errors.java index 4f59ca5d8ca..fb577259e3f 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/diagnostics/Errors.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/diagnostics/Errors.java @@ -337,6 +337,7 @@ public interface Errors { DiagnosticFactory1>> OVERLOAD_RESOLUTION_AMBIGUITY = DiagnosticFactory1.create(ERROR); DiagnosticFactory1>> NONE_APPLICABLE = DiagnosticFactory1.create(ERROR); DiagnosticFactory1>> CANNOT_COMPLETE_RESOLVE = DiagnosticFactory1.create(ERROR); + DiagnosticFactory1>> UNRESOLVED_REFERENCE_WRONG_RECEIVER = DiagnosticFactory1.create(ERROR); DiagnosticFactory0 DANGLING_FUNCTION_LITERAL_ARGUMENT_SUSPECTED = DiagnosticFactory0.create(WARNING); @@ -548,7 +549,7 @@ public interface Errors { // Error sets ImmutableSet UNRESOLVED_REFERENCE_DIAGNOSTICS = ImmutableSet.of( - UNRESOLVED_REFERENCE, NAMED_PARAMETER_NOT_FOUND); + UNRESOLVED_REFERENCE, NAMED_PARAMETER_NOT_FOUND, UNRESOLVED_REFERENCE_WRONG_RECEIVER); ImmutableSet UNUSED_ELEMENT_DIAGNOSTICS = ImmutableSet.of( UNUSED_VARIABLE, UNUSED_PARAMETER, ASSIGNED_BUT_NEVER_ACCESSED_VARIABLE); ImmutableSet REDECLARATION_DIAGNOSTICS = ImmutableSet.of( diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/diagnostics/rendering/DefaultErrorMessages.java b/compiler/frontend/src/org/jetbrains/jet/lang/diagnostics/rendering/DefaultErrorMessages.java index 6cf84bf8dfc..1303f0fd170 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/diagnostics/rendering/DefaultErrorMessages.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/diagnostics/rendering/DefaultErrorMessages.java @@ -410,6 +410,7 @@ public class DefaultErrorMessages { MAP.put(OVERLOAD_RESOLUTION_AMBIGUITY, "Overload resolution ambiguity: {0}", AMBIGUOUS_CALLS); MAP.put(NONE_APPLICABLE, "None of the following functions can be called with the arguments supplied: {0}", AMBIGUOUS_CALLS); MAP.put(CANNOT_COMPLETE_RESOLVE, "Cannot choose among the following candidates without completing type inference: {0}", AMBIGUOUS_CALLS); + MAP.put(UNRESOLVED_REFERENCE_WRONG_RECEIVER, "Unresolved reference. None of the following candidates is applicable because of receiver type mismatch: {0}", AMBIGUOUS_CALLS); MAP.put(NO_VALUE_FOR_PARAMETER, "No value passed for parameter {0}", NAME); MAP.put(MISSING_RECEIVER, "A receiver of type {0} is required", RENDER_TYPE); diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/ArgumentTypeResolver.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/ArgumentTypeResolver.java index d2a88eb2d61..8f3b800d54c 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/ArgumentTypeResolver.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/ArgumentTypeResolver.java @@ -56,8 +56,6 @@ import static org.jetbrains.jet.lang.resolve.calls.CallResolverUtil.ResolveArgum import static org.jetbrains.jet.lang.types.TypeUtils.NO_EXPECTED_TYPE; public class ArgumentTypeResolver { - @NotNull - private final JetTypeChecker typeChecker = JetTypeChecker.INSTANCE; @NotNull private TypeResolver typeResolver; @@ -74,14 +72,14 @@ public class ArgumentTypeResolver { this.expressionTypingServices = expressionTypingServices; } - public boolean isSubtypeOfForArgumentType(@NotNull JetType subtype, @NotNull JetType supertype) { + public static boolean isSubtypeOfForArgumentType(@NotNull JetType subtype, @NotNull JetType supertype) { if (subtype == PLACEHOLDER_FUNCTION_TYPE) { return isFunctionOrErrorType(supertype) || KotlinBuiltIns.getInstance().isAny(supertype); //todo function type extends } if (supertype == PLACEHOLDER_FUNCTION_TYPE) { return isFunctionOrErrorType(subtype); //todo extends function type } - return typeChecker.isSubtypeOf(subtype, supertype); + return JetTypeChecker.INSTANCE.isSubtypeOf(subtype, supertype); } private static boolean isFunctionOrErrorType(@NotNull JetType supertype) { 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 f5bb8302e8f..2f5ed68b8ec 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 @@ -31,10 +31,7 @@ import org.jetbrains.jet.lang.resolve.calls.autocasts.DataFlowInfo; import org.jetbrains.jet.lang.resolve.calls.context.*; import org.jetbrains.jet.lang.resolve.calls.model.ResolvedCallImpl; import org.jetbrains.jet.lang.resolve.calls.model.ResolvedCallWithTrace; -import org.jetbrains.jet.lang.resolve.calls.results.OverloadResolutionResults; -import org.jetbrains.jet.lang.resolve.calls.results.OverloadResolutionResultsImpl; -import org.jetbrains.jet.lang.resolve.calls.results.ResolutionDebugInfo; -import org.jetbrains.jet.lang.resolve.calls.results.ResolutionResultsHandler; +import org.jetbrains.jet.lang.resolve.calls.results.*; import org.jetbrains.jet.lang.resolve.calls.tasks.*; import org.jetbrains.jet.lang.resolve.calls.util.DelegatingCall; import org.jetbrains.jet.lang.resolve.calls.util.ExpressionAsFunctionDescriptor; @@ -59,6 +56,7 @@ import static org.jetbrains.jet.lang.diagnostics.Errors.*; import static org.jetbrains.jet.lang.resolve.BindingContext.NON_DEFAULT_EXPRESSION_DATA_FLOW; import static org.jetbrains.jet.lang.resolve.BindingContext.RESOLUTION_SCOPE; import static org.jetbrains.jet.lang.resolve.calls.CallResolverUtil.ResolveArgumentsMode.RESOLVE_FUNCTION_ARGUMENTS; +import static org.jetbrains.jet.lang.resolve.calls.results.OverloadResolutionResults.Code.*; import static org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverValue.NO_RECEIVER; import static org.jetbrains.jet.lang.types.TypeUtils.NO_EXPECTED_TYPE; @@ -274,8 +272,8 @@ public class CallResolver { private OverloadResolutionResultsImpl doResolveCallOrGetCachedResults( @NotNull ResolutionResultsCache.MemberType memberType, - @NotNull final BasicCallResolutionContext context, - @NotNull final List> prioritizedTasks, + @NotNull BasicCallResolutionContext context, + @NotNull List> prioritizedTasks, @NotNull CallTransformer callTransformer, @NotNull JetReferenceExpression reference ) { @@ -323,7 +321,7 @@ public class CallResolver { @NotNull TracingStrategy tracing ) { if (!results.isSingleResult()) { - if (results.getResultCode() == OverloadResolutionResults.Code.INCOMPLETE_TYPE_INFERENCE) { + if (results.getResultCode() == INCOMPLETE_TYPE_INFERENCE) { argumentTypeResolver.checkTypesWithNoCallee(context, RESOLVE_FUNCTION_ARGUMENTS); } return; @@ -427,11 +425,14 @@ public class CallResolver { resolveFunctionArguments(context, results); return results; } - if (results.getResultCode() == OverloadResolutionResults.Code.INCOMPLETE_TYPE_INFERENCE) { + if (results.getResultCode() == INCOMPLETE_TYPE_INFERENCE) { results.setTrace(taskTrace); return results; } - if (traceForFirstNonemptyCandidateSet == null && !task.getCandidates().isEmpty() && !results.isNothing()) { + boolean updateResults = traceForFirstNonemptyCandidateSet == null + || (resultsForFirstNonemptyCandidateSet.getResultCode() == CANDIDATES_WITH_WRONG_RECEIVER && + results.getResultCode() != CANDIDATES_WITH_WRONG_RECEIVER); + if (!task.getCandidates().isEmpty() && !results.isNothing() && updateResults) { traceForFirstNonemptyCandidateSet = taskTrace; resultsForFirstNonemptyCandidateSet = results; } @@ -488,8 +489,8 @@ public class CallResolver { // {...} // intended to be a returned from the outer literal // } // } - ImmutableSet someFailed = ImmutableSet.of(OverloadResolutionResults.Code.MANY_FAILED_CANDIDATES, - OverloadResolutionResults.Code.SINGLE_CANDIDATE_ARGUMENT_MISMATCH); + ImmutableSet someFailed = ImmutableSet.of(MANY_FAILED_CANDIDATES, + SINGLE_CANDIDATE_ARGUMENT_MISMATCH); 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 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 9cb99b27291..e2f6585dadd 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 @@ -83,6 +83,8 @@ public class CandidateResolver { ResolvedCallImpl candidateCall = context.candidateCall; D candidate = candidateCall.getCandidateDescriptor(); + candidateCall.addStatus(checkReceiver(context, context.trace, /*checkOnlyReceiverTypeError=*/true)); + if (ErrorUtils.isError(candidate)) { candidateCall.addStatus(SUCCESS); argumentTypeResolver.checkTypesWithNoCallee(context.toBasic()); @@ -110,7 +112,7 @@ public class CandidateResolver { candidateCall, unmappedArguments); if (!argumentMappingStatus.isSuccess()) { if (argumentMappingStatus == ValueArgumentsToParametersMapper.Status.STRONG_ERROR) { - candidateCall.addStatus(STRONG_ERROR); + candidateCall.addStatus(RECEIVER_PRESENCE_ERROR); } else { candidateCall.addStatus(OTHER_ERROR); @@ -563,6 +565,17 @@ public class CandidateResolver { ValueArgumentsCheckingResult checkingResult = checkValueArgumentTypes( context, context.candidateCall, trace, resolveFunctionArgumentBodies); ResolutionStatus resultStatus = checkingResult.status; + resultStatus = resultStatus.combine(checkReceiver(context, trace, false)); + + return new ValueArgumentsCheckingResult(resultStatus, checkingResult.argumentTypes); + } + + private static ResolutionStatus checkReceiver( + @NotNull CallCandidateResolutionContext context, + @NotNull BindingTrace trace, + boolean checkOnlyReceiverTypeError + ) { + ResolutionStatus resultStatus = SUCCESS; ResolvedCall candidateCall = context.candidateCall; // Comment about a very special case. @@ -573,15 +586,15 @@ public class CandidateResolver { resultStatus = resultStatus.combine(checkReceiver( context, candidateCall, trace, candidateCall.getResultingDescriptor().getReceiverParameter(), - candidateCall.getReceiverArgument(), candidateCall.getExplicitReceiverKind().isReceiver(), false)); + candidateCall.getReceiverArgument(), candidateCall.getExplicitReceiverKind().isReceiver(), false, checkOnlyReceiverTypeError)); resultStatus = resultStatus.combine(checkReceiver( context, candidateCall, trace, candidateCall.getResultingDescriptor().getExpectedThisObject(), candidateCall.getThisObject(), candidateCall.getExplicitReceiverKind().isThisObject(), // for the invocation 'foo(1)' where foo is a variable of function type we should mark 'foo' if there is unsafe call error - context.call instanceof CallForImplicitInvoke)); - return new ValueArgumentsCheckingResult(resultStatus, checkingResult.argumentTypes); + context.call instanceof CallForImplicitInvoke, checkOnlyReceiverTypeError)); + return resultStatus; } public ValueArgumentsCheckingResult checkValueArgumentTypes( @@ -623,7 +636,7 @@ public class CandidateResolver { } else { JetType resultingType; - if (expectedType == NO_EXPECTED_TYPE || argumentTypeResolver.isSubtypeOfForArgumentType(type, expectedType)) { + if (expectedType == NO_EXPECTED_TYPE || ArgumentTypeResolver.isSubtypeOfForArgumentType(type, expectedType)) { resultingType = type; } else { @@ -642,7 +655,7 @@ public class CandidateResolver { } @Nullable - private JetType autocastValueArgumentTypeIfPossible( + private static JetType autocastValueArgumentTypeIfPossible( @NotNull JetExpression expression, @NotNull JetType expectedType, @NotNull JetType actualType, @@ -653,38 +666,43 @@ public class CandidateResolver { List variants = AutoCastUtils.getAutoCastVariants(trace.getBindingContext(), dataFlowInfo, receiverToCast); for (ReceiverValue receiverValue : variants) { JetType possibleType = receiverValue.getType(); - if (argumentTypeResolver.isSubtypeOfForArgumentType(possibleType, expectedType)) { + if (ArgumentTypeResolver.isSubtypeOfForArgumentType(possibleType, expectedType)) { return possibleType; } } return null; } - private ResolutionStatus checkReceiver( + private static ResolutionStatus checkReceiver( @NotNull CallCandidateResolutionContext context, @NotNull ResolvedCall candidateCall, @NotNull BindingTrace trace, @Nullable ReceiverParameterDescriptor receiverParameter, @NotNull ReceiverValue receiverArgument, boolean isExplicitReceiver, - boolean implicitInvokeCheck + boolean implicitInvokeCheck, + boolean checkOnlyReceiverTypeError ) { if (receiverParameter == null || !receiverArgument.exists()) return SUCCESS; JetType receiverArgumentType = receiverArgument.getType(); JetType effectiveReceiverArgumentType = TypeUtils.makeNotNullable(receiverArgumentType); D candidateDescriptor = candidateCall.getCandidateDescriptor(); - if (!argumentTypeResolver.isSubtypeOfForArgumentType(effectiveReceiverArgumentType, receiverParameter.getType())) { + if (!ArgumentTypeResolver.isSubtypeOfForArgumentType(effectiveReceiverArgumentType, receiverParameter.getType())) { if (CallResolverUtil.checkArgumentCannotBeReceiver(effectiveReceiverArgumentType, candidateDescriptor) && !(candidateDescriptor instanceof ExpressionAsFunctionDescriptor)) { - return STRONG_ERROR; + return RECEIVER_TYPE_ERROR; } - if (!TypeUtils.dependsOnTypeParameters(receiverParameter.getType(), candidateDescriptor.getTypeParameters())) { + //todo + if (!TypeUtils.dependsOnTypeParameters(receiverParameter.getType(), candidateDescriptor.getTypeParameters()) + && !checkOnlyReceiverTypeError) { context.tracing.wrongReceiverType(trace, receiverParameter, receiverArgument); return OTHER_ERROR; } } + if (checkOnlyReceiverTypeError) return SUCCESS; + BindingContext bindingContext = trace.getBindingContext(); boolean safeAccess = isExplicitReceiver && !implicitInvokeCheck && candidateCall.isSafeCall(); AutoCastServiceImpl autoCastService = new AutoCastServiceImpl(context.dataFlowInfo, bindingContext); diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/results/OverloadResolutionResults.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/results/OverloadResolutionResults.java index 2e4337d1704..1b7f0eb48c1 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/results/OverloadResolutionResults.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/results/OverloadResolutionResults.java @@ -29,6 +29,7 @@ public interface OverloadResolutionResults { SINGLE_CANDIDATE_ARGUMENT_MISMATCH(false), AMBIGUITY(false), MANY_FAILED_CANDIDATES(false), + CANDIDATES_WITH_WRONG_RECEIVER(false), INCOMPLETE_TYPE_INFERENCE(false); private final boolean success; diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/results/OverloadResolutionResultsImpl.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/results/OverloadResolutionResultsImpl.java index 50d73d3eede..0dce2322f94 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/results/OverloadResolutionResultsImpl.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/results/OverloadResolutionResultsImpl.java @@ -41,6 +41,10 @@ public class OverloadResolutionResultsImpl impleme return new OverloadResolutionResultsImpl(Code.MANY_FAILED_CANDIDATES, failedCandidates); } + public static OverloadResolutionResultsImpl candidatesWithWrongReceiver(Collection> failedCandidates) { + return new OverloadResolutionResultsImpl(Code.CANDIDATES_WITH_WRONG_RECEIVER, failedCandidates); + } + public static OverloadResolutionResultsImpl ambiguity(Collection> candidates) { return new OverloadResolutionResultsImpl(Code.AMBIGUITY, candidates); } @@ -94,7 +98,7 @@ public class OverloadResolutionResultsImpl impleme @Override public boolean isSingleResult() { - return results.size() == 1; + return results.size() == 1 && getResultCode() != Code.CANDIDATES_WITH_WRONG_RECEIVER; } @Override diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/results/ResolutionResultsHandler.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/results/ResolutionResultsHandler.java index a427b80640e..fc6e393edac 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/results/ResolutionResultsHandler.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/results/ResolutionResultsHandler.java @@ -44,6 +44,7 @@ public class ResolutionResultsHandler { Set> successfulCandidates = Sets.newLinkedHashSet(); Set> failedCandidates = Sets.newLinkedHashSet(); Set> incompleteCandidates = Sets.newLinkedHashSet(); + Set> candidatesWithWrongReceiver = Sets.newLinkedHashSet(); for (ResolvedCallWithTrace candidateCall : candidates) { ResolutionStatus status = candidateCall.getStatus(); assert status != UNKNOWN_STATUS : "No resolution for " + candidateCall.getCandidateDescriptor(); @@ -53,7 +54,10 @@ public class ResolutionResultsHandler { else if (status == INCOMPLETE_TYPE_INFERENCE) { incompleteCandidates.add(candidateCall); } - else if (candidateCall.getStatus() != STRONG_ERROR) { + else if (candidateCall.getStatus() == RECEIVER_TYPE_ERROR) { + candidatesWithWrongReceiver.add(candidateCall); + } + else if (candidateCall.getStatus() != RECEIVER_PRESENCE_ERROR) { failedCandidates.add(candidateCall); } } @@ -65,10 +69,12 @@ public class ResolutionResultsHandler { else if (!failedCandidates.isEmpty()) { return computeFailedResult(trace, tracing, failedCandidates); } - else { - tracing.unresolvedReference(trace); - return OverloadResolutionResultsImpl.nameNotFound(); + if (!candidatesWithWrongReceiver.isEmpty()) { + tracing.unresolvedReferenceWrongReceiver(trace, candidatesWithWrongReceiver); + return OverloadResolutionResultsImpl.candidatesWithWrongReceiver(candidatesWithWrongReceiver); } + tracing.unresolvedReference(trace); + return OverloadResolutionResultsImpl.nameNotFound(); } @NotNull diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/results/ResolutionStatus.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/results/ResolutionStatus.java index 5d5ced260b9..22df4c52148 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/results/ResolutionStatus.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/results/ResolutionStatus.java @@ -22,7 +22,13 @@ public enum ResolutionStatus { UNKNOWN_STATUS, UNSAFE_CALL_ERROR, OTHER_ERROR, - STRONG_ERROR, + // '1.foo()' shouldn't be resolved to 'fun String.foo()' + // candidates with such error are treated specially + // (are mentioned in 'unresolved' error, if there are no other options) + RECEIVER_TYPE_ERROR, + // 'a.foo()' shouldn't be resolved to package level non-extension 'fun foo()' + // candidates with such error are thrown away completely + RECEIVER_PRESENCE_ERROR, INCOMPLETE_TYPE_INFERENCE, SUCCESS(true); @@ -30,7 +36,8 @@ public enum ResolutionStatus { public static final EnumSet[] SEVERITY_LEVELS = new EnumSet[] { EnumSet.of(UNSAFE_CALL_ERROR), // weakest EnumSet.of(OTHER_ERROR), - EnumSet.of(STRONG_ERROR), // most severe + EnumSet.of(RECEIVER_TYPE_ERROR), + EnumSet.of(RECEIVER_PRESENCE_ERROR), // most severe }; private final boolean success; diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/tasks/TracingStrategy.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/tasks/TracingStrategy.java index c8408c3446b..4e152fcc247 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/tasks/TracingStrategy.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/tasks/TracingStrategy.java @@ -23,7 +23,6 @@ import org.jetbrains.jet.lang.descriptors.ReceiverParameterDescriptor; import org.jetbrains.jet.lang.descriptors.ValueParameterDescriptor; import org.jetbrains.jet.lang.psi.JetExpression; import org.jetbrains.jet.lang.resolve.BindingTrace; -import org.jetbrains.jet.lang.resolve.calls.inference.ConstraintSystem; import org.jetbrains.jet.lang.resolve.calls.inference.InferenceErrorData; import org.jetbrains.jet.lang.resolve.calls.model.ResolvedCallWithTrace; import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverValue; @@ -47,7 +46,10 @@ public interface TracingStrategy { public void unresolvedReference(@NotNull BindingTrace trace) {} @Override - public void recordAmbiguity(BindingTrace trace, Collection> candidates) {} + public void unresolvedReferenceWrongReceiver(@NotNull BindingTrace trace, @NotNull Collection> candidates) {} + + @Override + public void recordAmbiguity(@NotNull BindingTrace trace, @NotNull Collection> candidates) {} @Override public void missingReceiver(@NotNull BindingTrace trace, @NotNull ReceiverParameterDescriptor expectedReceiver) {} @@ -104,7 +106,9 @@ public interface TracingStrategy { void unresolvedReference(@NotNull BindingTrace trace); - void recordAmbiguity(BindingTrace trace, Collection> candidates); + void unresolvedReferenceWrongReceiver(@NotNull BindingTrace trace, @NotNull Collection> candidates); + + void recordAmbiguity(@NotNull BindingTrace trace, @NotNull Collection> candidates); void missingReceiver(@NotNull BindingTrace trace, @NotNull ReceiverParameterDescriptor expectedReceiver); 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 07b192aa225..3236276728a 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 @@ -78,7 +78,7 @@ public class TracingStrategyImpl implements TracingStrategy { } @Override - public void recordAmbiguity(BindingTrace trace, Collection> candidates) { + public void recordAmbiguity(@NotNull BindingTrace trace, @NotNull Collection> candidates) { Collection descriptors = Sets.newHashSet(); for (ResolvedCallWithTrace candidate : candidates) { descriptors.add(candidate.getCandidateDescriptor()); @@ -91,6 +91,11 @@ public class TracingStrategyImpl implements TracingStrategy { trace.report(UNRESOLVED_REFERENCE.on(reference, reference)); } + @Override + public void unresolvedReferenceWrongReceiver(@NotNull BindingTrace trace, @NotNull Collection> candidates) { + trace.report(UNRESOLVED_REFERENCE_WRONG_RECEIVER.on(reference, candidates)); + } + @Override public void noValueForParameter(@NotNull BindingTrace trace, @NotNull ValueParameterDescriptor valueParameter) { JetElement reportOn; diff --git a/compiler/testData/diagnostics/tests/extensions/kt3563.kt b/compiler/testData/diagnostics/tests/extensions/kt3563.kt index e4401193846..03eb70fd746 100644 --- a/compiler/testData/diagnostics/tests/extensions/kt3563.kt +++ b/compiler/testData/diagnostics/tests/extensions/kt3563.kt @@ -9,9 +9,9 @@ class Customer(name: String) fun foo(f: File, c: Customer) { f.name - c.name // name should be unresolved here + c.name // name should be unresolved here } //from standard library val File.name: String - get() = getName() + get() = getName() \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/extensions/throwOutCandidatesByReceiver.kt b/compiler/testData/diagnostics/tests/extensions/throwOutCandidatesByReceiver.kt index 92a76c68f8b..65b24137aa0 100644 --- a/compiler/testData/diagnostics/tests/extensions/throwOutCandidatesByReceiver.kt +++ b/compiler/testData/diagnostics/tests/extensions/throwOutCandidatesByReceiver.kt @@ -6,26 +6,28 @@ package bar fun List.a() {} fun test1(i: Int?) { - 1.a() - i.a() + 1.a() + i.a() } fun test2(c: Collection) { - c.a() + c.a() } fun Int.foo() {} fun test3(s: String?) { - "".foo() - s.foo() + "".foo() + s.foo() + "".foo(1) + s.foo("a") } trait A fun T.c() {} fun test4() { - 1.c() + 1.c() } @@ -46,4 +48,8 @@ fun List.b() {} fun test7(l: List) { l.b() +} + +fun test8(l: List?) { + l.b() } \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/extensions/throwOutCandidatesByReceiver2.kt b/compiler/testData/diagnostics/tests/extensions/throwOutCandidatesByReceiver2.kt new file mode 100644 index 00000000000..dea949656a3 --- /dev/null +++ b/compiler/testData/diagnostics/tests/extensions/throwOutCandidatesByReceiver2.kt @@ -0,0 +1,14 @@ +package a + +class A {} + +fun test(a1: A, a2: A) { + val range = "island".."isle" + + a1..a2 +} + + +public fun > T.rangeTo(that: T): Range { + throw UnsupportedOperationException() +} \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/inference/regressions/kt742.kt b/compiler/testData/diagnostics/tests/inference/regressions/kt742.kt index 59c9090b75f..b26cfa17e88 100644 --- a/compiler/testData/diagnostics/tests/inference/regressions/kt742.kt +++ b/compiler/testData/diagnostics/tests/inference/regressions/kt742.kt @@ -9,4 +9,4 @@ fun List.map1(f: (T)-> Q): List? = tail!!.map1(f) fun List.map2(f: (T)-> Q): List? = tail.sure().map2(f) -fun List.map3(f: (T)-> Q): List? = tail.sure().map3(f) \ No newline at end of file +fun List.map3(f: (T)-> Q): List? = tail.sure().map3(f) \ No newline at end of file diff --git a/compiler/testData/resolve/candidatesPriority/wrongReceiverVsOtherError.resolve b/compiler/testData/resolve/candidatesPriority/wrongReceiverVsOtherError.resolve new file mode 100644 index 00000000000..36469cebc79 --- /dev/null +++ b/compiler/testData/resolve/candidatesPriority/wrongReceiverVsOtherError.resolve @@ -0,0 +1,17 @@ +fun Int.foo() {} + +open class A { + ~A.foo~fun foo(i: Int) {} +} +open class B {} + +fun test(a: A, b: B) { + with (a) { + with (b) { + // at first we try b.foo, so 'Int.foo' should have less priority to be thrown away + `A.foo`foo(1.0) + } + } +} + +fun with(receiver: T, f: T.() -> R) : R = receiver.f() \ 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 247de11cbc4..0ea7d1a1d8c 100644 --- a/compiler/tests/org/jetbrains/jet/checkers/JetDiagnosticsTestGenerated.java +++ b/compiler/tests/org/jetbrains/jet/checkers/JetDiagnosticsTestGenerated.java @@ -2297,6 +2297,11 @@ public class JetDiagnosticsTestGenerated extends AbstractDiagnosticsTestWithEage doTest("compiler/testData/diagnostics/tests/extensions/throwOutCandidatesByReceiver.kt"); } + @TestMetadata("throwOutCandidatesByReceiver2.kt") + public void testThrowOutCandidatesByReceiver2() throws Exception { + doTest("compiler/testData/diagnostics/tests/extensions/throwOutCandidatesByReceiver2.kt"); + } + } @TestMetadata("compiler/testData/diagnostics/tests/functionLiterals") diff --git a/compiler/tests/org/jetbrains/jet/resolve/JetResolveTestGenerated.java b/compiler/tests/org/jetbrains/jet/resolve/JetResolveTestGenerated.java index 3da417da3a5..faf1d4c2435 100644 --- a/compiler/tests/org/jetbrains/jet/resolve/JetResolveTestGenerated.java +++ b/compiler/tests/org/jetbrains/jet/resolve/JetResolveTestGenerated.java @@ -238,6 +238,11 @@ public class JetResolveTestGenerated extends AbstractResolveTest { doTest("compiler/testData/resolve/candidatesPriority/receiverVsThisObject2.resolve"); } + @TestMetadata("wrongReceiverVsOtherError.resolve") + public void testWrongReceiverVsOtherError() throws Exception { + doTest("compiler/testData/resolve/candidatesPriority/wrongReceiverVsOtherError.resolve"); + } + } @TestMetadata("compiler/testData/resolve/delegatedProperty") diff --git a/idea/src/org/jetbrains/jet/plugin/highlighter/IdeErrorMessages.java b/idea/src/org/jetbrains/jet/plugin/highlighter/IdeErrorMessages.java index 9e04c861bd9..65185a00894 100644 --- a/idea/src/org/jetbrains/jet/plugin/highlighter/IdeErrorMessages.java +++ b/idea/src/org/jetbrains/jet/plugin/highlighter/IdeErrorMessages.java @@ -21,7 +21,6 @@ import org.jetbrains.jet.lang.diagnostics.rendering.*; import org.jetbrains.jet.renderer.DescriptorRenderer; import static org.jetbrains.jet.lang.diagnostics.Errors.*; -import static org.jetbrains.jet.lang.diagnostics.rendering.Renderers.NAME; import static org.jetbrains.jet.lang.diagnostics.rendering.Renderers.RENDER_CLASS_OR_OBJECT; import static org.jetbrains.jet.lang.diagnostics.rendering.Renderers.TO_STRING; import static org.jetbrains.jet.lang.diagnostics.rendering.TabledDescriptorRenderer.TextElementType; @@ -93,6 +92,7 @@ public class IdeErrorMessages { MAP.put(NONE_APPLICABLE, "None of the following functions can be called with the arguments supplied.

    {0}
", HTML_NONE_APPLICABLE_CALLS); MAP.put(CANNOT_COMPLETE_RESOLVE, "Cannot choose among the following candidates without completing type inference:
    {0}
", HTML_AMBIGUOUS_CALLS); + MAP.put(UNRESOLVED_REFERENCE_WRONG_RECEIVER, "Unresolved reference.
None of the following candidates is applicable because of receiver type mismatch:
    {0}
", HTML_AMBIGUOUS_CALLS); MAP.put(DELEGATE_SPECIAL_FUNCTION_AMBIGUITY, "Overload resolution ambiguity on method ''{0}''. All these functions match.
    {1}
", TO_STRING, HTML_AMBIGUOUS_CALLS); MAP.put(DELEGATE_SPECIAL_FUNCTION_NONE_APPLICABLE, "Property delegate must have a ''{0}'' method. None of the following functions is suitable.
    {1}
", From 4403ea7b1dea3c6cdffcba9cd6d987d7e1dfffa6 Mon Sep 17 00:00:00 2001 From: Svetlana Isakova Date: Mon, 17 Jun 2013 19:08:18 +0400 Subject: [PATCH 156/291] added ThrowingScope --- .../lang/resolve/calls/CallResolverUtil.java | 2 +- .../jetbrains/jet/lang/types/ErrorUtils.java | 103 ++++++++++++++++++ 2 files changed, 104 insertions(+), 1 deletion(-) diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/CallResolverUtil.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/CallResolverUtil.java index 44bb0618819..34f856a3f4e 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/CallResolverUtil.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/CallResolverUtil.java @@ -183,6 +183,6 @@ public class CallResolverUtil { } return new JetTypeImpl( receiverType.getAnnotations(), receiverType.getConstructor(), receiverType.isNullable(), - fakeTypeArguments, receiverType.getMemberScope()); + fakeTypeArguments, ErrorUtils.createErrorScope("Error scope for erased receiver type", /*throwExceptions=*/true)); } } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/types/ErrorUtils.java b/compiler/frontend/src/org/jetbrains/jet/lang/types/ErrorUtils.java index ac80c845231..ccd90c59bad 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/types/ErrorUtils.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/types/ErrorUtils.java @@ -126,6 +126,102 @@ public class ErrorUtils { public Collection getOwnDeclaredDescriptors() { return Collections.emptyList(); } + + @Override + public String toString() { + return "ErrorScope{" + debugMessage + '}'; + } + } + + private static class ThrowingScope implements JetScope { + private final String debugMessage; + + private ThrowingScope(String message) { + debugMessage = message; + } + + @Nullable + @Override + public ClassifierDescriptor getClassifier(@NotNull Name name) { + throw new IllegalStateException(); + } + + @Nullable + @Override + public ClassDescriptor getObjectDescriptor(@NotNull Name name) { + throw new IllegalStateException(); + } + + @NotNull + @Override + public Collection getObjectDescriptors() { + throw new IllegalStateException(); + } + + @Nullable + @Override + public NamespaceDescriptor getNamespace(@NotNull Name name) { + throw new IllegalStateException(); + } + + @NotNull + @Override + public Collection getProperties(@NotNull Name name) { + throw new IllegalStateException(); + } + + @Nullable + @Override + public VariableDescriptor getLocalVariable(@NotNull Name name) { + throw new IllegalStateException(); + } + + @NotNull + @Override + public Collection getFunctions(@NotNull Name name) { + throw new IllegalStateException(); + } + + @NotNull + @Override + public DeclarationDescriptor getContainingDeclaration() { + return ERROR_MODULE; + } + + @NotNull + @Override + public Collection getDeclarationsByLabel(@NotNull LabelName labelName) { + throw new IllegalStateException(); + } + + @Nullable + @Override + public PropertyDescriptor getPropertyByFieldReference(@NotNull Name fieldName) { + throw new IllegalStateException(); + } + + @NotNull + @Override + public Collection getAllDescriptors() { + throw new IllegalStateException(); + } + + @NotNull + @Override + public List getImplicitReceiversHierarchy() { + throw new IllegalStateException(); + } + + @NotNull + @Override + public Collection getOwnDeclaredDescriptors() { + throw new IllegalStateException(); + } + + @Override + public String toString() { + return "ThrowingScope{" + debugMessage + '}'; + } } private static final ClassDescriptorImpl ERROR_CLASS = new ClassDescriptorImpl(ERROR_MODULE, Collections.emptyList(), Modality.OPEN, Name.special("")) { @@ -158,6 +254,13 @@ public class ErrorUtils { } public static JetScope createErrorScope(String debugMessage) { + return createErrorScope(debugMessage, false); + } + + public static JetScope createErrorScope(String debugMessage, boolean throwExceptions) { + if (throwExceptions) { + return new ThrowingScope(debugMessage); + } return new ErrorScope(debugMessage); } From eb85e9abce68e2e92b54bd3130441ea1439e4d2c Mon Sep 17 00:00:00 2001 From: Svetlana Isakova Date: Mon, 17 Jun 2013 20:16:45 +0400 Subject: [PATCH 157/291] fixed npe in comparing results --- .../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 ed226db868a..3d0dd6e488d 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.getText(), actual.getText()); + expected.getText(), actual != null ? actual.getText() : null); } } From 9bf5f16bb74d2178cbc956234493b9f4835ece7e Mon Sep 17 00:00:00 2001 From: Svetlana Isakova Date: Tue, 18 Jun 2013 19:52:42 +0400 Subject: [PATCH 158/291] refactoring extracted checkReceiverTypeError method to avoid 'checkOnlyReceiverTypeError' boolean flag --- .../lang/resolve/calls/CallResolverUtil.java | 24 ++------ .../lang/resolve/calls/CandidateResolver.java | 61 +++++++++++++------ 2 files changed, 47 insertions(+), 38 deletions(-) diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/CallResolverUtil.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/CallResolverUtil.java index 34f856a3f4e..f9467fffa71 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/CallResolverUtil.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/CallResolverUtil.java @@ -152,29 +152,15 @@ public class CallResolverUtil { return CallKey.create(context.call.getCallType(), (JetExpression) callElement); } - public static boolean checkArgumentCannotBeReceiver( - @NotNull JetType receiverArgumentType, + @NotNull + public static JetType getErasedReceiverType( + @NotNull ReceiverParameterDescriptor receiverParameterDescriptor, @NotNull CallableDescriptor descriptor ) { - JetType effectiveReceiverArgumentType = TypeUtils.makeNotNullable(receiverArgumentType); - - JetType erasedReceiverType = getErasedReceiverType(descriptor); - if (erasedReceiverType == null) return true; - - return !JetTypeChecker.INSTANCE.isSubtypeOf(effectiveReceiverArgumentType, erasedReceiverType); - } - - @Nullable - private static JetType getErasedReceiverType(@NotNull CallableDescriptor descriptor) { - ReceiverParameterDescriptor receiverDescriptor = descriptor.getReceiverParameter(); - ReceiverParameterDescriptor expectedThisObjectDescriptor = descriptor.getExpectedThisObject(); - JetType receiverType = receiverDescriptor != null ? receiverDescriptor.getType() : - expectedThisObjectDescriptor != null ? expectedThisObjectDescriptor.getType() : null; - if (receiverType == null) return null; - + JetType receiverType = receiverParameterDescriptor.getType(); for (TypeParameterDescriptor typeParameter : descriptor.getTypeParameters()) { if (typeParameter.getTypeConstructor().equals(receiverType.getConstructor())) { - return typeParameter.getUpperBoundsAsType(); + receiverType = typeParameter.getUpperBoundsAsType(); } } List fakeTypeArguments = Lists.newArrayList(); 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 e2f6585dadd..46f664a140c 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 @@ -45,6 +45,7 @@ import org.jetbrains.jet.lang.resolve.calls.util.ExpressionAsFunctionDescriptor; import org.jetbrains.jet.lang.resolve.scopes.receivers.ExpressionReceiver; import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverValue; import org.jetbrains.jet.lang.types.*; +import org.jetbrains.jet.lang.types.checker.JetTypeChecker; import org.jetbrains.jet.lang.types.expressions.DataFlowUtils; import org.jetbrains.jet.lang.types.expressions.ExpressionTypingUtils; import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns; @@ -83,7 +84,7 @@ public class CandidateResolver { ResolvedCallImpl candidateCall = context.candidateCall; D candidate = candidateCall.getCandidateDescriptor(); - candidateCall.addStatus(checkReceiver(context, context.trace, /*checkOnlyReceiverTypeError=*/true)); + candidateCall.addStatus(checkReceiverTypeError(context.candidateCall)); if (ErrorUtils.isError(candidate)) { candidateCall.addStatus(SUCCESS); @@ -578,6 +579,8 @@ public class CandidateResolver { ResolutionStatus resultStatus = SUCCESS; ResolvedCall candidateCall = context.candidateCall; + resultStatus = resultStatus.combine(checkReceiverTypeError(candidateCall)); + // Comment about a very special case. // Call 'b.foo(1)' where class 'Foo' has an extension member 'fun B.invoke(Int)' should be checked two times for safe call (in 'checkReceiver'), because // both 'b' (receiver) and 'foo' (this object) might be nullable. In the first case we mark dot, in the second 'foo'. @@ -586,14 +589,14 @@ public class CandidateResolver { resultStatus = resultStatus.combine(checkReceiver( context, candidateCall, trace, candidateCall.getResultingDescriptor().getReceiverParameter(), - candidateCall.getReceiverArgument(), candidateCall.getExplicitReceiverKind().isReceiver(), false, checkOnlyReceiverTypeError)); + candidateCall.getReceiverArgument(), candidateCall.getExplicitReceiverKind().isReceiver(), false)); resultStatus = resultStatus.combine(checkReceiver( context, candidateCall, trace, candidateCall.getResultingDescriptor().getExpectedThisObject(), candidateCall.getThisObject(), candidateCall.getExplicitReceiverKind().isThisObject(), // for the invocation 'foo(1)' where foo is a variable of function type we should mark 'foo' if there is unsafe call error - context.call instanceof CallForImplicitInvoke, checkOnlyReceiverTypeError)); + context.call instanceof CallForImplicitInvoke)); return resultStatus; } @@ -673,6 +676,37 @@ public class CandidateResolver { return null; } + private static ResolutionStatus checkReceiverTypeError( + @NotNull ResolvedCall candidateCall + ) { + D candidateDescriptor = candidateCall.getCandidateDescriptor(); + if (candidateDescriptor instanceof ExpressionAsFunctionDescriptor) return SUCCESS; + + ReceiverParameterDescriptor receiverDescriptor = candidateDescriptor.getReceiverParameter(); + ReceiverParameterDescriptor expectedThisObjectDescriptor = candidateDescriptor.getExpectedThisObject(); + ReceiverParameterDescriptor receiverParameterDescriptor; + JetType receiverArgumentType; + if (receiverDescriptor != null && candidateCall.getReceiverArgument().exists()) { + receiverParameterDescriptor = receiverDescriptor; + receiverArgumentType = candidateCall.getReceiverArgument().getType(); + } + else if (expectedThisObjectDescriptor != null && candidateCall.getThisObject().exists()) { + receiverParameterDescriptor = expectedThisObjectDescriptor; + receiverArgumentType = candidateCall.getThisObject().getType(); + } + else { + return SUCCESS; + } + + JetType effectiveReceiverArgumentType = TypeUtils.makeNotNullable(receiverArgumentType); + JetType erasedReceiverType = CallResolverUtil.getErasedReceiverType(receiverParameterDescriptor, candidateDescriptor); + + if (!JetTypeChecker.INSTANCE.isSubtypeOf(effectiveReceiverArgumentType, erasedReceiverType)) { + return RECEIVER_TYPE_ERROR; + } + return SUCCESS; + } + private static ResolutionStatus checkReceiver( @NotNull CallCandidateResolutionContext context, @NotNull ResolvedCall candidateCall, @@ -680,28 +714,18 @@ public class CandidateResolver { @Nullable ReceiverParameterDescriptor receiverParameter, @NotNull ReceiverValue receiverArgument, boolean isExplicitReceiver, - boolean implicitInvokeCheck, - boolean checkOnlyReceiverTypeError + boolean implicitInvokeCheck ) { if (receiverParameter == null || !receiverArgument.exists()) return SUCCESS; JetType receiverArgumentType = receiverArgument.getType(); JetType effectiveReceiverArgumentType = TypeUtils.makeNotNullable(receiverArgumentType); D candidateDescriptor = candidateCall.getCandidateDescriptor(); - if (!ArgumentTypeResolver.isSubtypeOfForArgumentType(effectiveReceiverArgumentType, receiverParameter.getType())) { - - if (CallResolverUtil.checkArgumentCannotBeReceiver(effectiveReceiverArgumentType, candidateDescriptor) - && !(candidateDescriptor instanceof ExpressionAsFunctionDescriptor)) { - return RECEIVER_TYPE_ERROR; - } - //todo - if (!TypeUtils.dependsOnTypeParameters(receiverParameter.getType(), candidateDescriptor.getTypeParameters()) - && !checkOnlyReceiverTypeError) { - context.tracing.wrongReceiverType(trace, receiverParameter, receiverArgument); - return OTHER_ERROR; - } + if (!ArgumentTypeResolver.isSubtypeOfForArgumentType(effectiveReceiverArgumentType, receiverParameter.getType()) + && !TypeUtils.dependsOnTypeParameters(receiverParameter.getType(), candidateDescriptor.getTypeParameters())) { + context.tracing.wrongReceiverType(trace, receiverParameter, receiverArgument); + return OTHER_ERROR; } - if (checkOnlyReceiverTypeError) return SUCCESS; BindingContext bindingContext = trace.getBindingContext(); boolean safeAccess = isExplicitReceiver && !implicitInvokeCheck && candidateCall.isSafeCall(); @@ -727,7 +751,6 @@ public class CandidateResolver { this.status = status; this.argumentTypes = argumentTypes; } - } @NotNull From 1c2ee72322ecd19df98c6e9d72080a4e84b614c3 Mon Sep 17 00:00:00 2001 From: Nikolay Krasko Date: Thu, 20 Jun 2013 14:55:15 +0400 Subject: [PATCH 159/291] Lazy analyze in counting parameters tips --- .../resolve/lazy/ResolveSessionUtils.java | 15 +++++--- .../JetFunctionParameterInfoHandler.java | 37 ++++++++++++++----- 2 files changed, 36 insertions(+), 16 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 548ec9d408a..f4874104c70 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 @@ -115,7 +115,7 @@ public class ResolveSessionUtils { public static @NotNull BindingContext resolveToExpression( @NotNull ResolveSession resolveSession, - @NotNull JetExpression expression + @NotNull JetElement expression ) { DelegatingBindingTrace trace = new DelegatingBindingTrace( resolveSession.getBindingContext(), "trace to resolve expression", expression); @@ -146,11 +146,14 @@ public class ResolveSessionUtils { return trace.getBindingContext(); } - // Setup resolution scope explicitly - if (trace.getBindingContext().get(BindingContext.RESOLUTION_SCOPE, expression) == null) { - JetScope scope = getExpressionMemberScope(resolveSession, expression); - if (scope != null) { - trace.record(BindingContext.RESOLUTION_SCOPE, expression, scope); + if (expression instanceof JetExpression) { + JetExpression jetExpression = (JetExpression) expression; + // Setup resolution scope explicitly + if (trace.getBindingContext().get(BindingContext.RESOLUTION_SCOPE, jetExpression) == null) { + JetScope scope = getExpressionMemberScope(resolveSession, jetExpression); + if (scope != null) { + trace.record(BindingContext.RESOLUTION_SCOPE, jetExpression, scope); + } } } diff --git a/idea/src/org/jetbrains/jet/plugin/parameterInfo/JetFunctionParameterInfoHandler.java b/idea/src/org/jetbrains/jet/plugin/parameterInfo/JetFunctionParameterInfoHandler.java index 9d5534e19ce..f824b962f26 100644 --- a/idea/src/org/jetbrains/jet/plugin/parameterInfo/JetFunctionParameterInfoHandler.java +++ b/idea/src/org/jetbrains/jet/plugin/parameterInfo/JetFunctionParameterInfoHandler.java @@ -20,6 +20,7 @@ import com.intellij.codeInsight.CodeInsightBundle; import com.intellij.codeInsight.lookup.LookupElement; import com.intellij.lang.ASTNode; import com.intellij.lang.parameterInfo.*; +import com.intellij.openapi.util.Pair; import com.intellij.psi.PsiElement; import com.intellij.psi.PsiFile; import com.intellij.psi.PsiReference; @@ -33,13 +34,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.lang.resolve.JetVisibilityChecker; +import org.jetbrains.jet.lang.resolve.lazy.ResolveSession; +import org.jetbrains.jet.lang.resolve.lazy.ResolveSessionUtils; 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.checker.JetTypeChecker; import org.jetbrains.jet.lexer.JetTokens; import org.jetbrains.jet.plugin.codeInsight.TipsManager; -import org.jetbrains.jet.plugin.project.AnalyzerFacadeWithCache; +import org.jetbrains.jet.plugin.project.WholeProjectAnalyzerFacade; import org.jetbrains.jet.renderer.DescriptorRenderer; import java.awt.*; @@ -189,28 +192,37 @@ public class JetFunctionParameterInfoHandler implements } @Override - public void updateUI(Object descriptor, ParameterInfoUIContext context) { + public void updateUI(Object itemToShow, ParameterInfoUIContext context) { //todo: when we will have ability to pass Array as vararg, implement such feature here too? if (context == null || context.getParameterOwner() == null || !context.getParameterOwner().isValid()) { + context.setUIComponentEnabled(false); return; } PsiElement parameterOwner = context.getParameterOwner(); if (!(parameterOwner instanceof JetValueArgumentList)) { + context.setUIComponentEnabled(false); return; } JetValueArgumentList argumentList = (JetValueArgumentList) parameterOwner; - if (!(descriptor instanceof FunctionDescriptor)) { + if (!(itemToShow instanceof Pair)) { context.setUIComponentEnabled(false); return; } - FunctionDescriptor functionDescriptor = (FunctionDescriptor) descriptor; + Pair pair = (Pair) itemToShow; + + if (!(pair.first instanceof FunctionDescriptor && pair.second instanceof ResolveSession)) { + context.setUIComponentEnabled(false); + return; + } + + FunctionDescriptor functionDescriptor = (FunctionDescriptor) pair.first; + ResolveSession resolveSession = (ResolveSession) pair.second; JetFile file = (JetFile) argumentList.getContainingFile(); - BindingContext bindingContext = AnalyzerFacadeWithCache.analyzeFileWithCache(file).getBindingContext(); List valueParameters = functionDescriptor.getValueParameters(); List valueArguments = argumentList.getArguments(); @@ -234,6 +246,9 @@ public class JetFunctionParameterInfoHandler implements builder.append(CodeInsightBundle.message("parameter.info.no.parameters")); } + PsiElement owner = context.getParameterOwner(); + BindingContext bindingContext = ResolveSessionUtils.resolveToExpression(resolveSession, (JetElement) owner); + for (int i = 0; i < valueParameters.size(); ++i) { if (i != 0) { builder.append(", "); @@ -358,7 +373,6 @@ public class JetFunctionParameterInfoHandler implements return context.getDefaultParameterColor(); } - private static JetValueArgumentList findCall(CreateParameterInfoContext context) { //todo: calls to this constructors, when we will have auxiliary constructors PsiFile file = context.getFile(); @@ -381,7 +395,10 @@ public class JetFunctionParameterInfoHandler implements return null; } - BindingContext bindingContext = AnalyzerFacadeWithCache.analyzeFileWithCache((JetFile) file).getBindingContext(); + ResolveSession resolveSession = WholeProjectAnalyzerFacade.getLazyResolveSessionForFile( + (JetFile) callNameExpression.getContainingFile()); + BindingContext bindingContext = ResolveSessionUtils.resolveToExpression(resolveSession, callNameExpression); + JetScope scope = bindingContext.get(BindingContext.RESOLUTION_SCOPE, callNameExpression); DeclarationDescriptor placeDescriptor = null; if (scope != null) { @@ -391,7 +408,7 @@ public class JetFunctionParameterInfoHandler implements Collection variants = TipsManager.getReferenceVariants(callNameExpression, bindingContext); Name refName = callNameExpression.getReferencedNameAsName(); - Collection itemsToShow = new ArrayList(); + Collection> itemsToShow = new ArrayList>(); for (DeclarationDescriptor variant : variants) { if (variant instanceof FunctionDescriptor) { FunctionDescriptor functionDescriptor = (FunctionDescriptor) variant; @@ -400,7 +417,7 @@ public class JetFunctionParameterInfoHandler implements if (placeDescriptor != null && !JetVisibilityChecker.isVisible(placeDescriptor, functionDescriptor)) { continue; } - itemsToShow.add(functionDescriptor); + itemsToShow.add(Pair.create(functionDescriptor, resolveSession)); } } else if (variant instanceof ClassDescriptor) { @@ -411,7 +428,7 @@ public class JetFunctionParameterInfoHandler implements if (placeDescriptor != null && !JetVisibilityChecker.isVisible(placeDescriptor, constructorDescriptor)) { continue; } - itemsToShow.add(constructorDescriptor); + itemsToShow.add(Pair.create(constructorDescriptor, resolveSession)); } } } From e7bdee79943fb5d32fc43b20a79dc4631a1ea6d9 Mon Sep 17 00:00:00 2001 From: Nikolay Krasko Date: Tue, 18 Jun 2013 18:19:20 +0400 Subject: [PATCH 160/291] Fix color for highlighting resolved method --- .../plugin/parameterInfo/JetFunctionParameterInfoHandler.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/idea/src/org/jetbrains/jet/plugin/parameterInfo/JetFunctionParameterInfoHandler.java b/idea/src/org/jetbrains/jet/plugin/parameterInfo/JetFunctionParameterInfoHandler.java index f824b962f26..e3d98549a56 100644 --- a/idea/src/org/jetbrains/jet/plugin/parameterInfo/JetFunctionParameterInfoHandler.java +++ b/idea/src/org/jetbrains/jet/plugin/parameterInfo/JetFunctionParameterInfoHandler.java @@ -26,6 +26,8 @@ import com.intellij.psi.PsiFile; import com.intellij.psi.PsiReference; import com.intellij.psi.tree.IElementType; import com.intellij.psi.util.PsiTreeUtil; +import com.intellij.ui.Gray; +import com.intellij.ui.JBColor; import com.intellij.util.ArrayUtil; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -55,7 +57,7 @@ import java.util.List; */ public class JetFunctionParameterInfoHandler implements ParameterInfoHandlerWithTabActionSupport { - public final static Color GREEN_BACKGROUND = new Color(231, 254, 234); + public final static Color GREEN_BACKGROUND = new JBColor(new Color(231, 254, 234), Gray._100); @NotNull @Override From b0484c96803fe00a8f0ef7f41aa71c4f2420e153 Mon Sep 17 00:00:00 2001 From: Nikolay Krasko Date: Wed, 19 Jun 2013 16:30:13 +0400 Subject: [PATCH 161/291] Refactorings in counting parameters tips --- .../JetFunctionParameterInfoHandler.java | 120 ++++++++---------- .../JetFunctionParameterInfoTest.java | 6 +- .../MockCreateParameterInfoContext.java | 4 +- 3 files changed, 60 insertions(+), 70 deletions(-) diff --git a/idea/src/org/jetbrains/jet/plugin/parameterInfo/JetFunctionParameterInfoHandler.java b/idea/src/org/jetbrains/jet/plugin/parameterInfo/JetFunctionParameterInfoHandler.java index e3d98549a56..7d56922aca4 100644 --- a/idea/src/org/jetbrains/jet/plugin/parameterInfo/JetFunctionParameterInfoHandler.java +++ b/idea/src/org/jetbrains/jet/plugin/parameterInfo/JetFunctionParameterInfoHandler.java @@ -16,6 +16,7 @@ package org.jetbrains.jet.plugin.parameterInfo; +import com.google.common.collect.Iterables; import com.intellij.codeInsight.CodeInsightBundle; import com.intellij.codeInsight.lookup.LookupElement; import com.intellij.lang.ASTNode; @@ -55,8 +56,11 @@ import java.util.List; * User: Alefas * Date: 17.01.12 */ -public class JetFunctionParameterInfoHandler implements - ParameterInfoHandlerWithTabActionSupport { +public class JetFunctionParameterInfoHandler implements ParameterInfoHandlerWithTabActionSupport< + JetValueArgumentList, + Pair, + JetValueArgument> +{ public final static Color GREEN_BACKGROUND = new JBColor(new Color(231, 254, 234), Gray._100); @NotNull @@ -106,8 +110,9 @@ public class JetFunctionParameterInfoHandler implements return ArrayUtil.EMPTY_OBJECT_ARRAY; //todo: ? } + @Nullable @Override - public Object[] getParametersForDocumentation(Object p, ParameterInfoContext context) { + public Object[] getParametersForDocumentation(Pair p, ParameterInfoContext context) { return ArrayUtil.EMPTY_OBJECT_ARRAY; //todo: ? } @@ -148,15 +153,16 @@ public class JetFunctionParameterInfoHandler implements public boolean tracksParameterIndex() { return true; } - + private static String renderParameter(ValueParameterDescriptor parameter, boolean named, BindingContext bindingContext) { StringBuilder builder = new StringBuilder(); if (named) builder.append("["); if (parameter.getVarargElementType() != null) { builder.append("vararg "); } - builder.append(parameter.getName()).append(": "). - append(DescriptorRenderer.SHORT_NAMES_IN_TYPES.renderType(getActualParameterType(parameter))); + builder.append(parameter.getName()) + .append(": ") + .append(DescriptorRenderer.SHORT_NAMES_IN_TYPES.renderType(getActualParameterType(parameter))); if (parameter.hasDefaultValue()) { PsiElement parameterDeclaration = BindingContextUtils.descriptorToDeclaration(bindingContext, parameter); builder.append(" = ").append(getDefaultExpressionString(parameterDeclaration)); @@ -194,7 +200,7 @@ public class JetFunctionParameterInfoHandler implements } @Override - public void updateUI(Object itemToShow, ParameterInfoUIContext context) { + public void updateUI(Pair itemToShow, ParameterInfoUIContext context) { //todo: when we will have ability to pass Array as vararg, implement such feature here too? if (context == null || context.getParameterOwner() == null || !context.getParameterOwner().isValid()) { context.setUIComponentEnabled(false); @@ -209,26 +215,12 @@ public class JetFunctionParameterInfoHandler implements JetValueArgumentList argumentList = (JetValueArgumentList) parameterOwner; - if (!(itemToShow instanceof Pair)) { - context.setUIComponentEnabled(false); - return; - } + FunctionDescriptor functionDescriptor = itemToShow.first; + ResolveSession resolveSession = itemToShow.second; - Pair pair = (Pair) itemToShow; - - if (!(pair.first instanceof FunctionDescriptor && pair.second instanceof ResolveSession)) { - context.setUIComponentEnabled(false); - return; - } - - FunctionDescriptor functionDescriptor = (FunctionDescriptor) pair.first; - ResolveSession resolveSession = (ResolveSession) pair.second; - - JetFile file = (JetFile) argumentList.getContainingFile(); List valueParameters = functionDescriptor.getValueParameters(); List valueArguments = argumentList.getArguments(); - StringBuilder builder = new StringBuilder(); int currentParameterIndex = context.getCurrentParameterIndex(); int boldStartOffset = -1; int boldEndOffset = -1; @@ -236,17 +228,15 @@ public class JetFunctionParameterInfoHandler implements boolean isDeprecated = false; //todo: add deprecation check boolean[] usedIndexes = new boolean[valueParameters.size()]; - boolean namedMode = false; Arrays.fill(usedIndexes, false); - if ((currentParameterIndex >= valueParameters.size() && (valueParameters.size() > 0 || currentParameterIndex > 0)) && - (valueParameters.size() == 0 || valueParameters.get(valueParameters.size() - 1).getVarargElementType() == null)) { + boolean namedMode = false; + + if (!isIndexValid(valueParameters, currentParameterIndex)) { isGrey = true; } - if (valueParameters.size() == 0) { - builder.append(CodeInsightBundle.message("parameter.info.no.parameters")); - } + StringBuilder builder = new StringBuilder(); PsiElement owner = context.getParameterOwner(); BindingContext bindingContext = ResolveSessionUtils.resolveToExpression(resolveSession, (JetElement) owner); @@ -257,7 +247,7 @@ public class JetFunctionParameterInfoHandler implements } boolean highlightParameter = i == currentParameterIndex || - (!namedMode && i < currentParameterIndex && valueParameters.get(valueParameters.size() - 1).getVarargElementType() != null); + (!namedMode && i < currentParameterIndex && Iterables.getLast(valueParameters).getVarargElementType() != null); if (highlightParameter) { boldStartOffset = builder.length(); @@ -272,18 +262,8 @@ public class JetFunctionParameterInfoHandler implements else { ValueParameterDescriptor param = valueParameters.get(i); builder.append(renderParameter(param, false, bindingContext)); - if (i < currentParameterIndex) { - if (argument.getArgumentExpression() != null) { - //check type - JetType paramType = getActualParameterType(param); - JetType exprType = bindingContext.get(BindingContext.EXPRESSION_TYPE, argument.getArgumentExpression()); - if (exprType != null && !JetTypeChecker.INSTANCE.isSubtypeOf(exprType, paramType)) { - isGrey = true; - } - } - else { - isGrey = true; - } + if (i <= currentParameterIndex && !isArgumentTypeValid(bindingContext, argument, param)) { + isGrey = true; } usedIndexes[i] = true; } @@ -293,6 +273,7 @@ public class JetFunctionParameterInfoHandler implements builder.append(renderParameter(param, false, bindingContext)); } } + if (namedMode) { boolean takeAnyArgument = true; if (valueArguments.size() > i) { @@ -301,21 +282,12 @@ public class JetFunctionParameterInfoHandler implements for (int j = 0; j < valueParameters.size(); ++j) { JetSimpleNameExpression referenceExpression = argument.getArgumentName().getReferenceExpression(); ValueParameterDescriptor param = valueParameters.get(j); - if (referenceExpression != null && !usedIndexes[j] && - param.getName().equals(referenceExpression.getReferencedNameAsName())) { + if (referenceExpression != null && !usedIndexes[j] && param.getName().equals(referenceExpression.getReferencedNameAsName())) { takeAnyArgument = false; usedIndexes[j] = true; builder.append(renderParameter(param, true, bindingContext)); - if (i < currentParameterIndex) { - if (argument.getArgumentExpression() != null) { - //check type - JetType paramType = getActualParameterType(param); - JetType exprType = bindingContext.get(BindingContext.EXPRESSION_TYPE, argument.getArgumentExpression()); - if (exprType != null && !JetTypeChecker.INSTANCE.isSubtypeOf(exprType, paramType)) isGrey = true; - } - else { - isGrey = true; - } + if (i < currentParameterIndex && !isArgumentTypeValid(bindingContext, argument, param)) { + isGrey = true; } break; } @@ -344,35 +316,48 @@ public class JetFunctionParameterInfoHandler implements } } - Color color = getBackgroundColor(context, argumentList, functionDescriptor, bindingContext); + if (valueParameters.size() == 0) { + builder.append(CodeInsightBundle.message("parameter.info.no.parameters")); + } - if (builder.toString().isEmpty()) { - context.setUIComponentEnabled(false); - } - else { - context.setupUIComponentPresentation(builder.toString(), boldStartOffset, boldEndOffset, isGrey, - isDeprecated, false, color); - } + assert !builder.toString().isEmpty() : "A message about 'no parameters' or some parameters should be present: " + functionDescriptor; + + Color color = isResolvedToDescriptor(argumentList, functionDescriptor, bindingContext) ? GREEN_BACKGROUND : context.getDefaultParameterColor(); + context.setupUIComponentPresentation(builder.toString(), boldStartOffset, boldEndOffset, isGrey, isDeprecated, false, color); } - private static Color getBackgroundColor( - ParameterInfoUIContext context, + private static boolean isArgumentTypeValid(BindingContext bindingContext, JetValueArgument argument, ValueParameterDescriptor param) { + if (argument.getArgumentExpression() != null) { + JetType paramType = getActualParameterType(param); + JetType exprType = bindingContext.get(BindingContext.EXPRESSION_TYPE, argument.getArgumentExpression()); + return exprType == null || JetTypeChecker.INSTANCE.isSubtypeOf(exprType, paramType); + } + + return false; + } + + private static boolean isIndexValid(List valueParameters, int index) { + // Index is within range of parameters or last parameter is vararg + return index < valueParameters.size() || + (valueParameters.size() > 0 && Iterables.getLast(valueParameters).getVarargElementType() != null); + } + + private static Boolean isResolvedToDescriptor( JetValueArgumentList argumentList, FunctionDescriptor functionDescriptor, BindingContext bindingContext ) { JetSimpleNameExpression callNameExpression = getCallSimpleNameExpression(argumentList); if (callNameExpression != null) { - // Mark with green background the variant with resolved call DeclarationDescriptor declarationDescriptor = bindingContext.get(BindingContext.REFERENCE_TARGET, callNameExpression); if (declarationDescriptor != null) { if (declarationDescriptor == functionDescriptor) { - return GREEN_BACKGROUND; + return true; } } } - return context.getDefaultParameterColor(); + return false; } private static JetValueArgumentList findCall(CreateParameterInfoContext context) { @@ -408,6 +393,7 @@ public class JetFunctionParameterInfoHandler implements } Collection variants = TipsManager.getReferenceVariants(callNameExpression, bindingContext); + Name refName = callNameExpression.getReferencedNameAsName(); Collection> itemsToShow = new ArrayList>(); diff --git a/idea/tests/org/jetbrains/jet/plugin/parameterInfo/JetFunctionParameterInfoTest.java b/idea/tests/org/jetbrains/jet/plugin/parameterInfo/JetFunctionParameterInfoTest.java index dbda75b5086..a1c3d1df638 100644 --- a/idea/tests/org/jetbrains/jet/plugin/parameterInfo/JetFunctionParameterInfoTest.java +++ b/idea/tests/org/jetbrains/jet/plugin/parameterInfo/JetFunctionParameterInfoTest.java @@ -16,10 +16,13 @@ package org.jetbrains.jet.plugin.parameterInfo; +import com.intellij.openapi.util.Pair; import com.intellij.psi.PsiElement; import com.intellij.testFramework.fixtures.LightCodeInsightFixtureTestCase; +import org.jetbrains.jet.lang.descriptors.FunctionDescriptor; import org.jetbrains.jet.lang.psi.JetFile; import org.jetbrains.jet.lang.psi.JetValueArgumentList; +import org.jetbrains.jet.lang.resolve.lazy.ResolveSession; import org.jetbrains.jet.lexer.JetTokens; import org.jetbrains.jet.plugin.PluginTestCaseBase; @@ -113,7 +116,8 @@ public class JetFunctionParameterInfoTest extends LightCodeInsightFixtureTestCas new MockParameterInfoUIContext(parameterOwner, updateContext.getCurrentParameter()); for (Object item : mockCreateParameterInfoContext.getItemsToShow()) { - parameterInfoHandler.updateUI(item, parameterInfoUIContext); + //noinspection unchecked + parameterInfoHandler.updateUI((Pair)item, parameterInfoUIContext); } assertEquals(expectedResultText, parameterInfoUIContext.getResultText()); } diff --git a/idea/tests/org/jetbrains/jet/plugin/parameterInfo/MockCreateParameterInfoContext.java b/idea/tests/org/jetbrains/jet/plugin/parameterInfo/MockCreateParameterInfoContext.java index 89ccadf53e2..21882263d77 100644 --- a/idea/tests/org/jetbrains/jet/plugin/parameterInfo/MockCreateParameterInfoContext.java +++ b/idea/tests/org/jetbrains/jet/plugin/parameterInfo/MockCreateParameterInfoContext.java @@ -33,8 +33,8 @@ import org.jetbrains.annotations.NotNull; public class MockCreateParameterInfoContext implements CreateParameterInfoContext { private Object[] myItemsToShow = ArrayUtil.EMPTY_OBJECT_ARRAY; private PsiElement myHighlightedElement = null; - private JavaCodeInsightTestFixture myFixture; - private PsiFile myFile; + private final JavaCodeInsightTestFixture myFixture; + private final PsiFile myFile; MockCreateParameterInfoContext(PsiFile file, JavaCodeInsightTestFixture fixture) { myFile = file; From f1a6d27d35b96c84f9193dae4688a4c0686e66e6 Mon Sep 17 00:00:00 2001 From: Alexander Udalov Date: Mon, 17 Jun 2013 21:14:46 +0400 Subject: [PATCH 162/291] Minor, prevent infinite loops in range tests --- .../boxWithStdlib/ranges/expression/emptyDownto.kt | 7 +++++++ .../boxWithStdlib/ranges/expression/emptyRange.kt | 7 +++++++ .../ranges/expression/inexactSteppedDownTo.kt | 7 +++++++ .../ranges/expression/inexactSteppedRange.kt | 7 +++++++ .../boxWithStdlib/ranges/expression/infiniteSteps.kt | 4 ++++ .../boxWithStdlib/ranges/expression/nanEnds.kt | 12 ++++++++++++ .../ranges/expression/oneElementDownTo.kt | 7 +++++++ .../ranges/expression/oneElementRange.kt | 7 +++++++ .../ranges/expression/reversedBackSequence.kt | 7 +++++++ .../ranges/expression/reversedEmptyBackSequence.kt | 7 +++++++ .../ranges/expression/reversedEmptyRange.kt | 7 +++++++ .../expression/reversedInexactSteppedDownTo.kt | 7 +++++++ .../boxWithStdlib/ranges/expression/reversedRange.kt | 7 +++++++ .../ranges/expression/reversedSimpleSteppedRange.kt | 7 +++++++ .../boxWithStdlib/ranges/expression/simpleDownTo.kt | 7 +++++++ .../boxWithStdlib/ranges/expression/simpleRange.kt | 7 +++++++ .../expression/simpleRangeWithNonConstantEnds.kt | 7 +++++++ .../ranges/expression/simpleSteppedDownTo.kt | 7 +++++++ .../ranges/expression/simpleSteppedRange.kt | 7 +++++++ .../boxWithStdlib/ranges/literal/emptyDownto.kt | 7 +++++++ .../boxWithStdlib/ranges/literal/emptyRange.kt | 7 +++++++ .../ranges/literal/inexactSteppedDownTo.kt | 7 +++++++ .../ranges/literal/inexactSteppedRange.kt | 7 +++++++ .../boxWithStdlib/ranges/literal/infiniteSteps.kt | 4 ++++ .../codegen/boxWithStdlib/ranges/literal/nanEnds.kt | 12 ++++++++++++ .../boxWithStdlib/ranges/literal/oneElementDownTo.kt | 7 +++++++ .../boxWithStdlib/ranges/literal/oneElementRange.kt | 7 +++++++ .../ranges/literal/reversedBackSequence.kt | 7 +++++++ .../ranges/literal/reversedEmptyBackSequence.kt | 7 +++++++ .../ranges/literal/reversedEmptyRange.kt | 7 +++++++ .../ranges/literal/reversedInexactSteppedDownTo.kt | 7 +++++++ .../boxWithStdlib/ranges/literal/reversedRange.kt | 7 +++++++ .../ranges/literal/reversedSimpleSteppedRange.kt | 7 +++++++ .../boxWithStdlib/ranges/literal/simpleDownTo.kt | 7 +++++++ .../boxWithStdlib/ranges/literal/simpleRange.kt | 7 +++++++ .../ranges/literal/simpleRangeWithNonConstantEnds.kt | 7 +++++++ .../ranges/literal/simpleSteppedDownTo.kt | 7 +++++++ .../ranges/literal/simpleSteppedRange.kt | 7 +++++++ .../tests/GenerateRangesCodegenTestData.java | 3 +++ 39 files changed, 273 insertions(+) diff --git a/compiler/testData/codegen/boxWithStdlib/ranges/expression/emptyDownto.kt b/compiler/testData/codegen/boxWithStdlib/ranges/expression/emptyDownto.kt index 92571e752fa..02cd6de4f71 100644 --- a/compiler/testData/codegen/boxWithStdlib/ranges/expression/emptyDownto.kt +++ b/compiler/testData/codegen/boxWithStdlib/ranges/expression/emptyDownto.kt @@ -7,6 +7,7 @@ fun box(): String { val range1 = 5 downTo 10 for (i in range1) { list1.add(i) + if (list1.size() > 23) break } if (list1 != listOf()) { return "Wrong elements for 5 downTo 10: $list1" @@ -16,6 +17,7 @@ fun box(): String { val range2 = 5.toByte() downTo 10.toByte() for (i in range2) { list2.add(i) + if (list2.size() > 23) break } if (list2 != listOf()) { return "Wrong elements for 5.toByte() downTo 10.toByte(): $list2" @@ -25,6 +27,7 @@ fun box(): String { val range3 = 5.toShort() downTo 10.toShort() for (i in range3) { list3.add(i) + if (list3.size() > 23) break } if (list3 != listOf()) { return "Wrong elements for 5.toShort() downTo 10.toShort(): $list3" @@ -34,6 +37,7 @@ fun box(): String { val range4 = 5.toLong() downTo 10.toLong() for (i in range4) { list4.add(i) + if (list4.size() > 23) break } if (list4 != listOf()) { return "Wrong elements for 5.toLong() downTo 10.toLong(): $list4" @@ -43,6 +47,7 @@ fun box(): String { val range5 = 'a' downTo 'z' for (i in range5) { list5.add(i) + if (list5.size() > 23) break } if (list5 != listOf()) { return "Wrong elements for 'a' downTo 'z': $list5" @@ -52,6 +57,7 @@ fun box(): String { val range6 = -1.0 downTo 5.0 for (i in range6) { list6.add(i) + if (list6.size() > 23) break } if (list6 != listOf()) { return "Wrong elements for -1.0 downTo 5.0: $list6" @@ -61,6 +67,7 @@ fun box(): String { val range7 = -1.0.toFloat() downTo 5.0.toFloat() for (i in range7) { list7.add(i) + if (list7.size() > 23) break } if (list7 != listOf()) { return "Wrong elements for -1.0.toFloat() downTo 5.0.toFloat(): $list7" diff --git a/compiler/testData/codegen/boxWithStdlib/ranges/expression/emptyRange.kt b/compiler/testData/codegen/boxWithStdlib/ranges/expression/emptyRange.kt index cff42474fb3..f9a083f633f 100644 --- a/compiler/testData/codegen/boxWithStdlib/ranges/expression/emptyRange.kt +++ b/compiler/testData/codegen/boxWithStdlib/ranges/expression/emptyRange.kt @@ -7,6 +7,7 @@ fun box(): String { val range1 = 10..5 for (i in range1) { list1.add(i) + if (list1.size() > 23) break } if (list1 != listOf()) { return "Wrong elements for 10..5: $list1" @@ -16,6 +17,7 @@ fun box(): String { val range2 = 10.toByte()..-5.toByte() for (i in range2) { list2.add(i) + if (list2.size() > 23) break } if (list2 != listOf()) { return "Wrong elements for 10.toByte()..-5.toByte(): $list2" @@ -25,6 +27,7 @@ fun box(): String { val range3 = 10.toShort()..-5.toShort() for (i in range3) { list3.add(i) + if (list3.size() > 23) break } if (list3 != listOf()) { return "Wrong elements for 10.toShort()..-5.toShort(): $list3" @@ -34,6 +37,7 @@ fun box(): String { val range4 = 10.toLong()..-5.toLong() for (i in range4) { list4.add(i) + if (list4.size() > 23) break } if (list4 != listOf()) { return "Wrong elements for 10.toLong()..-5.toLong(): $list4" @@ -43,6 +47,7 @@ fun box(): String { val range5 = 'z'..'a' for (i in range5) { list5.add(i) + if (list5.size() > 23) break } if (list5 != listOf()) { return "Wrong elements for 'z'..'a': $list5" @@ -52,6 +57,7 @@ fun box(): String { val range6 = 5.0..-1.0 for (i in range6) { list6.add(i) + if (list6.size() > 23) break } if (list6 != listOf()) { return "Wrong elements for 5.0..-1.0: $list6" @@ -61,6 +67,7 @@ fun box(): String { val range7 = 5.0.toFloat()..-1.0.toFloat() for (i in range7) { list7.add(i) + if (list7.size() > 23) break } if (list7 != listOf()) { return "Wrong elements for 5.0.toFloat()..-1.0.toFloat(): $list7" diff --git a/compiler/testData/codegen/boxWithStdlib/ranges/expression/inexactSteppedDownTo.kt b/compiler/testData/codegen/boxWithStdlib/ranges/expression/inexactSteppedDownTo.kt index 6571e0b4110..1dbe3bfff0e 100644 --- a/compiler/testData/codegen/boxWithStdlib/ranges/expression/inexactSteppedDownTo.kt +++ b/compiler/testData/codegen/boxWithStdlib/ranges/expression/inexactSteppedDownTo.kt @@ -7,6 +7,7 @@ fun box(): String { val range1 = 8 downTo 3 step 2 for (i in range1) { list1.add(i) + if (list1.size() > 23) break } if (list1 != listOf(8, 6, 4)) { return "Wrong elements for 8 downTo 3 step 2: $list1" @@ -16,6 +17,7 @@ fun box(): String { val range2 = 8.toByte() downTo 3.toByte() step 2 for (i in range2) { list2.add(i) + if (list2.size() > 23) break } if (list2 != listOf(8, 6, 4)) { return "Wrong elements for 8.toByte() downTo 3.toByte() step 2: $list2" @@ -25,6 +27,7 @@ fun box(): String { val range3 = 8.toShort() downTo 3.toShort() step 2 for (i in range3) { list3.add(i) + if (list3.size() > 23) break } if (list3 != listOf(8, 6, 4)) { return "Wrong elements for 8.toShort() downTo 3.toShort() step 2: $list3" @@ -34,6 +37,7 @@ fun box(): String { val range4 = 8.toLong() downTo 3.toLong() step 2.toLong() for (i in range4) { list4.add(i) + if (list4.size() > 23) break } if (list4 != listOf(8, 6, 4)) { return "Wrong elements for 8.toLong() downTo 3.toLong() step 2.toLong(): $list4" @@ -43,6 +47,7 @@ fun box(): String { val range5 = 'd' downTo 'a' step 2 for (i in range5) { list5.add(i) + if (list5.size() > 23) break } if (list5 != listOf('d', 'b')) { return "Wrong elements for 'd' downTo 'a' step 2: $list5" @@ -52,6 +57,7 @@ fun box(): String { val range6 = 5.5 downTo 3.7 step 0.5 for (i in range6) { list6.add(i) + if (list6.size() > 23) break } if (list6 != listOf(5.5, 5.0, 4.5, 4.0)) { return "Wrong elements for 5.5 downTo 3.7 step 0.5: $list6" @@ -61,6 +67,7 @@ fun box(): String { val range7 = 5.5.toFloat() downTo 3.7.toFloat() step 0.5.toFloat() for (i in range7) { list7.add(i) + if (list7.size() > 23) break } if (list7 != listOf(5.5, 5.0, 4.5, 4.0)) { return "Wrong elements for 5.5.toFloat() downTo 3.7.toFloat() step 0.5.toFloat(): $list7" diff --git a/compiler/testData/codegen/boxWithStdlib/ranges/expression/inexactSteppedRange.kt b/compiler/testData/codegen/boxWithStdlib/ranges/expression/inexactSteppedRange.kt index d055fe71051..1a0a82ba254 100644 --- a/compiler/testData/codegen/boxWithStdlib/ranges/expression/inexactSteppedRange.kt +++ b/compiler/testData/codegen/boxWithStdlib/ranges/expression/inexactSteppedRange.kt @@ -7,6 +7,7 @@ fun box(): String { val range1 = 3..8 step 2 for (i in range1) { list1.add(i) + if (list1.size() > 23) break } if (list1 != listOf(3, 5, 7)) { return "Wrong elements for 3..8 step 2: $list1" @@ -16,6 +17,7 @@ fun box(): String { val range2 = 3.toByte()..8.toByte() step 2 for (i in range2) { list2.add(i) + if (list2.size() > 23) break } if (list2 != listOf(3, 5, 7)) { return "Wrong elements for 3.toByte()..8.toByte() step 2: $list2" @@ -25,6 +27,7 @@ fun box(): String { val range3 = 3.toShort()..8.toShort() step 2 for (i in range3) { list3.add(i) + if (list3.size() > 23) break } if (list3 != listOf(3, 5, 7)) { return "Wrong elements for 3.toShort()..8.toShort() step 2: $list3" @@ -34,6 +37,7 @@ fun box(): String { val range4 = 3.toLong()..8.toLong() step 2.toLong() for (i in range4) { list4.add(i) + if (list4.size() > 23) break } if (list4 != listOf(3, 5, 7)) { return "Wrong elements for 3.toLong()..8.toLong() step 2.toLong(): $list4" @@ -43,6 +47,7 @@ fun box(): String { val range5 = 'a'..'d' step 2 for (i in range5) { list5.add(i) + if (list5.size() > 23) break } if (list5 != listOf('a', 'c')) { return "Wrong elements for 'a'..'d' step 2: $list5" @@ -52,6 +57,7 @@ fun box(): String { val range6 = 4.0..5.8 step 0.5 for (i in range6) { list6.add(i) + if (list6.size() > 23) break } if (list6 != listOf(4.0, 4.5, 5.0, 5.5)) { return "Wrong elements for 4.0..5.8 step 0.5: $list6" @@ -61,6 +67,7 @@ fun box(): String { val range7 = 4.0.toFloat()..5.8.toFloat() step 0.5.toFloat() for (i in range7) { list7.add(i) + if (list7.size() > 23) break } if (list7 != listOf(4.0, 4.5, 5.0, 5.5)) { return "Wrong elements for 4.0.toFloat()..5.8.toFloat() step 0.5.toFloat(): $list7" diff --git a/compiler/testData/codegen/boxWithStdlib/ranges/expression/infiniteSteps.kt b/compiler/testData/codegen/boxWithStdlib/ranges/expression/infiniteSteps.kt index 344c66148ed..58b2786a85d 100644 --- a/compiler/testData/codegen/boxWithStdlib/ranges/expression/infiniteSteps.kt +++ b/compiler/testData/codegen/boxWithStdlib/ranges/expression/infiniteSteps.kt @@ -7,6 +7,7 @@ fun box(): String { val range1 = 0.0..5.0 step j.Double.POSITIVE_INFINITY for (i in range1) { list1.add(i) + if (list1.size() > 23) break } if (list1 != listOf(0.0)) { return "Wrong elements for 0.0..5.0 step j.Double.POSITIVE_INFINITY: $list1" @@ -16,6 +17,7 @@ fun box(): String { val range2 = 0.0.toFloat()..5.0.toFloat() step j.Float.POSITIVE_INFINITY for (i in range2) { list2.add(i) + if (list2.size() > 23) break } if (list2 != listOf(0.0)) { return "Wrong elements for 0.0.toFloat()..5.0.toFloat() step j.Float.POSITIVE_INFINITY: $list2" @@ -25,6 +27,7 @@ fun box(): String { val range3 = 5.0 downTo 0.0 step j.Double.POSITIVE_INFINITY for (i in range3) { list3.add(i) + if (list3.size() > 23) break } if (list3 != listOf(5.0)) { return "Wrong elements for 5.0 downTo 0.0 step j.Double.POSITIVE_INFINITY: $list3" @@ -34,6 +37,7 @@ fun box(): String { val range4 = 5.0.toFloat() downTo 0.0.toFloat() step j.Float.POSITIVE_INFINITY for (i in range4) { list4.add(i) + if (list4.size() > 23) break } if (list4 != listOf(5.0)) { return "Wrong elements for 5.0.toFloat() downTo 0.0.toFloat() step j.Float.POSITIVE_INFINITY: $list4" diff --git a/compiler/testData/codegen/boxWithStdlib/ranges/expression/nanEnds.kt b/compiler/testData/codegen/boxWithStdlib/ranges/expression/nanEnds.kt index 150bcee767a..d414a07c133 100644 --- a/compiler/testData/codegen/boxWithStdlib/ranges/expression/nanEnds.kt +++ b/compiler/testData/codegen/boxWithStdlib/ranges/expression/nanEnds.kt @@ -7,6 +7,7 @@ fun box(): String { val range1 = j.Double.NaN..5.0 for (i in range1) { list1.add(i) + if (list1.size() > 23) break } if (list1 != listOf()) { return "Wrong elements for j.Double.NaN..5.0: $list1" @@ -16,6 +17,7 @@ fun box(): String { val range2 = j.Float.NaN.toFloat()..5.0.toFloat() for (i in range2) { list2.add(i) + if (list2.size() > 23) break } if (list2 != listOf()) { return "Wrong elements for j.Float.NaN.toFloat()..5.0.toFloat(): $list2" @@ -25,6 +27,7 @@ fun box(): String { val range3 = j.Double.NaN downTo 0.0 for (i in range3) { list3.add(i) + if (list3.size() > 23) break } if (list3 != listOf()) { return "Wrong elements for j.Double.NaN downTo 0.0: $list3" @@ -34,6 +37,7 @@ fun box(): String { val range4 = j.Float.NaN.toFloat() downTo 0.0.toFloat() for (i in range4) { list4.add(i) + if (list4.size() > 23) break } if (list4 != listOf()) { return "Wrong elements for j.Float.NaN.toFloat() downTo 0.0.toFloat(): $list4" @@ -43,6 +47,7 @@ fun box(): String { val range5 = 0.0..j.Double.NaN for (i in range5) { list5.add(i) + if (list5.size() > 23) break } if (list5 != listOf()) { return "Wrong elements for 0.0..j.Double.NaN: $list5" @@ -52,6 +57,7 @@ fun box(): String { val range6 = 0.0.toFloat()..j.Float.NaN for (i in range6) { list6.add(i) + if (list6.size() > 23) break } if (list6 != listOf()) { return "Wrong elements for 0.0.toFloat()..j.Float.NaN: $list6" @@ -61,6 +67,7 @@ fun box(): String { val range7 = 5.0 downTo j.Double.NaN for (i in range7) { list7.add(i) + if (list7.size() > 23) break } if (list7 != listOf()) { return "Wrong elements for 5.0 downTo j.Double.NaN: $list7" @@ -70,6 +77,7 @@ fun box(): String { val range8 = 5.0.toFloat() downTo j.Float.NaN for (i in range8) { list8.add(i) + if (list8.size() > 23) break } if (list8 != listOf()) { return "Wrong elements for 5.0.toFloat() downTo j.Float.NaN: $list8" @@ -79,6 +87,7 @@ fun box(): String { val range9 = j.Double.NaN..j.Double.NaN for (i in range9) { list9.add(i) + if (list9.size() > 23) break } if (list9 != listOf()) { return "Wrong elements for j.Double.NaN..j.Double.NaN: $list9" @@ -88,6 +97,7 @@ fun box(): String { val range10 = j.Float.NaN..j.Float.NaN for (i in range10) { list10.add(i) + if (list10.size() > 23) break } if (list10 != listOf()) { return "Wrong elements for j.Float.NaN..j.Float.NaN: $list10" @@ -97,6 +107,7 @@ fun box(): String { val range11 = j.Double.NaN downTo j.Double.NaN for (i in range11) { list11.add(i) + if (list11.size() > 23) break } if (list11 != listOf()) { return "Wrong elements for j.Double.NaN downTo j.Double.NaN: $list11" @@ -106,6 +117,7 @@ fun box(): String { val range12 = j.Float.NaN downTo j.Float.NaN for (i in range12) { list12.add(i) + if (list12.size() > 23) break } if (list12 != listOf()) { return "Wrong elements for j.Float.NaN downTo j.Float.NaN: $list12" diff --git a/compiler/testData/codegen/boxWithStdlib/ranges/expression/oneElementDownTo.kt b/compiler/testData/codegen/boxWithStdlib/ranges/expression/oneElementDownTo.kt index 3b00f72a284..3bb312e7495 100644 --- a/compiler/testData/codegen/boxWithStdlib/ranges/expression/oneElementDownTo.kt +++ b/compiler/testData/codegen/boxWithStdlib/ranges/expression/oneElementDownTo.kt @@ -7,6 +7,7 @@ fun box(): String { val range1 = 5 downTo 5 for (i in range1) { list1.add(i) + if (list1.size() > 23) break } if (list1 != listOf(5)) { return "Wrong elements for 5 downTo 5: $list1" @@ -16,6 +17,7 @@ fun box(): String { val range2 = 5.toByte() downTo 5.toByte() for (i in range2) { list2.add(i) + if (list2.size() > 23) break } if (list2 != listOf(5.toByte())) { return "Wrong elements for 5.toByte() downTo 5.toByte(): $list2" @@ -25,6 +27,7 @@ fun box(): String { val range3 = 5.toShort() downTo 5.toShort() for (i in range3) { list3.add(i) + if (list3.size() > 23) break } if (list3 != listOf(5.toShort())) { return "Wrong elements for 5.toShort() downTo 5.toShort(): $list3" @@ -34,6 +37,7 @@ fun box(): String { val range4 = 5.toLong() downTo 5.toLong() for (i in range4) { list4.add(i) + if (list4.size() > 23) break } if (list4 != listOf(5.toLong())) { return "Wrong elements for 5.toLong() downTo 5.toLong(): $list4" @@ -43,6 +47,7 @@ fun box(): String { val range5 = 'k' downTo 'k' for (i in range5) { list5.add(i) + if (list5.size() > 23) break } if (list5 != listOf('k')) { return "Wrong elements for 'k' downTo 'k': $list5" @@ -52,6 +57,7 @@ fun box(): String { val range6 = 5.0 downTo 5.0 for (i in range6) { list6.add(i) + if (list6.size() > 23) break } if (list6 != listOf(5.0)) { return "Wrong elements for 5.0 downTo 5.0: $list6" @@ -61,6 +67,7 @@ fun box(): String { val range7 = 5.0.toFloat() downTo 5.0.toFloat() for (i in range7) { list7.add(i) + if (list7.size() > 23) break } if (list7 != listOf(5.0.toFloat())) { return "Wrong elements for 5.0.toFloat() downTo 5.0.toFloat(): $list7" diff --git a/compiler/testData/codegen/boxWithStdlib/ranges/expression/oneElementRange.kt b/compiler/testData/codegen/boxWithStdlib/ranges/expression/oneElementRange.kt index 9170e18b334..e8fca65565e 100644 --- a/compiler/testData/codegen/boxWithStdlib/ranges/expression/oneElementRange.kt +++ b/compiler/testData/codegen/boxWithStdlib/ranges/expression/oneElementRange.kt @@ -7,6 +7,7 @@ fun box(): String { val range1 = 5..5 for (i in range1) { list1.add(i) + if (list1.size() > 23) break } if (list1 != listOf(5)) { return "Wrong elements for 5..5: $list1" @@ -16,6 +17,7 @@ fun box(): String { val range2 = 5.toByte()..5.toByte() for (i in range2) { list2.add(i) + if (list2.size() > 23) break } if (list2 != listOf(5.toByte())) { return "Wrong elements for 5.toByte()..5.toByte(): $list2" @@ -25,6 +27,7 @@ fun box(): String { val range3 = 5.toShort()..5.toShort() for (i in range3) { list3.add(i) + if (list3.size() > 23) break } if (list3 != listOf(5.toShort())) { return "Wrong elements for 5.toShort()..5.toShort(): $list3" @@ -34,6 +37,7 @@ fun box(): String { val range4 = 5.toLong()..5.toLong() for (i in range4) { list4.add(i) + if (list4.size() > 23) break } if (list4 != listOf(5.toLong())) { return "Wrong elements for 5.toLong()..5.toLong(): $list4" @@ -43,6 +47,7 @@ fun box(): String { val range5 = 'k'..'k' for (i in range5) { list5.add(i) + if (list5.size() > 23) break } if (list5 != listOf('k')) { return "Wrong elements for 'k'..'k': $list5" @@ -52,6 +57,7 @@ fun box(): String { val range6 = 5.0..5.0 for (i in range6) { list6.add(i) + if (list6.size() > 23) break } if (list6 != listOf(5.0)) { return "Wrong elements for 5.0..5.0: $list6" @@ -61,6 +67,7 @@ fun box(): String { val range7 = 5.0.toFloat()..5.0.toFloat() for (i in range7) { list7.add(i) + if (list7.size() > 23) break } if (list7 != listOf(5.0.toFloat())) { return "Wrong elements for 5.0.toFloat()..5.0.toFloat(): $list7" diff --git a/compiler/testData/codegen/boxWithStdlib/ranges/expression/reversedBackSequence.kt b/compiler/testData/codegen/boxWithStdlib/ranges/expression/reversedBackSequence.kt index 53ccda5a584..03f78831fc2 100644 --- a/compiler/testData/codegen/boxWithStdlib/ranges/expression/reversedBackSequence.kt +++ b/compiler/testData/codegen/boxWithStdlib/ranges/expression/reversedBackSequence.kt @@ -7,6 +7,7 @@ fun box(): String { val range1 = (5 downTo 3).reversed() for (i in range1) { list1.add(i) + if (list1.size() > 23) break } if (list1 != listOf(3, 4, 5)) { return "Wrong elements for (5 downTo 3).reversed(): $list1" @@ -16,6 +17,7 @@ fun box(): String { val range2 = (5.toByte() downTo 3.toByte()).reversed() for (i in range2) { list2.add(i) + if (list2.size() > 23) break } if (list2 != listOf(3, 4, 5)) { return "Wrong elements for (5.toByte() downTo 3.toByte()).reversed(): $list2" @@ -25,6 +27,7 @@ fun box(): String { val range3 = (5.toShort() downTo 3.toShort()).reversed() for (i in range3) { list3.add(i) + if (list3.size() > 23) break } if (list3 != listOf(3, 4, 5)) { return "Wrong elements for (5.toShort() downTo 3.toShort()).reversed(): $list3" @@ -34,6 +37,7 @@ fun box(): String { val range4 = (5.toLong() downTo 3.toLong()).reversed() for (i in range4) { list4.add(i) + if (list4.size() > 23) break } if (list4 != listOf(3, 4, 5)) { return "Wrong elements for (5.toLong() downTo 3.toLong()).reversed(): $list4" @@ -43,6 +47,7 @@ fun box(): String { val range5 = ('c' downTo 'a').reversed() for (i in range5) { list5.add(i) + if (list5.size() > 23) break } if (list5 != listOf('a', 'b', 'c')) { return "Wrong elements for ('c' downTo 'a').reversed(): $list5" @@ -52,6 +57,7 @@ fun box(): String { val range6 = (5.0 downTo 3.0).reversed() for (i in range6) { list6.add(i) + if (list6.size() > 23) break } if (list6 != listOf(3.0, 4.0, 5.0)) { return "Wrong elements for (5.0 downTo 3.0).reversed(): $list6" @@ -61,6 +67,7 @@ fun box(): String { val range7 = (5.0.toFloat() downTo 3.0.toFloat()).reversed() for (i in range7) { list7.add(i) + if (list7.size() > 23) break } if (list7 != listOf(3.0, 4.0, 5.0)) { return "Wrong elements for (5.0.toFloat() downTo 3.0.toFloat()).reversed(): $list7" diff --git a/compiler/testData/codegen/boxWithStdlib/ranges/expression/reversedEmptyBackSequence.kt b/compiler/testData/codegen/boxWithStdlib/ranges/expression/reversedEmptyBackSequence.kt index 61a5c3cdb5c..df179d3a841 100644 --- a/compiler/testData/codegen/boxWithStdlib/ranges/expression/reversedEmptyBackSequence.kt +++ b/compiler/testData/codegen/boxWithStdlib/ranges/expression/reversedEmptyBackSequence.kt @@ -7,6 +7,7 @@ fun box(): String { val range1 = (3 downTo 5).reversed() for (i in range1) { list1.add(i) + if (list1.size() > 23) break } if (list1 != listOf()) { return "Wrong elements for (3 downTo 5).reversed(): $list1" @@ -16,6 +17,7 @@ fun box(): String { val range2 = (3.toByte() downTo 5.toByte()).reversed() for (i in range2) { list2.add(i) + if (list2.size() > 23) break } if (list2 != listOf()) { return "Wrong elements for (3.toByte() downTo 5.toByte()).reversed(): $list2" @@ -25,6 +27,7 @@ fun box(): String { val range3 = (3.toShort() downTo 5.toShort()).reversed() for (i in range3) { list3.add(i) + if (list3.size() > 23) break } if (list3 != listOf()) { return "Wrong elements for (3.toShort() downTo 5.toShort()).reversed(): $list3" @@ -34,6 +37,7 @@ fun box(): String { val range4 = (3.toLong() downTo 5.toLong()).reversed() for (i in range4) { list4.add(i) + if (list4.size() > 23) break } if (list4 != listOf()) { return "Wrong elements for (3.toLong() downTo 5.toLong()).reversed(): $list4" @@ -43,6 +47,7 @@ fun box(): String { val range5 = ('a' downTo 'c').reversed() for (i in range5) { list5.add(i) + if (list5.size() > 23) break } if (list5 != listOf()) { return "Wrong elements for ('a' downTo 'c').reversed(): $list5" @@ -52,6 +57,7 @@ fun box(): String { val range6 = (3.0 downTo 5.0).reversed() for (i in range6) { list6.add(i) + if (list6.size() > 23) break } if (list6 != listOf()) { return "Wrong elements for (3.0 downTo 5.0).reversed(): $list6" @@ -61,6 +67,7 @@ fun box(): String { val range7 = (3.0.toFloat() downTo 5.0.toFloat()).reversed() for (i in range7) { list7.add(i) + if (list7.size() > 23) break } if (list7 != listOf()) { return "Wrong elements for (3.0.toFloat() downTo 5.0.toFloat()).reversed(): $list7" diff --git a/compiler/testData/codegen/boxWithStdlib/ranges/expression/reversedEmptyRange.kt b/compiler/testData/codegen/boxWithStdlib/ranges/expression/reversedEmptyRange.kt index a493181c0dd..da4eb9fe61b 100644 --- a/compiler/testData/codegen/boxWithStdlib/ranges/expression/reversedEmptyRange.kt +++ b/compiler/testData/codegen/boxWithStdlib/ranges/expression/reversedEmptyRange.kt @@ -7,6 +7,7 @@ fun box(): String { val range1 = (5..3).reversed() for (i in range1) { list1.add(i) + if (list1.size() > 23) break } if (list1 != listOf()) { return "Wrong elements for (5..3).reversed(): $list1" @@ -16,6 +17,7 @@ fun box(): String { val range2 = (5.toByte()..3.toByte()).reversed() for (i in range2) { list2.add(i) + if (list2.size() > 23) break } if (list2 != listOf()) { return "Wrong elements for (5.toByte()..3.toByte()).reversed(): $list2" @@ -25,6 +27,7 @@ fun box(): String { val range3 = (5.toShort()..3.toShort()).reversed() for (i in range3) { list3.add(i) + if (list3.size() > 23) break } if (list3 != listOf()) { return "Wrong elements for (5.toShort()..3.toShort()).reversed(): $list3" @@ -34,6 +37,7 @@ fun box(): String { val range4 = (5.toLong()..3.toLong()).reversed() for (i in range4) { list4.add(i) + if (list4.size() > 23) break } if (list4 != listOf()) { return "Wrong elements for (5.toLong()..3.toLong()).reversed(): $list4" @@ -43,6 +47,7 @@ fun box(): String { val range5 = ('c'..'a').reversed() for (i in range5) { list5.add(i) + if (list5.size() > 23) break } if (list5 != listOf()) { return "Wrong elements for ('c'..'a').reversed(): $list5" @@ -52,6 +57,7 @@ fun box(): String { val range6 = (5.0..3.0).reversed() for (i in range6) { list6.add(i) + if (list6.size() > 23) break } if (list6 != listOf()) { return "Wrong elements for (5.0..3.0).reversed(): $list6" @@ -61,6 +67,7 @@ fun box(): String { val range7 = (5.0.toFloat()..3.0.toFloat()).reversed() for (i in range7) { list7.add(i) + if (list7.size() > 23) break } if (list7 != listOf()) { return "Wrong elements for (5.0.toFloat()..3.0.toFloat()).reversed(): $list7" diff --git a/compiler/testData/codegen/boxWithStdlib/ranges/expression/reversedInexactSteppedDownTo.kt b/compiler/testData/codegen/boxWithStdlib/ranges/expression/reversedInexactSteppedDownTo.kt index e639e17447a..a761c892887 100644 --- a/compiler/testData/codegen/boxWithStdlib/ranges/expression/reversedInexactSteppedDownTo.kt +++ b/compiler/testData/codegen/boxWithStdlib/ranges/expression/reversedInexactSteppedDownTo.kt @@ -7,6 +7,7 @@ fun box(): String { val range1 = (8 downTo 3 step 2).reversed() for (i in range1) { list1.add(i) + if (list1.size() > 23) break } if (list1 != listOf(3, 5, 7)) { return "Wrong elements for (8 downTo 3 step 2).reversed(): $list1" @@ -16,6 +17,7 @@ fun box(): String { val range2 = (8.toByte() downTo 3.toByte() step 2).reversed() for (i in range2) { list2.add(i) + if (list2.size() > 23) break } if (list2 != listOf(3, 5, 7)) { return "Wrong elements for (8.toByte() downTo 3.toByte() step 2).reversed(): $list2" @@ -25,6 +27,7 @@ fun box(): String { val range3 = (8.toShort() downTo 3.toShort() step 2).reversed() for (i in range3) { list3.add(i) + if (list3.size() > 23) break } if (list3 != listOf(3, 5, 7)) { return "Wrong elements for (8.toShort() downTo 3.toShort() step 2).reversed(): $list3" @@ -34,6 +37,7 @@ fun box(): String { val range4 = (8.toLong() downTo 3.toLong() step 2.toLong()).reversed() for (i in range4) { list4.add(i) + if (list4.size() > 23) break } if (list4 != listOf(3, 5, 7)) { return "Wrong elements for (8.toLong() downTo 3.toLong() step 2.toLong()).reversed(): $list4" @@ -43,6 +47,7 @@ fun box(): String { val range5 = ('d' downTo 'a' step 2).reversed() for (i in range5) { list5.add(i) + if (list5.size() > 23) break } if (list5 != listOf('a', 'c')) { return "Wrong elements for ('d' downTo 'a' step 2).reversed(): $list5" @@ -52,6 +57,7 @@ fun box(): String { val range6 = (5.8 downTo 4.0 step 0.5).reversed() for (i in range6) { list6.add(i) + if (list6.size() > 23) break } if (list6 != listOf(4.0, 4.5, 5.0, 5.5)) { return "Wrong elements for (5.8 downTo 4.0 step 0.5).reversed(): $list6" @@ -61,6 +67,7 @@ fun box(): String { val range7 = (5.8.toFloat() downTo 4.0.toFloat() step 0.5).reversed() for (i in range7) { list7.add(i) + if (list7.size() > 23) break } if (list7 != listOf(4.0, 4.5, 5.0, 5.5)) { return "Wrong elements for (5.8.toFloat() downTo 4.0.toFloat() step 0.5).reversed(): $list7" diff --git a/compiler/testData/codegen/boxWithStdlib/ranges/expression/reversedRange.kt b/compiler/testData/codegen/boxWithStdlib/ranges/expression/reversedRange.kt index 8c8adfd47fe..5a6964cb98f 100644 --- a/compiler/testData/codegen/boxWithStdlib/ranges/expression/reversedRange.kt +++ b/compiler/testData/codegen/boxWithStdlib/ranges/expression/reversedRange.kt @@ -7,6 +7,7 @@ fun box(): String { val range1 = (3..5).reversed() for (i in range1) { list1.add(i) + if (list1.size() > 23) break } if (list1 != listOf(5, 4, 3)) { return "Wrong elements for (3..5).reversed(): $list1" @@ -16,6 +17,7 @@ fun box(): String { val range2 = (3.toByte()..5.toByte()).reversed() for (i in range2) { list2.add(i) + if (list2.size() > 23) break } if (list2 != listOf(5, 4, 3)) { return "Wrong elements for (3.toByte()..5.toByte()).reversed(): $list2" @@ -25,6 +27,7 @@ fun box(): String { val range3 = (3.toShort()..5.toShort()).reversed() for (i in range3) { list3.add(i) + if (list3.size() > 23) break } if (list3 != listOf(5, 4, 3)) { return "Wrong elements for (3.toShort()..5.toShort()).reversed(): $list3" @@ -34,6 +37,7 @@ fun box(): String { val range4 = (3.toLong()..5.toLong()).reversed() for (i in range4) { list4.add(i) + if (list4.size() > 23) break } if (list4 != listOf(5, 4, 3)) { return "Wrong elements for (3.toLong()..5.toLong()).reversed(): $list4" @@ -43,6 +47,7 @@ fun box(): String { val range5 = ('a'..'c').reversed() for (i in range5) { list5.add(i) + if (list5.size() > 23) break } if (list5 != listOf('c', 'b', 'a')) { return "Wrong elements for ('a'..'c').reversed(): $list5" @@ -52,6 +57,7 @@ fun box(): String { val range6 = (3.0..5.0).reversed() for (i in range6) { list6.add(i) + if (list6.size() > 23) break } if (list6 != listOf(5.0, 4.0, 3.0)) { return "Wrong elements for (3.0..5.0).reversed(): $list6" @@ -61,6 +67,7 @@ fun box(): String { val range7 = (3.0.toFloat()..5.0.toFloat()).reversed() for (i in range7) { list7.add(i) + if (list7.size() > 23) break } if (list7 != listOf(5.0, 4.0, 3.0)) { return "Wrong elements for (3.0.toFloat()..5.0.toFloat()).reversed(): $list7" diff --git a/compiler/testData/codegen/boxWithStdlib/ranges/expression/reversedSimpleSteppedRange.kt b/compiler/testData/codegen/boxWithStdlib/ranges/expression/reversedSimpleSteppedRange.kt index bcd75d9034f..c0f4ec141dc 100644 --- a/compiler/testData/codegen/boxWithStdlib/ranges/expression/reversedSimpleSteppedRange.kt +++ b/compiler/testData/codegen/boxWithStdlib/ranges/expression/reversedSimpleSteppedRange.kt @@ -7,6 +7,7 @@ fun box(): String { val range1 = (3..9 step 2).reversed() for (i in range1) { list1.add(i) + if (list1.size() > 23) break } if (list1 != listOf(9, 7, 5, 3)) { return "Wrong elements for (3..9 step 2).reversed(): $list1" @@ -16,6 +17,7 @@ fun box(): String { val range2 = (3.toByte()..9.toByte() step 2).reversed() for (i in range2) { list2.add(i) + if (list2.size() > 23) break } if (list2 != listOf(9, 7, 5, 3)) { return "Wrong elements for (3.toByte()..9.toByte() step 2).reversed(): $list2" @@ -25,6 +27,7 @@ fun box(): String { val range3 = (3.toShort()..9.toShort() step 2).reversed() for (i in range3) { list3.add(i) + if (list3.size() > 23) break } if (list3 != listOf(9, 7, 5, 3)) { return "Wrong elements for (3.toShort()..9.toShort() step 2).reversed(): $list3" @@ -34,6 +37,7 @@ fun box(): String { val range4 = (3.toLong()..9.toLong() step 2.toLong()).reversed() for (i in range4) { list4.add(i) + if (list4.size() > 23) break } if (list4 != listOf(9, 7, 5, 3)) { return "Wrong elements for (3.toLong()..9.toLong() step 2.toLong()).reversed(): $list4" @@ -43,6 +47,7 @@ fun box(): String { val range5 = ('c'..'g' step 2).reversed() for (i in range5) { list5.add(i) + if (list5.size() > 23) break } if (list5 != listOf('g', 'e', 'c')) { return "Wrong elements for ('c'..'g' step 2).reversed(): $list5" @@ -52,6 +57,7 @@ fun box(): String { val range6 = (4.0..6.0 step 0.5).reversed() for (i in range6) { list6.add(i) + if (list6.size() > 23) break } if (list6 != listOf(6.0, 5.5, 5.0, 4.5, 4.0)) { return "Wrong elements for (4.0..6.0 step 0.5).reversed(): $list6" @@ -61,6 +67,7 @@ fun box(): String { val range7 = (4.0.toFloat()..6.0.toFloat() step 0.5).reversed() for (i in range7) { list7.add(i) + if (list7.size() > 23) break } if (list7 != listOf(6.0, 5.5, 5.0, 4.5, 4.0)) { return "Wrong elements for (4.0.toFloat()..6.0.toFloat() step 0.5).reversed(): $list7" diff --git a/compiler/testData/codegen/boxWithStdlib/ranges/expression/simpleDownTo.kt b/compiler/testData/codegen/boxWithStdlib/ranges/expression/simpleDownTo.kt index 3fc16e23fd6..1070d3ed66e 100644 --- a/compiler/testData/codegen/boxWithStdlib/ranges/expression/simpleDownTo.kt +++ b/compiler/testData/codegen/boxWithStdlib/ranges/expression/simpleDownTo.kt @@ -7,6 +7,7 @@ fun box(): String { val range1 = 9 downTo 3 for (i in range1) { list1.add(i) + if (list1.size() > 23) break } if (list1 != listOf(9, 8, 7, 6, 5, 4, 3)) { return "Wrong elements for 9 downTo 3: $list1" @@ -16,6 +17,7 @@ fun box(): String { val range2 = 9.toByte() downTo 3.toByte() for (i in range2) { list2.add(i) + if (list2.size() > 23) break } if (list2 != listOf(9, 8, 7, 6, 5, 4, 3)) { return "Wrong elements for 9.toByte() downTo 3.toByte(): $list2" @@ -25,6 +27,7 @@ fun box(): String { val range3 = 9.toShort() downTo 3.toShort() for (i in range3) { list3.add(i) + if (list3.size() > 23) break } if (list3 != listOf(9, 8, 7, 6, 5, 4, 3)) { return "Wrong elements for 9.toShort() downTo 3.toShort(): $list3" @@ -34,6 +37,7 @@ fun box(): String { val range4 = 9.toLong() downTo 3.toLong() for (i in range4) { list4.add(i) + if (list4.size() > 23) break } if (list4 != listOf(9, 8, 7, 6, 5, 4, 3)) { return "Wrong elements for 9.toLong() downTo 3.toLong(): $list4" @@ -43,6 +47,7 @@ fun box(): String { val range5 = 'g' downTo 'c' for (i in range5) { list5.add(i) + if (list5.size() > 23) break } if (list5 != listOf('g', 'f', 'e', 'd', 'c')) { return "Wrong elements for 'g' downTo 'c': $list5" @@ -52,6 +57,7 @@ fun box(): String { val range6 = 9.0 downTo 3.0 for (i in range6) { list6.add(i) + if (list6.size() > 23) break } if (list6 != listOf(9.0, 8.0, 7.0, 6.0, 5.0, 4.0, 3.0)) { return "Wrong elements for 9.0 downTo 3.0: $list6" @@ -61,6 +67,7 @@ fun box(): String { val range7 = 9.0.toFloat() downTo 3.0.toFloat() for (i in range7) { list7.add(i) + if (list7.size() > 23) break } if (list7 != listOf(9.0, 8.0, 7.0, 6.0, 5.0, 4.0, 3.0)) { return "Wrong elements for 9.0.toFloat() downTo 3.0.toFloat(): $list7" diff --git a/compiler/testData/codegen/boxWithStdlib/ranges/expression/simpleRange.kt b/compiler/testData/codegen/boxWithStdlib/ranges/expression/simpleRange.kt index 8d9a7da508c..c3ff9692bb8 100644 --- a/compiler/testData/codegen/boxWithStdlib/ranges/expression/simpleRange.kt +++ b/compiler/testData/codegen/boxWithStdlib/ranges/expression/simpleRange.kt @@ -7,6 +7,7 @@ fun box(): String { val range1 = 3..9 for (i in range1) { list1.add(i) + if (list1.size() > 23) break } if (list1 != listOf(3, 4, 5, 6, 7, 8, 9)) { return "Wrong elements for 3..9: $list1" @@ -16,6 +17,7 @@ fun box(): String { val range2 = 3.toByte()..9.toByte() for (i in range2) { list2.add(i) + if (list2.size() > 23) break } if (list2 != listOf(3, 4, 5, 6, 7, 8, 9)) { return "Wrong elements for 3.toByte()..9.toByte(): $list2" @@ -25,6 +27,7 @@ fun box(): String { val range3 = 3.toShort()..9.toShort() for (i in range3) { list3.add(i) + if (list3.size() > 23) break } if (list3 != listOf(3, 4, 5, 6, 7, 8, 9)) { return "Wrong elements for 3.toShort()..9.toShort(): $list3" @@ -34,6 +37,7 @@ fun box(): String { val range4 = 3.toLong()..9.toLong() for (i in range4) { list4.add(i) + if (list4.size() > 23) break } if (list4 != listOf(3, 4, 5, 6, 7, 8, 9)) { return "Wrong elements for 3.toLong()..9.toLong(): $list4" @@ -43,6 +47,7 @@ fun box(): String { val range5 = 'c'..'g' for (i in range5) { list5.add(i) + if (list5.size() > 23) break } if (list5 != listOf('c', 'd', 'e', 'f', 'g')) { return "Wrong elements for 'c'..'g': $list5" @@ -52,6 +57,7 @@ fun box(): String { val range6 = 3.0..9.0 for (i in range6) { list6.add(i) + if (list6.size() > 23) break } if (list6 != listOf(3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0)) { return "Wrong elements for 3.0..9.0: $list6" @@ -61,6 +67,7 @@ fun box(): String { val range7 = 3.0.toFloat()..9.0.toFloat() for (i in range7) { list7.add(i) + if (list7.size() > 23) break } if (list7 != listOf(3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0)) { return "Wrong elements for 3.0.toFloat()..9.0.toFloat(): $list7" diff --git a/compiler/testData/codegen/boxWithStdlib/ranges/expression/simpleRangeWithNonConstantEnds.kt b/compiler/testData/codegen/boxWithStdlib/ranges/expression/simpleRangeWithNonConstantEnds.kt index eb07ee505a4..ccef5ad49db 100644 --- a/compiler/testData/codegen/boxWithStdlib/ranges/expression/simpleRangeWithNonConstantEnds.kt +++ b/compiler/testData/codegen/boxWithStdlib/ranges/expression/simpleRangeWithNonConstantEnds.kt @@ -7,6 +7,7 @@ fun box(): String { val range1 = (1 + 2)..(10 - 1) for (i in range1) { list1.add(i) + if (list1.size() > 23) break } if (list1 != listOf(3, 4, 5, 6, 7, 8, 9)) { return "Wrong elements for (1 + 2)..(10 - 1): $list1" @@ -16,6 +17,7 @@ fun box(): String { val range2 = (1.toByte() + 2.toByte()).toByte()..(10.toByte() - 1.toByte()).toByte() for (i in range2) { list2.add(i) + if (list2.size() > 23) break } if (list2 != listOf(3, 4, 5, 6, 7, 8, 9)) { return "Wrong elements for (1.toByte() + 2.toByte()).toByte()..(10.toByte() - 1.toByte()).toByte(): $list2" @@ -25,6 +27,7 @@ fun box(): String { val range3 = (1.toShort() + 2.toShort()).toShort()..(10.toShort() - 1.toShort()).toShort() for (i in range3) { list3.add(i) + if (list3.size() > 23) break } if (list3 != listOf(3, 4, 5, 6, 7, 8, 9)) { return "Wrong elements for (1.toShort() + 2.toShort()).toShort()..(10.toShort() - 1.toShort()).toShort(): $list3" @@ -34,6 +37,7 @@ fun box(): String { val range4 = (1.toLong() + 2.toLong())..(10.toLong() - 1.toLong()) for (i in range4) { list4.add(i) + if (list4.size() > 23) break } if (list4 != listOf(3, 4, 5, 6, 7, 8, 9)) { return "Wrong elements for (1.toLong() + 2.toLong())..(10.toLong() - 1.toLong()): $list4" @@ -43,6 +47,7 @@ fun box(): String { val range5 = ("ace"[1])..("age"[1]) for (i in range5) { list5.add(i) + if (list5.size() > 23) break } if (list5 != listOf('c', 'd', 'e', 'f', 'g')) { return "Wrong elements for (\"ace\"[1])..(\"age\"[1]): $list5" @@ -52,6 +57,7 @@ fun box(): String { val range6 = (1.5 * 2)..(3.0 * 3.0) for (i in range6) { list6.add(i) + if (list6.size() > 23) break } if (list6 != listOf(3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0)) { return "Wrong elements for (1.5 * 2)..(3.0 * 3.0): $list6" @@ -61,6 +67,7 @@ fun box(): String { val range7 = (1.5.toFloat() * 2.toFloat())..(3.0.toFloat() * 3.0.toFloat()) for (i in range7) { list7.add(i) + if (list7.size() > 23) break } if (list7 != listOf(3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0)) { return "Wrong elements for (1.5.toFloat() * 2.toFloat())..(3.0.toFloat() * 3.0.toFloat()): $list7" diff --git a/compiler/testData/codegen/boxWithStdlib/ranges/expression/simpleSteppedDownTo.kt b/compiler/testData/codegen/boxWithStdlib/ranges/expression/simpleSteppedDownTo.kt index 5fba12b32ff..ab6285a9141 100644 --- a/compiler/testData/codegen/boxWithStdlib/ranges/expression/simpleSteppedDownTo.kt +++ b/compiler/testData/codegen/boxWithStdlib/ranges/expression/simpleSteppedDownTo.kt @@ -7,6 +7,7 @@ fun box(): String { val range1 = 9 downTo 3 step 2 for (i in range1) { list1.add(i) + if (list1.size() > 23) break } if (list1 != listOf(9, 7, 5, 3)) { return "Wrong elements for 9 downTo 3 step 2: $list1" @@ -16,6 +17,7 @@ fun box(): String { val range2 = 9.toByte() downTo 3.toByte() step 2 for (i in range2) { list2.add(i) + if (list2.size() > 23) break } if (list2 != listOf(9, 7, 5, 3)) { return "Wrong elements for 9.toByte() downTo 3.toByte() step 2: $list2" @@ -25,6 +27,7 @@ fun box(): String { val range3 = 9.toShort() downTo 3.toShort() step 2 for (i in range3) { list3.add(i) + if (list3.size() > 23) break } if (list3 != listOf(9, 7, 5, 3)) { return "Wrong elements for 9.toShort() downTo 3.toShort() step 2: $list3" @@ -34,6 +37,7 @@ fun box(): String { val range4 = 9.toLong() downTo 3.toLong() step 2.toLong() for (i in range4) { list4.add(i) + if (list4.size() > 23) break } if (list4 != listOf(9, 7, 5, 3)) { return "Wrong elements for 9.toLong() downTo 3.toLong() step 2.toLong(): $list4" @@ -43,6 +47,7 @@ fun box(): String { val range5 = 'g' downTo 'c' step 2 for (i in range5) { list5.add(i) + if (list5.size() > 23) break } if (list5 != listOf('g', 'e', 'c')) { return "Wrong elements for 'g' downTo 'c' step 2: $list5" @@ -52,6 +57,7 @@ fun box(): String { val range6 = 6.0 downTo 4.0 step 0.5 for (i in range6) { list6.add(i) + if (list6.size() > 23) break } if (list6 != listOf(6.0, 5.5, 5.0, 4.5, 4.0)) { return "Wrong elements for 6.0 downTo 4.0 step 0.5: $list6" @@ -61,6 +67,7 @@ fun box(): String { val range7 = 6.0.toFloat() downTo 4.0.toFloat() step 0.5.toFloat() for (i in range7) { list7.add(i) + if (list7.size() > 23) break } if (list7 != listOf(6.0, 5.5, 5.0, 4.5, 4.0)) { return "Wrong elements for 6.0.toFloat() downTo 4.0.toFloat() step 0.5.toFloat(): $list7" diff --git a/compiler/testData/codegen/boxWithStdlib/ranges/expression/simpleSteppedRange.kt b/compiler/testData/codegen/boxWithStdlib/ranges/expression/simpleSteppedRange.kt index 4ca86a792ba..2805b5c1929 100644 --- a/compiler/testData/codegen/boxWithStdlib/ranges/expression/simpleSteppedRange.kt +++ b/compiler/testData/codegen/boxWithStdlib/ranges/expression/simpleSteppedRange.kt @@ -7,6 +7,7 @@ fun box(): String { val range1 = 3..9 step 2 for (i in range1) { list1.add(i) + if (list1.size() > 23) break } if (list1 != listOf(3, 5, 7, 9)) { return "Wrong elements for 3..9 step 2: $list1" @@ -16,6 +17,7 @@ fun box(): String { val range2 = 3.toByte()..9.toByte() step 2 for (i in range2) { list2.add(i) + if (list2.size() > 23) break } if (list2 != listOf(3, 5, 7, 9)) { return "Wrong elements for 3.toByte()..9.toByte() step 2: $list2" @@ -25,6 +27,7 @@ fun box(): String { val range3 = 3.toShort()..9.toShort() step 2 for (i in range3) { list3.add(i) + if (list3.size() > 23) break } if (list3 != listOf(3, 5, 7, 9)) { return "Wrong elements for 3.toShort()..9.toShort() step 2: $list3" @@ -34,6 +37,7 @@ fun box(): String { val range4 = 3.toLong()..9.toLong() step 2.toLong() for (i in range4) { list4.add(i) + if (list4.size() > 23) break } if (list4 != listOf(3, 5, 7, 9)) { return "Wrong elements for 3.toLong()..9.toLong() step 2.toLong(): $list4" @@ -43,6 +47,7 @@ fun box(): String { val range5 = 'c'..'g' step 2 for (i in range5) { list5.add(i) + if (list5.size() > 23) break } if (list5 != listOf('c', 'e', 'g')) { return "Wrong elements for 'c'..'g' step 2: $list5" @@ -52,6 +57,7 @@ fun box(): String { val range6 = 4.0..6.0 step 0.5 for (i in range6) { list6.add(i) + if (list6.size() > 23) break } if (list6 != listOf(4.0, 4.5, 5.0, 5.5, 6.0)) { return "Wrong elements for 4.0..6.0 step 0.5: $list6" @@ -61,6 +67,7 @@ fun box(): String { val range7 = 4.0.toFloat()..6.0.toFloat() step 0.5.toFloat() for (i in range7) { list7.add(i) + if (list7.size() > 23) break } if (list7 != listOf(4.0, 4.5, 5.0, 5.5, 6.0)) { return "Wrong elements for 4.0.toFloat()..6.0.toFloat() step 0.5.toFloat(): $list7" diff --git a/compiler/testData/codegen/boxWithStdlib/ranges/literal/emptyDownto.kt b/compiler/testData/codegen/boxWithStdlib/ranges/literal/emptyDownto.kt index 3ed19157778..6814674fb62 100644 --- a/compiler/testData/codegen/boxWithStdlib/ranges/literal/emptyDownto.kt +++ b/compiler/testData/codegen/boxWithStdlib/ranges/literal/emptyDownto.kt @@ -6,6 +6,7 @@ fun box(): String { val list1 = ArrayList() for (i in 5 downTo 10) { list1.add(i) + if (list1.size() > 23) break } if (list1 != listOf()) { return "Wrong elements for 5 downTo 10: $list1" @@ -14,6 +15,7 @@ fun box(): String { val list2 = ArrayList() for (i in 5.toByte() downTo 10.toByte()) { list2.add(i) + if (list2.size() > 23) break } if (list2 != listOf()) { return "Wrong elements for 5.toByte() downTo 10.toByte(): $list2" @@ -22,6 +24,7 @@ fun box(): String { val list3 = ArrayList() for (i in 5.toShort() downTo 10.toShort()) { list3.add(i) + if (list3.size() > 23) break } if (list3 != listOf()) { return "Wrong elements for 5.toShort() downTo 10.toShort(): $list3" @@ -30,6 +33,7 @@ fun box(): String { val list4 = ArrayList() for (i in 5.toLong() downTo 10.toLong()) { list4.add(i) + if (list4.size() > 23) break } if (list4 != listOf()) { return "Wrong elements for 5.toLong() downTo 10.toLong(): $list4" @@ -38,6 +42,7 @@ fun box(): String { val list5 = ArrayList() for (i in 'a' downTo 'z') { list5.add(i) + if (list5.size() > 23) break } if (list5 != listOf()) { return "Wrong elements for 'a' downTo 'z': $list5" @@ -46,6 +51,7 @@ fun box(): String { val list6 = ArrayList() for (i in -1.0 downTo 5.0) { list6.add(i) + if (list6.size() > 23) break } if (list6 != listOf()) { return "Wrong elements for -1.0 downTo 5.0: $list6" @@ -54,6 +60,7 @@ fun box(): String { val list7 = ArrayList() for (i in -1.0.toFloat() downTo 5.0.toFloat()) { list7.add(i) + if (list7.size() > 23) break } if (list7 != listOf()) { return "Wrong elements for -1.0.toFloat() downTo 5.0.toFloat(): $list7" diff --git a/compiler/testData/codegen/boxWithStdlib/ranges/literal/emptyRange.kt b/compiler/testData/codegen/boxWithStdlib/ranges/literal/emptyRange.kt index 6d0cd54010b..b91e44763e7 100644 --- a/compiler/testData/codegen/boxWithStdlib/ranges/literal/emptyRange.kt +++ b/compiler/testData/codegen/boxWithStdlib/ranges/literal/emptyRange.kt @@ -6,6 +6,7 @@ fun box(): String { val list1 = ArrayList() for (i in 10..5) { list1.add(i) + if (list1.size() > 23) break } if (list1 != listOf()) { return "Wrong elements for 10..5: $list1" @@ -14,6 +15,7 @@ fun box(): String { val list2 = ArrayList() for (i in 10.toByte()..-5.toByte()) { list2.add(i) + if (list2.size() > 23) break } if (list2 != listOf()) { return "Wrong elements for 10.toByte()..-5.toByte(): $list2" @@ -22,6 +24,7 @@ fun box(): String { val list3 = ArrayList() for (i in 10.toShort()..-5.toShort()) { list3.add(i) + if (list3.size() > 23) break } if (list3 != listOf()) { return "Wrong elements for 10.toShort()..-5.toShort(): $list3" @@ -30,6 +33,7 @@ fun box(): String { val list4 = ArrayList() for (i in 10.toLong()..-5.toLong()) { list4.add(i) + if (list4.size() > 23) break } if (list4 != listOf()) { return "Wrong elements for 10.toLong()..-5.toLong(): $list4" @@ -38,6 +42,7 @@ fun box(): String { val list5 = ArrayList() for (i in 'z'..'a') { list5.add(i) + if (list5.size() > 23) break } if (list5 != listOf()) { return "Wrong elements for 'z'..'a': $list5" @@ -46,6 +51,7 @@ fun box(): String { val list6 = ArrayList() for (i in 5.0..-1.0) { list6.add(i) + if (list6.size() > 23) break } if (list6 != listOf()) { return "Wrong elements for 5.0..-1.0: $list6" @@ -54,6 +60,7 @@ fun box(): String { val list7 = ArrayList() for (i in 5.0.toFloat()..-1.0.toFloat()) { list7.add(i) + if (list7.size() > 23) break } if (list7 != listOf()) { return "Wrong elements for 5.0.toFloat()..-1.0.toFloat(): $list7" diff --git a/compiler/testData/codegen/boxWithStdlib/ranges/literal/inexactSteppedDownTo.kt b/compiler/testData/codegen/boxWithStdlib/ranges/literal/inexactSteppedDownTo.kt index acf1c0ed06f..b6038b99651 100644 --- a/compiler/testData/codegen/boxWithStdlib/ranges/literal/inexactSteppedDownTo.kt +++ b/compiler/testData/codegen/boxWithStdlib/ranges/literal/inexactSteppedDownTo.kt @@ -6,6 +6,7 @@ fun box(): String { val list1 = ArrayList() for (i in 8 downTo 3 step 2) { list1.add(i) + if (list1.size() > 23) break } if (list1 != listOf(8, 6, 4)) { return "Wrong elements for 8 downTo 3 step 2: $list1" @@ -14,6 +15,7 @@ fun box(): String { val list2 = ArrayList() for (i in 8.toByte() downTo 3.toByte() step 2) { list2.add(i) + if (list2.size() > 23) break } if (list2 != listOf(8, 6, 4)) { return "Wrong elements for 8.toByte() downTo 3.toByte() step 2: $list2" @@ -22,6 +24,7 @@ fun box(): String { val list3 = ArrayList() for (i in 8.toShort() downTo 3.toShort() step 2) { list3.add(i) + if (list3.size() > 23) break } if (list3 != listOf(8, 6, 4)) { return "Wrong elements for 8.toShort() downTo 3.toShort() step 2: $list3" @@ -30,6 +33,7 @@ fun box(): String { val list4 = ArrayList() for (i in 8.toLong() downTo 3.toLong() step 2.toLong()) { list4.add(i) + if (list4.size() > 23) break } if (list4 != listOf(8, 6, 4)) { return "Wrong elements for 8.toLong() downTo 3.toLong() step 2.toLong(): $list4" @@ -38,6 +42,7 @@ fun box(): String { val list5 = ArrayList() for (i in 'd' downTo 'a' step 2) { list5.add(i) + if (list5.size() > 23) break } if (list5 != listOf('d', 'b')) { return "Wrong elements for 'd' downTo 'a' step 2: $list5" @@ -46,6 +51,7 @@ fun box(): String { val list6 = ArrayList() for (i in 5.5 downTo 3.7 step 0.5) { list6.add(i) + if (list6.size() > 23) break } if (list6 != listOf(5.5, 5.0, 4.5, 4.0)) { return "Wrong elements for 5.5 downTo 3.7 step 0.5: $list6" @@ -54,6 +60,7 @@ fun box(): String { val list7 = ArrayList() for (i in 5.5.toFloat() downTo 3.7.toFloat() step 0.5.toFloat()) { list7.add(i) + if (list7.size() > 23) break } if (list7 != listOf(5.5, 5.0, 4.5, 4.0)) { return "Wrong elements for 5.5.toFloat() downTo 3.7.toFloat() step 0.5.toFloat(): $list7" diff --git a/compiler/testData/codegen/boxWithStdlib/ranges/literal/inexactSteppedRange.kt b/compiler/testData/codegen/boxWithStdlib/ranges/literal/inexactSteppedRange.kt index b2d0f0e2e30..d1b6fd6c8a7 100644 --- a/compiler/testData/codegen/boxWithStdlib/ranges/literal/inexactSteppedRange.kt +++ b/compiler/testData/codegen/boxWithStdlib/ranges/literal/inexactSteppedRange.kt @@ -6,6 +6,7 @@ fun box(): String { val list1 = ArrayList() for (i in 3..8 step 2) { list1.add(i) + if (list1.size() > 23) break } if (list1 != listOf(3, 5, 7)) { return "Wrong elements for 3..8 step 2: $list1" @@ -14,6 +15,7 @@ fun box(): String { val list2 = ArrayList() for (i in 3.toByte()..8.toByte() step 2) { list2.add(i) + if (list2.size() > 23) break } if (list2 != listOf(3, 5, 7)) { return "Wrong elements for 3.toByte()..8.toByte() step 2: $list2" @@ -22,6 +24,7 @@ fun box(): String { val list3 = ArrayList() for (i in 3.toShort()..8.toShort() step 2) { list3.add(i) + if (list3.size() > 23) break } if (list3 != listOf(3, 5, 7)) { return "Wrong elements for 3.toShort()..8.toShort() step 2: $list3" @@ -30,6 +33,7 @@ fun box(): String { val list4 = ArrayList() for (i in 3.toLong()..8.toLong() step 2.toLong()) { list4.add(i) + if (list4.size() > 23) break } if (list4 != listOf(3, 5, 7)) { return "Wrong elements for 3.toLong()..8.toLong() step 2.toLong(): $list4" @@ -38,6 +42,7 @@ fun box(): String { val list5 = ArrayList() for (i in 'a'..'d' step 2) { list5.add(i) + if (list5.size() > 23) break } if (list5 != listOf('a', 'c')) { return "Wrong elements for 'a'..'d' step 2: $list5" @@ -46,6 +51,7 @@ fun box(): String { val list6 = ArrayList() for (i in 4.0..5.8 step 0.5) { list6.add(i) + if (list6.size() > 23) break } if (list6 != listOf(4.0, 4.5, 5.0, 5.5)) { return "Wrong elements for 4.0..5.8 step 0.5: $list6" @@ -54,6 +60,7 @@ fun box(): String { val list7 = ArrayList() for (i in 4.0.toFloat()..5.8.toFloat() step 0.5.toFloat()) { list7.add(i) + if (list7.size() > 23) break } if (list7 != listOf(4.0, 4.5, 5.0, 5.5)) { return "Wrong elements for 4.0.toFloat()..5.8.toFloat() step 0.5.toFloat(): $list7" diff --git a/compiler/testData/codegen/boxWithStdlib/ranges/literal/infiniteSteps.kt b/compiler/testData/codegen/boxWithStdlib/ranges/literal/infiniteSteps.kt index 8f1d3d63dc2..57882f521ae 100644 --- a/compiler/testData/codegen/boxWithStdlib/ranges/literal/infiniteSteps.kt +++ b/compiler/testData/codegen/boxWithStdlib/ranges/literal/infiniteSteps.kt @@ -6,6 +6,7 @@ fun box(): String { val list1 = ArrayList() for (i in 0.0..5.0 step j.Double.POSITIVE_INFINITY) { list1.add(i) + if (list1.size() > 23) break } if (list1 != listOf(0.0)) { return "Wrong elements for 0.0..5.0 step j.Double.POSITIVE_INFINITY: $list1" @@ -14,6 +15,7 @@ fun box(): String { val list2 = ArrayList() for (i in 0.0.toFloat()..5.0.toFloat() step j.Float.POSITIVE_INFINITY) { list2.add(i) + if (list2.size() > 23) break } if (list2 != listOf(0.0)) { return "Wrong elements for 0.0.toFloat()..5.0.toFloat() step j.Float.POSITIVE_INFINITY: $list2" @@ -22,6 +24,7 @@ fun box(): String { val list3 = ArrayList() for (i in 5.0 downTo 0.0 step j.Double.POSITIVE_INFINITY) { list3.add(i) + if (list3.size() > 23) break } if (list3 != listOf(5.0)) { return "Wrong elements for 5.0 downTo 0.0 step j.Double.POSITIVE_INFINITY: $list3" @@ -30,6 +33,7 @@ fun box(): String { val list4 = ArrayList() for (i in 5.0.toFloat() downTo 0.0.toFloat() step j.Float.POSITIVE_INFINITY) { list4.add(i) + if (list4.size() > 23) break } if (list4 != listOf(5.0)) { return "Wrong elements for 5.0.toFloat() downTo 0.0.toFloat() step j.Float.POSITIVE_INFINITY: $list4" diff --git a/compiler/testData/codegen/boxWithStdlib/ranges/literal/nanEnds.kt b/compiler/testData/codegen/boxWithStdlib/ranges/literal/nanEnds.kt index e1c98648da0..89ae2abe17b 100644 --- a/compiler/testData/codegen/boxWithStdlib/ranges/literal/nanEnds.kt +++ b/compiler/testData/codegen/boxWithStdlib/ranges/literal/nanEnds.kt @@ -6,6 +6,7 @@ fun box(): String { val list1 = ArrayList() for (i in j.Double.NaN..5.0) { list1.add(i) + if (list1.size() > 23) break } if (list1 != listOf()) { return "Wrong elements for j.Double.NaN..5.0: $list1" @@ -14,6 +15,7 @@ fun box(): String { val list2 = ArrayList() for (i in j.Float.NaN.toFloat()..5.0.toFloat()) { list2.add(i) + if (list2.size() > 23) break } if (list2 != listOf()) { return "Wrong elements for j.Float.NaN.toFloat()..5.0.toFloat(): $list2" @@ -22,6 +24,7 @@ fun box(): String { val list3 = ArrayList() for (i in j.Double.NaN downTo 0.0) { list3.add(i) + if (list3.size() > 23) break } if (list3 != listOf()) { return "Wrong elements for j.Double.NaN downTo 0.0: $list3" @@ -30,6 +33,7 @@ fun box(): String { val list4 = ArrayList() for (i in j.Float.NaN.toFloat() downTo 0.0.toFloat()) { list4.add(i) + if (list4.size() > 23) break } if (list4 != listOf()) { return "Wrong elements for j.Float.NaN.toFloat() downTo 0.0.toFloat(): $list4" @@ -38,6 +42,7 @@ fun box(): String { val list5 = ArrayList() for (i in 0.0..j.Double.NaN) { list5.add(i) + if (list5.size() > 23) break } if (list5 != listOf()) { return "Wrong elements for 0.0..j.Double.NaN: $list5" @@ -46,6 +51,7 @@ fun box(): String { val list6 = ArrayList() for (i in 0.0.toFloat()..j.Float.NaN) { list6.add(i) + if (list6.size() > 23) break } if (list6 != listOf()) { return "Wrong elements for 0.0.toFloat()..j.Float.NaN: $list6" @@ -54,6 +60,7 @@ fun box(): String { val list7 = ArrayList() for (i in 5.0 downTo j.Double.NaN) { list7.add(i) + if (list7.size() > 23) break } if (list7 != listOf()) { return "Wrong elements for 5.0 downTo j.Double.NaN: $list7" @@ -62,6 +69,7 @@ fun box(): String { val list8 = ArrayList() for (i in 5.0.toFloat() downTo j.Float.NaN) { list8.add(i) + if (list8.size() > 23) break } if (list8 != listOf()) { return "Wrong elements for 5.0.toFloat() downTo j.Float.NaN: $list8" @@ -70,6 +78,7 @@ fun box(): String { val list9 = ArrayList() for (i in j.Double.NaN..j.Double.NaN) { list9.add(i) + if (list9.size() > 23) break } if (list9 != listOf()) { return "Wrong elements for j.Double.NaN..j.Double.NaN: $list9" @@ -78,6 +87,7 @@ fun box(): String { val list10 = ArrayList() for (i in j.Float.NaN..j.Float.NaN) { list10.add(i) + if (list10.size() > 23) break } if (list10 != listOf()) { return "Wrong elements for j.Float.NaN..j.Float.NaN: $list10" @@ -86,6 +96,7 @@ fun box(): String { val list11 = ArrayList() for (i in j.Double.NaN downTo j.Double.NaN) { list11.add(i) + if (list11.size() > 23) break } if (list11 != listOf()) { return "Wrong elements for j.Double.NaN downTo j.Double.NaN: $list11" @@ -94,6 +105,7 @@ fun box(): String { val list12 = ArrayList() for (i in j.Float.NaN downTo j.Float.NaN) { list12.add(i) + if (list12.size() > 23) break } if (list12 != listOf()) { return "Wrong elements for j.Float.NaN downTo j.Float.NaN: $list12" diff --git a/compiler/testData/codegen/boxWithStdlib/ranges/literal/oneElementDownTo.kt b/compiler/testData/codegen/boxWithStdlib/ranges/literal/oneElementDownTo.kt index d5b5f4b2381..fa39f9cf3b6 100644 --- a/compiler/testData/codegen/boxWithStdlib/ranges/literal/oneElementDownTo.kt +++ b/compiler/testData/codegen/boxWithStdlib/ranges/literal/oneElementDownTo.kt @@ -6,6 +6,7 @@ fun box(): String { val list1 = ArrayList() for (i in 5 downTo 5) { list1.add(i) + if (list1.size() > 23) break } if (list1 != listOf(5)) { return "Wrong elements for 5 downTo 5: $list1" @@ -14,6 +15,7 @@ fun box(): String { val list2 = ArrayList() for (i in 5.toByte() downTo 5.toByte()) { list2.add(i) + if (list2.size() > 23) break } if (list2 != listOf(5.toByte())) { return "Wrong elements for 5.toByte() downTo 5.toByte(): $list2" @@ -22,6 +24,7 @@ fun box(): String { val list3 = ArrayList() for (i in 5.toShort() downTo 5.toShort()) { list3.add(i) + if (list3.size() > 23) break } if (list3 != listOf(5.toShort())) { return "Wrong elements for 5.toShort() downTo 5.toShort(): $list3" @@ -30,6 +33,7 @@ fun box(): String { val list4 = ArrayList() for (i in 5.toLong() downTo 5.toLong()) { list4.add(i) + if (list4.size() > 23) break } if (list4 != listOf(5.toLong())) { return "Wrong elements for 5.toLong() downTo 5.toLong(): $list4" @@ -38,6 +42,7 @@ fun box(): String { val list5 = ArrayList() for (i in 'k' downTo 'k') { list5.add(i) + if (list5.size() > 23) break } if (list5 != listOf('k')) { return "Wrong elements for 'k' downTo 'k': $list5" @@ -46,6 +51,7 @@ fun box(): String { val list6 = ArrayList() for (i in 5.0 downTo 5.0) { list6.add(i) + if (list6.size() > 23) break } if (list6 != listOf(5.0)) { return "Wrong elements for 5.0 downTo 5.0: $list6" @@ -54,6 +60,7 @@ fun box(): String { val list7 = ArrayList() for (i in 5.0.toFloat() downTo 5.0.toFloat()) { list7.add(i) + if (list7.size() > 23) break } if (list7 != listOf(5.0.toFloat())) { return "Wrong elements for 5.0.toFloat() downTo 5.0.toFloat(): $list7" diff --git a/compiler/testData/codegen/boxWithStdlib/ranges/literal/oneElementRange.kt b/compiler/testData/codegen/boxWithStdlib/ranges/literal/oneElementRange.kt index 891eb9cb7b4..1139e7d7074 100644 --- a/compiler/testData/codegen/boxWithStdlib/ranges/literal/oneElementRange.kt +++ b/compiler/testData/codegen/boxWithStdlib/ranges/literal/oneElementRange.kt @@ -6,6 +6,7 @@ fun box(): String { val list1 = ArrayList() for (i in 5..5) { list1.add(i) + if (list1.size() > 23) break } if (list1 != listOf(5)) { return "Wrong elements for 5..5: $list1" @@ -14,6 +15,7 @@ fun box(): String { val list2 = ArrayList() for (i in 5.toByte()..5.toByte()) { list2.add(i) + if (list2.size() > 23) break } if (list2 != listOf(5.toByte())) { return "Wrong elements for 5.toByte()..5.toByte(): $list2" @@ -22,6 +24,7 @@ fun box(): String { val list3 = ArrayList() for (i in 5.toShort()..5.toShort()) { list3.add(i) + if (list3.size() > 23) break } if (list3 != listOf(5.toShort())) { return "Wrong elements for 5.toShort()..5.toShort(): $list3" @@ -30,6 +33,7 @@ fun box(): String { val list4 = ArrayList() for (i in 5.toLong()..5.toLong()) { list4.add(i) + if (list4.size() > 23) break } if (list4 != listOf(5.toLong())) { return "Wrong elements for 5.toLong()..5.toLong(): $list4" @@ -38,6 +42,7 @@ fun box(): String { val list5 = ArrayList() for (i in 'k'..'k') { list5.add(i) + if (list5.size() > 23) break } if (list5 != listOf('k')) { return "Wrong elements for 'k'..'k': $list5" @@ -46,6 +51,7 @@ fun box(): String { val list6 = ArrayList() for (i in 5.0..5.0) { list6.add(i) + if (list6.size() > 23) break } if (list6 != listOf(5.0)) { return "Wrong elements for 5.0..5.0: $list6" @@ -54,6 +60,7 @@ fun box(): String { val list7 = ArrayList() for (i in 5.0.toFloat()..5.0.toFloat()) { list7.add(i) + if (list7.size() > 23) break } if (list7 != listOf(5.0.toFloat())) { return "Wrong elements for 5.0.toFloat()..5.0.toFloat(): $list7" diff --git a/compiler/testData/codegen/boxWithStdlib/ranges/literal/reversedBackSequence.kt b/compiler/testData/codegen/boxWithStdlib/ranges/literal/reversedBackSequence.kt index 4236e5d32bd..998e413a626 100644 --- a/compiler/testData/codegen/boxWithStdlib/ranges/literal/reversedBackSequence.kt +++ b/compiler/testData/codegen/boxWithStdlib/ranges/literal/reversedBackSequence.kt @@ -6,6 +6,7 @@ fun box(): String { val list1 = ArrayList() for (i in (5 downTo 3).reversed()) { list1.add(i) + if (list1.size() > 23) break } if (list1 != listOf(3, 4, 5)) { return "Wrong elements for (5 downTo 3).reversed(): $list1" @@ -14,6 +15,7 @@ fun box(): String { val list2 = ArrayList() for (i in (5.toByte() downTo 3.toByte()).reversed()) { list2.add(i) + if (list2.size() > 23) break } if (list2 != listOf(3, 4, 5)) { return "Wrong elements for (5.toByte() downTo 3.toByte()).reversed(): $list2" @@ -22,6 +24,7 @@ fun box(): String { val list3 = ArrayList() for (i in (5.toShort() downTo 3.toShort()).reversed()) { list3.add(i) + if (list3.size() > 23) break } if (list3 != listOf(3, 4, 5)) { return "Wrong elements for (5.toShort() downTo 3.toShort()).reversed(): $list3" @@ -30,6 +33,7 @@ fun box(): String { val list4 = ArrayList() for (i in (5.toLong() downTo 3.toLong()).reversed()) { list4.add(i) + if (list4.size() > 23) break } if (list4 != listOf(3, 4, 5)) { return "Wrong elements for (5.toLong() downTo 3.toLong()).reversed(): $list4" @@ -38,6 +42,7 @@ fun box(): String { val list5 = ArrayList() for (i in ('c' downTo 'a').reversed()) { list5.add(i) + if (list5.size() > 23) break } if (list5 != listOf('a', 'b', 'c')) { return "Wrong elements for ('c' downTo 'a').reversed(): $list5" @@ -46,6 +51,7 @@ fun box(): String { val list6 = ArrayList() for (i in (5.0 downTo 3.0).reversed()) { list6.add(i) + if (list6.size() > 23) break } if (list6 != listOf(3.0, 4.0, 5.0)) { return "Wrong elements for (5.0 downTo 3.0).reversed(): $list6" @@ -54,6 +60,7 @@ fun box(): String { val list7 = ArrayList() for (i in (5.0.toFloat() downTo 3.0.toFloat()).reversed()) { list7.add(i) + if (list7.size() > 23) break } if (list7 != listOf(3.0, 4.0, 5.0)) { return "Wrong elements for (5.0.toFloat() downTo 3.0.toFloat()).reversed(): $list7" diff --git a/compiler/testData/codegen/boxWithStdlib/ranges/literal/reversedEmptyBackSequence.kt b/compiler/testData/codegen/boxWithStdlib/ranges/literal/reversedEmptyBackSequence.kt index 6bd4d10e2a9..4e1ef059cba 100644 --- a/compiler/testData/codegen/boxWithStdlib/ranges/literal/reversedEmptyBackSequence.kt +++ b/compiler/testData/codegen/boxWithStdlib/ranges/literal/reversedEmptyBackSequence.kt @@ -6,6 +6,7 @@ fun box(): String { val list1 = ArrayList() for (i in (3 downTo 5).reversed()) { list1.add(i) + if (list1.size() > 23) break } if (list1 != listOf()) { return "Wrong elements for (3 downTo 5).reversed(): $list1" @@ -14,6 +15,7 @@ fun box(): String { val list2 = ArrayList() for (i in (3.toByte() downTo 5.toByte()).reversed()) { list2.add(i) + if (list2.size() > 23) break } if (list2 != listOf()) { return "Wrong elements for (3.toByte() downTo 5.toByte()).reversed(): $list2" @@ -22,6 +24,7 @@ fun box(): String { val list3 = ArrayList() for (i in (3.toShort() downTo 5.toShort()).reversed()) { list3.add(i) + if (list3.size() > 23) break } if (list3 != listOf()) { return "Wrong elements for (3.toShort() downTo 5.toShort()).reversed(): $list3" @@ -30,6 +33,7 @@ fun box(): String { val list4 = ArrayList() for (i in (3.toLong() downTo 5.toLong()).reversed()) { list4.add(i) + if (list4.size() > 23) break } if (list4 != listOf()) { return "Wrong elements for (3.toLong() downTo 5.toLong()).reversed(): $list4" @@ -38,6 +42,7 @@ fun box(): String { val list5 = ArrayList() for (i in ('a' downTo 'c').reversed()) { list5.add(i) + if (list5.size() > 23) break } if (list5 != listOf()) { return "Wrong elements for ('a' downTo 'c').reversed(): $list5" @@ -46,6 +51,7 @@ fun box(): String { val list6 = ArrayList() for (i in (3.0 downTo 5.0).reversed()) { list6.add(i) + if (list6.size() > 23) break } if (list6 != listOf()) { return "Wrong elements for (3.0 downTo 5.0).reversed(): $list6" @@ -54,6 +60,7 @@ fun box(): String { val list7 = ArrayList() for (i in (3.0.toFloat() downTo 5.0.toFloat()).reversed()) { list7.add(i) + if (list7.size() > 23) break } if (list7 != listOf()) { return "Wrong elements for (3.0.toFloat() downTo 5.0.toFloat()).reversed(): $list7" diff --git a/compiler/testData/codegen/boxWithStdlib/ranges/literal/reversedEmptyRange.kt b/compiler/testData/codegen/boxWithStdlib/ranges/literal/reversedEmptyRange.kt index dbbb6ef61e3..4553fa88299 100644 --- a/compiler/testData/codegen/boxWithStdlib/ranges/literal/reversedEmptyRange.kt +++ b/compiler/testData/codegen/boxWithStdlib/ranges/literal/reversedEmptyRange.kt @@ -6,6 +6,7 @@ fun box(): String { val list1 = ArrayList() for (i in (5..3).reversed()) { list1.add(i) + if (list1.size() > 23) break } if (list1 != listOf()) { return "Wrong elements for (5..3).reversed(): $list1" @@ -14,6 +15,7 @@ fun box(): String { val list2 = ArrayList() for (i in (5.toByte()..3.toByte()).reversed()) { list2.add(i) + if (list2.size() > 23) break } if (list2 != listOf()) { return "Wrong elements for (5.toByte()..3.toByte()).reversed(): $list2" @@ -22,6 +24,7 @@ fun box(): String { val list3 = ArrayList() for (i in (5.toShort()..3.toShort()).reversed()) { list3.add(i) + if (list3.size() > 23) break } if (list3 != listOf()) { return "Wrong elements for (5.toShort()..3.toShort()).reversed(): $list3" @@ -30,6 +33,7 @@ fun box(): String { val list4 = ArrayList() for (i in (5.toLong()..3.toLong()).reversed()) { list4.add(i) + if (list4.size() > 23) break } if (list4 != listOf()) { return "Wrong elements for (5.toLong()..3.toLong()).reversed(): $list4" @@ -38,6 +42,7 @@ fun box(): String { val list5 = ArrayList() for (i in ('c'..'a').reversed()) { list5.add(i) + if (list5.size() > 23) break } if (list5 != listOf()) { return "Wrong elements for ('c'..'a').reversed(): $list5" @@ -46,6 +51,7 @@ fun box(): String { val list6 = ArrayList() for (i in (5.0..3.0).reversed()) { list6.add(i) + if (list6.size() > 23) break } if (list6 != listOf()) { return "Wrong elements for (5.0..3.0).reversed(): $list6" @@ -54,6 +60,7 @@ fun box(): String { val list7 = ArrayList() for (i in (5.0.toFloat()..3.0.toFloat()).reversed()) { list7.add(i) + if (list7.size() > 23) break } if (list7 != listOf()) { return "Wrong elements for (5.0.toFloat()..3.0.toFloat()).reversed(): $list7" diff --git a/compiler/testData/codegen/boxWithStdlib/ranges/literal/reversedInexactSteppedDownTo.kt b/compiler/testData/codegen/boxWithStdlib/ranges/literal/reversedInexactSteppedDownTo.kt index 71252cbf93e..b3c7b83a6b4 100644 --- a/compiler/testData/codegen/boxWithStdlib/ranges/literal/reversedInexactSteppedDownTo.kt +++ b/compiler/testData/codegen/boxWithStdlib/ranges/literal/reversedInexactSteppedDownTo.kt @@ -6,6 +6,7 @@ fun box(): String { val list1 = ArrayList() for (i in (8 downTo 3 step 2).reversed()) { list1.add(i) + if (list1.size() > 23) break } if (list1 != listOf(3, 5, 7)) { return "Wrong elements for (8 downTo 3 step 2).reversed(): $list1" @@ -14,6 +15,7 @@ fun box(): String { val list2 = ArrayList() for (i in (8.toByte() downTo 3.toByte() step 2).reversed()) { list2.add(i) + if (list2.size() > 23) break } if (list2 != listOf(3, 5, 7)) { return "Wrong elements for (8.toByte() downTo 3.toByte() step 2).reversed(): $list2" @@ -22,6 +24,7 @@ fun box(): String { val list3 = ArrayList() for (i in (8.toShort() downTo 3.toShort() step 2).reversed()) { list3.add(i) + if (list3.size() > 23) break } if (list3 != listOf(3, 5, 7)) { return "Wrong elements for (8.toShort() downTo 3.toShort() step 2).reversed(): $list3" @@ -30,6 +33,7 @@ fun box(): String { val list4 = ArrayList() for (i in (8.toLong() downTo 3.toLong() step 2.toLong()).reversed()) { list4.add(i) + if (list4.size() > 23) break } if (list4 != listOf(3, 5, 7)) { return "Wrong elements for (8.toLong() downTo 3.toLong() step 2.toLong()).reversed(): $list4" @@ -38,6 +42,7 @@ fun box(): String { val list5 = ArrayList() for (i in ('d' downTo 'a' step 2).reversed()) { list5.add(i) + if (list5.size() > 23) break } if (list5 != listOf('a', 'c')) { return "Wrong elements for ('d' downTo 'a' step 2).reversed(): $list5" @@ -46,6 +51,7 @@ fun box(): String { val list6 = ArrayList() for (i in (5.8 downTo 4.0 step 0.5).reversed()) { list6.add(i) + if (list6.size() > 23) break } if (list6 != listOf(4.0, 4.5, 5.0, 5.5)) { return "Wrong elements for (5.8 downTo 4.0 step 0.5).reversed(): $list6" @@ -54,6 +60,7 @@ fun box(): String { val list7 = ArrayList() for (i in (5.8.toFloat() downTo 4.0.toFloat() step 0.5).reversed()) { list7.add(i) + if (list7.size() > 23) break } if (list7 != listOf(4.0, 4.5, 5.0, 5.5)) { return "Wrong elements for (5.8.toFloat() downTo 4.0.toFloat() step 0.5).reversed(): $list7" diff --git a/compiler/testData/codegen/boxWithStdlib/ranges/literal/reversedRange.kt b/compiler/testData/codegen/boxWithStdlib/ranges/literal/reversedRange.kt index af36f4fc816..1aa39786688 100644 --- a/compiler/testData/codegen/boxWithStdlib/ranges/literal/reversedRange.kt +++ b/compiler/testData/codegen/boxWithStdlib/ranges/literal/reversedRange.kt @@ -6,6 +6,7 @@ fun box(): String { val list1 = ArrayList() for (i in (3..5).reversed()) { list1.add(i) + if (list1.size() > 23) break } if (list1 != listOf(5, 4, 3)) { return "Wrong elements for (3..5).reversed(): $list1" @@ -14,6 +15,7 @@ fun box(): String { val list2 = ArrayList() for (i in (3.toByte()..5.toByte()).reversed()) { list2.add(i) + if (list2.size() > 23) break } if (list2 != listOf(5, 4, 3)) { return "Wrong elements for (3.toByte()..5.toByte()).reversed(): $list2" @@ -22,6 +24,7 @@ fun box(): String { val list3 = ArrayList() for (i in (3.toShort()..5.toShort()).reversed()) { list3.add(i) + if (list3.size() > 23) break } if (list3 != listOf(5, 4, 3)) { return "Wrong elements for (3.toShort()..5.toShort()).reversed(): $list3" @@ -30,6 +33,7 @@ fun box(): String { val list4 = ArrayList() for (i in (3.toLong()..5.toLong()).reversed()) { list4.add(i) + if (list4.size() > 23) break } if (list4 != listOf(5, 4, 3)) { return "Wrong elements for (3.toLong()..5.toLong()).reversed(): $list4" @@ -38,6 +42,7 @@ fun box(): String { val list5 = ArrayList() for (i in ('a'..'c').reversed()) { list5.add(i) + if (list5.size() > 23) break } if (list5 != listOf('c', 'b', 'a')) { return "Wrong elements for ('a'..'c').reversed(): $list5" @@ -46,6 +51,7 @@ fun box(): String { val list6 = ArrayList() for (i in (3.0..5.0).reversed()) { list6.add(i) + if (list6.size() > 23) break } if (list6 != listOf(5.0, 4.0, 3.0)) { return "Wrong elements for (3.0..5.0).reversed(): $list6" @@ -54,6 +60,7 @@ fun box(): String { val list7 = ArrayList() for (i in (3.0.toFloat()..5.0.toFloat()).reversed()) { list7.add(i) + if (list7.size() > 23) break } if (list7 != listOf(5.0, 4.0, 3.0)) { return "Wrong elements for (3.0.toFloat()..5.0.toFloat()).reversed(): $list7" diff --git a/compiler/testData/codegen/boxWithStdlib/ranges/literal/reversedSimpleSteppedRange.kt b/compiler/testData/codegen/boxWithStdlib/ranges/literal/reversedSimpleSteppedRange.kt index 8c27f607f35..9a66ec1025e 100644 --- a/compiler/testData/codegen/boxWithStdlib/ranges/literal/reversedSimpleSteppedRange.kt +++ b/compiler/testData/codegen/boxWithStdlib/ranges/literal/reversedSimpleSteppedRange.kt @@ -6,6 +6,7 @@ fun box(): String { val list1 = ArrayList() for (i in (3..9 step 2).reversed()) { list1.add(i) + if (list1.size() > 23) break } if (list1 != listOf(9, 7, 5, 3)) { return "Wrong elements for (3..9 step 2).reversed(): $list1" @@ -14,6 +15,7 @@ fun box(): String { val list2 = ArrayList() for (i in (3.toByte()..9.toByte() step 2).reversed()) { list2.add(i) + if (list2.size() > 23) break } if (list2 != listOf(9, 7, 5, 3)) { return "Wrong elements for (3.toByte()..9.toByte() step 2).reversed(): $list2" @@ -22,6 +24,7 @@ fun box(): String { val list3 = ArrayList() for (i in (3.toShort()..9.toShort() step 2).reversed()) { list3.add(i) + if (list3.size() > 23) break } if (list3 != listOf(9, 7, 5, 3)) { return "Wrong elements for (3.toShort()..9.toShort() step 2).reversed(): $list3" @@ -30,6 +33,7 @@ fun box(): String { val list4 = ArrayList() for (i in (3.toLong()..9.toLong() step 2.toLong()).reversed()) { list4.add(i) + if (list4.size() > 23) break } if (list4 != listOf(9, 7, 5, 3)) { return "Wrong elements for (3.toLong()..9.toLong() step 2.toLong()).reversed(): $list4" @@ -38,6 +42,7 @@ fun box(): String { val list5 = ArrayList() for (i in ('c'..'g' step 2).reversed()) { list5.add(i) + if (list5.size() > 23) break } if (list5 != listOf('g', 'e', 'c')) { return "Wrong elements for ('c'..'g' step 2).reversed(): $list5" @@ -46,6 +51,7 @@ fun box(): String { val list6 = ArrayList() for (i in (4.0..6.0 step 0.5).reversed()) { list6.add(i) + if (list6.size() > 23) break } if (list6 != listOf(6.0, 5.5, 5.0, 4.5, 4.0)) { return "Wrong elements for (4.0..6.0 step 0.5).reversed(): $list6" @@ -54,6 +60,7 @@ fun box(): String { val list7 = ArrayList() for (i in (4.0.toFloat()..6.0.toFloat() step 0.5).reversed()) { list7.add(i) + if (list7.size() > 23) break } if (list7 != listOf(6.0, 5.5, 5.0, 4.5, 4.0)) { return "Wrong elements for (4.0.toFloat()..6.0.toFloat() step 0.5).reversed(): $list7" diff --git a/compiler/testData/codegen/boxWithStdlib/ranges/literal/simpleDownTo.kt b/compiler/testData/codegen/boxWithStdlib/ranges/literal/simpleDownTo.kt index 64a28d75a93..1683b877b1f 100644 --- a/compiler/testData/codegen/boxWithStdlib/ranges/literal/simpleDownTo.kt +++ b/compiler/testData/codegen/boxWithStdlib/ranges/literal/simpleDownTo.kt @@ -6,6 +6,7 @@ fun box(): String { val list1 = ArrayList() for (i in 9 downTo 3) { list1.add(i) + if (list1.size() > 23) break } if (list1 != listOf(9, 8, 7, 6, 5, 4, 3)) { return "Wrong elements for 9 downTo 3: $list1" @@ -14,6 +15,7 @@ fun box(): String { val list2 = ArrayList() for (i in 9.toByte() downTo 3.toByte()) { list2.add(i) + if (list2.size() > 23) break } if (list2 != listOf(9, 8, 7, 6, 5, 4, 3)) { return "Wrong elements for 9.toByte() downTo 3.toByte(): $list2" @@ -22,6 +24,7 @@ fun box(): String { val list3 = ArrayList() for (i in 9.toShort() downTo 3.toShort()) { list3.add(i) + if (list3.size() > 23) break } if (list3 != listOf(9, 8, 7, 6, 5, 4, 3)) { return "Wrong elements for 9.toShort() downTo 3.toShort(): $list3" @@ -30,6 +33,7 @@ fun box(): String { val list4 = ArrayList() for (i in 9.toLong() downTo 3.toLong()) { list4.add(i) + if (list4.size() > 23) break } if (list4 != listOf(9, 8, 7, 6, 5, 4, 3)) { return "Wrong elements for 9.toLong() downTo 3.toLong(): $list4" @@ -38,6 +42,7 @@ fun box(): String { val list5 = ArrayList() for (i in 'g' downTo 'c') { list5.add(i) + if (list5.size() > 23) break } if (list5 != listOf('g', 'f', 'e', 'd', 'c')) { return "Wrong elements for 'g' downTo 'c': $list5" @@ -46,6 +51,7 @@ fun box(): String { val list6 = ArrayList() for (i in 9.0 downTo 3.0) { list6.add(i) + if (list6.size() > 23) break } if (list6 != listOf(9.0, 8.0, 7.0, 6.0, 5.0, 4.0, 3.0)) { return "Wrong elements for 9.0 downTo 3.0: $list6" @@ -54,6 +60,7 @@ fun box(): String { val list7 = ArrayList() for (i in 9.0.toFloat() downTo 3.0.toFloat()) { list7.add(i) + if (list7.size() > 23) break } if (list7 != listOf(9.0, 8.0, 7.0, 6.0, 5.0, 4.0, 3.0)) { return "Wrong elements for 9.0.toFloat() downTo 3.0.toFloat(): $list7" diff --git a/compiler/testData/codegen/boxWithStdlib/ranges/literal/simpleRange.kt b/compiler/testData/codegen/boxWithStdlib/ranges/literal/simpleRange.kt index 3efabe43227..610b9842f99 100644 --- a/compiler/testData/codegen/boxWithStdlib/ranges/literal/simpleRange.kt +++ b/compiler/testData/codegen/boxWithStdlib/ranges/literal/simpleRange.kt @@ -6,6 +6,7 @@ fun box(): String { val list1 = ArrayList() for (i in 3..9) { list1.add(i) + if (list1.size() > 23) break } if (list1 != listOf(3, 4, 5, 6, 7, 8, 9)) { return "Wrong elements for 3..9: $list1" @@ -14,6 +15,7 @@ fun box(): String { val list2 = ArrayList() for (i in 3.toByte()..9.toByte()) { list2.add(i) + if (list2.size() > 23) break } if (list2 != listOf(3, 4, 5, 6, 7, 8, 9)) { return "Wrong elements for 3.toByte()..9.toByte(): $list2" @@ -22,6 +24,7 @@ fun box(): String { val list3 = ArrayList() for (i in 3.toShort()..9.toShort()) { list3.add(i) + if (list3.size() > 23) break } if (list3 != listOf(3, 4, 5, 6, 7, 8, 9)) { return "Wrong elements for 3.toShort()..9.toShort(): $list3" @@ -30,6 +33,7 @@ fun box(): String { val list4 = ArrayList() for (i in 3.toLong()..9.toLong()) { list4.add(i) + if (list4.size() > 23) break } if (list4 != listOf(3, 4, 5, 6, 7, 8, 9)) { return "Wrong elements for 3.toLong()..9.toLong(): $list4" @@ -38,6 +42,7 @@ fun box(): String { val list5 = ArrayList() for (i in 'c'..'g') { list5.add(i) + if (list5.size() > 23) break } if (list5 != listOf('c', 'd', 'e', 'f', 'g')) { return "Wrong elements for 'c'..'g': $list5" @@ -46,6 +51,7 @@ fun box(): String { val list6 = ArrayList() for (i in 3.0..9.0) { list6.add(i) + if (list6.size() > 23) break } if (list6 != listOf(3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0)) { return "Wrong elements for 3.0..9.0: $list6" @@ -54,6 +60,7 @@ fun box(): String { val list7 = ArrayList() for (i in 3.0.toFloat()..9.0.toFloat()) { list7.add(i) + if (list7.size() > 23) break } if (list7 != listOf(3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0)) { return "Wrong elements for 3.0.toFloat()..9.0.toFloat(): $list7" diff --git a/compiler/testData/codegen/boxWithStdlib/ranges/literal/simpleRangeWithNonConstantEnds.kt b/compiler/testData/codegen/boxWithStdlib/ranges/literal/simpleRangeWithNonConstantEnds.kt index d26272d298e..f8348b94ef3 100644 --- a/compiler/testData/codegen/boxWithStdlib/ranges/literal/simpleRangeWithNonConstantEnds.kt +++ b/compiler/testData/codegen/boxWithStdlib/ranges/literal/simpleRangeWithNonConstantEnds.kt @@ -6,6 +6,7 @@ fun box(): String { val list1 = ArrayList() for (i in (1 + 2)..(10 - 1)) { list1.add(i) + if (list1.size() > 23) break } if (list1 != listOf(3, 4, 5, 6, 7, 8, 9)) { return "Wrong elements for (1 + 2)..(10 - 1): $list1" @@ -14,6 +15,7 @@ fun box(): String { val list2 = ArrayList() for (i in (1.toByte() + 2.toByte()).toByte()..(10.toByte() - 1.toByte()).toByte()) { list2.add(i) + if (list2.size() > 23) break } if (list2 != listOf(3, 4, 5, 6, 7, 8, 9)) { return "Wrong elements for (1.toByte() + 2.toByte()).toByte()..(10.toByte() - 1.toByte()).toByte(): $list2" @@ -22,6 +24,7 @@ fun box(): String { val list3 = ArrayList() for (i in (1.toShort() + 2.toShort()).toShort()..(10.toShort() - 1.toShort()).toShort()) { list3.add(i) + if (list3.size() > 23) break } if (list3 != listOf(3, 4, 5, 6, 7, 8, 9)) { return "Wrong elements for (1.toShort() + 2.toShort()).toShort()..(10.toShort() - 1.toShort()).toShort(): $list3" @@ -30,6 +33,7 @@ fun box(): String { val list4 = ArrayList() for (i in (1.toLong() + 2.toLong())..(10.toLong() - 1.toLong())) { list4.add(i) + if (list4.size() > 23) break } if (list4 != listOf(3, 4, 5, 6, 7, 8, 9)) { return "Wrong elements for (1.toLong() + 2.toLong())..(10.toLong() - 1.toLong()): $list4" @@ -38,6 +42,7 @@ fun box(): String { val list5 = ArrayList() for (i in ("ace"[1])..("age"[1])) { list5.add(i) + if (list5.size() > 23) break } if (list5 != listOf('c', 'd', 'e', 'f', 'g')) { return "Wrong elements for (\"ace\"[1])..(\"age\"[1]): $list5" @@ -46,6 +51,7 @@ fun box(): String { val list6 = ArrayList() for (i in (1.5 * 2)..(3.0 * 3.0)) { list6.add(i) + if (list6.size() > 23) break } if (list6 != listOf(3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0)) { return "Wrong elements for (1.5 * 2)..(3.0 * 3.0): $list6" @@ -54,6 +60,7 @@ fun box(): String { val list7 = ArrayList() for (i in (1.5.toFloat() * 2.toFloat())..(3.0.toFloat() * 3.0.toFloat())) { list7.add(i) + if (list7.size() > 23) break } if (list7 != listOf(3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0)) { return "Wrong elements for (1.5.toFloat() * 2.toFloat())..(3.0.toFloat() * 3.0.toFloat()): $list7" diff --git a/compiler/testData/codegen/boxWithStdlib/ranges/literal/simpleSteppedDownTo.kt b/compiler/testData/codegen/boxWithStdlib/ranges/literal/simpleSteppedDownTo.kt index 1546b1a4c60..f769365351d 100644 --- a/compiler/testData/codegen/boxWithStdlib/ranges/literal/simpleSteppedDownTo.kt +++ b/compiler/testData/codegen/boxWithStdlib/ranges/literal/simpleSteppedDownTo.kt @@ -6,6 +6,7 @@ fun box(): String { val list1 = ArrayList() for (i in 9 downTo 3 step 2) { list1.add(i) + if (list1.size() > 23) break } if (list1 != listOf(9, 7, 5, 3)) { return "Wrong elements for 9 downTo 3 step 2: $list1" @@ -14,6 +15,7 @@ fun box(): String { val list2 = ArrayList() for (i in 9.toByte() downTo 3.toByte() step 2) { list2.add(i) + if (list2.size() > 23) break } if (list2 != listOf(9, 7, 5, 3)) { return "Wrong elements for 9.toByte() downTo 3.toByte() step 2: $list2" @@ -22,6 +24,7 @@ fun box(): String { val list3 = ArrayList() for (i in 9.toShort() downTo 3.toShort() step 2) { list3.add(i) + if (list3.size() > 23) break } if (list3 != listOf(9, 7, 5, 3)) { return "Wrong elements for 9.toShort() downTo 3.toShort() step 2: $list3" @@ -30,6 +33,7 @@ fun box(): String { val list4 = ArrayList() for (i in 9.toLong() downTo 3.toLong() step 2.toLong()) { list4.add(i) + if (list4.size() > 23) break } if (list4 != listOf(9, 7, 5, 3)) { return "Wrong elements for 9.toLong() downTo 3.toLong() step 2.toLong(): $list4" @@ -38,6 +42,7 @@ fun box(): String { val list5 = ArrayList() for (i in 'g' downTo 'c' step 2) { list5.add(i) + if (list5.size() > 23) break } if (list5 != listOf('g', 'e', 'c')) { return "Wrong elements for 'g' downTo 'c' step 2: $list5" @@ -46,6 +51,7 @@ fun box(): String { val list6 = ArrayList() for (i in 6.0 downTo 4.0 step 0.5) { list6.add(i) + if (list6.size() > 23) break } if (list6 != listOf(6.0, 5.5, 5.0, 4.5, 4.0)) { return "Wrong elements for 6.0 downTo 4.0 step 0.5: $list6" @@ -54,6 +60,7 @@ fun box(): String { val list7 = ArrayList() for (i in 6.0.toFloat() downTo 4.0.toFloat() step 0.5.toFloat()) { list7.add(i) + if (list7.size() > 23) break } if (list7 != listOf(6.0, 5.5, 5.0, 4.5, 4.0)) { return "Wrong elements for 6.0.toFloat() downTo 4.0.toFloat() step 0.5.toFloat(): $list7" diff --git a/compiler/testData/codegen/boxWithStdlib/ranges/literal/simpleSteppedRange.kt b/compiler/testData/codegen/boxWithStdlib/ranges/literal/simpleSteppedRange.kt index 9374e456f4e..8c0a921f561 100644 --- a/compiler/testData/codegen/boxWithStdlib/ranges/literal/simpleSteppedRange.kt +++ b/compiler/testData/codegen/boxWithStdlib/ranges/literal/simpleSteppedRange.kt @@ -6,6 +6,7 @@ fun box(): String { val list1 = ArrayList() for (i in 3..9 step 2) { list1.add(i) + if (list1.size() > 23) break } if (list1 != listOf(3, 5, 7, 9)) { return "Wrong elements for 3..9 step 2: $list1" @@ -14,6 +15,7 @@ fun box(): String { val list2 = ArrayList() for (i in 3.toByte()..9.toByte() step 2) { list2.add(i) + if (list2.size() > 23) break } if (list2 != listOf(3, 5, 7, 9)) { return "Wrong elements for 3.toByte()..9.toByte() step 2: $list2" @@ -22,6 +24,7 @@ fun box(): String { val list3 = ArrayList() for (i in 3.toShort()..9.toShort() step 2) { list3.add(i) + if (list3.size() > 23) break } if (list3 != listOf(3, 5, 7, 9)) { return "Wrong elements for 3.toShort()..9.toShort() step 2: $list3" @@ -30,6 +33,7 @@ fun box(): String { val list4 = ArrayList() for (i in 3.toLong()..9.toLong() step 2.toLong()) { list4.add(i) + if (list4.size() > 23) break } if (list4 != listOf(3, 5, 7, 9)) { return "Wrong elements for 3.toLong()..9.toLong() step 2.toLong(): $list4" @@ -38,6 +42,7 @@ fun box(): String { val list5 = ArrayList() for (i in 'c'..'g' step 2) { list5.add(i) + if (list5.size() > 23) break } if (list5 != listOf('c', 'e', 'g')) { return "Wrong elements for 'c'..'g' step 2: $list5" @@ -46,6 +51,7 @@ fun box(): String { val list6 = ArrayList() for (i in 4.0..6.0 step 0.5) { list6.add(i) + if (list6.size() > 23) break } if (list6 != listOf(4.0, 4.5, 5.0, 5.5, 6.0)) { return "Wrong elements for 4.0..6.0 step 0.5: $list6" @@ -54,6 +60,7 @@ fun box(): String { val list7 = ArrayList() for (i in 4.0.toFloat()..6.0.toFloat() step 0.5.toFloat()) { list7.add(i) + if (list7.size() > 23) break } if (list7 != listOf(4.0, 4.5, 5.0, 5.5, 6.0)) { return "Wrong elements for 4.0.toFloat()..6.0.toFloat() step 0.5.toFloat(): $list7" diff --git a/generators/org/jetbrains/jet/generators/tests/GenerateRangesCodegenTestData.java b/generators/org/jetbrains/jet/generators/tests/GenerateRangesCodegenTestData.java index 2f5564e6e45..94809600e8a 100644 --- a/generators/org/jetbrains/jet/generators/tests/GenerateRangesCodegenTestData.java +++ b/generators/org/jetbrains/jet/generators/tests/GenerateRangesCodegenTestData.java @@ -36,9 +36,11 @@ public class GenerateRangesCodegenTestData { private static final Pattern TEST_FUN_PATTERN = Pattern.compile("test fun (\\w+)\\(\\) \\{.+?}", Pattern.DOTALL); private static final Pattern SUBTEST_INVOCATION_PATTERN = Pattern.compile("doTest\\(([^,]+), [^,]+, [^,]+, [^,]+,\\s+listOf[\\w<>]*\\(([^\\n]*)\\)\\)", Pattern.DOTALL); + // $LIST.size() check is needed in order for tests not to run forever public static final String LITERAL_TEMPLATE = " val $LIST = ArrayList<$TYPE>()\n" + " for (i in $RANGE_EXPR) {\n" + " $LIST.add(i)\n" + + " if ($LIST.size() > 23) break\n" + " }\n" + " if ($LIST != listOf<$TYPE>($LIST_ELEMENTS)) {\n" + " return \"Wrong elements for $RANGE_EXPR_ESCAPED: $$LIST\"\n" + @@ -49,6 +51,7 @@ public class GenerateRangesCodegenTestData { " val $RANGE = $RANGE_EXPR\n" + " for (i in $RANGE) {\n" + " $LIST.add(i)\n" + + " if ($LIST.size() > 23) break\n" + " }\n" + " if ($LIST != listOf<$TYPE>($LIST_ELEMENTS)) {\n" + " return \"Wrong elements for $RANGE_EXPR_ESCAPED: $$LIST\"\n" + From 33d6347876d9d0ac73f5b2c47591c2930b0cfa16 Mon Sep 17 00:00:00 2001 From: Alexander Udalov Date: Mon, 17 Jun 2013 21:47:41 +0400 Subject: [PATCH 163/291] Fix loop over a range literal up to MAX_VALUE #KT-492 In Progress For Byte, Char and Short explicit casting from Int is removed -- loop parameter is already stored in an Int anyway. For Int and Long comparison "i < end" at the beginning of the loop is replaced to "i != end" at the end of the loop + a special check for an empty loop --- .../jet/codegen/ExpressionCodegen.java | 86 +++++++++++++++---- .../expression/maxValueMinusTwoToMaxValue.kt | 68 +++++++++++++++ .../ranges/expression/maxValueToMaxValue.kt | 68 +++++++++++++++ .../ranges/expression/maxValueToMinValue.kt | 68 +++++++++++++++ .../literal/maxValueMinusTwoToMaxValue.kt | 63 ++++++++++++++ .../ranges/literal/maxValueToMaxValue.kt | 63 ++++++++++++++ .../ranges/literal/maxValueToMinValue.kt | 63 ++++++++++++++ ...lackBoxWithStdlibCodegenTestGenerated.java | 30 +++++++ .../tests/GenerateRangesCodegenTestData.java | 43 +++++++--- .../test/language/RangeIterationTest.kt | 40 ++++++++- 10 files changed, 561 insertions(+), 31 deletions(-) create mode 100644 compiler/testData/codegen/boxWithStdlib/ranges/expression/maxValueMinusTwoToMaxValue.kt create mode 100644 compiler/testData/codegen/boxWithStdlib/ranges/expression/maxValueToMaxValue.kt create mode 100644 compiler/testData/codegen/boxWithStdlib/ranges/expression/maxValueToMinValue.kt create mode 100644 compiler/testData/codegen/boxWithStdlib/ranges/literal/maxValueMinusTwoToMaxValue.kt create mode 100644 compiler/testData/codegen/boxWithStdlib/ranges/literal/maxValueToMaxValue.kt create mode 100644 compiler/testData/codegen/boxWithStdlib/ranges/literal/maxValueToMinValue.kt diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java index 41d1dd24b84..1ae21c4ccd2 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java @@ -509,6 +509,7 @@ public class ExpressionCodegen extends JetVisitor implem Label continueLabel = new Label(); generator.beforeLoop(); + generator.checkEmptyLoop(loopExit); v.mark(loopEntry); generator.conditionAndJump(loopExit); @@ -518,7 +519,7 @@ public class ExpressionCodegen extends JetVisitor implem generator.body(); blockStackElements.pop(); v.mark(continueLabel); - generator.afterBody(); + generator.afterBody(loopExit); v.goTo(loopEntry); @@ -583,6 +584,8 @@ public class ExpressionCodegen extends JetVisitor implem } } + public abstract void checkEmptyLoop(@NotNull Label loopExit); + public abstract void conditionAndJump(@NotNull Label loopExit); public void beforeBody() { @@ -628,7 +631,7 @@ public class ExpressionCodegen extends JetVisitor implem protected abstract void assignToLoopParameter(); - protected abstract void increment(); + protected abstract void increment(@NotNull Label loopExit); public void body() { gen(forExpression.getBody(), Type.VOID_TYPE); @@ -649,8 +652,8 @@ public class ExpressionCodegen extends JetVisitor implem return varIndex; } - public void afterBody() { - increment(); + public void afterBody(@NotNull Label loopExit) { + increment(loopExit); v.mark(bodyEnd); } @@ -712,6 +715,10 @@ public class ExpressionCodegen extends JetVisitor implem v.store(iteratorVarIndex, asmTypeForIterator); } + @Override + public void checkEmptyLoop(@NotNull Label loopExit) { + } + @Override public void conditionAndJump(@NotNull Label loopExit) { // tmp.hasNext() @@ -741,7 +748,7 @@ public class ExpressionCodegen extends JetVisitor implem } @Override - protected void increment() { + protected void increment(@NotNull Label loopExit) { } } @@ -777,6 +784,10 @@ public class ExpressionCodegen extends JetVisitor implem v.store(indexVar, Type.INT_TYPE); } + @Override + public void checkEmptyLoop(@NotNull Label loopExit) { + } + @Override public void conditionAndJump(@NotNull Label loopExit) { v.load(indexVar, Type.INT_TYPE); @@ -803,7 +814,7 @@ public class ExpressionCodegen extends JetVisitor implem } @Override - protected void increment() { + protected void increment(@NotNull Label loopExit) { v.iinc(indexVar, 1); } } @@ -811,8 +822,13 @@ public class ExpressionCodegen extends JetVisitor implem private abstract class AbstractForInRangeLoopGenerator extends AbstractForLoopGenerator { protected int endVar; + // True iff instead of comparing loopParameterVar < endVar at the beginning of an iteration we check whether + // loopParameterVar == endVar at the end of the iteration (and also if there should be any iterations at all, before the loop) + private final boolean checkEqualityInsteadOfComparison; + private AbstractForInRangeLoopGenerator(@NotNull JetForExpression forExpression) { super(forExpression); + checkEqualityInsteadOfComparison = asmElementType.getSort() == Type.INT || asmElementType.getSort() == Type.LONG; } @Override @@ -823,27 +839,41 @@ public class ExpressionCodegen extends JetVisitor implem storeRangeStartAndEnd(); } + @Override + public void checkEmptyLoop(@NotNull Label loopExit) { + if (!checkEqualityInsteadOfComparison) return; + + v.load(loopParameterVar, asmElementType); + v.load(endVar, asmElementType); + if (asmElementType.getSort() == Type.INT) { + v.ificmpgt(loopExit); + } + else if (asmElementType.getSort() == Type.LONG) { + v.lcmp(); + v.ifgt(loopExit); + } + else { + throw new IllegalStateException("Unexpected type for empty loop checking: " + asmElementType); + } + } + protected abstract void storeRangeStartAndEnd(); @Override public void conditionAndJump(@NotNull Label loopExit) { + if (checkEqualityInsteadOfComparison) return; + v.load(loopParameterVar, asmElementType); v.load(endVar, asmElementType); int sort = asmElementType.getSort(); switch (sort) { - case Type.INT: case Type.CHAR: case Type.BYTE: case Type.SHORT: v.ificmpgt(loopExit); break; - case Type.LONG: - v.lcmp(); - v.ifgt(loopExit); - break; - case Type.FLOAT: case Type.DOUBLE: v.cmpg(asmElementType); @@ -859,8 +889,27 @@ public class ExpressionCodegen extends JetVisitor implem protected void assignToLoopParameter() { } + private void checkPostCondition(@NotNull Label loopExit) { + v.load(loopParameterVar, asmElementType); + v.load(endVar, asmElementType); + if (asmElementType.getSort() == Type.INT) { + v.ificmpeq(loopExit); + } + else if (asmElementType.getSort() == Type.LONG) { + v.lcmp(); + v.ifeq(loopExit); + } + else { + throw new IllegalStateException("Unexpected type for equality: " + asmElementType); + } + } + @Override - protected void increment() { + protected void increment(@NotNull Label loopExit) { + if (checkEqualityInsteadOfComparison) { + checkPostCondition(loopExit); + } + int sort = asmElementType.getSort(); switch (sort) { case Type.INT: @@ -868,11 +917,6 @@ public class ExpressionCodegen extends JetVisitor implem case Type.BYTE: case Type.SHORT: v.iinc(loopParameterVar, 1); - if (sort != Type.INT) { - v.load(loopParameterVar, Type.INT_TYPE); - StackValue.coerce(Type.INT_TYPE, asmElementType, v); - v.store(loopParameterVar, asmElementType); - } break; case Type.LONG: @@ -973,6 +1017,10 @@ public class ExpressionCodegen extends JetVisitor implem generateRangeOrProgressionProperty(asmLoopRangeType, "getIncrement", incrementType, incrementVar); } + @Override + public void checkEmptyLoop(@NotNull Label loopExit) { + } + @Override public void conditionAndJump(@NotNull Label loopExit) { v.load(loopParameterVar, asmElementType); @@ -1059,7 +1107,7 @@ public class ExpressionCodegen extends JetVisitor implem } @Override - protected void increment() { + protected void increment(@NotNull Label loopExit) { v.load(loopParameterVar, asmElementType); v.load(incrementVar, asmElementType); diff --git a/compiler/testData/codegen/boxWithStdlib/ranges/expression/maxValueMinusTwoToMaxValue.kt b/compiler/testData/codegen/boxWithStdlib/ranges/expression/maxValueMinusTwoToMaxValue.kt new file mode 100644 index 00000000000..ddca33a8b2c --- /dev/null +++ b/compiler/testData/codegen/boxWithStdlib/ranges/expression/maxValueMinusTwoToMaxValue.kt @@ -0,0 +1,68 @@ +// Auto-generated by org.jetbrains.jet.generators.tests.GenerateRangesCodegenTestData. DO NOT EDIT! +import java.util.ArrayList +import java.lang as j + +import java.lang.Integer.MAX_VALUE as MaxI +import java.lang.Integer.MIN_VALUE as MinI +import java.lang.Byte.MAX_VALUE as MaxB +import java.lang.Byte.MIN_VALUE as MinB +import java.lang.Short.MAX_VALUE as MaxS +import java.lang.Short.MIN_VALUE as MinS +import java.lang.Long.MAX_VALUE as MaxL +import java.lang.Long.MIN_VALUE as MinL +import java.lang.Character.MAX_VALUE as MaxC +import java.lang.Character.MIN_VALUE as MinC + +fun box(): String { + val list1 = ArrayList() + val range1 = (MaxI - 2)..MaxI + for (i in range1) { + list1.add(i) + if (list1.size() > 23) break + } + if (list1 != listOf(MaxI - 2, MaxI - 1, MaxI)) { + return "Wrong elements for (MaxI - 2)..MaxI: $list1" + } + + val list2 = ArrayList() + val range2 = (MaxB - 2).toByte()..MaxB + for (i in range2) { + list2.add(i) + if (list2.size() > 23) break + } + if (list2 != listOf((MaxB - 2).toByte(), (MaxB - 1).toByte(), MaxB)) { + return "Wrong elements for (MaxB - 2).toByte()..MaxB: $list2" + } + + val list3 = ArrayList() + val range3 = (MaxS - 2).toShort()..MaxS + for (i in range3) { + list3.add(i) + if (list3.size() > 23) break + } + if (list3 != listOf((MaxS - 2).toShort(), (MaxS - 1).toShort(), MaxS)) { + return "Wrong elements for (MaxS - 2).toShort()..MaxS: $list3" + } + + val list4 = ArrayList() + val range4 = (MaxL - 2).toLong()..MaxL + for (i in range4) { + list4.add(i) + if (list4.size() > 23) break + } + if (list4 != listOf((MaxL - 2).toLong(), (MaxL - 1).toLong(), MaxL)) { + return "Wrong elements for (MaxL - 2).toLong()..MaxL: $list4" + } + + val list5 = ArrayList() + val range5 = (MaxC - 2).toChar()..MaxC + for (i in range5) { + list5.add(i) + if (list5.size() > 23) break + } + if (list5 != listOf((MaxC - 2).toChar(), (MaxC - 1).toChar(), MaxC)) { + return "Wrong elements for (MaxC - 2).toChar()..MaxC: $list5" + } + + return "OK" +} diff --git a/compiler/testData/codegen/boxWithStdlib/ranges/expression/maxValueToMaxValue.kt b/compiler/testData/codegen/boxWithStdlib/ranges/expression/maxValueToMaxValue.kt new file mode 100644 index 00000000000..0ddb0f8dc26 --- /dev/null +++ b/compiler/testData/codegen/boxWithStdlib/ranges/expression/maxValueToMaxValue.kt @@ -0,0 +1,68 @@ +// Auto-generated by org.jetbrains.jet.generators.tests.GenerateRangesCodegenTestData. DO NOT EDIT! +import java.util.ArrayList +import java.lang as j + +import java.lang.Integer.MAX_VALUE as MaxI +import java.lang.Integer.MIN_VALUE as MinI +import java.lang.Byte.MAX_VALUE as MaxB +import java.lang.Byte.MIN_VALUE as MinB +import java.lang.Short.MAX_VALUE as MaxS +import java.lang.Short.MIN_VALUE as MinS +import java.lang.Long.MAX_VALUE as MaxL +import java.lang.Long.MIN_VALUE as MinL +import java.lang.Character.MAX_VALUE as MaxC +import java.lang.Character.MIN_VALUE as MinC + +fun box(): String { + val list1 = ArrayList() + val range1 = MaxI..MaxI + for (i in range1) { + list1.add(i) + if (list1.size() > 23) break + } + if (list1 != listOf(MaxI)) { + return "Wrong elements for MaxI..MaxI: $list1" + } + + val list2 = ArrayList() + val range2 = MaxB..MaxB + for (i in range2) { + list2.add(i) + if (list2.size() > 23) break + } + if (list2 != listOf(MaxB)) { + return "Wrong elements for MaxB..MaxB: $list2" + } + + val list3 = ArrayList() + val range3 = MaxS..MaxS + for (i in range3) { + list3.add(i) + if (list3.size() > 23) break + } + if (list3 != listOf(MaxS)) { + return "Wrong elements for MaxS..MaxS: $list3" + } + + val list4 = ArrayList() + val range4 = MaxL..MaxL + for (i in range4) { + list4.add(i) + if (list4.size() > 23) break + } + if (list4 != listOf(MaxL)) { + return "Wrong elements for MaxL..MaxL: $list4" + } + + val list5 = ArrayList() + val range5 = MaxC..MaxC + for (i in range5) { + list5.add(i) + if (list5.size() > 23) break + } + if (list5 != listOf(MaxC)) { + return "Wrong elements for MaxC..MaxC: $list5" + } + + return "OK" +} diff --git a/compiler/testData/codegen/boxWithStdlib/ranges/expression/maxValueToMinValue.kt b/compiler/testData/codegen/boxWithStdlib/ranges/expression/maxValueToMinValue.kt new file mode 100644 index 00000000000..42f641c76e8 --- /dev/null +++ b/compiler/testData/codegen/boxWithStdlib/ranges/expression/maxValueToMinValue.kt @@ -0,0 +1,68 @@ +// Auto-generated by org.jetbrains.jet.generators.tests.GenerateRangesCodegenTestData. DO NOT EDIT! +import java.util.ArrayList +import java.lang as j + +import java.lang.Integer.MAX_VALUE as MaxI +import java.lang.Integer.MIN_VALUE as MinI +import java.lang.Byte.MAX_VALUE as MaxB +import java.lang.Byte.MIN_VALUE as MinB +import java.lang.Short.MAX_VALUE as MaxS +import java.lang.Short.MIN_VALUE as MinS +import java.lang.Long.MAX_VALUE as MaxL +import java.lang.Long.MIN_VALUE as MinL +import java.lang.Character.MAX_VALUE as MaxC +import java.lang.Character.MIN_VALUE as MinC + +fun box(): String { + val list1 = ArrayList() + val range1 = MaxI..MinI + for (i in range1) { + list1.add(i) + if (list1.size() > 23) break + } + if (list1 != listOf()) { + return "Wrong elements for MaxI..MinI: $list1" + } + + val list2 = ArrayList() + val range2 = MaxB..MinB + for (i in range2) { + list2.add(i) + if (list2.size() > 23) break + } + if (list2 != listOf()) { + return "Wrong elements for MaxB..MinB: $list2" + } + + val list3 = ArrayList() + val range3 = MaxS..MinS + for (i in range3) { + list3.add(i) + if (list3.size() > 23) break + } + if (list3 != listOf()) { + return "Wrong elements for MaxS..MinS: $list3" + } + + val list4 = ArrayList() + val range4 = MaxL..MinL + for (i in range4) { + list4.add(i) + if (list4.size() > 23) break + } + if (list4 != listOf()) { + return "Wrong elements for MaxL..MinL: $list4" + } + + val list5 = ArrayList() + val range5 = MaxC..MinC + for (i in range5) { + list5.add(i) + if (list5.size() > 23) break + } + if (list5 != listOf()) { + return "Wrong elements for MaxC..MinC: $list5" + } + + return "OK" +} diff --git a/compiler/testData/codegen/boxWithStdlib/ranges/literal/maxValueMinusTwoToMaxValue.kt b/compiler/testData/codegen/boxWithStdlib/ranges/literal/maxValueMinusTwoToMaxValue.kt new file mode 100644 index 00000000000..e5aa948b769 --- /dev/null +++ b/compiler/testData/codegen/boxWithStdlib/ranges/literal/maxValueMinusTwoToMaxValue.kt @@ -0,0 +1,63 @@ +// Auto-generated by org.jetbrains.jet.generators.tests.GenerateRangesCodegenTestData. DO NOT EDIT! +import java.util.ArrayList +import java.lang as j + +import java.lang.Integer.MAX_VALUE as MaxI +import java.lang.Integer.MIN_VALUE as MinI +import java.lang.Byte.MAX_VALUE as MaxB +import java.lang.Byte.MIN_VALUE as MinB +import java.lang.Short.MAX_VALUE as MaxS +import java.lang.Short.MIN_VALUE as MinS +import java.lang.Long.MAX_VALUE as MaxL +import java.lang.Long.MIN_VALUE as MinL +import java.lang.Character.MAX_VALUE as MaxC +import java.lang.Character.MIN_VALUE as MinC + +fun box(): String { + val list1 = ArrayList() + for (i in (MaxI - 2)..MaxI) { + list1.add(i) + if (list1.size() > 23) break + } + if (list1 != listOf(MaxI - 2, MaxI - 1, MaxI)) { + return "Wrong elements for (MaxI - 2)..MaxI: $list1" + } + + val list2 = ArrayList() + for (i in (MaxB - 2).toByte()..MaxB) { + list2.add(i) + if (list2.size() > 23) break + } + if (list2 != listOf((MaxB - 2).toByte(), (MaxB - 1).toByte(), MaxB)) { + return "Wrong elements for (MaxB - 2).toByte()..MaxB: $list2" + } + + val list3 = ArrayList() + for (i in (MaxS - 2).toShort()..MaxS) { + list3.add(i) + if (list3.size() > 23) break + } + if (list3 != listOf((MaxS - 2).toShort(), (MaxS - 1).toShort(), MaxS)) { + return "Wrong elements for (MaxS - 2).toShort()..MaxS: $list3" + } + + val list4 = ArrayList() + for (i in (MaxL - 2).toLong()..MaxL) { + list4.add(i) + if (list4.size() > 23) break + } + if (list4 != listOf((MaxL - 2).toLong(), (MaxL - 1).toLong(), MaxL)) { + return "Wrong elements for (MaxL - 2).toLong()..MaxL: $list4" + } + + val list5 = ArrayList() + for (i in (MaxC - 2).toChar()..MaxC) { + list5.add(i) + if (list5.size() > 23) break + } + if (list5 != listOf((MaxC - 2).toChar(), (MaxC - 1).toChar(), MaxC)) { + return "Wrong elements for (MaxC - 2).toChar()..MaxC: $list5" + } + + return "OK" +} diff --git a/compiler/testData/codegen/boxWithStdlib/ranges/literal/maxValueToMaxValue.kt b/compiler/testData/codegen/boxWithStdlib/ranges/literal/maxValueToMaxValue.kt new file mode 100644 index 00000000000..c0c9e1a49d7 --- /dev/null +++ b/compiler/testData/codegen/boxWithStdlib/ranges/literal/maxValueToMaxValue.kt @@ -0,0 +1,63 @@ +// Auto-generated by org.jetbrains.jet.generators.tests.GenerateRangesCodegenTestData. DO NOT EDIT! +import java.util.ArrayList +import java.lang as j + +import java.lang.Integer.MAX_VALUE as MaxI +import java.lang.Integer.MIN_VALUE as MinI +import java.lang.Byte.MAX_VALUE as MaxB +import java.lang.Byte.MIN_VALUE as MinB +import java.lang.Short.MAX_VALUE as MaxS +import java.lang.Short.MIN_VALUE as MinS +import java.lang.Long.MAX_VALUE as MaxL +import java.lang.Long.MIN_VALUE as MinL +import java.lang.Character.MAX_VALUE as MaxC +import java.lang.Character.MIN_VALUE as MinC + +fun box(): String { + val list1 = ArrayList() + for (i in MaxI..MaxI) { + list1.add(i) + if (list1.size() > 23) break + } + if (list1 != listOf(MaxI)) { + return "Wrong elements for MaxI..MaxI: $list1" + } + + val list2 = ArrayList() + for (i in MaxB..MaxB) { + list2.add(i) + if (list2.size() > 23) break + } + if (list2 != listOf(MaxB)) { + return "Wrong elements for MaxB..MaxB: $list2" + } + + val list3 = ArrayList() + for (i in MaxS..MaxS) { + list3.add(i) + if (list3.size() > 23) break + } + if (list3 != listOf(MaxS)) { + return "Wrong elements for MaxS..MaxS: $list3" + } + + val list4 = ArrayList() + for (i in MaxL..MaxL) { + list4.add(i) + if (list4.size() > 23) break + } + if (list4 != listOf(MaxL)) { + return "Wrong elements for MaxL..MaxL: $list4" + } + + val list5 = ArrayList() + for (i in MaxC..MaxC) { + list5.add(i) + if (list5.size() > 23) break + } + if (list5 != listOf(MaxC)) { + return "Wrong elements for MaxC..MaxC: $list5" + } + + return "OK" +} diff --git a/compiler/testData/codegen/boxWithStdlib/ranges/literal/maxValueToMinValue.kt b/compiler/testData/codegen/boxWithStdlib/ranges/literal/maxValueToMinValue.kt new file mode 100644 index 00000000000..8722f4f4e1b --- /dev/null +++ b/compiler/testData/codegen/boxWithStdlib/ranges/literal/maxValueToMinValue.kt @@ -0,0 +1,63 @@ +// Auto-generated by org.jetbrains.jet.generators.tests.GenerateRangesCodegenTestData. DO NOT EDIT! +import java.util.ArrayList +import java.lang as j + +import java.lang.Integer.MAX_VALUE as MaxI +import java.lang.Integer.MIN_VALUE as MinI +import java.lang.Byte.MAX_VALUE as MaxB +import java.lang.Byte.MIN_VALUE as MinB +import java.lang.Short.MAX_VALUE as MaxS +import java.lang.Short.MIN_VALUE as MinS +import java.lang.Long.MAX_VALUE as MaxL +import java.lang.Long.MIN_VALUE as MinL +import java.lang.Character.MAX_VALUE as MaxC +import java.lang.Character.MIN_VALUE as MinC + +fun box(): String { + val list1 = ArrayList() + for (i in MaxI..MinI) { + list1.add(i) + if (list1.size() > 23) break + } + if (list1 != listOf()) { + return "Wrong elements for MaxI..MinI: $list1" + } + + val list2 = ArrayList() + for (i in MaxB..MinB) { + list2.add(i) + if (list2.size() > 23) break + } + if (list2 != listOf()) { + return "Wrong elements for MaxB..MinB: $list2" + } + + val list3 = ArrayList() + for (i in MaxS..MinS) { + list3.add(i) + if (list3.size() > 23) break + } + if (list3 != listOf()) { + return "Wrong elements for MaxS..MinS: $list3" + } + + val list4 = ArrayList() + for (i in MaxL..MinL) { + list4.add(i) + if (list4.size() > 23) break + } + if (list4 != listOf()) { + return "Wrong elements for MaxL..MinL: $list4" + } + + val list5 = ArrayList() + for (i in MaxC..MinC) { + list5.add(i) + if (list5.size() > 23) break + } + if (list5 != listOf()) { + return "Wrong elements for MaxC..MinC: $list5" + } + + 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 96533c05d3e..26cc88726d3 100644 --- a/compiler/tests/org/jetbrains/jet/codegen/generated/BlackBoxWithStdlibCodegenTestGenerated.java +++ b/compiler/tests/org/jetbrains/jet/codegen/generated/BlackBoxWithStdlibCodegenTestGenerated.java @@ -439,6 +439,21 @@ public class BlackBoxWithStdlibCodegenTestGenerated extends AbstractBlackBoxCode doTestWithStdlib("compiler/testData/codegen/boxWithStdlib/ranges/expression/infiniteSteps.kt"); } + @TestMetadata("maxValueMinusTwoToMaxValue.kt") + public void testMaxValueMinusTwoToMaxValue() throws Exception { + doTestWithStdlib("compiler/testData/codegen/boxWithStdlib/ranges/expression/maxValueMinusTwoToMaxValue.kt"); + } + + @TestMetadata("maxValueToMaxValue.kt") + public void testMaxValueToMaxValue() throws Exception { + doTestWithStdlib("compiler/testData/codegen/boxWithStdlib/ranges/expression/maxValueToMaxValue.kt"); + } + + @TestMetadata("maxValueToMinValue.kt") + public void testMaxValueToMinValue() throws Exception { + doTestWithStdlib("compiler/testData/codegen/boxWithStdlib/ranges/expression/maxValueToMinValue.kt"); + } + @TestMetadata("nanEnds.kt") public void testNanEnds() throws Exception { doTestWithStdlib("compiler/testData/codegen/boxWithStdlib/ranges/expression/nanEnds.kt"); @@ -542,6 +557,21 @@ public class BlackBoxWithStdlibCodegenTestGenerated extends AbstractBlackBoxCode doTestWithStdlib("compiler/testData/codegen/boxWithStdlib/ranges/literal/infiniteSteps.kt"); } + @TestMetadata("maxValueMinusTwoToMaxValue.kt") + public void testMaxValueMinusTwoToMaxValue() throws Exception { + doTestWithStdlib("compiler/testData/codegen/boxWithStdlib/ranges/literal/maxValueMinusTwoToMaxValue.kt"); + } + + @TestMetadata("maxValueToMaxValue.kt") + public void testMaxValueToMaxValue() throws Exception { + doTestWithStdlib("compiler/testData/codegen/boxWithStdlib/ranges/literal/maxValueToMaxValue.kt"); + } + + @TestMetadata("maxValueToMinValue.kt") + public void testMaxValueToMinValue() throws Exception { + doTestWithStdlib("compiler/testData/codegen/boxWithStdlib/ranges/literal/maxValueToMinValue.kt"); + } + @TestMetadata("nanEnds.kt") public void testNanEnds() throws Exception { doTestWithStdlib("compiler/testData/codegen/boxWithStdlib/ranges/literal/nanEnds.kt"); diff --git a/generators/org/jetbrains/jet/generators/tests/GenerateRangesCodegenTestData.java b/generators/org/jetbrains/jet/generators/tests/GenerateRangesCodegenTestData.java index 94809600e8a..fabedee33f9 100644 --- a/generators/org/jetbrains/jet/generators/tests/GenerateRangesCodegenTestData.java +++ b/generators/org/jetbrains/jet/generators/tests/GenerateRangesCodegenTestData.java @@ -19,11 +19,15 @@ package org.jetbrains.jet.generators.tests; import com.intellij.openapi.util.io.FileUtil; import com.intellij.openapi.util.text.StringUtil; import com.intellij.util.LineSeparator; +import com.intellij.util.containers.ContainerUtil; import java.io.File; import java.io.FileNotFoundException; import java.io.IOException; import java.io.PrintWriter; +import java.util.Arrays; +import java.util.List; +import java.util.Map; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -58,22 +62,29 @@ public class GenerateRangesCodegenTestData { " }\n" + "\n"; + private static final Map ELEMENT_TYPE_KNOWN_SUBSTRINGS = new ContainerUtil.ImmutableMapBuilder() + .put("'", "Char") + .put("\"", "Char") + .put("Float.NaN", "Float") + .put("Double.NaN", "Double") + .put("MaxB", "Byte") + .put("MaxS", "Short") + .put("MaxL", "Long") + .put("MaxC", "Char") + .build(); + private static String detectElementType(String rangeExpression) { Matcher matcher = Pattern.compile("\\.to(\\w+)").matcher(rangeExpression); if (matcher.find()) { return matcher.group(1); } - if (rangeExpression.contains("'") || rangeExpression.contains("\"")) { - return "Char"; - } if (Pattern.compile("\\d\\.\\d").matcher(rangeExpression).find()) { return "Double"; } - if (rangeExpression.contains("Float.NaN")) { - return "Float"; - } - if (rangeExpression.contains("Double.NaN")) { - return "Double"; + for (String substring : ELEMENT_TYPE_KNOWN_SUBSTRINGS.keySet()) { + if (rangeExpression.contains(substring)) { + return ELEMENT_TYPE_KNOWN_SUBSTRINGS.get(substring); + } } return "Int"; } @@ -89,7 +100,9 @@ public class GenerateRangesCodegenTestData { .replace("\n", LineSeparator.getSystemLineSeparator().getSeparatorString()); } - private static void writeToFile(File file, CharSequence generatedBody) { + private static final List INTEGER_PRIMITIVES = Arrays.asList("Integer", "Byte", "Short", "Long", "Character"); + + private static void writeToFile(File file, String generatedBody) { PrintWriter out; try { //noinspection IOResourceOpenedButNotSafelyClosed @@ -102,6 +115,14 @@ public class GenerateRangesCodegenTestData { out.println("// Auto-generated by " + GenerateRangesCodegenTestData.class.getName() + ". DO NOT EDIT!"); out.println("import java.util.ArrayList"); out.println("import java.lang as j"); + if (generatedBody.contains("Max") || generatedBody.contains("Min")) { + // Import min/max values, but only in case when the generated test case actually uses them (not to clutter tests which don't) + out.println(); + for (String primitive : INTEGER_PRIMITIVES) { + out.println("import java.lang." + primitive + ".MAX_VALUE as Max" + primitive.charAt(0)); + out.println("import java.lang." + primitive + ".MIN_VALUE as Min" + primitive.charAt(0)); + } + } out.println(); out.println("fun box(): String {"); out.print(generatedBody); @@ -146,8 +167,8 @@ public class GenerateRangesCodegenTestData { } String fileName = testFunName + ".kt"; - writeToFile(new File(AS_LITERAL_DIR, fileName), asLiteralBody); - writeToFile(new File(AS_EXPRESSION_DIR, fileName), asExpressionBody); + writeToFile(new File(AS_LITERAL_DIR, fileName), asLiteralBody.toString()); + writeToFile(new File(AS_EXPRESSION_DIR, fileName), asExpressionBody.toString()); } } diff --git a/libraries/stdlib/test/language/RangeIterationTest.kt b/libraries/stdlib/test/language/RangeIterationTest.kt index d7251c454bb..37fcd7e9e48 100644 --- a/libraries/stdlib/test/language/RangeIterationTest.kt +++ b/libraries/stdlib/test/language/RangeIterationTest.kt @@ -4,6 +4,17 @@ import kotlin.test.assertEquals import org.junit.Test as test import java.lang as j +import java.lang.Integer.MAX_VALUE as MaxI +import java.lang.Integer.MIN_VALUE as MinI +import java.lang.Byte.MAX_VALUE as MaxB +import java.lang.Byte.MIN_VALUE as MinB +import java.lang.Short.MAX_VALUE as MaxS +import java.lang.Short.MIN_VALUE as MinS +import java.lang.Long.MAX_VALUE as MaxL +import java.lang.Long.MIN_VALUE as MinL +import java.lang.Character.MAX_VALUE as MaxC +import java.lang.Character.MIN_VALUE as MinC + // Test data for codegen is generated from this class. If you change it, rerun GenerateTests public class RangeIterationTest { private fun doTest( @@ -280,4 +291,31 @@ public class RangeIterationTest { doTest(j.Double.NaN downTo j.Double.NaN, j.Double.NaN, j.Double.NaN, -1.0, listOf()) doTest(j.Float.NaN downTo j.Float.NaN, j.Float.NaN, j.Float.NaN, -1.0.toFloat(), listOf()) } -} \ No newline at end of file + + test fun maxValueToMaxValue() { + doTest(MaxI..MaxI, MaxI, MaxI, 1, listOf(MaxI)) + doTest(MaxB..MaxB, MaxB, MaxB, 1, listOf(MaxB)) + doTest(MaxS..MaxS, MaxS, MaxS, 1, listOf(MaxS)) + doTest(MaxL..MaxL, MaxL, MaxL, 1.toLong(), listOf(MaxL)) + + doTest(MaxC..MaxC, MaxC, MaxC, 1, listOf(MaxC)) + } + + test fun maxValueMinusTwoToMaxValue() { + doTest((MaxI - 2)..MaxI, MaxI - 2, MaxI, 1, listOf(MaxI - 2, MaxI - 1, MaxI)) + doTest((MaxB - 2).toByte()..MaxB, (MaxB - 2).toByte(), MaxB, 1, listOf((MaxB - 2).toByte(), (MaxB - 1).toByte(), MaxB)) + doTest((MaxS - 2).toShort()..MaxS, (MaxS - 2).toShort(), MaxS, 1, listOf((MaxS - 2).toShort(), (MaxS - 1).toShort(), MaxS)) + doTest((MaxL - 2).toLong()..MaxL, (MaxL - 2).toLong(), MaxL, 1.toLong(), listOf((MaxL - 2).toLong(), (MaxL - 1).toLong(), MaxL)) + + doTest((MaxC - 2).toChar()..MaxC, (MaxC - 2).toChar(), MaxC, 1, listOf((MaxC - 2).toChar(), (MaxC - 1).toChar(), MaxC)) + } + + test fun maxValueToMinValue() { + doTest(MaxI..MinI, MaxI, MinI, 1, listOf()) + doTest(MaxB..MinB, MaxB, MinB, 1, listOf()) + doTest(MaxS..MinS, MaxS, MinS, 1, listOf()) + doTest(MaxL..MinL, MaxL, MinL, 1.toLong(), listOf()) + + doTest(MaxC..MinC, MaxC, MinC, 1, listOf()) + } +} From ee80e0b8ca6182e9bd60fe0f3d90642db9c3a5da Mon Sep 17 00:00:00 2001 From: Alexander Udalov Date: Tue, 18 Jun 2013 19:41:38 +0400 Subject: [PATCH 164/291] Fix loops over progressions near to MAX_VALUE/MIN_VALUE #KT-492 Fixed For Byte, Char and Short ranges, promote the type of the loop parameter to int to avoid overflows. For Int and Long ranges at the end of the loop over a progression we now check if the new (incremented) value of the loop parameter is greater than the old value iff increment > 0 --- .../org/jetbrains/jet/codegen/AsmUtil.java | 22 +++++- .../jet/codegen/ExpressionCodegen.java | 62 +++++++++++++--- .../org/jetbrains/jet/codegen/StackValue.java | 16 +---- .../expression/inexactDownToMinValue.kt | 68 ++++++++++++++++++ .../ranges/expression/inexactToMaxValue.kt | 68 ++++++++++++++++++ .../expression/progressionDownToMinValue.kt | 68 ++++++++++++++++++ .../progressionMaxValueMinusTwoToMaxValue.kt | 68 ++++++++++++++++++ .../progressionMaxValueToMaxValue.kt | 68 ++++++++++++++++++ .../progressionMaxValueToMinValue.kt | 68 ++++++++++++++++++ .../progressionMinValueToMinValue.kt | 68 ++++++++++++++++++ .../ranges/literal/inexactDownToMinValue.kt | 63 +++++++++++++++++ .../ranges/literal/inexactToMaxValue.kt | 63 +++++++++++++++++ .../literal/progressionDownToMinValue.kt | 63 +++++++++++++++++ .../progressionMaxValueMinusTwoToMaxValue.kt | 63 +++++++++++++++++ .../literal/progressionMaxValueToMaxValue.kt | 63 +++++++++++++++++ .../literal/progressionMaxValueToMinValue.kt | 63 +++++++++++++++++ .../literal/progressionMinValueToMinValue.kt | 63 +++++++++++++++++ ...lackBoxWithStdlibCodegenTestGenerated.java | 70 +++++++++++++++++++ .../tests/GenerateRangesCodegenTestData.java | 4 ++ .../test/language/RangeIterationTest.kt | 63 +++++++++++++++++ runtime/src/jet/ByteProgressionIterator.java | 6 +- runtime/src/jet/CharProgressionIterator.java | 6 +- runtime/src/jet/IntProgressionIterator.java | 6 +- runtime/src/jet/LongProgressionIterator.java | 6 +- runtime/src/jet/ShortProgressionIterator.java | 6 +- 25 files changed, 1148 insertions(+), 36 deletions(-) create mode 100644 compiler/testData/codegen/boxWithStdlib/ranges/expression/inexactDownToMinValue.kt create mode 100644 compiler/testData/codegen/boxWithStdlib/ranges/expression/inexactToMaxValue.kt create mode 100644 compiler/testData/codegen/boxWithStdlib/ranges/expression/progressionDownToMinValue.kt create mode 100644 compiler/testData/codegen/boxWithStdlib/ranges/expression/progressionMaxValueMinusTwoToMaxValue.kt create mode 100644 compiler/testData/codegen/boxWithStdlib/ranges/expression/progressionMaxValueToMaxValue.kt create mode 100644 compiler/testData/codegen/boxWithStdlib/ranges/expression/progressionMaxValueToMinValue.kt create mode 100644 compiler/testData/codegen/boxWithStdlib/ranges/expression/progressionMinValueToMinValue.kt create mode 100644 compiler/testData/codegen/boxWithStdlib/ranges/literal/inexactDownToMinValue.kt create mode 100644 compiler/testData/codegen/boxWithStdlib/ranges/literal/inexactToMaxValue.kt create mode 100644 compiler/testData/codegen/boxWithStdlib/ranges/literal/progressionDownToMinValue.kt create mode 100644 compiler/testData/codegen/boxWithStdlib/ranges/literal/progressionMaxValueMinusTwoToMaxValue.kt create mode 100644 compiler/testData/codegen/boxWithStdlib/ranges/literal/progressionMaxValueToMaxValue.kt create mode 100644 compiler/testData/codegen/boxWithStdlib/ranges/literal/progressionMaxValueToMinValue.kt create mode 100644 compiler/testData/codegen/boxWithStdlib/ranges/literal/progressionMinValueToMinValue.kt diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/AsmUtil.java b/compiler/backend/src/org/jetbrains/jet/codegen/AsmUtil.java index a2c63c40d4f..9116696fa30 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/AsmUtil.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/AsmUtil.java @@ -47,9 +47,7 @@ import java.util.Set; import static org.jetbrains.asm4.Opcodes.*; import static org.jetbrains.jet.codegen.CodegenUtil.*; -import static org.jetbrains.jet.lang.resolve.DescriptorUtils.isClassObject; -import static org.jetbrains.jet.lang.resolve.DescriptorUtils.isEnumEntry; -import static org.jetbrains.jet.lang.resolve.DescriptorUtils.isKindOf; +import static org.jetbrains.jet.lang.resolve.DescriptorUtils.*; import static org.jetbrains.jet.lang.resolve.java.AsmTypeConstants.JAVA_STRING_TYPE; public class AsmUtil { @@ -642,4 +640,22 @@ public class AsmUtil { return Type.INT_TYPE; } + public static void pop(@NotNull InstructionAdapter v, @NotNull Type type) { + if (type.getSize() == 2) { + v.pop2(); + } + else { + v.pop(); + } + } + + public static void dup(@NotNull InstructionAdapter v, @NotNull Type type) { + if (type.getSize() == 2) { + v.dup2(); + } + else { + v.dup(); + } + } + } diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java index 1ae21c4ccd2..66edba467db 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java @@ -1108,20 +1108,69 @@ public class ExpressionCodegen extends JetVisitor implem @Override protected void increment(@NotNull Label loopExit) { - v.load(loopParameterVar, asmElementType); v.load(incrementVar, asmElementType); v.add(asmElementType); int sort = asmElementType.getSort(); - if (sort == Type.CHAR || sort == Type.BYTE || sort == Type.SHORT) { - StackValue.coerce(Type.INT_TYPE, asmElementType, v); + if (sort == Type.INT || sort == Type.LONG) { + checkNewLoopParameterValue(loopExit); } v.store(loopParameterVar, asmElementType); } + + // Checks that (increment > 0) == (new value of loop parameter > old value of loop parameter). + // Old value should be stored in loopParameterVar, new value should be on top of the stack + private void checkNewLoopParameterValue(@NotNull Label loopExit) { + Label negativeIncrement = new Label(); + Label afterIf = new Label(); + Label popAndExit = new Label(); + + dup(v, asmElementType); + v.load(loopParameterVar, asmElementType); + + v.load(incrementVar, asmElementType); + + if (asmElementType.getSort() == Type.LONG) { + v.lconst(0L); + v.lcmp(); + v.ifle(negativeIncrement); + + // increment > 0 + v.lcmp(); + v.iflt(popAndExit); + v.goTo(afterIf); + + // increment < 0 + v.mark(negativeIncrement); + v.lcmp(); + v.ifgt(popAndExit); + v.goTo(afterIf); + } + else { + v.ifle(negativeIncrement); + + // increment > 0 + v.ificmplt(popAndExit); + v.goTo(afterIf); + + // increment < 0 + v.mark(negativeIncrement); + v.ificmpgt(popAndExit); + v.goTo(afterIf); + } + + // Pop the new value of loop parameter from the stack and exit the loop + v.mark(popAndExit); + pop(v, asmElementType); + v.goTo(loopExit); + + v.mark(afterIf); + } } + @Override public StackValue visitBreakExpression(JetBreakExpression expression, StackValue receiver) { JetSimpleNameExpression labelElement = expression.getTargetLabel(); @@ -3059,12 +3108,7 @@ public class ExpressionCodegen extends JetVisitor implem switch (value.receiverSize()) { case 0: - if (type.getSize() == 2) { - v.dup2(); - } - else { - v.dup(); - } + dup(v, type); break; case 1: diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/StackValue.java b/compiler/backend/src/org/jetbrains/jet/codegen/StackValue.java index db0639e04af..89b63089c40 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/StackValue.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/StackValue.java @@ -30,7 +30,6 @@ import org.jetbrains.jet.lang.descriptors.*; import org.jetbrains.jet.lang.psi.JetExpression; import org.jetbrains.jet.lang.resolve.calls.model.ResolvedCall; import org.jetbrains.jet.lang.resolve.java.AsmTypeConstants; -import org.jetbrains.jet.lang.resolve.java.JvmAbi; import org.jetbrains.jet.lang.resolve.java.JvmClassName; import org.jetbrains.jet.lang.resolve.java.JvmPrimitiveType; import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverValue; @@ -211,15 +210,6 @@ public abstract class StackValue { } } - private static void pop(Type type, InstructionAdapter v) { - if (type.getSize() == 1) { - v.pop(); - } - else { - v.pop2(); - } - } - protected void coerceTo(Type toType, InstructionAdapter v) { coerce(this.type, toType, v); } @@ -232,7 +222,7 @@ public abstract class StackValue { if (toType.equals(fromType)) return; if (toType.getSort() == Type.VOID) { - pop(fromType, v); + pop(v, fromType); } else if (fromType.getSort() == Type.VOID) { if (toType.equals(JET_UNIT_TYPE) || toType.equals(OBJECT_TYPE)) { @@ -246,7 +236,7 @@ public abstract class StackValue { } } else if (toType.equals(JET_UNIT_TYPE)) { - pop(fromType, v); + pop(v, fromType); putUnitInstance(v); } else if (toType.getSort() == Type.ARRAY) { @@ -646,7 +636,7 @@ public abstract class StackValue { method.invokeWithNotNullAssertion(v, state, resolvedSetCall); Type returnType = asmMethod.getReturnType(); if (returnType != Type.VOID_TYPE) { - pop(returnType, v); + pop(v, returnType); } } else { diff --git a/compiler/testData/codegen/boxWithStdlib/ranges/expression/inexactDownToMinValue.kt b/compiler/testData/codegen/boxWithStdlib/ranges/expression/inexactDownToMinValue.kt new file mode 100644 index 00000000000..c7f0bf53896 --- /dev/null +++ b/compiler/testData/codegen/boxWithStdlib/ranges/expression/inexactDownToMinValue.kt @@ -0,0 +1,68 @@ +// Auto-generated by org.jetbrains.jet.generators.tests.GenerateRangesCodegenTestData. DO NOT EDIT! +import java.util.ArrayList +import java.lang as j + +import java.lang.Integer.MAX_VALUE as MaxI +import java.lang.Integer.MIN_VALUE as MinI +import java.lang.Byte.MAX_VALUE as MaxB +import java.lang.Byte.MIN_VALUE as MinB +import java.lang.Short.MAX_VALUE as MaxS +import java.lang.Short.MIN_VALUE as MinS +import java.lang.Long.MAX_VALUE as MaxL +import java.lang.Long.MIN_VALUE as MinL +import java.lang.Character.MAX_VALUE as MaxC +import java.lang.Character.MIN_VALUE as MinC + +fun box(): String { + val list1 = ArrayList() + val range1 = (MinI + 5) downTo MinI step 3 + for (i in range1) { + list1.add(i) + if (list1.size() > 23) break + } + if (list1 != listOf(MinI + 5, MinI + 2)) { + return "Wrong elements for (MinI + 5) downTo MinI step 3: $list1" + } + + val list2 = ArrayList() + val range2 = (MinB + 5).toByte() downTo MinB step 3 + for (i in range2) { + list2.add(i) + if (list2.size() > 23) break + } + if (list2 != listOf((MinB + 5).toByte(), (MinB + 2).toByte())) { + return "Wrong elements for (MinB + 5).toByte() downTo MinB step 3: $list2" + } + + val list3 = ArrayList() + val range3 = (MinS + 5).toShort() downTo MinS step 3 + for (i in range3) { + list3.add(i) + if (list3.size() > 23) break + } + if (list3 != listOf((MinS + 5).toShort(), (MinS + 2).toShort())) { + return "Wrong elements for (MinS + 5).toShort() downTo MinS step 3: $list3" + } + + val list4 = ArrayList() + val range4 = (MinL + 5).toLong() downTo MinL step 3 + for (i in range4) { + list4.add(i) + if (list4.size() > 23) break + } + if (list4 != listOf((MinL + 5).toLong(), (MinL + 2).toLong())) { + return "Wrong elements for (MinL + 5).toLong() downTo MinL step 3: $list4" + } + + val list5 = ArrayList() + val range5 = (MinC + 5).toChar() downTo MinC step 3 + for (i in range5) { + list5.add(i) + if (list5.size() > 23) break + } + if (list5 != listOf((MinC + 5).toChar(), (MinC + 2).toChar())) { + return "Wrong elements for (MinC + 5).toChar() downTo MinC step 3: $list5" + } + + return "OK" +} diff --git a/compiler/testData/codegen/boxWithStdlib/ranges/expression/inexactToMaxValue.kt b/compiler/testData/codegen/boxWithStdlib/ranges/expression/inexactToMaxValue.kt new file mode 100644 index 00000000000..18c099542cc --- /dev/null +++ b/compiler/testData/codegen/boxWithStdlib/ranges/expression/inexactToMaxValue.kt @@ -0,0 +1,68 @@ +// Auto-generated by org.jetbrains.jet.generators.tests.GenerateRangesCodegenTestData. DO NOT EDIT! +import java.util.ArrayList +import java.lang as j + +import java.lang.Integer.MAX_VALUE as MaxI +import java.lang.Integer.MIN_VALUE as MinI +import java.lang.Byte.MAX_VALUE as MaxB +import java.lang.Byte.MIN_VALUE as MinB +import java.lang.Short.MAX_VALUE as MaxS +import java.lang.Short.MIN_VALUE as MinS +import java.lang.Long.MAX_VALUE as MaxL +import java.lang.Long.MIN_VALUE as MinL +import java.lang.Character.MAX_VALUE as MaxC +import java.lang.Character.MIN_VALUE as MinC + +fun box(): String { + val list1 = ArrayList() + val range1 = (MaxI - 5)..MaxI step 3 + for (i in range1) { + list1.add(i) + if (list1.size() > 23) break + } + if (list1 != listOf(MaxI - 5, MaxI - 2)) { + return "Wrong elements for (MaxI - 5)..MaxI step 3: $list1" + } + + val list2 = ArrayList() + val range2 = (MaxB - 5).toByte()..MaxB step 3 + for (i in range2) { + list2.add(i) + if (list2.size() > 23) break + } + if (list2 != listOf((MaxB - 5).toByte(), (MaxB - 2).toByte())) { + return "Wrong elements for (MaxB - 5).toByte()..MaxB step 3: $list2" + } + + val list3 = ArrayList() + val range3 = (MaxS - 5).toShort()..MaxS step 3 + for (i in range3) { + list3.add(i) + if (list3.size() > 23) break + } + if (list3 != listOf((MaxS - 5).toShort(), (MaxS - 2).toShort())) { + return "Wrong elements for (MaxS - 5).toShort()..MaxS step 3: $list3" + } + + val list4 = ArrayList() + val range4 = (MaxL - 5).toLong()..MaxL step 3 + for (i in range4) { + list4.add(i) + if (list4.size() > 23) break + } + if (list4 != listOf((MaxL - 5).toLong(), (MaxL - 2).toLong())) { + return "Wrong elements for (MaxL - 5).toLong()..MaxL step 3: $list4" + } + + val list5 = ArrayList() + val range5 = (MaxC - 5).toChar()..MaxC step 3 + for (i in range5) { + list5.add(i) + if (list5.size() > 23) break + } + if (list5 != listOf((MaxC - 5).toChar(), (MaxC - 2).toChar())) { + return "Wrong elements for (MaxC - 5).toChar()..MaxC step 3: $list5" + } + + return "OK" +} diff --git a/compiler/testData/codegen/boxWithStdlib/ranges/expression/progressionDownToMinValue.kt b/compiler/testData/codegen/boxWithStdlib/ranges/expression/progressionDownToMinValue.kt new file mode 100644 index 00000000000..4784f93dc6b --- /dev/null +++ b/compiler/testData/codegen/boxWithStdlib/ranges/expression/progressionDownToMinValue.kt @@ -0,0 +1,68 @@ +// Auto-generated by org.jetbrains.jet.generators.tests.GenerateRangesCodegenTestData. DO NOT EDIT! +import java.util.ArrayList +import java.lang as j + +import java.lang.Integer.MAX_VALUE as MaxI +import java.lang.Integer.MIN_VALUE as MinI +import java.lang.Byte.MAX_VALUE as MaxB +import java.lang.Byte.MIN_VALUE as MinB +import java.lang.Short.MAX_VALUE as MaxS +import java.lang.Short.MIN_VALUE as MinS +import java.lang.Long.MAX_VALUE as MaxL +import java.lang.Long.MIN_VALUE as MinL +import java.lang.Character.MAX_VALUE as MaxC +import java.lang.Character.MIN_VALUE as MinC + +fun box(): String { + val list1 = ArrayList() + val range1 = (MinI + 2) downTo MinI step 1 + for (i in range1) { + list1.add(i) + if (list1.size() > 23) break + } + if (list1 != listOf(MinI + 2, MinI + 1, MinI)) { + return "Wrong elements for (MinI + 2) downTo MinI step 1: $list1" + } + + val list2 = ArrayList() + val range2 = (MinB + 2).toByte() downTo MinB step 1 + for (i in range2) { + list2.add(i) + if (list2.size() > 23) break + } + if (list2 != listOf((MinB + 2).toByte(), (MinB + 1).toByte(), MinB)) { + return "Wrong elements for (MinB + 2).toByte() downTo MinB step 1: $list2" + } + + val list3 = ArrayList() + val range3 = (MinS + 2).toShort() downTo MinS step 1 + for (i in range3) { + list3.add(i) + if (list3.size() > 23) break + } + if (list3 != listOf((MinS + 2).toShort(), (MinS + 1).toShort(), MinS)) { + return "Wrong elements for (MinS + 2).toShort() downTo MinS step 1: $list3" + } + + val list4 = ArrayList() + val range4 = (MinL + 2).toLong() downTo MinL step 1 + for (i in range4) { + list4.add(i) + if (list4.size() > 23) break + } + if (list4 != listOf((MinL + 2).toLong(), (MinL + 1).toLong(), MinL)) { + return "Wrong elements for (MinL + 2).toLong() downTo MinL step 1: $list4" + } + + val list5 = ArrayList() + val range5 = (MinC + 2).toChar() downTo MinC step 1 + for (i in range5) { + list5.add(i) + if (list5.size() > 23) break + } + if (list5 != listOf((MinC + 2).toChar(), (MinC + 1).toChar(), MinC)) { + return "Wrong elements for (MinC + 2).toChar() downTo MinC step 1: $list5" + } + + return "OK" +} diff --git a/compiler/testData/codegen/boxWithStdlib/ranges/expression/progressionMaxValueMinusTwoToMaxValue.kt b/compiler/testData/codegen/boxWithStdlib/ranges/expression/progressionMaxValueMinusTwoToMaxValue.kt new file mode 100644 index 00000000000..58a8f51eb91 --- /dev/null +++ b/compiler/testData/codegen/boxWithStdlib/ranges/expression/progressionMaxValueMinusTwoToMaxValue.kt @@ -0,0 +1,68 @@ +// Auto-generated by org.jetbrains.jet.generators.tests.GenerateRangesCodegenTestData. DO NOT EDIT! +import java.util.ArrayList +import java.lang as j + +import java.lang.Integer.MAX_VALUE as MaxI +import java.lang.Integer.MIN_VALUE as MinI +import java.lang.Byte.MAX_VALUE as MaxB +import java.lang.Byte.MIN_VALUE as MinB +import java.lang.Short.MAX_VALUE as MaxS +import java.lang.Short.MIN_VALUE as MinS +import java.lang.Long.MAX_VALUE as MaxL +import java.lang.Long.MIN_VALUE as MinL +import java.lang.Character.MAX_VALUE as MaxC +import java.lang.Character.MIN_VALUE as MinC + +fun box(): String { + val list1 = ArrayList() + val range1 = (MaxI - 2)..MaxI step 2 + for (i in range1) { + list1.add(i) + if (list1.size() > 23) break + } + if (list1 != listOf(MaxI - 2, MaxI)) { + return "Wrong elements for (MaxI - 2)..MaxI step 2: $list1" + } + + val list2 = ArrayList() + val range2 = (MaxB - 2).toByte()..MaxB step 2 + for (i in range2) { + list2.add(i) + if (list2.size() > 23) break + } + if (list2 != listOf((MaxB - 2).toByte(), MaxB)) { + return "Wrong elements for (MaxB - 2).toByte()..MaxB step 2: $list2" + } + + val list3 = ArrayList() + val range3 = (MaxS - 2).toShort()..MaxS step 2 + for (i in range3) { + list3.add(i) + if (list3.size() > 23) break + } + if (list3 != listOf((MaxS - 2).toShort(), MaxS)) { + return "Wrong elements for (MaxS - 2).toShort()..MaxS step 2: $list3" + } + + val list4 = ArrayList() + val range4 = (MaxL - 2).toLong()..MaxL step 2 + for (i in range4) { + list4.add(i) + if (list4.size() > 23) break + } + if (list4 != listOf((MaxL - 2).toLong(), MaxL)) { + return "Wrong elements for (MaxL - 2).toLong()..MaxL step 2: $list4" + } + + val list5 = ArrayList() + val range5 = (MaxC - 2).toChar()..MaxC step 2 + for (i in range5) { + list5.add(i) + if (list5.size() > 23) break + } + if (list5 != listOf((MaxC - 2).toChar(), MaxC)) { + return "Wrong elements for (MaxC - 2).toChar()..MaxC step 2: $list5" + } + + return "OK" +} diff --git a/compiler/testData/codegen/boxWithStdlib/ranges/expression/progressionMaxValueToMaxValue.kt b/compiler/testData/codegen/boxWithStdlib/ranges/expression/progressionMaxValueToMaxValue.kt new file mode 100644 index 00000000000..f98142eb761 --- /dev/null +++ b/compiler/testData/codegen/boxWithStdlib/ranges/expression/progressionMaxValueToMaxValue.kt @@ -0,0 +1,68 @@ +// Auto-generated by org.jetbrains.jet.generators.tests.GenerateRangesCodegenTestData. DO NOT EDIT! +import java.util.ArrayList +import java.lang as j + +import java.lang.Integer.MAX_VALUE as MaxI +import java.lang.Integer.MIN_VALUE as MinI +import java.lang.Byte.MAX_VALUE as MaxB +import java.lang.Byte.MIN_VALUE as MinB +import java.lang.Short.MAX_VALUE as MaxS +import java.lang.Short.MIN_VALUE as MinS +import java.lang.Long.MAX_VALUE as MaxL +import java.lang.Long.MIN_VALUE as MinL +import java.lang.Character.MAX_VALUE as MaxC +import java.lang.Character.MIN_VALUE as MinC + +fun box(): String { + val list1 = ArrayList() + val range1 = MaxI..MaxI step 1 + for (i in range1) { + list1.add(i) + if (list1.size() > 23) break + } + if (list1 != listOf(MaxI)) { + return "Wrong elements for MaxI..MaxI step 1: $list1" + } + + val list2 = ArrayList() + val range2 = MaxB..MaxB step 1 + for (i in range2) { + list2.add(i) + if (list2.size() > 23) break + } + if (list2 != listOf(MaxB)) { + return "Wrong elements for MaxB..MaxB step 1: $list2" + } + + val list3 = ArrayList() + val range3 = MaxS..MaxS step 1 + for (i in range3) { + list3.add(i) + if (list3.size() > 23) break + } + if (list3 != listOf(MaxS)) { + return "Wrong elements for MaxS..MaxS step 1: $list3" + } + + val list4 = ArrayList() + val range4 = MaxL..MaxL step 1 + for (i in range4) { + list4.add(i) + if (list4.size() > 23) break + } + if (list4 != listOf(MaxL)) { + return "Wrong elements for MaxL..MaxL step 1: $list4" + } + + val list5 = ArrayList() + val range5 = MaxC..MaxC step 1 + for (i in range5) { + list5.add(i) + if (list5.size() > 23) break + } + if (list5 != listOf(MaxC)) { + return "Wrong elements for MaxC..MaxC step 1: $list5" + } + + return "OK" +} diff --git a/compiler/testData/codegen/boxWithStdlib/ranges/expression/progressionMaxValueToMinValue.kt b/compiler/testData/codegen/boxWithStdlib/ranges/expression/progressionMaxValueToMinValue.kt new file mode 100644 index 00000000000..f98fa931b5f --- /dev/null +++ b/compiler/testData/codegen/boxWithStdlib/ranges/expression/progressionMaxValueToMinValue.kt @@ -0,0 +1,68 @@ +// Auto-generated by org.jetbrains.jet.generators.tests.GenerateRangesCodegenTestData. DO NOT EDIT! +import java.util.ArrayList +import java.lang as j + +import java.lang.Integer.MAX_VALUE as MaxI +import java.lang.Integer.MIN_VALUE as MinI +import java.lang.Byte.MAX_VALUE as MaxB +import java.lang.Byte.MIN_VALUE as MinB +import java.lang.Short.MAX_VALUE as MaxS +import java.lang.Short.MIN_VALUE as MinS +import java.lang.Long.MAX_VALUE as MaxL +import java.lang.Long.MIN_VALUE as MinL +import java.lang.Character.MAX_VALUE as MaxC +import java.lang.Character.MIN_VALUE as MinC + +fun box(): String { + val list1 = ArrayList() + val range1 = MaxI..MinI step 1 + for (i in range1) { + list1.add(i) + if (list1.size() > 23) break + } + if (list1 != listOf()) { + return "Wrong elements for MaxI..MinI step 1: $list1" + } + + val list2 = ArrayList() + val range2 = MaxB..MinB step 1 + for (i in range2) { + list2.add(i) + if (list2.size() > 23) break + } + if (list2 != listOf()) { + return "Wrong elements for MaxB..MinB step 1: $list2" + } + + val list3 = ArrayList() + val range3 = MaxS..MinS step 1 + for (i in range3) { + list3.add(i) + if (list3.size() > 23) break + } + if (list3 != listOf()) { + return "Wrong elements for MaxS..MinS step 1: $list3" + } + + val list4 = ArrayList() + val range4 = MaxL..MinL step 1 + for (i in range4) { + list4.add(i) + if (list4.size() > 23) break + } + if (list4 != listOf()) { + return "Wrong elements for MaxL..MinL step 1: $list4" + } + + val list5 = ArrayList() + val range5 = MaxC..MinC step 1 + for (i in range5) { + list5.add(i) + if (list5.size() > 23) break + } + if (list5 != listOf()) { + return "Wrong elements for MaxC..MinC step 1: $list5" + } + + return "OK" +} diff --git a/compiler/testData/codegen/boxWithStdlib/ranges/expression/progressionMinValueToMinValue.kt b/compiler/testData/codegen/boxWithStdlib/ranges/expression/progressionMinValueToMinValue.kt new file mode 100644 index 00000000000..841e4a2f972 --- /dev/null +++ b/compiler/testData/codegen/boxWithStdlib/ranges/expression/progressionMinValueToMinValue.kt @@ -0,0 +1,68 @@ +// Auto-generated by org.jetbrains.jet.generators.tests.GenerateRangesCodegenTestData. DO NOT EDIT! +import java.util.ArrayList +import java.lang as j + +import java.lang.Integer.MAX_VALUE as MaxI +import java.lang.Integer.MIN_VALUE as MinI +import java.lang.Byte.MAX_VALUE as MaxB +import java.lang.Byte.MIN_VALUE as MinB +import java.lang.Short.MAX_VALUE as MaxS +import java.lang.Short.MIN_VALUE as MinS +import java.lang.Long.MAX_VALUE as MaxL +import java.lang.Long.MIN_VALUE as MinL +import java.lang.Character.MAX_VALUE as MaxC +import java.lang.Character.MIN_VALUE as MinC + +fun box(): String { + val list1 = ArrayList() + val range1 = MinI..MinI step 1 + for (i in range1) { + list1.add(i) + if (list1.size() > 23) break + } + if (list1 != listOf(MinI)) { + return "Wrong elements for MinI..MinI step 1: $list1" + } + + val list2 = ArrayList() + val range2 = MinB..MinB step 1 + for (i in range2) { + list2.add(i) + if (list2.size() > 23) break + } + if (list2 != listOf(MinB)) { + return "Wrong elements for MinB..MinB step 1: $list2" + } + + val list3 = ArrayList() + val range3 = MinS..MinS step 1 + for (i in range3) { + list3.add(i) + if (list3.size() > 23) break + } + if (list3 != listOf(MinS)) { + return "Wrong elements for MinS..MinS step 1: $list3" + } + + val list4 = ArrayList() + val range4 = MinL..MinL step 1 + for (i in range4) { + list4.add(i) + if (list4.size() > 23) break + } + if (list4 != listOf(MinL)) { + return "Wrong elements for MinL..MinL step 1: $list4" + } + + val list5 = ArrayList() + val range5 = MinC..MinC step 1 + for (i in range5) { + list5.add(i) + if (list5.size() > 23) break + } + if (list5 != listOf(MinC)) { + return "Wrong elements for MinC..MinC step 1: $list5" + } + + return "OK" +} diff --git a/compiler/testData/codegen/boxWithStdlib/ranges/literal/inexactDownToMinValue.kt b/compiler/testData/codegen/boxWithStdlib/ranges/literal/inexactDownToMinValue.kt new file mode 100644 index 00000000000..377f478c9d4 --- /dev/null +++ b/compiler/testData/codegen/boxWithStdlib/ranges/literal/inexactDownToMinValue.kt @@ -0,0 +1,63 @@ +// Auto-generated by org.jetbrains.jet.generators.tests.GenerateRangesCodegenTestData. DO NOT EDIT! +import java.util.ArrayList +import java.lang as j + +import java.lang.Integer.MAX_VALUE as MaxI +import java.lang.Integer.MIN_VALUE as MinI +import java.lang.Byte.MAX_VALUE as MaxB +import java.lang.Byte.MIN_VALUE as MinB +import java.lang.Short.MAX_VALUE as MaxS +import java.lang.Short.MIN_VALUE as MinS +import java.lang.Long.MAX_VALUE as MaxL +import java.lang.Long.MIN_VALUE as MinL +import java.lang.Character.MAX_VALUE as MaxC +import java.lang.Character.MIN_VALUE as MinC + +fun box(): String { + val list1 = ArrayList() + for (i in (MinI + 5) downTo MinI step 3) { + list1.add(i) + if (list1.size() > 23) break + } + if (list1 != listOf(MinI + 5, MinI + 2)) { + return "Wrong elements for (MinI + 5) downTo MinI step 3: $list1" + } + + val list2 = ArrayList() + for (i in (MinB + 5).toByte() downTo MinB step 3) { + list2.add(i) + if (list2.size() > 23) break + } + if (list2 != listOf((MinB + 5).toByte(), (MinB + 2).toByte())) { + return "Wrong elements for (MinB + 5).toByte() downTo MinB step 3: $list2" + } + + val list3 = ArrayList() + for (i in (MinS + 5).toShort() downTo MinS step 3) { + list3.add(i) + if (list3.size() > 23) break + } + if (list3 != listOf((MinS + 5).toShort(), (MinS + 2).toShort())) { + return "Wrong elements for (MinS + 5).toShort() downTo MinS step 3: $list3" + } + + val list4 = ArrayList() + for (i in (MinL + 5).toLong() downTo MinL step 3) { + list4.add(i) + if (list4.size() > 23) break + } + if (list4 != listOf((MinL + 5).toLong(), (MinL + 2).toLong())) { + return "Wrong elements for (MinL + 5).toLong() downTo MinL step 3: $list4" + } + + val list5 = ArrayList() + for (i in (MinC + 5).toChar() downTo MinC step 3) { + list5.add(i) + if (list5.size() > 23) break + } + if (list5 != listOf((MinC + 5).toChar(), (MinC + 2).toChar())) { + return "Wrong elements for (MinC + 5).toChar() downTo MinC step 3: $list5" + } + + return "OK" +} diff --git a/compiler/testData/codegen/boxWithStdlib/ranges/literal/inexactToMaxValue.kt b/compiler/testData/codegen/boxWithStdlib/ranges/literal/inexactToMaxValue.kt new file mode 100644 index 00000000000..d587c6179c7 --- /dev/null +++ b/compiler/testData/codegen/boxWithStdlib/ranges/literal/inexactToMaxValue.kt @@ -0,0 +1,63 @@ +// Auto-generated by org.jetbrains.jet.generators.tests.GenerateRangesCodegenTestData. DO NOT EDIT! +import java.util.ArrayList +import java.lang as j + +import java.lang.Integer.MAX_VALUE as MaxI +import java.lang.Integer.MIN_VALUE as MinI +import java.lang.Byte.MAX_VALUE as MaxB +import java.lang.Byte.MIN_VALUE as MinB +import java.lang.Short.MAX_VALUE as MaxS +import java.lang.Short.MIN_VALUE as MinS +import java.lang.Long.MAX_VALUE as MaxL +import java.lang.Long.MIN_VALUE as MinL +import java.lang.Character.MAX_VALUE as MaxC +import java.lang.Character.MIN_VALUE as MinC + +fun box(): String { + val list1 = ArrayList() + for (i in (MaxI - 5)..MaxI step 3) { + list1.add(i) + if (list1.size() > 23) break + } + if (list1 != listOf(MaxI - 5, MaxI - 2)) { + return "Wrong elements for (MaxI - 5)..MaxI step 3: $list1" + } + + val list2 = ArrayList() + for (i in (MaxB - 5).toByte()..MaxB step 3) { + list2.add(i) + if (list2.size() > 23) break + } + if (list2 != listOf((MaxB - 5).toByte(), (MaxB - 2).toByte())) { + return "Wrong elements for (MaxB - 5).toByte()..MaxB step 3: $list2" + } + + val list3 = ArrayList() + for (i in (MaxS - 5).toShort()..MaxS step 3) { + list3.add(i) + if (list3.size() > 23) break + } + if (list3 != listOf((MaxS - 5).toShort(), (MaxS - 2).toShort())) { + return "Wrong elements for (MaxS - 5).toShort()..MaxS step 3: $list3" + } + + val list4 = ArrayList() + for (i in (MaxL - 5).toLong()..MaxL step 3) { + list4.add(i) + if (list4.size() > 23) break + } + if (list4 != listOf((MaxL - 5).toLong(), (MaxL - 2).toLong())) { + return "Wrong elements for (MaxL - 5).toLong()..MaxL step 3: $list4" + } + + val list5 = ArrayList() + for (i in (MaxC - 5).toChar()..MaxC step 3) { + list5.add(i) + if (list5.size() > 23) break + } + if (list5 != listOf((MaxC - 5).toChar(), (MaxC - 2).toChar())) { + return "Wrong elements for (MaxC - 5).toChar()..MaxC step 3: $list5" + } + + return "OK" +} diff --git a/compiler/testData/codegen/boxWithStdlib/ranges/literal/progressionDownToMinValue.kt b/compiler/testData/codegen/boxWithStdlib/ranges/literal/progressionDownToMinValue.kt new file mode 100644 index 00000000000..c46ecb75624 --- /dev/null +++ b/compiler/testData/codegen/boxWithStdlib/ranges/literal/progressionDownToMinValue.kt @@ -0,0 +1,63 @@ +// Auto-generated by org.jetbrains.jet.generators.tests.GenerateRangesCodegenTestData. DO NOT EDIT! +import java.util.ArrayList +import java.lang as j + +import java.lang.Integer.MAX_VALUE as MaxI +import java.lang.Integer.MIN_VALUE as MinI +import java.lang.Byte.MAX_VALUE as MaxB +import java.lang.Byte.MIN_VALUE as MinB +import java.lang.Short.MAX_VALUE as MaxS +import java.lang.Short.MIN_VALUE as MinS +import java.lang.Long.MAX_VALUE as MaxL +import java.lang.Long.MIN_VALUE as MinL +import java.lang.Character.MAX_VALUE as MaxC +import java.lang.Character.MIN_VALUE as MinC + +fun box(): String { + val list1 = ArrayList() + for (i in (MinI + 2) downTo MinI step 1) { + list1.add(i) + if (list1.size() > 23) break + } + if (list1 != listOf(MinI + 2, MinI + 1, MinI)) { + return "Wrong elements for (MinI + 2) downTo MinI step 1: $list1" + } + + val list2 = ArrayList() + for (i in (MinB + 2).toByte() downTo MinB step 1) { + list2.add(i) + if (list2.size() > 23) break + } + if (list2 != listOf((MinB + 2).toByte(), (MinB + 1).toByte(), MinB)) { + return "Wrong elements for (MinB + 2).toByte() downTo MinB step 1: $list2" + } + + val list3 = ArrayList() + for (i in (MinS + 2).toShort() downTo MinS step 1) { + list3.add(i) + if (list3.size() > 23) break + } + if (list3 != listOf((MinS + 2).toShort(), (MinS + 1).toShort(), MinS)) { + return "Wrong elements for (MinS + 2).toShort() downTo MinS step 1: $list3" + } + + val list4 = ArrayList() + for (i in (MinL + 2).toLong() downTo MinL step 1) { + list4.add(i) + if (list4.size() > 23) break + } + if (list4 != listOf((MinL + 2).toLong(), (MinL + 1).toLong(), MinL)) { + return "Wrong elements for (MinL + 2).toLong() downTo MinL step 1: $list4" + } + + val list5 = ArrayList() + for (i in (MinC + 2).toChar() downTo MinC step 1) { + list5.add(i) + if (list5.size() > 23) break + } + if (list5 != listOf((MinC + 2).toChar(), (MinC + 1).toChar(), MinC)) { + return "Wrong elements for (MinC + 2).toChar() downTo MinC step 1: $list5" + } + + return "OK" +} diff --git a/compiler/testData/codegen/boxWithStdlib/ranges/literal/progressionMaxValueMinusTwoToMaxValue.kt b/compiler/testData/codegen/boxWithStdlib/ranges/literal/progressionMaxValueMinusTwoToMaxValue.kt new file mode 100644 index 00000000000..6898b60201c --- /dev/null +++ b/compiler/testData/codegen/boxWithStdlib/ranges/literal/progressionMaxValueMinusTwoToMaxValue.kt @@ -0,0 +1,63 @@ +// Auto-generated by org.jetbrains.jet.generators.tests.GenerateRangesCodegenTestData. DO NOT EDIT! +import java.util.ArrayList +import java.lang as j + +import java.lang.Integer.MAX_VALUE as MaxI +import java.lang.Integer.MIN_VALUE as MinI +import java.lang.Byte.MAX_VALUE as MaxB +import java.lang.Byte.MIN_VALUE as MinB +import java.lang.Short.MAX_VALUE as MaxS +import java.lang.Short.MIN_VALUE as MinS +import java.lang.Long.MAX_VALUE as MaxL +import java.lang.Long.MIN_VALUE as MinL +import java.lang.Character.MAX_VALUE as MaxC +import java.lang.Character.MIN_VALUE as MinC + +fun box(): String { + val list1 = ArrayList() + for (i in (MaxI - 2)..MaxI step 2) { + list1.add(i) + if (list1.size() > 23) break + } + if (list1 != listOf(MaxI - 2, MaxI)) { + return "Wrong elements for (MaxI - 2)..MaxI step 2: $list1" + } + + val list2 = ArrayList() + for (i in (MaxB - 2).toByte()..MaxB step 2) { + list2.add(i) + if (list2.size() > 23) break + } + if (list2 != listOf((MaxB - 2).toByte(), MaxB)) { + return "Wrong elements for (MaxB - 2).toByte()..MaxB step 2: $list2" + } + + val list3 = ArrayList() + for (i in (MaxS - 2).toShort()..MaxS step 2) { + list3.add(i) + if (list3.size() > 23) break + } + if (list3 != listOf((MaxS - 2).toShort(), MaxS)) { + return "Wrong elements for (MaxS - 2).toShort()..MaxS step 2: $list3" + } + + val list4 = ArrayList() + for (i in (MaxL - 2).toLong()..MaxL step 2) { + list4.add(i) + if (list4.size() > 23) break + } + if (list4 != listOf((MaxL - 2).toLong(), MaxL)) { + return "Wrong elements for (MaxL - 2).toLong()..MaxL step 2: $list4" + } + + val list5 = ArrayList() + for (i in (MaxC - 2).toChar()..MaxC step 2) { + list5.add(i) + if (list5.size() > 23) break + } + if (list5 != listOf((MaxC - 2).toChar(), MaxC)) { + return "Wrong elements for (MaxC - 2).toChar()..MaxC step 2: $list5" + } + + return "OK" +} diff --git a/compiler/testData/codegen/boxWithStdlib/ranges/literal/progressionMaxValueToMaxValue.kt b/compiler/testData/codegen/boxWithStdlib/ranges/literal/progressionMaxValueToMaxValue.kt new file mode 100644 index 00000000000..273c3f130c0 --- /dev/null +++ b/compiler/testData/codegen/boxWithStdlib/ranges/literal/progressionMaxValueToMaxValue.kt @@ -0,0 +1,63 @@ +// Auto-generated by org.jetbrains.jet.generators.tests.GenerateRangesCodegenTestData. DO NOT EDIT! +import java.util.ArrayList +import java.lang as j + +import java.lang.Integer.MAX_VALUE as MaxI +import java.lang.Integer.MIN_VALUE as MinI +import java.lang.Byte.MAX_VALUE as MaxB +import java.lang.Byte.MIN_VALUE as MinB +import java.lang.Short.MAX_VALUE as MaxS +import java.lang.Short.MIN_VALUE as MinS +import java.lang.Long.MAX_VALUE as MaxL +import java.lang.Long.MIN_VALUE as MinL +import java.lang.Character.MAX_VALUE as MaxC +import java.lang.Character.MIN_VALUE as MinC + +fun box(): String { + val list1 = ArrayList() + for (i in MaxI..MaxI step 1) { + list1.add(i) + if (list1.size() > 23) break + } + if (list1 != listOf(MaxI)) { + return "Wrong elements for MaxI..MaxI step 1: $list1" + } + + val list2 = ArrayList() + for (i in MaxB..MaxB step 1) { + list2.add(i) + if (list2.size() > 23) break + } + if (list2 != listOf(MaxB)) { + return "Wrong elements for MaxB..MaxB step 1: $list2" + } + + val list3 = ArrayList() + for (i in MaxS..MaxS step 1) { + list3.add(i) + if (list3.size() > 23) break + } + if (list3 != listOf(MaxS)) { + return "Wrong elements for MaxS..MaxS step 1: $list3" + } + + val list4 = ArrayList() + for (i in MaxL..MaxL step 1) { + list4.add(i) + if (list4.size() > 23) break + } + if (list4 != listOf(MaxL)) { + return "Wrong elements for MaxL..MaxL step 1: $list4" + } + + val list5 = ArrayList() + for (i in MaxC..MaxC step 1) { + list5.add(i) + if (list5.size() > 23) break + } + if (list5 != listOf(MaxC)) { + return "Wrong elements for MaxC..MaxC step 1: $list5" + } + + return "OK" +} diff --git a/compiler/testData/codegen/boxWithStdlib/ranges/literal/progressionMaxValueToMinValue.kt b/compiler/testData/codegen/boxWithStdlib/ranges/literal/progressionMaxValueToMinValue.kt new file mode 100644 index 00000000000..a3c79c8f816 --- /dev/null +++ b/compiler/testData/codegen/boxWithStdlib/ranges/literal/progressionMaxValueToMinValue.kt @@ -0,0 +1,63 @@ +// Auto-generated by org.jetbrains.jet.generators.tests.GenerateRangesCodegenTestData. DO NOT EDIT! +import java.util.ArrayList +import java.lang as j + +import java.lang.Integer.MAX_VALUE as MaxI +import java.lang.Integer.MIN_VALUE as MinI +import java.lang.Byte.MAX_VALUE as MaxB +import java.lang.Byte.MIN_VALUE as MinB +import java.lang.Short.MAX_VALUE as MaxS +import java.lang.Short.MIN_VALUE as MinS +import java.lang.Long.MAX_VALUE as MaxL +import java.lang.Long.MIN_VALUE as MinL +import java.lang.Character.MAX_VALUE as MaxC +import java.lang.Character.MIN_VALUE as MinC + +fun box(): String { + val list1 = ArrayList() + for (i in MaxI..MinI step 1) { + list1.add(i) + if (list1.size() > 23) break + } + if (list1 != listOf()) { + return "Wrong elements for MaxI..MinI step 1: $list1" + } + + val list2 = ArrayList() + for (i in MaxB..MinB step 1) { + list2.add(i) + if (list2.size() > 23) break + } + if (list2 != listOf()) { + return "Wrong elements for MaxB..MinB step 1: $list2" + } + + val list3 = ArrayList() + for (i in MaxS..MinS step 1) { + list3.add(i) + if (list3.size() > 23) break + } + if (list3 != listOf()) { + return "Wrong elements for MaxS..MinS step 1: $list3" + } + + val list4 = ArrayList() + for (i in MaxL..MinL step 1) { + list4.add(i) + if (list4.size() > 23) break + } + if (list4 != listOf()) { + return "Wrong elements for MaxL..MinL step 1: $list4" + } + + val list5 = ArrayList() + for (i in MaxC..MinC step 1) { + list5.add(i) + if (list5.size() > 23) break + } + if (list5 != listOf()) { + return "Wrong elements for MaxC..MinC step 1: $list5" + } + + return "OK" +} diff --git a/compiler/testData/codegen/boxWithStdlib/ranges/literal/progressionMinValueToMinValue.kt b/compiler/testData/codegen/boxWithStdlib/ranges/literal/progressionMinValueToMinValue.kt new file mode 100644 index 00000000000..88400d8192a --- /dev/null +++ b/compiler/testData/codegen/boxWithStdlib/ranges/literal/progressionMinValueToMinValue.kt @@ -0,0 +1,63 @@ +// Auto-generated by org.jetbrains.jet.generators.tests.GenerateRangesCodegenTestData. DO NOT EDIT! +import java.util.ArrayList +import java.lang as j + +import java.lang.Integer.MAX_VALUE as MaxI +import java.lang.Integer.MIN_VALUE as MinI +import java.lang.Byte.MAX_VALUE as MaxB +import java.lang.Byte.MIN_VALUE as MinB +import java.lang.Short.MAX_VALUE as MaxS +import java.lang.Short.MIN_VALUE as MinS +import java.lang.Long.MAX_VALUE as MaxL +import java.lang.Long.MIN_VALUE as MinL +import java.lang.Character.MAX_VALUE as MaxC +import java.lang.Character.MIN_VALUE as MinC + +fun box(): String { + val list1 = ArrayList() + for (i in MinI..MinI step 1) { + list1.add(i) + if (list1.size() > 23) break + } + if (list1 != listOf(MinI)) { + return "Wrong elements for MinI..MinI step 1: $list1" + } + + val list2 = ArrayList() + for (i in MinB..MinB step 1) { + list2.add(i) + if (list2.size() > 23) break + } + if (list2 != listOf(MinB)) { + return "Wrong elements for MinB..MinB step 1: $list2" + } + + val list3 = ArrayList() + for (i in MinS..MinS step 1) { + list3.add(i) + if (list3.size() > 23) break + } + if (list3 != listOf(MinS)) { + return "Wrong elements for MinS..MinS step 1: $list3" + } + + val list4 = ArrayList() + for (i in MinL..MinL step 1) { + list4.add(i) + if (list4.size() > 23) break + } + if (list4 != listOf(MinL)) { + return "Wrong elements for MinL..MinL step 1: $list4" + } + + val list5 = ArrayList() + for (i in MinC..MinC step 1) { + list5.add(i) + if (list5.size() > 23) break + } + if (list5 != listOf(MinC)) { + return "Wrong elements for MinC..MinC step 1: $list5" + } + + 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 26cc88726d3..540c6ab73aa 100644 --- a/compiler/tests/org/jetbrains/jet/codegen/generated/BlackBoxWithStdlibCodegenTestGenerated.java +++ b/compiler/tests/org/jetbrains/jet/codegen/generated/BlackBoxWithStdlibCodegenTestGenerated.java @@ -424,6 +424,11 @@ public class BlackBoxWithStdlibCodegenTestGenerated extends AbstractBlackBoxCode doTestWithStdlib("compiler/testData/codegen/boxWithStdlib/ranges/expression/emptyRange.kt"); } + @TestMetadata("inexactDownToMinValue.kt") + public void testInexactDownToMinValue() throws Exception { + doTestWithStdlib("compiler/testData/codegen/boxWithStdlib/ranges/expression/inexactDownToMinValue.kt"); + } + @TestMetadata("inexactSteppedDownTo.kt") public void testInexactSteppedDownTo() throws Exception { doTestWithStdlib("compiler/testData/codegen/boxWithStdlib/ranges/expression/inexactSteppedDownTo.kt"); @@ -434,6 +439,11 @@ public class BlackBoxWithStdlibCodegenTestGenerated extends AbstractBlackBoxCode doTestWithStdlib("compiler/testData/codegen/boxWithStdlib/ranges/expression/inexactSteppedRange.kt"); } + @TestMetadata("inexactToMaxValue.kt") + public void testInexactToMaxValue() throws Exception { + doTestWithStdlib("compiler/testData/codegen/boxWithStdlib/ranges/expression/inexactToMaxValue.kt"); + } + @TestMetadata("infiniteSteps.kt") public void testInfiniteSteps() throws Exception { doTestWithStdlib("compiler/testData/codegen/boxWithStdlib/ranges/expression/infiniteSteps.kt"); @@ -469,6 +479,31 @@ public class BlackBoxWithStdlibCodegenTestGenerated extends AbstractBlackBoxCode doTestWithStdlib("compiler/testData/codegen/boxWithStdlib/ranges/expression/oneElementRange.kt"); } + @TestMetadata("progressionDownToMinValue.kt") + public void testProgressionDownToMinValue() throws Exception { + doTestWithStdlib("compiler/testData/codegen/boxWithStdlib/ranges/expression/progressionDownToMinValue.kt"); + } + + @TestMetadata("progressionMaxValueMinusTwoToMaxValue.kt") + public void testProgressionMaxValueMinusTwoToMaxValue() throws Exception { + doTestWithStdlib("compiler/testData/codegen/boxWithStdlib/ranges/expression/progressionMaxValueMinusTwoToMaxValue.kt"); + } + + @TestMetadata("progressionMaxValueToMaxValue.kt") + public void testProgressionMaxValueToMaxValue() throws Exception { + doTestWithStdlib("compiler/testData/codegen/boxWithStdlib/ranges/expression/progressionMaxValueToMaxValue.kt"); + } + + @TestMetadata("progressionMaxValueToMinValue.kt") + public void testProgressionMaxValueToMinValue() throws Exception { + doTestWithStdlib("compiler/testData/codegen/boxWithStdlib/ranges/expression/progressionMaxValueToMinValue.kt"); + } + + @TestMetadata("progressionMinValueToMinValue.kt") + public void testProgressionMinValueToMinValue() throws Exception { + doTestWithStdlib("compiler/testData/codegen/boxWithStdlib/ranges/expression/progressionMinValueToMinValue.kt"); + } + @TestMetadata("reversedBackSequence.kt") public void testReversedBackSequence() throws Exception { doTestWithStdlib("compiler/testData/codegen/boxWithStdlib/ranges/expression/reversedBackSequence.kt"); @@ -542,6 +577,11 @@ public class BlackBoxWithStdlibCodegenTestGenerated extends AbstractBlackBoxCode doTestWithStdlib("compiler/testData/codegen/boxWithStdlib/ranges/literal/emptyRange.kt"); } + @TestMetadata("inexactDownToMinValue.kt") + public void testInexactDownToMinValue() throws Exception { + doTestWithStdlib("compiler/testData/codegen/boxWithStdlib/ranges/literal/inexactDownToMinValue.kt"); + } + @TestMetadata("inexactSteppedDownTo.kt") public void testInexactSteppedDownTo() throws Exception { doTestWithStdlib("compiler/testData/codegen/boxWithStdlib/ranges/literal/inexactSteppedDownTo.kt"); @@ -552,6 +592,11 @@ public class BlackBoxWithStdlibCodegenTestGenerated extends AbstractBlackBoxCode doTestWithStdlib("compiler/testData/codegen/boxWithStdlib/ranges/literal/inexactSteppedRange.kt"); } + @TestMetadata("inexactToMaxValue.kt") + public void testInexactToMaxValue() throws Exception { + doTestWithStdlib("compiler/testData/codegen/boxWithStdlib/ranges/literal/inexactToMaxValue.kt"); + } + @TestMetadata("infiniteSteps.kt") public void testInfiniteSteps() throws Exception { doTestWithStdlib("compiler/testData/codegen/boxWithStdlib/ranges/literal/infiniteSteps.kt"); @@ -587,6 +632,31 @@ public class BlackBoxWithStdlibCodegenTestGenerated extends AbstractBlackBoxCode doTestWithStdlib("compiler/testData/codegen/boxWithStdlib/ranges/literal/oneElementRange.kt"); } + @TestMetadata("progressionDownToMinValue.kt") + public void testProgressionDownToMinValue() throws Exception { + doTestWithStdlib("compiler/testData/codegen/boxWithStdlib/ranges/literal/progressionDownToMinValue.kt"); + } + + @TestMetadata("progressionMaxValueMinusTwoToMaxValue.kt") + public void testProgressionMaxValueMinusTwoToMaxValue() throws Exception { + doTestWithStdlib("compiler/testData/codegen/boxWithStdlib/ranges/literal/progressionMaxValueMinusTwoToMaxValue.kt"); + } + + @TestMetadata("progressionMaxValueToMaxValue.kt") + public void testProgressionMaxValueToMaxValue() throws Exception { + doTestWithStdlib("compiler/testData/codegen/boxWithStdlib/ranges/literal/progressionMaxValueToMaxValue.kt"); + } + + @TestMetadata("progressionMaxValueToMinValue.kt") + public void testProgressionMaxValueToMinValue() throws Exception { + doTestWithStdlib("compiler/testData/codegen/boxWithStdlib/ranges/literal/progressionMaxValueToMinValue.kt"); + } + + @TestMetadata("progressionMinValueToMinValue.kt") + public void testProgressionMinValueToMinValue() throws Exception { + doTestWithStdlib("compiler/testData/codegen/boxWithStdlib/ranges/literal/progressionMinValueToMinValue.kt"); + } + @TestMetadata("reversedBackSequence.kt") public void testReversedBackSequence() throws Exception { doTestWithStdlib("compiler/testData/codegen/boxWithStdlib/ranges/literal/reversedBackSequence.kt"); diff --git a/generators/org/jetbrains/jet/generators/tests/GenerateRangesCodegenTestData.java b/generators/org/jetbrains/jet/generators/tests/GenerateRangesCodegenTestData.java index fabedee33f9..75a7235299e 100644 --- a/generators/org/jetbrains/jet/generators/tests/GenerateRangesCodegenTestData.java +++ b/generators/org/jetbrains/jet/generators/tests/GenerateRangesCodegenTestData.java @@ -68,9 +68,13 @@ public class GenerateRangesCodegenTestData { .put("Float.NaN", "Float") .put("Double.NaN", "Double") .put("MaxB", "Byte") + .put("MinB", "Byte") .put("MaxS", "Short") + .put("MinS", "Short") .put("MaxL", "Long") + .put("MinL", "Long") .put("MaxC", "Char") + .put("MinC", "Char") .build(); private static String detectElementType(String rangeExpression) { diff --git a/libraries/stdlib/test/language/RangeIterationTest.kt b/libraries/stdlib/test/language/RangeIterationTest.kt index 37fcd7e9e48..7806eb9b6f6 100644 --- a/libraries/stdlib/test/language/RangeIterationTest.kt +++ b/libraries/stdlib/test/language/RangeIterationTest.kt @@ -318,4 +318,67 @@ public class RangeIterationTest { doTest(MaxC..MinC, MaxC, MinC, 1, listOf()) } + + test fun progressionMaxValueToMaxValue() { + doTest(MaxI..MaxI step 1, MaxI, MaxI, 1, listOf(MaxI)) + doTest(MaxB..MaxB step 1, MaxB, MaxB, 1, listOf(MaxB)) + doTest(MaxS..MaxS step 1, MaxS, MaxS, 1, listOf(MaxS)) + doTest(MaxL..MaxL step 1, MaxL, MaxL, 1.toLong(), listOf(MaxL)) + + doTest(MaxC..MaxC step 1, MaxC, MaxC, 1, listOf(MaxC)) + } + + test fun progressionMaxValueMinusTwoToMaxValue() { + doTest((MaxI - 2)..MaxI step 2, MaxI - 2, MaxI, 2, listOf(MaxI - 2, MaxI)) + doTest((MaxB - 2).toByte()..MaxB step 2, (MaxB - 2).toByte(), MaxB, 2, listOf((MaxB - 2).toByte(), MaxB)) + doTest((MaxS - 2).toShort()..MaxS step 2, (MaxS - 2).toShort(), MaxS, 2, listOf((MaxS - 2).toShort(), MaxS)) + doTest((MaxL - 2).toLong()..MaxL step 2, (MaxL - 2).toLong(), MaxL, 2.toLong(), listOf((MaxL - 2).toLong(), MaxL)) + + doTest((MaxC - 2).toChar()..MaxC step 2, (MaxC - 2).toChar(), MaxC, 2, listOf((MaxC - 2).toChar(), MaxC)) + } + + test fun progressionMaxValueToMinValue() { + doTest(MaxI..MinI step 1, MaxI, MinI, 1, listOf()) + doTest(MaxB..MinB step 1, MaxB, MinB, 1, listOf()) + doTest(MaxS..MinS step 1, MaxS, MinS, 1, listOf()) + doTest(MaxL..MinL step 1, MaxL, MinL, 1.toLong(), listOf()) + + doTest(MaxC..MinC step 1, MaxC, MinC, 1, listOf()) + } + + test fun progressionMinValueToMinValue() { + doTest(MinI..MinI step 1, MinI, MinI, 1, listOf(MinI)) + doTest(MinB..MinB step 1, MinB, MinB, 1, listOf(MinB)) + doTest(MinS..MinS step 1, MinS, MinS, 1, listOf(MinS)) + doTest(MinL..MinL step 1, MinL, MinL, 1.toLong(), listOf(MinL)) + + doTest(MinC..MinC step 1, MinC, MinC, 1, listOf(MinC)) + } + + test fun inexactToMaxValue() { + doTest((MaxI - 5)..MaxI step 3, MaxI - 5, MaxI, 3, listOf(MaxI - 5, MaxI - 2)) + doTest((MaxB - 5).toByte()..MaxB step 3, (MaxB - 5).toByte(), MaxB, 3, listOf((MaxB - 5).toByte(), (MaxB - 2).toByte())) + doTest((MaxS - 5).toShort()..MaxS step 3, (MaxS - 5).toShort(), MaxS, 3, listOf((MaxS - 5).toShort(), (MaxS - 2).toShort())) + doTest((MaxL - 5).toLong()..MaxL step 3, (MaxL - 5).toLong(), MaxL, 3.toLong(), listOf((MaxL - 5).toLong(), (MaxL - 2).toLong())) + + doTest((MaxC - 5).toChar()..MaxC step 3, (MaxC - 5).toChar(), MaxC, 3, listOf((MaxC - 5).toChar(), (MaxC - 2).toChar())) + } + + test fun progressionDownToMinValue() { + doTest((MinI + 2) downTo MinI step 1, MinI + 2, MinI, -1, listOf(MinI + 2, MinI + 1, MinI)) + doTest((MinB + 2).toByte() downTo MinB step 1, (MinB + 2).toByte(), MinB, -1, listOf((MinB + 2).toByte(), (MinB + 1).toByte(), MinB)) + doTest((MinS + 2).toShort() downTo MinS step 1, (MinS + 2).toShort(), MinS, -1, listOf((MinS + 2).toShort(), (MinS + 1).toShort(), MinS)) + doTest((MinL + 2).toLong() downTo MinL step 1, (MinL + 2).toLong(), MinL, -1.toLong(), listOf((MinL + 2).toLong(), (MinL + 1).toLong(), MinL)) + + doTest((MinC + 2).toChar() downTo MinC step 1, (MinC + 2).toChar(), MinC, -1, listOf((MinC + 2).toChar(), (MinC + 1).toChar(), MinC)) + } + + test fun inexactDownToMinValue() { + doTest((MinI + 5) downTo MinI step 3, MinI + 5, MinI, -3, listOf(MinI + 5, MinI + 2)) + doTest((MinB + 5).toByte() downTo MinB step 3, (MinB + 5).toByte(), MinB, -3, listOf((MinB + 5).toByte(), (MinB + 2).toByte())) + doTest((MinS + 5).toShort() downTo MinS step 3, (MinS + 5).toShort(), MinS, -3, listOf((MinS + 5).toShort(), (MinS + 2).toShort())) + doTest((MinL + 5).toLong() downTo MinL step 3, (MinL + 5).toLong(), MinL, -3.toLong(), listOf((MinL + 5).toLong(), (MinL + 2).toLong())) + + doTest((MinC + 5).toChar() downTo MinC step 3, (MinC + 5).toChar(), MinC, -3, listOf((MinC + 5).toChar(), (MinC + 2).toChar())) + } } diff --git a/runtime/src/jet/ByteProgressionIterator.java b/runtime/src/jet/ByteProgressionIterator.java index e2989bc789c..85243e18f2f 100644 --- a/runtime/src/jet/ByteProgressionIterator.java +++ b/runtime/src/jet/ByteProgressionIterator.java @@ -17,7 +17,7 @@ package jet; class ByteProgressionIterator extends ByteIterator { - private byte next; + private int next; private final byte end; private final int increment; @@ -34,8 +34,8 @@ class ByteProgressionIterator extends ByteIterator { @Override public byte nextByte() { - byte value = next; + int value = next; next += increment; - return value; + return (byte) value; } } diff --git a/runtime/src/jet/CharProgressionIterator.java b/runtime/src/jet/CharProgressionIterator.java index 49f8dab710f..dc608162f9f 100644 --- a/runtime/src/jet/CharProgressionIterator.java +++ b/runtime/src/jet/CharProgressionIterator.java @@ -17,7 +17,7 @@ package jet; class CharProgressionIterator extends CharIterator { - private char next; + private int next; private final char end; private final int increment; @@ -34,8 +34,8 @@ class CharProgressionIterator extends CharIterator { @Override public char nextChar() { - char value = next; + int value = next; next += increment; - return value; + return (char) value; } } diff --git a/runtime/src/jet/IntProgressionIterator.java b/runtime/src/jet/IntProgressionIterator.java index 21845098713..3d7dda17af8 100644 --- a/runtime/src/jet/IntProgressionIterator.java +++ b/runtime/src/jet/IntProgressionIterator.java @@ -20,6 +20,7 @@ class IntProgressionIterator extends IntIterator { private int next; private final int end; private final int increment; + private boolean overflowHappened = false; public IntProgressionIterator(int start, int end, int increment) { this.next = start; @@ -29,13 +30,16 @@ class IntProgressionIterator extends IntIterator { @Override public boolean hasNext() { - return increment > 0 ? next <= end : next >= end; + return !overflowHappened && (increment > 0 ? next <= end : next >= end); } @Override public int nextInt() { int value = next; next += increment; + if ((increment > 0) != (next > value)) { + overflowHappened = true; + } return value; } } diff --git a/runtime/src/jet/LongProgressionIterator.java b/runtime/src/jet/LongProgressionIterator.java index 71fc911794d..f6c613cf3fa 100644 --- a/runtime/src/jet/LongProgressionIterator.java +++ b/runtime/src/jet/LongProgressionIterator.java @@ -20,6 +20,7 @@ class LongProgressionIterator extends LongIterator { private long next; private final long end; private final long increment; + private boolean overflowHappened = false; public LongProgressionIterator(long start, long end, long increment) { this.next = start; @@ -29,13 +30,16 @@ class LongProgressionIterator extends LongIterator { @Override public boolean hasNext() { - return increment > 0 ? next <= end : next >= end; + return !overflowHappened && (increment > 0 ? next <= end : next >= end); } @Override public long nextLong() { long value = next; next += increment; + if ((increment > 0) != (next > value)) { + overflowHappened = true; + } return value; } } diff --git a/runtime/src/jet/ShortProgressionIterator.java b/runtime/src/jet/ShortProgressionIterator.java index 3b7bf8cf4f5..cd3b77200f9 100644 --- a/runtime/src/jet/ShortProgressionIterator.java +++ b/runtime/src/jet/ShortProgressionIterator.java @@ -17,7 +17,7 @@ package jet; class ShortProgressionIterator extends ShortIterator { - private short next; + private int next; private final short end; private final int increment; @@ -34,8 +34,8 @@ class ShortProgressionIterator extends ShortIterator { @Override public short nextShort() { - short value = next; + int value = next; next += increment; - return value; + return (short) value; } } From e22947281ca6786f77c8e2d86f83feb3d4f3d07b Mon Sep 17 00:00:00 2001 From: Alexander Udalov Date: Tue, 18 Jun 2013 19:47:03 +0400 Subject: [PATCH 165/291] Minor, cut down unnecessary 'load' in for-progression codegen --- .../src/org/jetbrains/jet/codegen/ExpressionCodegen.java | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java index 66edba467db..74da585b067 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java @@ -1024,6 +1024,8 @@ public class ExpressionCodegen extends JetVisitor implem @Override public void conditionAndJump(@NotNull Label loopExit) { v.load(loopParameterVar, asmElementType); + v.load(endVar, asmElementType); + v.load(incrementVar, asmElementType); Label negativeIncrement = new Label(); @@ -1038,13 +1040,11 @@ public class ExpressionCodegen extends JetVisitor implem v.ifle(negativeIncrement); // if increment < 0, jump // increment > 0 - v.load(endVar, asmElementType); v.ificmpgt(loopExit); v.goTo(afterIf); // increment < 0 v.visitLabel(negativeIncrement); - v.load(endVar, asmElementType); v.ificmplt(loopExit); v.visitLabel(afterIf); @@ -1056,14 +1056,12 @@ public class ExpressionCodegen extends JetVisitor implem v.ifle(negativeIncrement); // if increment < 0, jump // increment > 0 - v.load(endVar, asmElementType); v.lcmp(); v.ifgt(loopExit); v.goTo(afterIf); // increment < 0 v.visitLabel(negativeIncrement); - v.load(endVar, asmElementType); v.lcmp(); v.iflt(loopExit); v.visitLabel(afterIf); @@ -1082,14 +1080,12 @@ public class ExpressionCodegen extends JetVisitor implem v.ifle(negativeIncrement); // if increment < 0, jump // increment > 0 - v.load(endVar, asmElementType); v.cmpg(asmElementType); // if loop parameter is NaN, exit from loop, as well v.ifgt(loopExit); v.goTo(afterIf); // increment < 0 v.visitLabel(negativeIncrement); - v.load(endVar, asmElementType); v.cmpl(asmElementType); // if loop parameter is NaN, exit from loop, as well v.iflt(loopExit); v.visitLabel(afterIf); From 3ff5acd69ceca399dda67507878102a11083dd5c Mon Sep 17 00:00:00 2001 From: Alexander Udalov Date: Tue, 18 Jun 2013 20:08:22 +0400 Subject: [PATCH 166/291] Minor, ignore android dependencies when looking for @author --- .../tests/org/jetbrains/jet/parsing/JetCodeConformanceTest.java | 1 + 1 file changed, 1 insertion(+) diff --git a/compiler/tests/org/jetbrains/jet/parsing/JetCodeConformanceTest.java b/compiler/tests/org/jetbrains/jet/parsing/JetCodeConformanceTest.java index f95b82cf8a6..ad64b31989d 100644 --- a/compiler/tests/org/jetbrains/jet/parsing/JetCodeConformanceTest.java +++ b/compiler/tests/org/jetbrains/jet/parsing/JetCodeConformanceTest.java @@ -34,6 +34,7 @@ public class JetCodeConformanceTest extends TestCase { private static final Pattern JAVA_FILE_PATTERN = Pattern.compile(".+\\.java"); private static final Pattern SOURCES_FILE_PATTERN = Pattern.compile("(.+\\.java|.+\\.kt|.+\\.jet|.+\\.js)"); private static final List EXCLUDED_FILES_AND_DIRS = Arrays.asList( + new File("android.tests.dependencies"), new File("dependencies"), new File("examples"), new File("js/js.translator/qunit/qunit.js"), From 8a14b62a238002c310ddbedb3bf95faa4e2b9edc Mon Sep 17 00:00:00 2001 From: Alexander Udalov Date: Wed, 19 Jun 2013 18:46:58 +0400 Subject: [PATCH 167/291] KT-3574 Assertion error when using ?: in for range #KT-3574 Fixed Do not assert that resolvedCall is non-null, since getRangeAsBinaryCall can return a BinaryCall that doesn't represent a range at all (as specified by the comment in getRangeAsBinaryCall) --- .../org/jetbrains/jet/codegen/ExpressionCodegen.java | 11 +++++------ .../testData/codegen/box/controlStructures/kt3574.kt | 9 +++++++++ .../generated/BlackBoxCodegenTestGenerated.java | 5 +++++ 3 files changed, 19 insertions(+), 6 deletions(-) create mode 100644 compiler/testData/codegen/box/controlStructures/kt3574.kt diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java index 74da585b067..97e43c748eb 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java @@ -466,12 +466,11 @@ public class ExpressionCodegen extends JetVisitor implem RangeCodegenUtil.BinaryCall binaryCall = RangeCodegenUtil.getRangeAsBinaryCall(forExpression); if (binaryCall != null) { ResolvedCall resolvedCall = bindingContext.get(RESOLVED_CALL, binaryCall.op); - assert resolvedCall != null; - - CallableDescriptor rangeTo = resolvedCall.getResultingDescriptor(); - if (RangeCodegenUtil.isOptimizableRangeTo(rangeTo)) { - generateForLoop(new ForInRangeLiteralLoopGenerator(forExpression, binaryCall)); - return StackValue.none(); + if (resolvedCall != null) { + if (RangeCodegenUtil.isOptimizableRangeTo(resolvedCall.getResultingDescriptor())) { + generateForLoop(new ForInRangeLiteralLoopGenerator(forExpression, binaryCall)); + return StackValue.none(); + } } } diff --git a/compiler/testData/codegen/box/controlStructures/kt3574.kt b/compiler/testData/codegen/box/controlStructures/kt3574.kt new file mode 100644 index 00000000000..3a739e33d87 --- /dev/null +++ b/compiler/testData/codegen/box/controlStructures/kt3574.kt @@ -0,0 +1,9 @@ +fun nil() = null + +fun list() = java.util.Arrays.asList("1") + +fun box(): String { + for (x in nil()?:list()) { + } + 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 81f312778e2..c7d3a2c1a75 100644 --- a/compiler/tests/org/jetbrains/jet/codegen/generated/BlackBoxCodegenTestGenerated.java +++ b/compiler/tests/org/jetbrains/jet/codegen/generated/BlackBoxCodegenTestGenerated.java @@ -1436,6 +1436,11 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest { doTest("compiler/testData/codegen/box/controlStructures/kt3280.kt"); } + @TestMetadata("kt3574.kt") + public void testKt3574() throws Exception { + doTest("compiler/testData/codegen/box/controlStructures/kt3574.kt"); + } + @TestMetadata("kt416.kt") public void testKt416() throws Exception { doTest("compiler/testData/codegen/box/controlStructures/kt416.kt"); From d85ca4718488322843b6c85f1fc76352ffdea466 Mon Sep 17 00:00:00 2001 From: Alexander Udalov Date: Thu, 20 Jun 2013 18:06:55 +0400 Subject: [PATCH 168/291] Generate optimized bytecode for 'for' in progression Instead of checking for overflow at the end of each iteration, calculate the actual final loop parameter value before the loop, save it to the local variable and at the end of the iteration check if the loop parameter is exactly equal to this final value. ProgressionUtil.getProgressionFinalElement() credits go to @geevee --- .../jet/codegen/ExpressionCodegen.java | 350 +++++++++--------- runtime/src/jet/runtime/ProgressionUtil.java | 83 +++++ 2 files changed, 252 insertions(+), 181 deletions(-) create mode 100644 runtime/src/jet/runtime/ProgressionUtil.java diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java index 97e43c748eb..e62e277244f 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java @@ -818,65 +818,28 @@ public class ExpressionCodegen extends JetVisitor implem } } - private abstract class AbstractForInRangeLoopGenerator extends AbstractForLoopGenerator { + private abstract class AbstractForInProgressionOrRangeLoopGenerator extends AbstractForLoopGenerator { protected int endVar; - // True iff instead of comparing loopParameterVar < endVar at the beginning of an iteration we check whether - // loopParameterVar == endVar at the end of the iteration (and also if there should be any iterations at all, before the loop) - private final boolean checkEqualityInsteadOfComparison; + // For integer progressions instead of comparing loopParameterVar with endVar at the beginning of an iteration we check whether + // loopParameterVar == finalVar at the end of the iteration (and also if there should be any iterations at all, before the loop) + protected final boolean isIntegerProgression; - private AbstractForInRangeLoopGenerator(@NotNull JetForExpression forExpression) { + private AbstractForInProgressionOrRangeLoopGenerator(@NotNull JetForExpression forExpression) { super(forExpression); - checkEqualityInsteadOfComparison = asmElementType.getSort() == Type.INT || asmElementType.getSort() == Type.LONG; - } - @Override - public void beforeLoop() { - super.beforeLoop(); - - endVar = createLoopTempVariable(asmElementType); - storeRangeStartAndEnd(); - } - - @Override - public void checkEmptyLoop(@NotNull Label loopExit) { - if (!checkEqualityInsteadOfComparison) return; - - v.load(loopParameterVar, asmElementType); - v.load(endVar, asmElementType); - if (asmElementType.getSort() == Type.INT) { - v.ificmpgt(loopExit); - } - else if (asmElementType.getSort() == Type.LONG) { - v.lcmp(); - v.ifgt(loopExit); - } - else { - throw new IllegalStateException("Unexpected type for empty loop checking: " + asmElementType); - } - } - - protected abstract void storeRangeStartAndEnd(); - - @Override - public void conditionAndJump(@NotNull Label loopExit) { - if (checkEqualityInsteadOfComparison) return; - - v.load(loopParameterVar, asmElementType); - v.load(endVar, asmElementType); - - int sort = asmElementType.getSort(); - switch (sort) { - case Type.CHAR: + switch (asmElementType.getSort()) { + case Type.INT: case Type.BYTE: case Type.SHORT: - v.ificmpgt(loopExit); + case Type.CHAR: + case Type.LONG: + isIntegerProgression = true; break; - case Type.FLOAT: case Type.DOUBLE: - v.cmpg(asmElementType); - v.ifgt(loopExit); + case Type.FLOAT: + isIntegerProgression = false; break; default: @@ -885,27 +848,85 @@ public class ExpressionCodegen extends JetVisitor implem } @Override - protected void assignToLoopParameter() { + public void beforeLoop() { + super.beforeLoop(); + + endVar = createLoopTempVariable(asmElementType); } - private void checkPostCondition(@NotNull Label loopExit) { + // The local variable holding the actual last value of the loop parameter. + // For ranges it equals end, for progressions it's a function of start, end and increment + protected abstract int getFinalVar(); + + protected void checkPostCondition(@NotNull Label loopExit) { + int finalVar = getFinalVar(); + assert isIntegerProgression && finalVar != -1 : + "Post-condition should be checked only in case of integer progressions, finalVar = " + finalVar; + v.load(loopParameterVar, asmElementType); - v.load(endVar, asmElementType); - if (asmElementType.getSort() == Type.INT) { - v.ificmpeq(loopExit); - } - else if (asmElementType.getSort() == Type.LONG) { + v.load(finalVar, asmElementType); + if (asmElementType.getSort() == Type.LONG) { v.lcmp(); v.ifeq(loopExit); } else { - throw new IllegalStateException("Unexpected type for equality: " + asmElementType); + v.ificmpeq(loopExit); + } + } + } + + private abstract class AbstractForInRangeLoopGenerator extends AbstractForInProgressionOrRangeLoopGenerator { + private AbstractForInRangeLoopGenerator(@NotNull JetForExpression forExpression) { + super(forExpression); + } + + @Override + public void beforeLoop() { + super.beforeLoop(); + + storeRangeStartAndEnd(); + } + + protected abstract void storeRangeStartAndEnd(); + + @Override + protected int getFinalVar() { + return endVar; + } + + @Override + public void conditionAndJump(@NotNull Label loopExit) { + if (isIntegerProgression) return; + + v.load(loopParameterVar, asmElementType); + v.load(endVar, asmElementType); + + v.cmpg(asmElementType); + v.ifgt(loopExit); + } + + @Override + public void checkEmptyLoop(@NotNull Label loopExit) { + if (!isIntegerProgression) return; + + v.load(loopParameterVar, asmElementType); + v.load(endVar, asmElementType); + if (asmElementType.getSort() == Type.LONG) { + v.lcmp(); + v.ifgt(loopExit); + } + else { + v.ificmpgt(loopExit); } } + @Override + protected void assignToLoopParameter() { + } + @Override protected void increment(@NotNull Label loopExit) { - if (checkEqualityInsteadOfComparison) { + if (isIntegerProgression) { checkPostCondition(loopExit); } @@ -983,20 +1004,25 @@ public class ExpressionCodegen extends JetVisitor implem } } - private class ForInProgressionExpressionLoopGenerator extends AbstractForLoopGenerator { - private int endVar; + private class ForInProgressionExpressionLoopGenerator extends AbstractForInProgressionOrRangeLoopGenerator { private int incrementVar; private Type incrementType; + private int finalVar; + private ForInProgressionExpressionLoopGenerator(@NotNull JetForExpression forExpression) { super(forExpression); } + @Override + protected int getFinalVar() { + return finalVar; + } + @Override public void beforeLoop() { super.beforeLoop(); - endVar = createLoopTempVariable(asmElementType); incrementVar = createLoopTempVariable(asmElementType); JetType loopRangeType = bindingContext.get(EXPRESSION_TYPE, forExpression.getLoopRange()); @@ -1014,87 +1040,99 @@ public class ExpressionCodegen extends JetVisitor implem generateRangeOrProgressionProperty(asmLoopRangeType, "getStart", asmElementType, loopParameterVar); generateRangeOrProgressionProperty(asmLoopRangeType, "getEnd", asmElementType, endVar); generateRangeOrProgressionProperty(asmLoopRangeType, "getIncrement", incrementType, incrementVar); + + storeFinalVar(); } - @Override - public void checkEmptyLoop(@NotNull Label loopExit) { + private void storeFinalVar() { + if (!isIntegerProgression) { + finalVar = -1; + return; + } + + v.load(loopParameterVar, asmElementType); + v.load(endVar, asmElementType); + v.load(incrementVar, incrementType); + + Type methodParamType = asmElementType.getSort() == Type.LONG ? Type.LONG_TYPE : Type.INT_TYPE; + v.invokestatic("jet/runtime/ProgressionUtil", "getProgressionFinalElement", + Type.getMethodDescriptor(methodParamType, methodParamType, methodParamType, methodParamType)); + + finalVar = createLoopTempVariable(asmElementType); + v.store(finalVar, asmElementType); } @Override public void conditionAndJump(@NotNull Label loopExit) { + if (isIntegerProgression) return; + v.load(loopParameterVar, asmElementType); v.load(endVar, asmElementType); - v.load(incrementVar, asmElementType); Label negativeIncrement = new Label(); Label afterIf = new Label(); - int sort = asmElementType.getSort(); - switch (sort) { - case Type.INT: - case Type.CHAR: - case Type.BYTE: - case Type.SHORT: - v.ifle(negativeIncrement); // if increment < 0, jump - - // increment > 0 - v.ificmpgt(loopExit); - v.goTo(afterIf); - - // increment < 0 - v.visitLabel(negativeIncrement); - v.ificmplt(loopExit); - v.visitLabel(afterIf); - - break; - - case Type.LONG: - v.lconst(0L); - v.lcmp(); - v.ifle(negativeIncrement); // if increment < 0, jump - - // increment > 0 - v.lcmp(); - v.ifgt(loopExit); - v.goTo(afterIf); - - // increment < 0 - v.visitLabel(negativeIncrement); - v.lcmp(); - v.iflt(loopExit); - v.visitLabel(afterIf); - - break; - - case Type.DOUBLE: - case Type.FLOAT: - if (sort == Type.DOUBLE) { - v.dconst(0.0); - } - else { - v.fconst(0.0f); - } - v.cmpl(incrementType); - v.ifle(negativeIncrement); // if increment < 0, jump - - // increment > 0 - v.cmpg(asmElementType); // if loop parameter is NaN, exit from loop, as well - v.ifgt(loopExit); - v.goTo(afterIf); - - // increment < 0 - v.visitLabel(negativeIncrement); - v.cmpl(asmElementType); // if loop parameter is NaN, exit from loop, as well - v.iflt(loopExit); - v.visitLabel(afterIf); - - break; - - default: - throw new IllegalStateException("Unexpected range element type: " + asmElementType); + if (asmElementType.getSort() == Type.DOUBLE) { + v.dconst(0.0); } + else { + v.fconst(0.0f); + } + v.cmpl(incrementType); + v.ifle(negativeIncrement); // if increment < 0, jump + // increment > 0 + v.cmpg(asmElementType); // if loop parameter is NaN, exit from loop, as well + v.ifgt(loopExit); + v.goTo(afterIf); + + // increment < 0 + v.mark(negativeIncrement); + v.cmpl(asmElementType); // if loop parameter is NaN, exit from loop, as well + v.iflt(loopExit); + v.mark(afterIf); + } + + @Override + public void checkEmptyLoop(@NotNull Label loopExit) { + if (!isIntegerProgression) return; + + v.load(loopParameterVar, asmElementType); + v.load(endVar, asmElementType); + v.load(incrementVar, asmElementType); + + Label negativeIncrement = new Label(); + Label afterIf = new Label(); + + if (asmElementType.getSort() == Type.LONG) { + v.lconst(0L); + v.lcmp(); + v.ifle(negativeIncrement); // if increment < 0, jump + + // increment > 0 + v.lcmp(); + v.ifgt(loopExit); + v.goTo(afterIf); + + // increment < 0 + v.mark(negativeIncrement); + v.lcmp(); + v.iflt(loopExit); + v.mark(afterIf); + } + else { + v.ifle(negativeIncrement); // if increment < 0, jump + + // increment > 0 + v.ificmpgt(loopExit); + v.goTo(afterIf); + + // increment < 0 + v.mark(negativeIncrement); + v.ificmplt(loopExit); + v.mark(afterIf); + } } @Override @@ -1103,66 +1141,16 @@ public class ExpressionCodegen extends JetVisitor implem @Override protected void increment(@NotNull Label loopExit) { + if (isIntegerProgression) { + checkPostCondition(loopExit); + } + v.load(loopParameterVar, asmElementType); v.load(incrementVar, asmElementType); v.add(asmElementType); - int sort = asmElementType.getSort(); - if (sort == Type.INT || sort == Type.LONG) { - checkNewLoopParameterValue(loopExit); - } - v.store(loopParameterVar, asmElementType); } - - // Checks that (increment > 0) == (new value of loop parameter > old value of loop parameter). - // Old value should be stored in loopParameterVar, new value should be on top of the stack - private void checkNewLoopParameterValue(@NotNull Label loopExit) { - Label negativeIncrement = new Label(); - Label afterIf = new Label(); - Label popAndExit = new Label(); - - dup(v, asmElementType); - v.load(loopParameterVar, asmElementType); - - v.load(incrementVar, asmElementType); - - if (asmElementType.getSort() == Type.LONG) { - v.lconst(0L); - v.lcmp(); - v.ifle(negativeIncrement); - - // increment > 0 - v.lcmp(); - v.iflt(popAndExit); - v.goTo(afterIf); - - // increment < 0 - v.mark(negativeIncrement); - v.lcmp(); - v.ifgt(popAndExit); - v.goTo(afterIf); - } - else { - v.ifle(negativeIncrement); - - // increment > 0 - v.ificmplt(popAndExit); - v.goTo(afterIf); - - // increment < 0 - v.mark(negativeIncrement); - v.ificmpgt(popAndExit); - v.goTo(afterIf); - } - - // Pop the new value of loop parameter from the stack and exit the loop - v.mark(popAndExit); - pop(v, asmElementType); - v.goTo(loopExit); - - v.mark(afterIf); - } } diff --git a/runtime/src/jet/runtime/ProgressionUtil.java b/runtime/src/jet/runtime/ProgressionUtil.java new file mode 100644 index 00000000000..a03226a82ce --- /dev/null +++ b/runtime/src/jet/runtime/ProgressionUtil.java @@ -0,0 +1,83 @@ +/* + * 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 jet.runtime; + +public class ProgressionUtil { + private ProgressionUtil() { + } + + // a mod b (in arithmetical sense) + private static int mod(int a, int b) { + return a >= 0 ? a % b : a % b + b; + } + + private static long mod(long a, long b) { + return a >= 0 ? a % b : a % b + b; + } + + // (a - b) mod c + private static int differenceModulo(int a, int b, int c) { + return mod(mod(a, c) - mod(b, c), c); + } + + private static long differenceModulo(long a, long b, long c) { + return mod(mod(a, c) - mod(b, c), c); + } + + + /** + * Calculates the final element of a bounded arithmetic progression, i.e. the last element of the progression which is in the range + * from {@code start} to {@code end} in case of a positive {@code increment}, or from {@code end} to {@code start} in case of a negative + * increment. + * + *

No validation on passed parameters is performed. The given parameters should satisfy the condition: either + * {@code increment > 0} and {@code start <= end}, or {@code increment < 0} and {@code start >= end}. + * @param start first element of the progression + * @param end ending bound for the progression + * @param increment increment, or difference of successive elements in the progression + * @return the final element of the progression + */ + public static int getProgressionFinalElement(int start, int end, int increment) { + if (increment > 0) { + return end - differenceModulo(end, start, increment); + } + else { + return end + differenceModulo(start, end, -increment); + } + } + + /** + * Calculates the final element of a bounded arithmetic progression, i.e. the last element of the progression which is in the range + * from {@code start} to {@code end} in case of a positive {@code increment}, or from {@code end} to {@code start} in case of a negative + * increment. + * + *

No validation on passed parameters is performed. The given parameters should satisfy the condition: either + * {@code increment > 0} and {@code start <= end}, or {@code increment < 0} and {@code start >= end}. + * @param start first element of the progression + * @param end ending bound for the progression + * @param increment increment, or difference of successive elements in the progression + * @return the final element of the progression + */ + public static long getProgressionFinalElement(long start, long end, long increment) { + if (increment > 0) { + return end - differenceModulo(end, start, increment); + } + else { + return end + differenceModulo(start, end, -increment); + } + } +} From 980e409768d4fbf94bcd87b572bb357253a69921 Mon Sep 17 00:00:00 2001 From: Alexander Udalov Date: Thu, 20 Jun 2013 19:50:17 +0400 Subject: [PATCH 169/291] Optimize integer progression iterators With the help of ProgressionUtil hasNext and next* consist now of only several bytecode instructions --- runtime/src/jet/ByteProgressionIterator.java | 18 +++++++++++++---- runtime/src/jet/CharProgressionIterator.java | 18 +++++++++++++---- runtime/src/jet/IntProgressionIterator.java | 20 ++++++++++++------- runtime/src/jet/LongProgressionIterator.java | 20 ++++++++++++------- runtime/src/jet/ShortProgressionIterator.java | 18 +++++++++++++---- 5 files changed, 68 insertions(+), 26 deletions(-) diff --git a/runtime/src/jet/ByteProgressionIterator.java b/runtime/src/jet/ByteProgressionIterator.java index 85243e18f2f..fc5fc8417bc 100644 --- a/runtime/src/jet/ByteProgressionIterator.java +++ b/runtime/src/jet/ByteProgressionIterator.java @@ -16,26 +16,36 @@ package jet; +import jet.runtime.ProgressionUtil; + class ByteProgressionIterator extends ByteIterator { private int next; - private final byte end; private final int increment; + private final byte finalElement; + private boolean hasNext; public ByteProgressionIterator(byte start, byte end, int increment) { this.next = start; - this.end = end; this.increment = increment; + + this.finalElement = (byte) ProgressionUtil.getProgressionFinalElement(start, end, increment); + this.hasNext = increment < 0 ? start > end : start < end; } @Override public boolean hasNext() { - return increment > 0 ? next <= end : next >= end; + return hasNext; } @Override public byte nextByte() { int value = next; - next += increment; + if (value == finalElement) { + hasNext = false; + } + else { + next += increment; + } return (byte) value; } } diff --git a/runtime/src/jet/CharProgressionIterator.java b/runtime/src/jet/CharProgressionIterator.java index dc608162f9f..cb09aeb5347 100644 --- a/runtime/src/jet/CharProgressionIterator.java +++ b/runtime/src/jet/CharProgressionIterator.java @@ -16,26 +16,36 @@ package jet; +import jet.runtime.ProgressionUtil; + class CharProgressionIterator extends CharIterator { private int next; - private final char end; private final int increment; + private final char finalElement; + private boolean hasNext; public CharProgressionIterator(char start, char end, int increment) { this.next = start; - this.end = end; this.increment = increment; + + this.finalElement = (char) ProgressionUtil.getProgressionFinalElement(start, end, increment); + this.hasNext = increment < 0 ? start > end : start < end; } @Override public boolean hasNext() { - return increment > 0 ? next <= end : next >= end; + return hasNext; } @Override public char nextChar() { int value = next; - next += increment; + if (value == finalElement) { + hasNext = false; + } + else { + next += increment; + } return (char) value; } } diff --git a/runtime/src/jet/IntProgressionIterator.java b/runtime/src/jet/IntProgressionIterator.java index 3d7dda17af8..0b6f9bb5175 100644 --- a/runtime/src/jet/IntProgressionIterator.java +++ b/runtime/src/jet/IntProgressionIterator.java @@ -16,29 +16,35 @@ package jet; +import jet.runtime.ProgressionUtil; + class IntProgressionIterator extends IntIterator { private int next; - private final int end; private final int increment; - private boolean overflowHappened = false; + private final int finalElement; + private boolean hasNext; public IntProgressionIterator(int start, int end, int increment) { this.next = start; - this.end = end; this.increment = increment; + + this.finalElement = ProgressionUtil.getProgressionFinalElement(start, end, increment); + this.hasNext = increment < 0 ? start > end : start < end; } @Override public boolean hasNext() { - return !overflowHappened && (increment > 0 ? next <= end : next >= end); + return hasNext; } @Override public int nextInt() { int value = next; - next += increment; - if ((increment > 0) != (next > value)) { - overflowHappened = true; + if (value == finalElement) { + hasNext = false; + } + else { + next += increment; } return value; } diff --git a/runtime/src/jet/LongProgressionIterator.java b/runtime/src/jet/LongProgressionIterator.java index f6c613cf3fa..70493e39972 100644 --- a/runtime/src/jet/LongProgressionIterator.java +++ b/runtime/src/jet/LongProgressionIterator.java @@ -16,29 +16,35 @@ package jet; +import jet.runtime.ProgressionUtil; + class LongProgressionIterator extends LongIterator { private long next; - private final long end; private final long increment; - private boolean overflowHappened = false; + private final long finalElement; + private boolean hasNext; public LongProgressionIterator(long start, long end, long increment) { this.next = start; - this.end = end; this.increment = increment; + + this.finalElement = ProgressionUtil.getProgressionFinalElement(start, end, increment); + this.hasNext = increment < 0 ? start > end : start < end; } @Override public boolean hasNext() { - return !overflowHappened && (increment > 0 ? next <= end : next >= end); + return hasNext; } @Override public long nextLong() { long value = next; - next += increment; - if ((increment > 0) != (next > value)) { - overflowHappened = true; + if (value == finalElement) { + hasNext = false; + } + else { + next += increment; } return value; } diff --git a/runtime/src/jet/ShortProgressionIterator.java b/runtime/src/jet/ShortProgressionIterator.java index cd3b77200f9..d3da9e80326 100644 --- a/runtime/src/jet/ShortProgressionIterator.java +++ b/runtime/src/jet/ShortProgressionIterator.java @@ -16,26 +16,36 @@ package jet; +import jet.runtime.ProgressionUtil; + class ShortProgressionIterator extends ShortIterator { private int next; - private final short end; private final int increment; + private final short finalElement; + private boolean hasNext; public ShortProgressionIterator(short start, short end, int increment) { this.next = start; - this.end = end; this.increment = increment; + + this.finalElement = (short) ProgressionUtil.getProgressionFinalElement(start, end, increment); + this.hasNext = increment < 0 ? start > end : start < end; } @Override public boolean hasNext() { - return increment > 0 ? next <= end : next >= end; + return hasNext; } @Override public short nextShort() { int value = next; - next += increment; + if (value == finalElement) { + hasNext = false; + } + else { + next += increment; + } return (short) value; } } From 53cc582040e41590c02e07284b62c0de3db021f9 Mon Sep 17 00:00:00 2001 From: Alexander Udalov Date: Thu, 20 Jun 2013 20:14:52 +0400 Subject: [PATCH 170/291] Minor, use incrementType in for-progression codegen This doesn't fix anything, just makes it easier to figure out values of what types are used where. Progression increment is of its own type, which may be different from asmElementType in case of Byte, Char, Short progressions --- .../src/org/jetbrains/jet/codegen/ExpressionCodegen.java | 6 +++--- .../ranges/forByteProgressionWithIntIncrement.kt | 7 +++++++ .../generated/BlackBoxWithStdlibCodegenTestGenerated.java | 5 +++++ .../org/jetbrains/jet/resolve/JetResolveTestGenerated.java | 2 +- 4 files changed, 16 insertions(+), 4 deletions(-) create mode 100644 compiler/testData/codegen/boxWithStdlib/ranges/forByteProgressionWithIntIncrement.kt diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java index e62e277244f..1ece17f99fa 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java @@ -1068,12 +1068,12 @@ public class ExpressionCodegen extends JetVisitor implem v.load(loopParameterVar, asmElementType); v.load(endVar, asmElementType); - v.load(incrementVar, asmElementType); + v.load(incrementVar, incrementType); Label negativeIncrement = new Label(); Label afterIf = new Label(); - if (asmElementType.getSort() == Type.DOUBLE) { + if (incrementType.getSort() == Type.DOUBLE) { v.dconst(0.0); } else { @@ -1100,7 +1100,7 @@ public class ExpressionCodegen extends JetVisitor implem v.load(loopParameterVar, asmElementType); v.load(endVar, asmElementType); - v.load(incrementVar, asmElementType); + v.load(incrementVar, incrementType); Label negativeIncrement = new Label(); Label afterIf = new Label(); diff --git a/compiler/testData/codegen/boxWithStdlib/ranges/forByteProgressionWithIntIncrement.kt b/compiler/testData/codegen/boxWithStdlib/ranges/forByteProgressionWithIntIncrement.kt new file mode 100644 index 00000000000..ec16945a875 --- /dev/null +++ b/compiler/testData/codegen/boxWithStdlib/ranges/forByteProgressionWithIntIncrement.kt @@ -0,0 +1,7 @@ +fun box(): String { + for (element in 5.toByte()..1.toByte() step 255) { + return "Fail: iterating over an empty progression, element: $element" + } + + 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 540c6ab73aa..e187758dbe1 100644 --- a/compiler/tests/org/jetbrains/jet/codegen/generated/BlackBoxWithStdlibCodegenTestGenerated.java +++ b/compiler/tests/org/jetbrains/jet/codegen/generated/BlackBoxWithStdlibCodegenTestGenerated.java @@ -403,6 +403,11 @@ public class BlackBoxWithStdlibCodegenTestGenerated extends AbstractBlackBoxCode JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.GenerateTests", new File("compiler/testData/codegen/boxWithStdlib/ranges"), Pattern.compile("^(.+)\\.kt$"), true); } + @TestMetadata("forByteProgressionWithIntIncrement.kt") + public void testForByteProgressionWithIntIncrement() throws Exception { + doTestWithStdlib("compiler/testData/codegen/boxWithStdlib/ranges/forByteProgressionWithIntIncrement.kt"); + } + @TestMetadata("multiAssignmentIterationOverIntRange.kt") public void testMultiAssignmentIterationOverIntRange() throws Exception { doTestWithStdlib("compiler/testData/codegen/boxWithStdlib/ranges/multiAssignmentIterationOverIntRange.kt"); diff --git a/compiler/tests/org/jetbrains/jet/resolve/JetResolveTestGenerated.java b/compiler/tests/org/jetbrains/jet/resolve/JetResolveTestGenerated.java index faf1d4c2435..5b23f67300b 100644 --- a/compiler/tests/org/jetbrains/jet/resolve/JetResolveTestGenerated.java +++ b/compiler/tests/org/jetbrains/jet/resolve/JetResolveTestGenerated.java @@ -162,7 +162,7 @@ public class JetResolveTestGenerated 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("classObjectOuterResolve.resolve") public void testClassObjectOuterResolve() throws Exception { doTest("compiler/testData/resolve/candidatesPriority/classObjectOuterResolve.resolve"); From aea8f3bcee9523df5f0a8d8a4cabc8084b667797 Mon Sep 17 00:00:00 2001 From: Alexander Udalov Date: Thu, 20 Jun 2013 21:04:42 +0400 Subject: [PATCH 171/291] Fix and test ProgressionUtil Arithmetical modulo implementation was incorrect (-10 mod 1 == 0, but was 1) --- .../jetbrains/jet/ProgressionUtilTest.java | 96 +++++++++++++++++++ runtime/src/jet/runtime/ProgressionUtil.java | 6 +- 2 files changed, 100 insertions(+), 2 deletions(-) create mode 100644 compiler/tests/org/jetbrains/jet/ProgressionUtilTest.java diff --git a/compiler/tests/org/jetbrains/jet/ProgressionUtilTest.java b/compiler/tests/org/jetbrains/jet/ProgressionUtilTest.java new file mode 100644 index 00000000000..d03eff40fc5 --- /dev/null +++ b/compiler/tests/org/jetbrains/jet/ProgressionUtilTest.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; + +import jet.runtime.ProgressionUtil; +import org.junit.Test; + +import static junit.framework.Assert.assertEquals; + +public class ProgressionUtilTest { + private static final int MAX = Integer.MAX_VALUE; + private static final int MIN = Integer.MIN_VALUE; + + private static void doTest(int start, int end, int increment, int expected) { + int actualInt = ProgressionUtil.getProgressionFinalElement(start, end, increment); + assertEquals(expected, actualInt); + + long actualLong = ProgressionUtil.getProgressionFinalElement((long) start, (long) end, (long) increment); + assertEquals(expected, actualLong); + } + + private static final int[] INTERESTING = new int[]{ MIN, MIN / 2, -239, -23, -1, 0, 1, 42, 239, MAX / 2, MAX }; + + @Test + public void testGetFinalElement() { + // start == end + for (int x : INTERESTING) { + for (int increment : INTERESTING) if (increment != 0) { + doTest(x, x, increment, x); + } + } + + // increment == 1 + for (int start = 0; start < INTERESTING.length; start++) { + for (int end = start; end < INTERESTING.length; end++) { + doTest(INTERESTING[start], INTERESTING[end], 1, INTERESTING[end]); + } + } + + // increment == -1 + for (int end = 0; end < INTERESTING.length; end++) { + for (int start = end; start < INTERESTING.length; start++) { + doTest(INTERESTING[start], INTERESTING[end], -1, INTERESTING[end]); + } + } + + // end == MAX + doTest(0, MAX, MAX, MAX); + doTest(0, MAX, MAX / 2, MAX - 1); + doTest(MIN + 1, MAX, MAX, MAX); + doTest(MAX - 7, MAX, 3, MAX - 1); + doTest(MAX - 7, MAX, MAX, MAX - 7); + + // end == MIN + doTest(0, MIN, MIN, MIN); + doTest(0, MIN, MIN / 2, MIN); + doTest(MAX, MIN, MIN, -1); + doTest(MIN + 7, MIN, -3, MIN + 1); + doTest(MIN + 7, MIN, MIN, MIN + 7); + + // Small tests + for (int start = -10; start < 10; start++) { + for (int end = -10; end < 10; end++) { + for (int increment = -20; increment < 20; increment++) { + // Cut down incorrect test data + if (increment == 0) continue; + if ((increment > 0) != (start <= end)) continue; + + // Iterate over the progression and obtain the expected result + int x = start; + while (true) { + int next = x + increment; + if (next < Math.min(start, end) || next > Math.max(start, end)) break; + x = next; + } + + doTest(start, end, increment, x); + } + } + } + } +} diff --git a/runtime/src/jet/runtime/ProgressionUtil.java b/runtime/src/jet/runtime/ProgressionUtil.java index a03226a82ce..876262c3e32 100644 --- a/runtime/src/jet/runtime/ProgressionUtil.java +++ b/runtime/src/jet/runtime/ProgressionUtil.java @@ -22,11 +22,13 @@ public class ProgressionUtil { // a mod b (in arithmetical sense) private static int mod(int a, int b) { - return a >= 0 ? a % b : a % b + b; + int mod = a % b; + return mod >= 0 ? mod : mod + b; } private static long mod(long a, long b) { - return a >= 0 ? a % b : a % b + b; + long mod = a % b; + return mod >= 0 ? mod : mod + b; } // (a - b) mod c From 9a6979aa6cbac14c64fd56cc1652fef61ef418bf Mon Sep 17 00:00:00 2001 From: Alexander Udalov Date: Thu, 20 Jun 2013 22:20:13 +0400 Subject: [PATCH 172/291] Minor, rename method --- .../jetbrains/jet/codegen/ExpressionCodegen.java | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java index 1ece17f99fa..66971d59270 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java @@ -511,7 +511,7 @@ public class ExpressionCodegen extends JetVisitor implem generator.checkEmptyLoop(loopExit); v.mark(loopEntry); - generator.conditionAndJump(loopExit); + generator.checkPreCondition(loopExit); generator.beforeBody(); blockStackElements.push(new LoopBlockStackElement(loopExit, continueLabel, targetLabel(generator.forExpression))); @@ -585,7 +585,7 @@ public class ExpressionCodegen extends JetVisitor implem public abstract void checkEmptyLoop(@NotNull Label loopExit); - public abstract void conditionAndJump(@NotNull Label loopExit); + public abstract void checkPreCondition(@NotNull Label loopExit); public void beforeBody() { v.mark(bodyStart); @@ -719,7 +719,7 @@ public class ExpressionCodegen extends JetVisitor implem } @Override - public void conditionAndJump(@NotNull Label loopExit) { + public void checkPreCondition(@NotNull Label loopExit) { // tmp.hasNext() JetExpression loopRange = forExpression.getLoopRange(); @@ -788,7 +788,7 @@ public class ExpressionCodegen extends JetVisitor implem } @Override - public void conditionAndJump(@NotNull Label loopExit) { + public void checkPreCondition(@NotNull Label loopExit) { v.load(indexVar, Type.INT_TYPE); v.load(arrayVar, OBJECT_TYPE); v.arraylength(); @@ -854,7 +854,7 @@ public class ExpressionCodegen extends JetVisitor implem endVar = createLoopTempVariable(asmElementType); } - // The local variable holding the actual last value of the loop parameter. + // Index of the local variable holding the actual last value of the loop parameter. // For ranges it equals end, for progressions it's a function of start, end and increment protected abstract int getFinalVar(); @@ -895,7 +895,7 @@ public class ExpressionCodegen extends JetVisitor implem } @Override - public void conditionAndJump(@NotNull Label loopExit) { + public void checkPreCondition(@NotNull Label loopExit) { if (isIntegerProgression) return; v.load(loopParameterVar, asmElementType); @@ -1063,7 +1063,7 @@ public class ExpressionCodegen extends JetVisitor implem } @Override - public void conditionAndJump(@NotNull Label loopExit) { + public void checkPreCondition(@NotNull Label loopExit) { if (isIntegerProgression) return; v.load(loopParameterVar, asmElementType); From 33bcee7d6d5bd881726dbec94d5bdcbaa67f3078 Mon Sep 17 00:00:00 2001 From: Alexander Udalov Date: Thu, 20 Jun 2013 23:25:17 +0400 Subject: [PATCH 173/291] Fix iterators for one-element progressions In case of start==end hasNext was always false, which resulted in iterators over one-element progressions not iterating that element --- runtime/src/jet/ByteProgressionIterator.java | 2 +- runtime/src/jet/CharProgressionIterator.java | 2 +- runtime/src/jet/IntProgressionIterator.java | 2 +- runtime/src/jet/LongProgressionIterator.java | 2 +- runtime/src/jet/ShortProgressionIterator.java | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/runtime/src/jet/ByteProgressionIterator.java b/runtime/src/jet/ByteProgressionIterator.java index fc5fc8417bc..d2461dab02a 100644 --- a/runtime/src/jet/ByteProgressionIterator.java +++ b/runtime/src/jet/ByteProgressionIterator.java @@ -29,7 +29,7 @@ class ByteProgressionIterator extends ByteIterator { this.increment = increment; this.finalElement = (byte) ProgressionUtil.getProgressionFinalElement(start, end, increment); - this.hasNext = increment < 0 ? start > end : start < end; + this.hasNext = increment > 0 ? start <= end : start >= end; } @Override diff --git a/runtime/src/jet/CharProgressionIterator.java b/runtime/src/jet/CharProgressionIterator.java index cb09aeb5347..1b5306db656 100644 --- a/runtime/src/jet/CharProgressionIterator.java +++ b/runtime/src/jet/CharProgressionIterator.java @@ -29,7 +29,7 @@ class CharProgressionIterator extends CharIterator { this.increment = increment; this.finalElement = (char) ProgressionUtil.getProgressionFinalElement(start, end, increment); - this.hasNext = increment < 0 ? start > end : start < end; + this.hasNext = increment > 0 ? start <= end : start >= end; } @Override diff --git a/runtime/src/jet/IntProgressionIterator.java b/runtime/src/jet/IntProgressionIterator.java index 0b6f9bb5175..a6a0c9da842 100644 --- a/runtime/src/jet/IntProgressionIterator.java +++ b/runtime/src/jet/IntProgressionIterator.java @@ -29,7 +29,7 @@ class IntProgressionIterator extends IntIterator { this.increment = increment; this.finalElement = ProgressionUtil.getProgressionFinalElement(start, end, increment); - this.hasNext = increment < 0 ? start > end : start < end; + this.hasNext = increment > 0 ? start <= end : start >= end; } @Override diff --git a/runtime/src/jet/LongProgressionIterator.java b/runtime/src/jet/LongProgressionIterator.java index 70493e39972..a2593216be1 100644 --- a/runtime/src/jet/LongProgressionIterator.java +++ b/runtime/src/jet/LongProgressionIterator.java @@ -29,7 +29,7 @@ class LongProgressionIterator extends LongIterator { this.increment = increment; this.finalElement = ProgressionUtil.getProgressionFinalElement(start, end, increment); - this.hasNext = increment < 0 ? start > end : start < end; + this.hasNext = increment > 0 ? start <= end : start >= end; } @Override diff --git a/runtime/src/jet/ShortProgressionIterator.java b/runtime/src/jet/ShortProgressionIterator.java index d3da9e80326..bb63d7788c0 100644 --- a/runtime/src/jet/ShortProgressionIterator.java +++ b/runtime/src/jet/ShortProgressionIterator.java @@ -29,7 +29,7 @@ class ShortProgressionIterator extends ShortIterator { this.increment = increment; this.finalElement = (short) ProgressionUtil.getProgressionFinalElement(start, end, increment); - this.hasNext = increment < 0 ? start > end : start < end; + this.hasNext = increment > 0 ? start <= end : start >= end; } @Override From 7e628a6d02242348243c10aa420df034f88f5800 Mon Sep 17 00:00:00 2001 From: Alexander Kirillin Date: Mon, 17 Jun 2013 13:16:44 +0400 Subject: [PATCH 174/291] EA-46007 --- .../changeSignature/JetChangeSignatureUsageProcessor.java | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/idea/src/org/jetbrains/jet/plugin/refactoring/changeSignature/JetChangeSignatureUsageProcessor.java b/idea/src/org/jetbrains/jet/plugin/refactoring/changeSignature/JetChangeSignatureUsageProcessor.java index 3da566624e7..77b83d1665b 100644 --- a/idea/src/org/jetbrains/jet/plugin/refactoring/changeSignature/JetChangeSignatureUsageProcessor.java +++ b/idea/src/org/jetbrains/jet/plugin/refactoring/changeSignature/JetChangeSignatureUsageProcessor.java @@ -57,7 +57,11 @@ public class JetChangeSignatureUsageProcessor implements ChangeSignatureUsagePro @Override public UsageInfo[] findUsages(ChangeInfo info) { Set result = new HashSet(); - findAllMethodUsages((JetChangeInfo)info, result); + + if (info instanceof JetChangeInfo) { + findAllMethodUsages((JetChangeInfo)info, result); + } + return result.toArray(new UsageInfo[result.size()]); } From 9b9c85cdca6540a1c833980b46780d3fdca33665 Mon Sep 17 00:00:00 2001 From: Alexander Kirillin Date: Mon, 17 Jun 2013 13:21:27 +0400 Subject: [PATCH 175/291] EA-46366 --- .../changeSignature/JetChangeSignatureUsageProcessor.java | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/idea/src/org/jetbrains/jet/plugin/refactoring/changeSignature/JetChangeSignatureUsageProcessor.java b/idea/src/org/jetbrains/jet/plugin/refactoring/changeSignature/JetChangeSignatureUsageProcessor.java index 77b83d1665b..4127364e860 100644 --- a/idea/src/org/jetbrains/jet/plugin/refactoring/changeSignature/JetChangeSignatureUsageProcessor.java +++ b/idea/src/org/jetbrains/jet/plugin/refactoring/changeSignature/JetChangeSignatureUsageProcessor.java @@ -126,6 +126,11 @@ public class JetChangeSignatureUsageProcessor implements ChangeSignatureUsagePro @Override public MultiMap findConflicts(ChangeInfo info, Ref refUsages) { MultiMap result = new MultiMap(); + + if (!(info instanceof JetChangeInfo)) { + return result; + } + Set parameterNames = new HashSet(); JetChangeInfo changeInfo = (JetChangeInfo) info; PsiElement function = info.getMethod(); From 07ede8898b49c5f56690d9860001b2e4d89deaac Mon Sep 17 00:00:00 2001 From: Alexander Kirillin Date: Mon, 17 Jun 2013 14:57:02 +0400 Subject: [PATCH 176/291] EA-46365 --- .../jet/plugin/quickfix/ChangeFunctionSignatureFix.java | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/idea/src/org/jetbrains/jet/plugin/quickfix/ChangeFunctionSignatureFix.java b/idea/src/org/jetbrains/jet/plugin/quickfix/ChangeFunctionSignatureFix.java index 0412b7191e4..4c049854818 100644 --- a/idea/src/org/jetbrains/jet/plugin/quickfix/ChangeFunctionSignatureFix.java +++ b/idea/src/org/jetbrains/jet/plugin/quickfix/ChangeFunctionSignatureFix.java @@ -195,8 +195,13 @@ public abstract class ChangeFunctionSignatureFix extends JetIntentionAction parameters = functionDescriptor.getValueParameters(); + List arguments = callElement.getValueArguments(); + + if (arguments.size() > parameters.size()) { + boolean hasTypeMismatches = hasTypeMismatches(parameters, arguments, bindingContext); + return new AddFunctionParametersFix(declaration, callElement, functionDescriptor, hasTypeMismatches); + } } } } From fa01d59ef8d54e71f36fc9ec7e89b98097357a6e Mon Sep 17 00:00:00 2001 From: Alexey Sedunov Date: Thu, 20 Jun 2013 15:18:22 +0400 Subject: [PATCH 177/291] Fixed moving of classes without body --- .../upDownMover/JetDeclarationMover.java | 37 ++++++++++++++++--- .../class/classWithoutBody1.kt | 8 ++++ .../class/classWithoutBody1.kt.after | 8 ++++ .../class/classWithoutBody2.kt | 8 ++++ .../class/classWithoutBody2.kt.after | 8 ++++ .../class/classWithoutBody3.kt | 5 +++ .../class/classWithoutBody3.kt.after | 5 +++ .../class/classWithoutBody4.kt | 5 +++ .../class/classWithoutBody4.kt.after | 5 +++ .../moveUpDown/CodeMoverTestGenerated.java | 20 ++++++++++ 10 files changed, 104 insertions(+), 5 deletions(-) create mode 100644 idea/testData/codeInsight/moveUpDown/classBodyDeclarations/class/classWithoutBody1.kt create mode 100644 idea/testData/codeInsight/moveUpDown/classBodyDeclarations/class/classWithoutBody1.kt.after create mode 100644 idea/testData/codeInsight/moveUpDown/classBodyDeclarations/class/classWithoutBody2.kt create mode 100644 idea/testData/codeInsight/moveUpDown/classBodyDeclarations/class/classWithoutBody2.kt.after create mode 100644 idea/testData/codeInsight/moveUpDown/classBodyDeclarations/class/classWithoutBody3.kt create mode 100644 idea/testData/codeInsight/moveUpDown/classBodyDeclarations/class/classWithoutBody3.kt.after create mode 100644 idea/testData/codeInsight/moveUpDown/classBodyDeclarations/class/classWithoutBody4.kt create mode 100644 idea/testData/codeInsight/moveUpDown/classBodyDeclarations/class/classWithoutBody4.kt.after 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 ae95da053c8..08915e34933 100644 --- a/idea/src/org/jetbrains/jet/plugin/codeInsight/upDownMover/JetDeclarationMover.java +++ b/idea/src/org/jetbrains/jet/plugin/codeInsight/upDownMover/JetDeclarationMover.java @@ -106,16 +106,36 @@ public class JetDeclarationMover extends AbstractJetUpDownMover { return element instanceof JetDeclaration; } + @Nullable + private static PsiElement skipInsignificantElements(@NotNull PsiElement element, boolean down) { + PsiElement result = element; + + while (result instanceof PsiWhiteSpace || result.getTextLength() == 0) { + result = down ? result.getNextSibling() : result.getPrevSibling(); + if (result == null) break; + } + + return result; + } + @Override protected LineRange getElementSourceLineRange(@NotNull PsiElement element, @NotNull Editor editor, @NotNull LineRange oldRange) { JetDeclaration declaration = (JetDeclaration) element; - Document doc = editor.getDocument(); - TextRange textRange = declaration.getTextRange(); - if (doc.getTextLength() < textRange.getEndOffset()) return null; + PsiElement first = skipInsignificantElements(declaration.getFirstChild(), true); + PsiElement last = skipInsignificantElements(declaration.getLastChild(), false); - int startLine = editor.offsetToLogicalPosition(textRange.getStartOffset()).line; - int endLine = editor.offsetToLogicalPosition(textRange.getEndOffset()).line + 1; + if (first == null || last == null) return null; + + TextRange textRange1 = first.getTextRange(); + TextRange textRange2 = last.getTextRange(); + + Document doc = editor.getDocument(); + + if (doc.getTextLength() < textRange2.getEndOffset()) return null; + + int startLine = editor.offsetToLogicalPosition(textRange1.getStartOffset()).line; + int endLine = editor.offsetToLogicalPosition(textRange2.getEndOffset()).line + 1; if (startLine == oldRange.startLine || startLine == oldRange.endLine || endLine == oldRange.startLine || endLine == oldRange.endLine) { @@ -188,6 +208,13 @@ public class JetDeclarationMover extends AbstractJetUpDownMover { if (target instanceof JetPropertyAccessor && !(sibling instanceof JetPropertyAccessor)) return null; + if (start != null && start.getFirstChild() != null) { + start = skipInsignificantElements(start.getFirstChild(), true); + } + if (end != null && end.getFirstChild() != null) { + end = skipInsignificantElements(end.getLastChild(), false); + } + return start != null && end != null ? new LineRange(start, end, editor.getDocument()) : null; } diff --git a/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/class/classWithoutBody1.kt b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/class/classWithoutBody1.kt new file mode 100644 index 00000000000..ab8ed8c756d --- /dev/null +++ b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/class/classWithoutBody1.kt @@ -0,0 +1,8 @@ +// MOVE: down +class A + +class D { +} + +class C { +} \ No newline at end of file diff --git a/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/class/classWithoutBody1.kt.after b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/class/classWithoutBody1.kt.after new file mode 100644 index 00000000000..2b29f95113c --- /dev/null +++ b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/class/classWithoutBody1.kt.after @@ -0,0 +1,8 @@ +// MOVE: down +class D { + + class A +} + +class C { +} \ No newline at end of file diff --git a/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/class/classWithoutBody2.kt b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/class/classWithoutBody2.kt new file mode 100644 index 00000000000..44bdd3dcd47 --- /dev/null +++ b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/class/classWithoutBody2.kt @@ -0,0 +1,8 @@ +// MOVE: up +class D { +} + +class A + +class C { +} \ No newline at end of file diff --git a/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/class/classWithoutBody2.kt.after b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/class/classWithoutBody2.kt.after new file mode 100644 index 00000000000..3581434ea68 --- /dev/null +++ b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/class/classWithoutBody2.kt.after @@ -0,0 +1,8 @@ +// MOVE: up +class D { + class A + +} + +class C { +} \ No newline at end of file diff --git a/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/class/classWithoutBody3.kt b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/class/classWithoutBody3.kt new file mode 100644 index 00000000000..33ad1e2f29f --- /dev/null +++ b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/class/classWithoutBody3.kt @@ -0,0 +1,5 @@ +// MOVE: down +class A + +class D { +} \ No newline at end of file diff --git a/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/class/classWithoutBody3.kt.after b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/class/classWithoutBody3.kt.after new file mode 100644 index 00000000000..07aa38c878f --- /dev/null +++ b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/class/classWithoutBody3.kt.after @@ -0,0 +1,5 @@ +// MOVE: down +class D { + + class A +} \ No newline at end of file diff --git a/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/class/classWithoutBody4.kt b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/class/classWithoutBody4.kt new file mode 100644 index 00000000000..4027fb30c70 --- /dev/null +++ b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/class/classWithoutBody4.kt @@ -0,0 +1,5 @@ +// MOVE: up +class D { +} + +class A \ No newline at end of file diff --git a/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/class/classWithoutBody4.kt.after b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/class/classWithoutBody4.kt.after new file mode 100644 index 00000000000..d52a3645981 --- /dev/null +++ b/idea/testData/codeInsight/moveUpDown/classBodyDeclarations/class/classWithoutBody4.kt.after @@ -0,0 +1,5 @@ +// MOVE: up +class D { + class A + +} 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 244b9db74ff..ecd5afbec5c 100644 --- a/idea/tests/org/jetbrains/jet/plugin/codeInsight/moveUpDown/CodeMoverTestGenerated.java +++ b/idea/tests/org/jetbrains/jet/plugin/codeInsight/moveUpDown/CodeMoverTestGenerated.java @@ -153,6 +153,26 @@ public class CodeMoverTestGenerated extends AbstractCodeMoverTest { doTestClassBodyDeclaration("idea/testData/codeInsight/moveUpDown/classBodyDeclarations/class/classAtProperty2.kt"); } + @TestMetadata("classWithoutBody1.kt") + public void testClassWithoutBody1() throws Exception { + doTestClassBodyDeclaration("idea/testData/codeInsight/moveUpDown/classBodyDeclarations/class/classWithoutBody1.kt"); + } + + @TestMetadata("classWithoutBody2.kt") + public void testClassWithoutBody2() throws Exception { + doTestClassBodyDeclaration("idea/testData/codeInsight/moveUpDown/classBodyDeclarations/class/classWithoutBody2.kt"); + } + + @TestMetadata("classWithoutBody3.kt") + public void testClassWithoutBody3() throws Exception { + doTestClassBodyDeclaration("idea/testData/codeInsight/moveUpDown/classBodyDeclarations/class/classWithoutBody3.kt"); + } + + @TestMetadata("classWithoutBody4.kt") + public void testClassWithoutBody4() throws Exception { + doTestClassBodyDeclaration("idea/testData/codeInsight/moveUpDown/classBodyDeclarations/class/classWithoutBody4.kt"); + } + } @TestMetadata("idea/testData/codeInsight/moveUpDown/classBodyDeclarations/classInitializer") From 8964e0e15272ef4f71a2d415d6009f5bf55fa0e8 Mon Sep 17 00:00:00 2001 From: Alexey Sedunov Date: Tue, 18 Jun 2013 17:21:50 +0400 Subject: [PATCH 178/291] Implement Unwrap/Remove for conditionals and loops --- .../jet/generators/tests/GenerateTests.java | 11 ++ idea/src/META-INF/plugin.xml | 1 + .../jetbrains/jet/plugin/JetBundle.properties | 5 + .../codeInsight/unwrap/KoitlinUnwrappers.java | 79 +++++++++++ .../unwrap/KotlinComponentUnwrapper.java | 51 +++++++ .../unwrap/KotlinUnwrapDescriptor.java | 32 +++++ .../unwrap/KotlinUnwrapRemoveBase.java | 92 +++++++++++++ .../refactoring/JetRefactoringUtil.java | 4 +- .../unwrapAndRemove/removeElse/else.kt | 8 ++ .../unwrapAndRemove/removeElse/else.kt.after | 6 + .../unwrapElse/elseCompoundInBlock.kt | 12 ++ .../unwrapElse/elseCompoundInBlock.kt.after | 7 + .../unwrapElse/elseCompoundInReturn.kt | 10 ++ .../unwrapElse/elseSimpleInReturn.kt | 8 ++ .../unwrapElse/elseSimpleInReturn.kt.after | 4 + .../unwrapAndRemove/unwrapLoop/doWhile.kt | 8 ++ .../unwrapLoop/doWhile.kt.after | 6 + .../unwrapAndRemove/unwrapLoop/for.kt | 6 + .../unwrapAndRemove/unwrapLoop/for.kt.after | 4 + .../unwrapAndRemove/unwrapLoop/while.kt | 8 ++ .../unwrapAndRemove/unwrapLoop/while.kt.after | 6 + .../unwrapThen/thenCompoundInBlock.kt | 12 ++ .../unwrapThen/thenCompoundInBlock.kt.after | 7 + .../unwrapThen/thenCompoundInReturn.kt | 10 ++ .../unwrapThen/thenSimpleInReturn.kt | 8 ++ .../unwrapThen/thenSimpleInReturn.kt.after | 4 + .../unwrap/AbstractUnwrapRemoveTest.java | 86 ++++++++++++ .../unwrap/UnwrapRemoveTestGenerated.java | 125 ++++++++++++++++++ 28 files changed, 618 insertions(+), 2 deletions(-) create mode 100644 idea/src/org/jetbrains/jet/plugin/codeInsight/unwrap/KoitlinUnwrappers.java create mode 100644 idea/src/org/jetbrains/jet/plugin/codeInsight/unwrap/KotlinComponentUnwrapper.java create mode 100644 idea/src/org/jetbrains/jet/plugin/codeInsight/unwrap/KotlinUnwrapDescriptor.java create mode 100644 idea/src/org/jetbrains/jet/plugin/codeInsight/unwrap/KotlinUnwrapRemoveBase.java create mode 100644 idea/testData/codeInsight/unwrapAndRemove/removeElse/else.kt create mode 100644 idea/testData/codeInsight/unwrapAndRemove/removeElse/else.kt.after create mode 100644 idea/testData/codeInsight/unwrapAndRemove/unwrapElse/elseCompoundInBlock.kt create mode 100644 idea/testData/codeInsight/unwrapAndRemove/unwrapElse/elseCompoundInBlock.kt.after create mode 100644 idea/testData/codeInsight/unwrapAndRemove/unwrapElse/elseCompoundInReturn.kt create mode 100644 idea/testData/codeInsight/unwrapAndRemove/unwrapElse/elseSimpleInReturn.kt create mode 100644 idea/testData/codeInsight/unwrapAndRemove/unwrapElse/elseSimpleInReturn.kt.after create mode 100644 idea/testData/codeInsight/unwrapAndRemove/unwrapLoop/doWhile.kt create mode 100644 idea/testData/codeInsight/unwrapAndRemove/unwrapLoop/doWhile.kt.after create mode 100644 idea/testData/codeInsight/unwrapAndRemove/unwrapLoop/for.kt create mode 100644 idea/testData/codeInsight/unwrapAndRemove/unwrapLoop/for.kt.after create mode 100644 idea/testData/codeInsight/unwrapAndRemove/unwrapLoop/while.kt create mode 100644 idea/testData/codeInsight/unwrapAndRemove/unwrapLoop/while.kt.after create mode 100644 idea/testData/codeInsight/unwrapAndRemove/unwrapThen/thenCompoundInBlock.kt create mode 100644 idea/testData/codeInsight/unwrapAndRemove/unwrapThen/thenCompoundInBlock.kt.after create mode 100644 idea/testData/codeInsight/unwrapAndRemove/unwrapThen/thenCompoundInReturn.kt create mode 100644 idea/testData/codeInsight/unwrapAndRemove/unwrapThen/thenSimpleInReturn.kt create mode 100644 idea/testData/codeInsight/unwrapAndRemove/unwrapThen/thenSimpleInReturn.kt.after create mode 100644 idea/tests/org/jetbrains/jet/plugin/codeInsight/unwrap/AbstractUnwrapRemoveTest.java create mode 100644 idea/tests/org/jetbrains/jet/plugin/codeInsight/unwrap/UnwrapRemoveTestGenerated.java diff --git a/generators/org/jetbrains/jet/generators/tests/GenerateTests.java b/generators/org/jetbrains/jet/generators/tests/GenerateTests.java index 6bfb8439a2c..c50df4959b5 100644 --- a/generators/org/jetbrains/jet/generators/tests/GenerateTests.java +++ b/generators/org/jetbrains/jet/generators/tests/GenerateTests.java @@ -36,6 +36,7 @@ import org.jetbrains.jet.lang.resolve.lazy.AbstractLazyResolveDescriptorRenderer import org.jetbrains.jet.lang.resolve.lazy.AbstractLazyResolveNamespaceComparingTest; import org.jetbrains.jet.lang.resolve.lazy.AbstractLazyResolveTest; import org.jetbrains.jet.modules.xml.AbstractModuleXmlParserTest; +import org.jetbrains.jet.plugin.codeInsight.unwrap.AbstractUnwrapRemoveTest; import org.jetbrains.jet.plugin.intentions.AbstractCodeTransformationTest; import org.jetbrains.jet.plugin.codeInsight.moveUpDown.AbstractCodeMoverTest; import org.jetbrains.jet.plugin.codeInsight.surroundWith.AbstractSurroundWithTest; @@ -369,6 +370,16 @@ public class GenerateTests { testModel("idea/testData/codeInsight/moveUpDown/closingBraces", "doTestExpression"), testModel("idea/testData/codeInsight/moveUpDown/expressions", "doTestExpression") ); + + generateTest( + "idea/tests/", + "UnwrapRemoveTestGenerated", + AbstractUnwrapRemoveTest.class, + testModel("idea/testData/codeInsight/unwrapAndRemove/unwrapThen", "doTestThenUnwrapper"), + testModel("idea/testData/codeInsight/unwrapAndRemove/unwrapElse", "doTestElseUnwrapper"), + testModel("idea/testData/codeInsight/unwrapAndRemove/removeElse", "doTestElseRemover"), + testModel("idea/testData/codeInsight/unwrapAndRemove/unwrapLoop", "doTestLoopUnwrapper") + ); } private static SimpleTestClassModel testModel(@NotNull String rootPath) { diff --git a/idea/src/META-INF/plugin.xml b/idea/src/META-INF/plugin.xml index fcf0e0c2ae7..a2c7b3152d6 100644 --- a/idea/src/META-INF/plugin.xml +++ b/idea/src/META-INF/plugin.xml @@ -124,6 +124,7 @@ implementationClass="org.jetbrains.jet.plugin.codeInsight.surroundWith.expression.KotlinExpressionSurroundDescriptor"/> + diff --git a/idea/src/org/jetbrains/jet/plugin/JetBundle.properties b/idea/src/org/jetbrains/jet/plugin/JetBundle.properties index d5268f23f8b..3fd4c5848b8 100644 --- a/idea/src/org/jetbrains/jet/plugin/JetBundle.properties +++ b/idea/src/org/jetbrains/jet/plugin/JetBundle.properties @@ -228,3 +228,8 @@ 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... + +remove.expression = Remove ''{0}'' +unwrap.expression = Unwrap ''{0}'' +remove.else = Remove else in ''{0}'' +unwrap.else = Unwrap else in ''{0}'' \ No newline at end of file diff --git a/idea/src/org/jetbrains/jet/plugin/codeInsight/unwrap/KoitlinUnwrappers.java b/idea/src/org/jetbrains/jet/plugin/codeInsight/unwrap/KoitlinUnwrappers.java new file mode 100644 index 00000000000..fe5c517be1c --- /dev/null +++ b/idea/src/org/jetbrains/jet/plugin/codeInsight/unwrap/KoitlinUnwrappers.java @@ -0,0 +1,79 @@ +/* + * 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.unwrap; + +import com.intellij.psi.PsiElement; +import com.intellij.util.IncorrectOperationException; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +import org.jetbrains.jet.lang.psi.*; + +public class KoitlinUnwrappers { + private KoitlinUnwrappers() { + } + + public static class KotlinElseUnwrapper extends KotlinComponentUnwrapper { + public KotlinElseUnwrapper(String key) { + super(key); + } + + @Override + protected JetExpression getExpressionToUnwrap(@NotNull JetElement target) { + return target instanceof JetIfExpression ? ((JetIfExpression) target).getElse() : null; + } + } + + public static class KotlinThenUnwrapper extends KotlinComponentUnwrapper { + public KotlinThenUnwrapper(String key) { + super(key); + } + + @Override + protected JetExpression getExpressionToUnwrap(@NotNull JetElement target) { + return target instanceof JetIfExpression ? ((JetIfExpression) target).getThen() : null; + } + } + + public static class KotlinElseRemover extends KotlinUnwrapRemoveBase { + public KotlinElseRemover(String key) { + super(key); + } + + @Override + public boolean isApplicableTo(PsiElement e) { + return e instanceof JetIfExpression && ((JetIfExpression) e).getElse() != null; + } + + @Override + protected void doUnwrap(PsiElement element, Context context) throws IncorrectOperationException { + JetIfExpression ifExpr = (JetIfExpression) element; + context.replace(ifExpr, JetPsiFactory.createIf(ifExpr.getProject(), ifExpr.getCondition(), ifExpr.getThen(), null)); + } + } + + public static class KotlinLoopUnwrapper extends KotlinComponentUnwrapper { + public KotlinLoopUnwrapper(String key) { + super(key); + } + + @Override + @Nullable + protected JetExpression getExpressionToUnwrap(@NotNull JetElement target) { + return target instanceof JetLoopExpression ? ((JetLoopExpression) target).getBody() : null; + } + } +} diff --git a/idea/src/org/jetbrains/jet/plugin/codeInsight/unwrap/KotlinComponentUnwrapper.java b/idea/src/org/jetbrains/jet/plugin/codeInsight/unwrap/KotlinComponentUnwrapper.java new file mode 100644 index 00000000000..be72bcaf98a --- /dev/null +++ b/idea/src/org/jetbrains/jet/plugin/codeInsight/unwrap/KotlinComponentUnwrapper.java @@ -0,0 +1,51 @@ +/* + * 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.unwrap; + +import com.intellij.psi.PsiElement; +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; + +public abstract class KotlinComponentUnwrapper extends KotlinUnwrapRemoveBase { + public KotlinComponentUnwrapper(String key) { + super(key); + } + + @Nullable + protected abstract JetExpression getExpressionToUnwrap(@NotNull JetElement target); + + @Override + public boolean isApplicableTo(PsiElement e) { + if (!(e instanceof JetElement)) return false; + + JetExpression expressionToUnwrap = getExpressionToUnwrap((JetElement) e); + return expressionToUnwrap != null && canExtractExpression(expressionToUnwrap, (JetElement) e.getParent()); + } + + @Override + protected void doUnwrap(PsiElement element, Context context) throws IncorrectOperationException { + JetExpression targetExpression = (JetExpression) element; + JetExpression expressionToUnwrap = getExpressionToUnwrap(targetExpression); + assert expressionToUnwrap != null; + + context.extractFromExpression(expressionToUnwrap, targetExpression); + context.delete(targetExpression); + } +} diff --git a/idea/src/org/jetbrains/jet/plugin/codeInsight/unwrap/KotlinUnwrapDescriptor.java b/idea/src/org/jetbrains/jet/plugin/codeInsight/unwrap/KotlinUnwrapDescriptor.java new file mode 100644 index 00000000000..337c33de3a0 --- /dev/null +++ b/idea/src/org/jetbrains/jet/plugin/codeInsight/unwrap/KotlinUnwrapDescriptor.java @@ -0,0 +1,32 @@ +/* + * 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.unwrap; + +import com.intellij.codeInsight.unwrap.UnwrapDescriptorBase; +import com.intellij.codeInsight.unwrap.Unwrapper; + +public class KotlinUnwrapDescriptor extends UnwrapDescriptorBase { + @Override + protected Unwrapper[] createUnwrappers() { + return new Unwrapper[] { + new KoitlinUnwrappers.KotlinThenUnwrapper("unwrap.expression"), + new KoitlinUnwrappers.KotlinElseRemover("remove.else"), + new KoitlinUnwrappers.KotlinElseUnwrapper("unwrap.else"), + new KoitlinUnwrappers.KotlinLoopUnwrapper("unwrap.expression"), + }; + } +} diff --git a/idea/src/org/jetbrains/jet/plugin/codeInsight/unwrap/KotlinUnwrapRemoveBase.java b/idea/src/org/jetbrains/jet/plugin/codeInsight/unwrap/KotlinUnwrapRemoveBase.java new file mode 100644 index 00000000000..ac021d0880b --- /dev/null +++ b/idea/src/org/jetbrains/jet/plugin/codeInsight/unwrap/KotlinUnwrapRemoveBase.java @@ -0,0 +1,92 @@ +/* + * 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.unwrap; + +import com.intellij.codeInsight.unwrap.AbstractUnwrapper; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiWhiteSpace; +import com.intellij.util.IncorrectOperationException; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.jet.lang.psi.JetBlockExpression; +import org.jetbrains.jet.lang.psi.JetElement; +import org.jetbrains.jet.lang.psi.JetExpression; +import org.jetbrains.jet.plugin.JetBundle; +import org.jetbrains.jet.plugin.refactoring.JetRefactoringUtil; + +import java.util.List; + +public abstract class KotlinUnwrapRemoveBase extends AbstractUnwrapper { + private final String key; + + protected KotlinUnwrapRemoveBase(@NotNull String key) { + /* + Pass empty description to superclass since actual description + is computed based on the Psi element at hand + */ + super(""); + this.key = key; + } + + @Override + public String getDescription(PsiElement e) { + assert e instanceof JetElement; + return JetBundle.message(key, JetRefactoringUtil.getExpressionShortText((JetElement) e)); + } + + protected boolean canExtractExpression(@NotNull JetExpression expression, @NotNull JetElement parent) { + if (expression instanceof JetBlockExpression) { + JetBlockExpression block = (JetBlockExpression) expression; + + return block.getStatements().size() <= 1 || parent instanceof JetBlockExpression; + } + return true; + } + + protected static class Context extends AbstractUnwrapper.AbstractContext { + @Override + protected boolean isWhiteSpace(PsiElement element) { + return element instanceof PsiWhiteSpace; + } + + public void extractFromBlock(@NotNull JetBlockExpression block, @NotNull JetElement from) throws IncorrectOperationException { + List expressions = block.getStatements(); + if (!expressions.isEmpty()) { + extract(expressions.get(0), expressions.get(expressions.size() - 1), from); + } + } + + public void extractFromExpression(@NotNull JetExpression expression, @NotNull JetElement from) throws IncorrectOperationException { + if (expression instanceof JetBlockExpression) { + extractFromBlock((JetBlockExpression) expression, from); + } + else { + extract(expression, expression, from); + } + } + + public void replace(@NotNull JetElement originalElement, @NotNull JetElement newElement) { + if (myIsEffective) { + originalElement.replace(newElement); + } + } + } + + @Override + protected Context createContext() { + return new Context(); + } +} \ No newline at end of file diff --git a/idea/src/org/jetbrains/jet/plugin/refactoring/JetRefactoringUtil.java b/idea/src/org/jetbrains/jet/plugin/refactoring/JetRefactoringUtil.java index 4414aecf145..c08c7aa94d1 100644 --- a/idea/src/org/jetbrains/jet/plugin/refactoring/JetRefactoringUtil.java +++ b/idea/src/org/jetbrains/jet/plugin/refactoring/JetRefactoringUtil.java @@ -189,8 +189,8 @@ public class JetRefactoringUtil { } - public static String getExpressionShortText(@NotNull JetExpression expression) { //todo: write appropriate implementation - String expressionText = expression.getText(); + public static String getExpressionShortText(@NotNull JetElement element) { //todo: write appropriate implementation + String expressionText = element.getText(); if (expressionText.length() > 20) { expressionText = expressionText.substring(0, 17) + "..."; } diff --git a/idea/testData/codeInsight/unwrapAndRemove/removeElse/else.kt b/idea/testData/codeInsight/unwrapAndRemove/removeElse/else.kt new file mode 100644 index 00000000000..99d795908f0 --- /dev/null +++ b/idea/testData/codeInsight/unwrapAndRemove/removeElse/else.kt @@ -0,0 +1,8 @@ +// OPTION: 1 +fun foo(n: Int): Int { + return if (n > 0) { + n + 10 + } else { + n - 10 + } +} diff --git a/idea/testData/codeInsight/unwrapAndRemove/removeElse/else.kt.after b/idea/testData/codeInsight/unwrapAndRemove/removeElse/else.kt.after new file mode 100644 index 00000000000..129fc978d17 --- /dev/null +++ b/idea/testData/codeInsight/unwrapAndRemove/removeElse/else.kt.after @@ -0,0 +1,6 @@ +// OPTION: 1 +fun foo(n: Int): Int { + return if (n > 0) { + n + 10 + } +} diff --git a/idea/testData/codeInsight/unwrapAndRemove/unwrapElse/elseCompoundInBlock.kt b/idea/testData/codeInsight/unwrapAndRemove/unwrapElse/elseCompoundInBlock.kt new file mode 100644 index 00000000000..271d5913dbf --- /dev/null +++ b/idea/testData/codeInsight/unwrapAndRemove/unwrapElse/elseCompoundInBlock.kt @@ -0,0 +1,12 @@ +// OPTION: 3 +fun foo(n: Int): Int { + if (n > 0) { + println("> 0") + n + 10 + } else { + println("<= 0") + n - 10 + } + + return n +} diff --git a/idea/testData/codeInsight/unwrapAndRemove/unwrapElse/elseCompoundInBlock.kt.after b/idea/testData/codeInsight/unwrapAndRemove/unwrapElse/elseCompoundInBlock.kt.after new file mode 100644 index 00000000000..7b6f54d5da5 --- /dev/null +++ b/idea/testData/codeInsight/unwrapAndRemove/unwrapElse/elseCompoundInBlock.kt.after @@ -0,0 +1,7 @@ +// OPTION: 3 +fun foo(n: Int): Int { + println("<= 0") + n - 10 + + return n +} diff --git a/idea/testData/codeInsight/unwrapAndRemove/unwrapElse/elseCompoundInReturn.kt b/idea/testData/codeInsight/unwrapAndRemove/unwrapElse/elseCompoundInReturn.kt new file mode 100644 index 00000000000..be9f48ed1ce --- /dev/null +++ b/idea/testData/codeInsight/unwrapAndRemove/unwrapElse/elseCompoundInReturn.kt @@ -0,0 +1,10 @@ +// IS_APPLICABLE: false +fun foo(n: Int): Int { + return if (n > 0) { + println("> 0") + n + 10 + } else { + println("<= 0") + n - 10 + } +} diff --git a/idea/testData/codeInsight/unwrapAndRemove/unwrapElse/elseSimpleInReturn.kt b/idea/testData/codeInsight/unwrapAndRemove/unwrapElse/elseSimpleInReturn.kt new file mode 100644 index 00000000000..c7ab0d75ffc --- /dev/null +++ b/idea/testData/codeInsight/unwrapAndRemove/unwrapElse/elseSimpleInReturn.kt @@ -0,0 +1,8 @@ +// OPTION: 2 +fun foo(n: Int): Int { + return if (n > 0) { + n + 10 + } else { + n - 10 + } +} diff --git a/idea/testData/codeInsight/unwrapAndRemove/unwrapElse/elseSimpleInReturn.kt.after b/idea/testData/codeInsight/unwrapAndRemove/unwrapElse/elseSimpleInReturn.kt.after new file mode 100644 index 00000000000..d15dc9845b3 --- /dev/null +++ b/idea/testData/codeInsight/unwrapAndRemove/unwrapElse/elseSimpleInReturn.kt.after @@ -0,0 +1,4 @@ +// OPTION: 2 +fun foo(n: Int): Int { + return n - 10 +} diff --git a/idea/testData/codeInsight/unwrapAndRemove/unwrapLoop/doWhile.kt b/idea/testData/codeInsight/unwrapAndRemove/unwrapLoop/doWhile.kt new file mode 100644 index 00000000000..1436ff29b01 --- /dev/null +++ b/idea/testData/codeInsight/unwrapAndRemove/unwrapLoop/doWhile.kt @@ -0,0 +1,8 @@ +// OPTION: 1 +fun foo(n: Int) { + var m = n + do { + m-- + println(m) + } while (m > 0) +} diff --git a/idea/testData/codeInsight/unwrapAndRemove/unwrapLoop/doWhile.kt.after b/idea/testData/codeInsight/unwrapAndRemove/unwrapLoop/doWhile.kt.after new file mode 100644 index 00000000000..f70074a7387 --- /dev/null +++ b/idea/testData/codeInsight/unwrapAndRemove/unwrapLoop/doWhile.kt.after @@ -0,0 +1,6 @@ +// OPTION: 1 +fun foo(n: Int) { + var m = n + m-- + println(m) +} diff --git a/idea/testData/codeInsight/unwrapAndRemove/unwrapLoop/for.kt b/idea/testData/codeInsight/unwrapAndRemove/unwrapLoop/for.kt new file mode 100644 index 00000000000..2b8820078e9 --- /dev/null +++ b/idea/testData/codeInsight/unwrapAndRemove/unwrapLoop/for.kt @@ -0,0 +1,6 @@ +// OPTION: 1 +fun foo(n: Int) { + for (k in 0..n) { + println(k) + } +} diff --git a/idea/testData/codeInsight/unwrapAndRemove/unwrapLoop/for.kt.after b/idea/testData/codeInsight/unwrapAndRemove/unwrapLoop/for.kt.after new file mode 100644 index 00000000000..73dec51eae0 --- /dev/null +++ b/idea/testData/codeInsight/unwrapAndRemove/unwrapLoop/for.kt.after @@ -0,0 +1,4 @@ +// OPTION: 1 +fun foo(n: Int) { + println(k) +} diff --git a/idea/testData/codeInsight/unwrapAndRemove/unwrapLoop/while.kt b/idea/testData/codeInsight/unwrapAndRemove/unwrapLoop/while.kt new file mode 100644 index 00000000000..7ca52bb6790 --- /dev/null +++ b/idea/testData/codeInsight/unwrapAndRemove/unwrapLoop/while.kt @@ -0,0 +1,8 @@ +// OPTION: 1 +fun foo(n: Int) { + var m = n + while (m > 0) { + m-- + println(m) + } +} diff --git a/idea/testData/codeInsight/unwrapAndRemove/unwrapLoop/while.kt.after b/idea/testData/codeInsight/unwrapAndRemove/unwrapLoop/while.kt.after new file mode 100644 index 00000000000..f70074a7387 --- /dev/null +++ b/idea/testData/codeInsight/unwrapAndRemove/unwrapLoop/while.kt.after @@ -0,0 +1,6 @@ +// OPTION: 1 +fun foo(n: Int) { + var m = n + m-- + println(m) +} diff --git a/idea/testData/codeInsight/unwrapAndRemove/unwrapThen/thenCompoundInBlock.kt b/idea/testData/codeInsight/unwrapAndRemove/unwrapThen/thenCompoundInBlock.kt new file mode 100644 index 00000000000..9c7f402e5ad --- /dev/null +++ b/idea/testData/codeInsight/unwrapAndRemove/unwrapThen/thenCompoundInBlock.kt @@ -0,0 +1,12 @@ +// OPTION: 1 +fun foo(n: Int): Int { + if (n > 0) { + println("> 0") + n + 10 + } else { + println("<= 0") + n - 10 + } + + return n +} diff --git a/idea/testData/codeInsight/unwrapAndRemove/unwrapThen/thenCompoundInBlock.kt.after b/idea/testData/codeInsight/unwrapAndRemove/unwrapThen/thenCompoundInBlock.kt.after new file mode 100644 index 00000000000..eeb88bdc504 --- /dev/null +++ b/idea/testData/codeInsight/unwrapAndRemove/unwrapThen/thenCompoundInBlock.kt.after @@ -0,0 +1,7 @@ +// OPTION: 1 +fun foo(n: Int): Int { + println("> 0") + n + 10 + + return n +} diff --git a/idea/testData/codeInsight/unwrapAndRemove/unwrapThen/thenCompoundInReturn.kt b/idea/testData/codeInsight/unwrapAndRemove/unwrapThen/thenCompoundInReturn.kt new file mode 100644 index 00000000000..7a91c658fb3 --- /dev/null +++ b/idea/testData/codeInsight/unwrapAndRemove/unwrapThen/thenCompoundInReturn.kt @@ -0,0 +1,10 @@ +// IS_APPLICABLE: false +fun foo(n: Int): Int { + return if (n > 0) { + println("> 0") + n + 10 + } else { + println("<= 0") + n - 10 + } +} diff --git a/idea/testData/codeInsight/unwrapAndRemove/unwrapThen/thenSimpleInReturn.kt b/idea/testData/codeInsight/unwrapAndRemove/unwrapThen/thenSimpleInReturn.kt new file mode 100644 index 00000000000..340d3cf0916 --- /dev/null +++ b/idea/testData/codeInsight/unwrapAndRemove/unwrapThen/thenSimpleInReturn.kt @@ -0,0 +1,8 @@ +// OPTION: 0 +fun foo(n: Int): Int { + return if (n > 0) { + n + 10 + } else { + n - 10 + } +} diff --git a/idea/testData/codeInsight/unwrapAndRemove/unwrapThen/thenSimpleInReturn.kt.after b/idea/testData/codeInsight/unwrapAndRemove/unwrapThen/thenSimpleInReturn.kt.after new file mode 100644 index 00000000000..fcb37fc6edb --- /dev/null +++ b/idea/testData/codeInsight/unwrapAndRemove/unwrapThen/thenSimpleInReturn.kt.after @@ -0,0 +1,4 @@ +// OPTION: 0 +fun foo(n: Int): Int { + return n + 10 +} diff --git a/idea/tests/org/jetbrains/jet/plugin/codeInsight/unwrap/AbstractUnwrapRemoveTest.java b/idea/tests/org/jetbrains/jet/plugin/codeInsight/unwrap/AbstractUnwrapRemoveTest.java new file mode 100644 index 00000000000..c3a610bab7f --- /dev/null +++ b/idea/tests/org/jetbrains/jet/plugin/codeInsight/unwrap/AbstractUnwrapRemoveTest.java @@ -0,0 +1,86 @@ +/* + * 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.unwrap; + +import com.intellij.codeInsight.unwrap.Unwrapper; +import com.intellij.openapi.util.Condition; +import com.intellij.openapi.util.Pair; +import com.intellij.openapi.util.io.FileUtil; +import com.intellij.psi.PsiElement; +import com.intellij.testFramework.LightCodeInsightTestCase; +import com.intellij.util.containers.ContainerUtil; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.jet.InTextDirectivesUtils; + +import java.io.File; +import java.util.List; + +public abstract class AbstractUnwrapRemoveTest extends LightCodeInsightTestCase { + public void doTestThenUnwrapper(@NotNull String path) throws Exception { + doTest(path, KoitlinUnwrappers.KotlinThenUnwrapper.class); + } + + public void doTestElseUnwrapper(@NotNull String path) throws Exception { + doTest(path, KoitlinUnwrappers.KotlinElseUnwrapper.class); + } + + public void doTestElseRemover(@NotNull String path) throws Exception { + doTest(path, KoitlinUnwrappers.KotlinElseRemover.class); + } + + public void doTestLoopUnwrapper(@NotNull String path) throws Exception { + doTest(path, KoitlinUnwrappers.KotlinLoopUnwrapper.class); + } + + private void doTest(@NotNull String path, final Class unwrapperClass) throws Exception { + configureByFile(path); + + String fileText = FileUtil.loadFile(new File(path), true); + + String isApplicableString = InTextDirectivesUtils.findStringWithPrefixes(fileText, "// IS_APPLICABLE: "); + boolean isApplicableExpected = isApplicableString == null || isApplicableString.equals("true"); + + String option = InTextDirectivesUtils.findStringWithPrefixes(fileText, "// OPTION: "); + Integer optionIndex = option != null ? Integer.parseInt(option) : 0; + + List> unwrappersWithPsi = + new KotlinUnwrapDescriptor().collectUnwrappers(getProject(), getEditor(), getFile()); + + if (isApplicableExpected) { + Pair selectedUnwrapperWithPsi = unwrappersWithPsi.get(optionIndex); + assertEquals(unwrapperClass, selectedUnwrapperWithPsi.second.getClass()); + + selectedUnwrapperWithPsi.second.unwrap(getEditor(), selectedUnwrapperWithPsi.first); + checkResultByFile(path + ".after"); + } else { + assertTrue( + ContainerUtil.and(unwrappersWithPsi, new Condition>() { + @Override + public boolean value(Pair pair) { + return pair.second.getClass() != unwrapperClass; + } + }) + ); + } + } + + @NotNull + @Override + protected String getTestDataPath() { + return ""; + } +} diff --git a/idea/tests/org/jetbrains/jet/plugin/codeInsight/unwrap/UnwrapRemoveTestGenerated.java b/idea/tests/org/jetbrains/jet/plugin/codeInsight/unwrap/UnwrapRemoveTestGenerated.java new file mode 100644 index 00000000000..f91dadce89a --- /dev/null +++ b/idea/tests/org/jetbrains/jet/plugin/codeInsight/unwrap/UnwrapRemoveTestGenerated.java @@ -0,0 +1,125 @@ +/* + * 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.unwrap; + +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.unwrap.AbstractUnwrapRemoveTest; + +/** This class is generated by {@link org.jetbrains.jet.generators.tests.GenerateTests}. DO NOT MODIFY MANUALLY */ +@SuppressWarnings("all") +@InnerTestClasses({UnwrapRemoveTestGenerated.UnwrapThen.class, UnwrapRemoveTestGenerated.UnwrapElse.class, UnwrapRemoveTestGenerated.RemoveElse.class, UnwrapRemoveTestGenerated.UnwrapLoop.class}) +public class UnwrapRemoveTestGenerated extends AbstractUnwrapRemoveTest { + @TestMetadata("idea/testData/codeInsight/unwrapAndRemove/unwrapThen") + public static class UnwrapThen extends AbstractUnwrapRemoveTest { + public void testAllFilesPresentInUnwrapThen() throws Exception { + JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.GenerateTests", new File("idea/testData/codeInsight/unwrapAndRemove/unwrapThen"), Pattern.compile("^(.+)\\.kt$"), true); + } + + @TestMetadata("thenCompoundInBlock.kt") + public void testThenCompoundInBlock() throws Exception { + doTestThenUnwrapper("idea/testData/codeInsight/unwrapAndRemove/unwrapThen/thenCompoundInBlock.kt"); + } + + @TestMetadata("thenCompoundInReturn.kt") + public void testThenCompoundInReturn() throws Exception { + doTestThenUnwrapper("idea/testData/codeInsight/unwrapAndRemove/unwrapThen/thenCompoundInReturn.kt"); + } + + @TestMetadata("thenSimpleInReturn.kt") + public void testThenSimpleInReturn() throws Exception { + doTestThenUnwrapper("idea/testData/codeInsight/unwrapAndRemove/unwrapThen/thenSimpleInReturn.kt"); + } + + } + + @TestMetadata("idea/testData/codeInsight/unwrapAndRemove/unwrapElse") + public static class UnwrapElse extends AbstractUnwrapRemoveTest { + public void testAllFilesPresentInUnwrapElse() throws Exception { + JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.GenerateTests", new File("idea/testData/codeInsight/unwrapAndRemove/unwrapElse"), Pattern.compile("^(.+)\\.kt$"), true); + } + + @TestMetadata("elseCompoundInBlock.kt") + public void testElseCompoundInBlock() throws Exception { + doTestElseUnwrapper("idea/testData/codeInsight/unwrapAndRemove/unwrapElse/elseCompoundInBlock.kt"); + } + + @TestMetadata("elseCompoundInReturn.kt") + public void testElseCompoundInReturn() throws Exception { + doTestElseUnwrapper("idea/testData/codeInsight/unwrapAndRemove/unwrapElse/elseCompoundInReturn.kt"); + } + + @TestMetadata("elseSimpleInReturn.kt") + public void testElseSimpleInReturn() throws Exception { + doTestElseUnwrapper("idea/testData/codeInsight/unwrapAndRemove/unwrapElse/elseSimpleInReturn.kt"); + } + + } + + @TestMetadata("idea/testData/codeInsight/unwrapAndRemove/removeElse") + public static class RemoveElse extends AbstractUnwrapRemoveTest { + public void testAllFilesPresentInRemoveElse() throws Exception { + JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.GenerateTests", new File("idea/testData/codeInsight/unwrapAndRemove/removeElse"), Pattern.compile("^(.+)\\.kt$"), true); + } + + @TestMetadata("else.kt") + public void testElse() throws Exception { + doTestElseRemover("idea/testData/codeInsight/unwrapAndRemove/removeElse/else.kt"); + } + + } + + @TestMetadata("idea/testData/codeInsight/unwrapAndRemove/unwrapLoop") + public static class UnwrapLoop extends AbstractUnwrapRemoveTest { + public void testAllFilesPresentInUnwrapLoop() throws Exception { + JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.GenerateTests", new File("idea/testData/codeInsight/unwrapAndRemove/unwrapLoop"), Pattern.compile("^(.+)\\.kt$"), true); + } + + @TestMetadata("doWhile.kt") + public void testDoWhile() throws Exception { + doTestLoopUnwrapper("idea/testData/codeInsight/unwrapAndRemove/unwrapLoop/doWhile.kt"); + } + + @TestMetadata("for.kt") + public void testFor() throws Exception { + doTestLoopUnwrapper("idea/testData/codeInsight/unwrapAndRemove/unwrapLoop/for.kt"); + } + + @TestMetadata("while.kt") + public void testWhile() throws Exception { + doTestLoopUnwrapper("idea/testData/codeInsight/unwrapAndRemove/unwrapLoop/while.kt"); + } + + } + + public static Test suite() { + TestSuite suite = new TestSuite("UnwrapRemoveTestGenerated"); + suite.addTestSuite(UnwrapThen.class); + suite.addTestSuite(UnwrapElse.class); + suite.addTestSuite(RemoveElse.class); + suite.addTestSuite(UnwrapLoop.class); + return suite; + } +} From 9d46c901652ecf37f34379e72178aab0b935b2f8 Mon Sep 17 00:00:00 2001 From: Alexey Sedunov Date: Wed, 19 Jun 2013 15:13:49 +0400 Subject: [PATCH 179/291] Implement Unwrap/Remove for lambdas --- .../jet/generators/tests/GenerateTests.java | 3 +- .../unwrap/KotlinLambdaUnwrapper.java | 70 +++++++++++++++++++ .../unwrap/KotlinUnwrapDescriptor.java | 1 + .../unwrapLambda/lambdaCallCompoundInBlock.kt | 7 ++ .../lambdaCallCompoundInBlock.kt.after | 5 ++ .../lambdaCallCompoundInReturn.kt | 7 ++ .../unwrapLambda/lambdaCallInBlock.kt | 6 ++ .../unwrapLambda/lambdaCallInBlock.kt.after | 4 ++ .../unwrapLambda/lambdaCallInBlock2.kt | 6 ++ .../unwrapLambda/lambdaCallInBlock2.kt.after | 4 ++ .../unwrapLambda/lambdaCallSimpleInReturn.kt | 6 ++ .../lambdaCallSimpleInReturn.kt.after | 4 ++ .../unwrapLambda/lambdaInBlock.kt | 6 ++ .../unwrapLambda/lambdaInBlock.kt.after | 4 ++ .../lambdaNonLocalPropertyCompoundInBlock.kt | 5 ++ .../lambdaNonLocalPropertyInBlock.kt | 4 ++ .../lambdaNonLocalPropertyInBlock.kt.after | 2 + .../lambdaPropertyCompoundInBlock.kt | 7 ++ .../lambdaPropertyCompoundInBlock.kt.after | 5 ++ .../unwrapLambda/lambdaPropertyInBlock.kt | 6 ++ .../lambdaPropertyInBlock.kt.after | 4 ++ .../unwrap/AbstractUnwrapRemoveTest.java | 4 ++ .../unwrap/UnwrapRemoveTestGenerated.java | 61 +++++++++++++++- 23 files changed, 229 insertions(+), 2 deletions(-) create mode 100644 idea/src/org/jetbrains/jet/plugin/codeInsight/unwrap/KotlinLambdaUnwrapper.java create mode 100644 idea/testData/codeInsight/unwrapAndRemove/unwrapLambda/lambdaCallCompoundInBlock.kt create mode 100644 idea/testData/codeInsight/unwrapAndRemove/unwrapLambda/lambdaCallCompoundInBlock.kt.after create mode 100644 idea/testData/codeInsight/unwrapAndRemove/unwrapLambda/lambdaCallCompoundInReturn.kt create mode 100644 idea/testData/codeInsight/unwrapAndRemove/unwrapLambda/lambdaCallInBlock.kt create mode 100644 idea/testData/codeInsight/unwrapAndRemove/unwrapLambda/lambdaCallInBlock.kt.after create mode 100644 idea/testData/codeInsight/unwrapAndRemove/unwrapLambda/lambdaCallInBlock2.kt create mode 100644 idea/testData/codeInsight/unwrapAndRemove/unwrapLambda/lambdaCallInBlock2.kt.after create mode 100644 idea/testData/codeInsight/unwrapAndRemove/unwrapLambda/lambdaCallSimpleInReturn.kt create mode 100644 idea/testData/codeInsight/unwrapAndRemove/unwrapLambda/lambdaCallSimpleInReturn.kt.after create mode 100644 idea/testData/codeInsight/unwrapAndRemove/unwrapLambda/lambdaInBlock.kt create mode 100644 idea/testData/codeInsight/unwrapAndRemove/unwrapLambda/lambdaInBlock.kt.after create mode 100644 idea/testData/codeInsight/unwrapAndRemove/unwrapLambda/lambdaNonLocalPropertyCompoundInBlock.kt create mode 100644 idea/testData/codeInsight/unwrapAndRemove/unwrapLambda/lambdaNonLocalPropertyInBlock.kt create mode 100644 idea/testData/codeInsight/unwrapAndRemove/unwrapLambda/lambdaNonLocalPropertyInBlock.kt.after create mode 100644 idea/testData/codeInsight/unwrapAndRemove/unwrapLambda/lambdaPropertyCompoundInBlock.kt create mode 100644 idea/testData/codeInsight/unwrapAndRemove/unwrapLambda/lambdaPropertyCompoundInBlock.kt.after create mode 100644 idea/testData/codeInsight/unwrapAndRemove/unwrapLambda/lambdaPropertyInBlock.kt create mode 100644 idea/testData/codeInsight/unwrapAndRemove/unwrapLambda/lambdaPropertyInBlock.kt.after diff --git a/generators/org/jetbrains/jet/generators/tests/GenerateTests.java b/generators/org/jetbrains/jet/generators/tests/GenerateTests.java index c50df4959b5..89d576bba48 100644 --- a/generators/org/jetbrains/jet/generators/tests/GenerateTests.java +++ b/generators/org/jetbrains/jet/generators/tests/GenerateTests.java @@ -378,7 +378,8 @@ public class GenerateTests { testModel("idea/testData/codeInsight/unwrapAndRemove/unwrapThen", "doTestThenUnwrapper"), testModel("idea/testData/codeInsight/unwrapAndRemove/unwrapElse", "doTestElseUnwrapper"), testModel("idea/testData/codeInsight/unwrapAndRemove/removeElse", "doTestElseRemover"), - testModel("idea/testData/codeInsight/unwrapAndRemove/unwrapLoop", "doTestLoopUnwrapper") + testModel("idea/testData/codeInsight/unwrapAndRemove/unwrapLoop", "doTestLoopUnwrapper"), + testModel("idea/testData/codeInsight/unwrapAndRemove/unwrapLambda", "doTestLambdaUnwrapper") ); } diff --git a/idea/src/org/jetbrains/jet/plugin/codeInsight/unwrap/KotlinLambdaUnwrapper.java b/idea/src/org/jetbrains/jet/plugin/codeInsight/unwrap/KotlinLambdaUnwrapper.java new file mode 100644 index 00000000000..f262fba9b48 --- /dev/null +++ b/idea/src/org/jetbrains/jet/plugin/codeInsight/unwrap/KotlinLambdaUnwrapper.java @@ -0,0 +1,70 @@ +/* + * 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.unwrap; + +import com.intellij.psi.PsiElement; +import com.intellij.psi.util.PsiTreeUtil; +import com.intellij.util.IncorrectOperationException; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.jet.lang.psi.*; + +public class KotlinLambdaUnwrapper extends KotlinUnwrapRemoveBase { + public KotlinLambdaUnwrapper(String key) { + super(key); + } + + private static JetElement getLambdaEnclosingElement(@NotNull JetFunctionLiteralExpression lambda) { + PsiElement parent = lambda.getParent(); + + if (parent instanceof JetValueArgument) { + return PsiTreeUtil.getParentOfType(parent, JetCallExpression.class, true); + } + + if (parent instanceof JetCallExpression) { + return (JetElement) parent; + } + + if (parent instanceof JetProperty && ((JetProperty) parent).isLocal()) { + return (JetElement) parent; + } + + return lambda; + } + + @Override + public boolean isApplicableTo(PsiElement e) { + if (!(e instanceof JetFunctionLiteralExpression)) return false; + + JetFunctionLiteralExpression lambda = (JetFunctionLiteralExpression) e; + JetBlockExpression body = lambda.getBodyExpression(); + JetElement enclosingElement = getLambdaEnclosingElement((JetFunctionLiteralExpression) e); + + if (body == null || enclosingElement == null) return false; + + return canExtractExpression(body, (JetElement)enclosingElement.getParent()); + } + + @Override + protected void doUnwrap(PsiElement element, Context context) throws IncorrectOperationException { + JetFunctionLiteralExpression lambda = (JetFunctionLiteralExpression) element; + JetBlockExpression body = lambda.getBodyExpression(); + JetElement enclosingExpression = getLambdaEnclosingElement(lambda); + + context.extractFromBlock(body, enclosingExpression); + context.delete(enclosingExpression); + } +} diff --git a/idea/src/org/jetbrains/jet/plugin/codeInsight/unwrap/KotlinUnwrapDescriptor.java b/idea/src/org/jetbrains/jet/plugin/codeInsight/unwrap/KotlinUnwrapDescriptor.java index 337c33de3a0..d3f661f6433 100644 --- a/idea/src/org/jetbrains/jet/plugin/codeInsight/unwrap/KotlinUnwrapDescriptor.java +++ b/idea/src/org/jetbrains/jet/plugin/codeInsight/unwrap/KotlinUnwrapDescriptor.java @@ -27,6 +27,7 @@ public class KotlinUnwrapDescriptor extends UnwrapDescriptorBase { new KoitlinUnwrappers.KotlinElseRemover("remove.else"), new KoitlinUnwrappers.KotlinElseUnwrapper("unwrap.else"), new KoitlinUnwrappers.KotlinLoopUnwrapper("unwrap.expression"), + new KotlinLambdaUnwrapper("unwrap.expression"), }; } } diff --git a/idea/testData/codeInsight/unwrapAndRemove/unwrapLambda/lambdaCallCompoundInBlock.kt b/idea/testData/codeInsight/unwrapAndRemove/unwrapLambda/lambdaCallCompoundInBlock.kt new file mode 100644 index 00000000000..cb28bebdc7f --- /dev/null +++ b/idea/testData/codeInsight/unwrapAndRemove/unwrapLambda/lambdaCallCompoundInBlock.kt @@ -0,0 +1,7 @@ +// OPTION: 0 +fun foo() { + run(1, 2) { + println("lambda") + println("another lambda") + } +} diff --git a/idea/testData/codeInsight/unwrapAndRemove/unwrapLambda/lambdaCallCompoundInBlock.kt.after b/idea/testData/codeInsight/unwrapAndRemove/unwrapLambda/lambdaCallCompoundInBlock.kt.after new file mode 100644 index 00000000000..921c5bac342 --- /dev/null +++ b/idea/testData/codeInsight/unwrapAndRemove/unwrapLambda/lambdaCallCompoundInBlock.kt.after @@ -0,0 +1,5 @@ +// OPTION: 0 +fun foo() { + println("lambda") + println("another lambda") +} diff --git a/idea/testData/codeInsight/unwrapAndRemove/unwrapLambda/lambdaCallCompoundInReturn.kt b/idea/testData/codeInsight/unwrapAndRemove/unwrapLambda/lambdaCallCompoundInReturn.kt new file mode 100644 index 00000000000..2ad75880d74 --- /dev/null +++ b/idea/testData/codeInsight/unwrapAndRemove/unwrapLambda/lambdaCallCompoundInReturn.kt @@ -0,0 +1,7 @@ +// IS_APPLICABLE: false +fun foo() { + return run(1, 2) { + println("lambda") + println("another lambda") + } +} diff --git a/idea/testData/codeInsight/unwrapAndRemove/unwrapLambda/lambdaCallInBlock.kt b/idea/testData/codeInsight/unwrapAndRemove/unwrapLambda/lambdaCallInBlock.kt new file mode 100644 index 00000000000..4e2bff439c0 --- /dev/null +++ b/idea/testData/codeInsight/unwrapAndRemove/unwrapLambda/lambdaCallInBlock.kt @@ -0,0 +1,6 @@ +// OPTION: 0 +fun foo() { + run(1, 2) { + println("lambda") + } +} diff --git a/idea/testData/codeInsight/unwrapAndRemove/unwrapLambda/lambdaCallInBlock.kt.after b/idea/testData/codeInsight/unwrapAndRemove/unwrapLambda/lambdaCallInBlock.kt.after new file mode 100644 index 00000000000..b65ed1f3154 --- /dev/null +++ b/idea/testData/codeInsight/unwrapAndRemove/unwrapLambda/lambdaCallInBlock.kt.after @@ -0,0 +1,4 @@ +// OPTION: 0 +fun foo() { + println("lambda") +} diff --git a/idea/testData/codeInsight/unwrapAndRemove/unwrapLambda/lambdaCallInBlock2.kt b/idea/testData/codeInsight/unwrapAndRemove/unwrapLambda/lambdaCallInBlock2.kt new file mode 100644 index 00000000000..2dad0fed3e1 --- /dev/null +++ b/idea/testData/codeInsight/unwrapAndRemove/unwrapLambda/lambdaCallInBlock2.kt @@ -0,0 +1,6 @@ +// OPTION: 0 +fun foo() { + run({ + println("lambda") + }, 1) +} diff --git a/idea/testData/codeInsight/unwrapAndRemove/unwrapLambda/lambdaCallInBlock2.kt.after b/idea/testData/codeInsight/unwrapAndRemove/unwrapLambda/lambdaCallInBlock2.kt.after new file mode 100644 index 00000000000..b65ed1f3154 --- /dev/null +++ b/idea/testData/codeInsight/unwrapAndRemove/unwrapLambda/lambdaCallInBlock2.kt.after @@ -0,0 +1,4 @@ +// OPTION: 0 +fun foo() { + println("lambda") +} diff --git a/idea/testData/codeInsight/unwrapAndRemove/unwrapLambda/lambdaCallSimpleInReturn.kt b/idea/testData/codeInsight/unwrapAndRemove/unwrapLambda/lambdaCallSimpleInReturn.kt new file mode 100644 index 00000000000..340be5d64e1 --- /dev/null +++ b/idea/testData/codeInsight/unwrapAndRemove/unwrapLambda/lambdaCallSimpleInReturn.kt @@ -0,0 +1,6 @@ +// OPTION: 0 +fun foo() { + return run(1, 2) { + println("lambda") + } +} diff --git a/idea/testData/codeInsight/unwrapAndRemove/unwrapLambda/lambdaCallSimpleInReturn.kt.after b/idea/testData/codeInsight/unwrapAndRemove/unwrapLambda/lambdaCallSimpleInReturn.kt.after new file mode 100644 index 00000000000..391cca9da17 --- /dev/null +++ b/idea/testData/codeInsight/unwrapAndRemove/unwrapLambda/lambdaCallSimpleInReturn.kt.after @@ -0,0 +1,4 @@ +// OPTION: 0 +fun foo() { + return println("lambda") +} diff --git a/idea/testData/codeInsight/unwrapAndRemove/unwrapLambda/lambdaInBlock.kt b/idea/testData/codeInsight/unwrapAndRemove/unwrapLambda/lambdaInBlock.kt new file mode 100644 index 00000000000..d0cfb1fdec5 --- /dev/null +++ b/idea/testData/codeInsight/unwrapAndRemove/unwrapLambda/lambdaInBlock.kt @@ -0,0 +1,6 @@ +// OPTION: 1 +fun foo() { + { + println("lambda") + } +} diff --git a/idea/testData/codeInsight/unwrapAndRemove/unwrapLambda/lambdaInBlock.kt.after b/idea/testData/codeInsight/unwrapAndRemove/unwrapLambda/lambdaInBlock.kt.after new file mode 100644 index 00000000000..9613f1898d7 --- /dev/null +++ b/idea/testData/codeInsight/unwrapAndRemove/unwrapLambda/lambdaInBlock.kt.after @@ -0,0 +1,4 @@ +// OPTION: 1 +fun foo() { + println("lambda") +} diff --git a/idea/testData/codeInsight/unwrapAndRemove/unwrapLambda/lambdaNonLocalPropertyCompoundInBlock.kt b/idea/testData/codeInsight/unwrapAndRemove/unwrapLambda/lambdaNonLocalPropertyCompoundInBlock.kt new file mode 100644 index 00000000000..1d64a4c5819 --- /dev/null +++ b/idea/testData/codeInsight/unwrapAndRemove/unwrapLambda/lambdaNonLocalPropertyCompoundInBlock.kt @@ -0,0 +1,5 @@ +// IS_APPLICABLE: false +val x = { + println("lambda") + println("another lambda") +} diff --git a/idea/testData/codeInsight/unwrapAndRemove/unwrapLambda/lambdaNonLocalPropertyInBlock.kt b/idea/testData/codeInsight/unwrapAndRemove/unwrapLambda/lambdaNonLocalPropertyInBlock.kt new file mode 100644 index 00000000000..c8d7ed1c58b --- /dev/null +++ b/idea/testData/codeInsight/unwrapAndRemove/unwrapLambda/lambdaNonLocalPropertyInBlock.kt @@ -0,0 +1,4 @@ +// OPTION: 0 +val x = { + println("lambda") +} diff --git a/idea/testData/codeInsight/unwrapAndRemove/unwrapLambda/lambdaNonLocalPropertyInBlock.kt.after b/idea/testData/codeInsight/unwrapAndRemove/unwrapLambda/lambdaNonLocalPropertyInBlock.kt.after new file mode 100644 index 00000000000..e35380fe13e --- /dev/null +++ b/idea/testData/codeInsight/unwrapAndRemove/unwrapLambda/lambdaNonLocalPropertyInBlock.kt.after @@ -0,0 +1,2 @@ +// OPTION: 0 +val x = println("lambda") diff --git a/idea/testData/codeInsight/unwrapAndRemove/unwrapLambda/lambdaPropertyCompoundInBlock.kt b/idea/testData/codeInsight/unwrapAndRemove/unwrapLambda/lambdaPropertyCompoundInBlock.kt new file mode 100644 index 00000000000..518f0a85fd6 --- /dev/null +++ b/idea/testData/codeInsight/unwrapAndRemove/unwrapLambda/lambdaPropertyCompoundInBlock.kt @@ -0,0 +1,7 @@ +// OPTION: 0 +fun foo() { + val x = { + println("lambda") + println("another lambda") + } +} diff --git a/idea/testData/codeInsight/unwrapAndRemove/unwrapLambda/lambdaPropertyCompoundInBlock.kt.after b/idea/testData/codeInsight/unwrapAndRemove/unwrapLambda/lambdaPropertyCompoundInBlock.kt.after new file mode 100644 index 00000000000..921c5bac342 --- /dev/null +++ b/idea/testData/codeInsight/unwrapAndRemove/unwrapLambda/lambdaPropertyCompoundInBlock.kt.after @@ -0,0 +1,5 @@ +// OPTION: 0 +fun foo() { + println("lambda") + println("another lambda") +} diff --git a/idea/testData/codeInsight/unwrapAndRemove/unwrapLambda/lambdaPropertyInBlock.kt b/idea/testData/codeInsight/unwrapAndRemove/unwrapLambda/lambdaPropertyInBlock.kt new file mode 100644 index 00000000000..e196b88c954 --- /dev/null +++ b/idea/testData/codeInsight/unwrapAndRemove/unwrapLambda/lambdaPropertyInBlock.kt @@ -0,0 +1,6 @@ +// OPTION: 0 +fun foo() { + val x = { + println("lambda") + } +} diff --git a/idea/testData/codeInsight/unwrapAndRemove/unwrapLambda/lambdaPropertyInBlock.kt.after b/idea/testData/codeInsight/unwrapAndRemove/unwrapLambda/lambdaPropertyInBlock.kt.after new file mode 100644 index 00000000000..b65ed1f3154 --- /dev/null +++ b/idea/testData/codeInsight/unwrapAndRemove/unwrapLambda/lambdaPropertyInBlock.kt.after @@ -0,0 +1,4 @@ +// OPTION: 0 +fun foo() { + println("lambda") +} diff --git a/idea/tests/org/jetbrains/jet/plugin/codeInsight/unwrap/AbstractUnwrapRemoveTest.java b/idea/tests/org/jetbrains/jet/plugin/codeInsight/unwrap/AbstractUnwrapRemoveTest.java index c3a610bab7f..fdb85ac02f2 100644 --- a/idea/tests/org/jetbrains/jet/plugin/codeInsight/unwrap/AbstractUnwrapRemoveTest.java +++ b/idea/tests/org/jetbrains/jet/plugin/codeInsight/unwrap/AbstractUnwrapRemoveTest.java @@ -46,6 +46,10 @@ public abstract class AbstractUnwrapRemoveTest extends LightCodeInsightTestCase doTest(path, KoitlinUnwrappers.KotlinLoopUnwrapper.class); } + public void doTestLambdaUnwrapper(@NotNull String path) throws Exception { + doTest(path, KotlinLambdaUnwrapper.class); + } + private void doTest(@NotNull String path, final Class unwrapperClass) throws Exception { configureByFile(path); diff --git a/idea/tests/org/jetbrains/jet/plugin/codeInsight/unwrap/UnwrapRemoveTestGenerated.java b/idea/tests/org/jetbrains/jet/plugin/codeInsight/unwrap/UnwrapRemoveTestGenerated.java index f91dadce89a..79a7e9fd9b4 100644 --- a/idea/tests/org/jetbrains/jet/plugin/codeInsight/unwrap/UnwrapRemoveTestGenerated.java +++ b/idea/tests/org/jetbrains/jet/plugin/codeInsight/unwrap/UnwrapRemoveTestGenerated.java @@ -30,7 +30,7 @@ import org.jetbrains.jet.plugin.codeInsight.unwrap.AbstractUnwrapRemoveTest; /** This class is generated by {@link org.jetbrains.jet.generators.tests.GenerateTests}. DO NOT MODIFY MANUALLY */ @SuppressWarnings("all") -@InnerTestClasses({UnwrapRemoveTestGenerated.UnwrapThen.class, UnwrapRemoveTestGenerated.UnwrapElse.class, UnwrapRemoveTestGenerated.RemoveElse.class, UnwrapRemoveTestGenerated.UnwrapLoop.class}) +@InnerTestClasses({UnwrapRemoveTestGenerated.UnwrapThen.class, UnwrapRemoveTestGenerated.UnwrapElse.class, UnwrapRemoveTestGenerated.RemoveElse.class, UnwrapRemoveTestGenerated.UnwrapLoop.class, UnwrapRemoveTestGenerated.UnwrapLambda.class}) public class UnwrapRemoveTestGenerated extends AbstractUnwrapRemoveTest { @TestMetadata("idea/testData/codeInsight/unwrapAndRemove/unwrapThen") public static class UnwrapThen extends AbstractUnwrapRemoveTest { @@ -114,12 +114,71 @@ public class UnwrapRemoveTestGenerated extends AbstractUnwrapRemoveTest { } + @TestMetadata("idea/testData/codeInsight/unwrapAndRemove/unwrapLambda") + public static class UnwrapLambda extends AbstractUnwrapRemoveTest { + public void testAllFilesPresentInUnwrapLambda() throws Exception { + JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.GenerateTests", new File("idea/testData/codeInsight/unwrapAndRemove/unwrapLambda"), Pattern.compile("^(.+)\\.kt$"), true); + } + + @TestMetadata("lambdaCallCompoundInBlock.kt") + public void testLambdaCallCompoundInBlock() throws Exception { + doTestLambdaUnwrapper("idea/testData/codeInsight/unwrapAndRemove/unwrapLambda/lambdaCallCompoundInBlock.kt"); + } + + @TestMetadata("lambdaCallCompoundInReturn.kt") + public void testLambdaCallCompoundInReturn() throws Exception { + doTestLambdaUnwrapper("idea/testData/codeInsight/unwrapAndRemove/unwrapLambda/lambdaCallCompoundInReturn.kt"); + } + + @TestMetadata("lambdaCallInBlock.kt") + public void testLambdaCallInBlock() throws Exception { + doTestLambdaUnwrapper("idea/testData/codeInsight/unwrapAndRemove/unwrapLambda/lambdaCallInBlock.kt"); + } + + @TestMetadata("lambdaCallInBlock2.kt") + public void testLambdaCallInBlock2() throws Exception { + doTestLambdaUnwrapper("idea/testData/codeInsight/unwrapAndRemove/unwrapLambda/lambdaCallInBlock2.kt"); + } + + @TestMetadata("lambdaCallSimpleInReturn.kt") + public void testLambdaCallSimpleInReturn() throws Exception { + doTestLambdaUnwrapper("idea/testData/codeInsight/unwrapAndRemove/unwrapLambda/lambdaCallSimpleInReturn.kt"); + } + + @TestMetadata("lambdaInBlock.kt") + public void testLambdaInBlock() throws Exception { + doTestLambdaUnwrapper("idea/testData/codeInsight/unwrapAndRemove/unwrapLambda/lambdaInBlock.kt"); + } + + @TestMetadata("lambdaNonLocalPropertyCompoundInBlock.kt") + public void testLambdaNonLocalPropertyCompoundInBlock() throws Exception { + doTestLambdaUnwrapper("idea/testData/codeInsight/unwrapAndRemove/unwrapLambda/lambdaNonLocalPropertyCompoundInBlock.kt"); + } + + @TestMetadata("lambdaNonLocalPropertyInBlock.kt") + public void testLambdaNonLocalPropertyInBlock() throws Exception { + doTestLambdaUnwrapper("idea/testData/codeInsight/unwrapAndRemove/unwrapLambda/lambdaNonLocalPropertyInBlock.kt"); + } + + @TestMetadata("lambdaPropertyCompoundInBlock.kt") + public void testLambdaPropertyCompoundInBlock() throws Exception { + doTestLambdaUnwrapper("idea/testData/codeInsight/unwrapAndRemove/unwrapLambda/lambdaPropertyCompoundInBlock.kt"); + } + + @TestMetadata("lambdaPropertyInBlock.kt") + public void testLambdaPropertyInBlock() throws Exception { + doTestLambdaUnwrapper("idea/testData/codeInsight/unwrapAndRemove/unwrapLambda/lambdaPropertyInBlock.kt"); + } + + } + public static Test suite() { TestSuite suite = new TestSuite("UnwrapRemoveTestGenerated"); suite.addTestSuite(UnwrapThen.class); suite.addTestSuite(UnwrapElse.class); suite.addTestSuite(RemoveElse.class); suite.addTestSuite(UnwrapLoop.class); + suite.addTestSuite(UnwrapLambda.class); return suite; } } From 0b634cc9189d920fe9b5ff846bfaf418c8082414 Mon Sep 17 00:00:00 2001 From: Alexey Sedunov Date: Wed, 19 Jun 2013 16:08:53 +0400 Subject: [PATCH 180/291] Implement Unwrap/Remove for try expressions --- .../jet/generators/tests/GenerateTests.java | 5 + .../codeInsight/unwrap/KoitlinUnwrappers.java | 73 ++++++++++++ .../unwrap/KotlinComponentUnwrapper.java | 17 ++- .../codeInsight/unwrap/KotlinRemover.java | 31 +++++ .../unwrap/KotlinUnwrapDescriptor.java | 5 + .../unwrapAndRemove/removeCatch/catch.kt | 15 +++ .../removeCatch/catch.kt.after | 12 ++ .../removeFinally/finallyInBlock.kt | 18 +++ .../removeFinally/finallyInBlock.kt.after | 15 +++ .../removeFinally/finallyInReturn.kt | 15 +++ .../removeFinally/finallyInReturn.kt.after | 12 ++ .../unwrapCatch/catchCompoundInBlock.kt | 18 +++ .../unwrapCatch/catchCompoundInBlock.kt.after | 7 ++ .../unwrapCatch/catchCompoundInReturn.kt | 16 +++ .../unwrapCatch/catchSimpleInReturn.kt | 15 +++ .../unwrapCatch/catchSimpleInReturn.kt.after | 4 + .../unwrapFinally/finallyCompoundInBlock.kt | 18 +++ .../finallyCompoundInBlock.kt.after | 7 ++ .../unwrapFinally/finallyCompoundInReturn.kt | 16 +++ .../unwrapFinally/finallySimpleInReturn.kt | 15 +++ .../unwrapTry/tryCompoundInBlock.kt | 11 ++ .../unwrapTry/tryCompoundInBlock.kt.after | 7 ++ .../unwrapTry/tryCompoundInReturn.kt | 9 ++ .../unwrapTry/trySimpleInReturn.kt | 8 ++ .../unwrapTry/trySimpleInReturn.kt.after | 4 + .../unwrap/AbstractUnwrapRemoveTest.java | 20 ++++ .../unwrap/UnwrapRemoveTestGenerated.java | 107 +++++++++++++++++- 27 files changed, 494 insertions(+), 6 deletions(-) create mode 100644 idea/src/org/jetbrains/jet/plugin/codeInsight/unwrap/KotlinRemover.java create mode 100644 idea/testData/codeInsight/unwrapAndRemove/removeCatch/catch.kt create mode 100644 idea/testData/codeInsight/unwrapAndRemove/removeCatch/catch.kt.after create mode 100644 idea/testData/codeInsight/unwrapAndRemove/removeFinally/finallyInBlock.kt create mode 100644 idea/testData/codeInsight/unwrapAndRemove/removeFinally/finallyInBlock.kt.after create mode 100644 idea/testData/codeInsight/unwrapAndRemove/removeFinally/finallyInReturn.kt create mode 100644 idea/testData/codeInsight/unwrapAndRemove/removeFinally/finallyInReturn.kt.after create mode 100644 idea/testData/codeInsight/unwrapAndRemove/unwrapCatch/catchCompoundInBlock.kt create mode 100644 idea/testData/codeInsight/unwrapAndRemove/unwrapCatch/catchCompoundInBlock.kt.after create mode 100644 idea/testData/codeInsight/unwrapAndRemove/unwrapCatch/catchCompoundInReturn.kt create mode 100644 idea/testData/codeInsight/unwrapAndRemove/unwrapCatch/catchSimpleInReturn.kt create mode 100644 idea/testData/codeInsight/unwrapAndRemove/unwrapCatch/catchSimpleInReturn.kt.after create mode 100644 idea/testData/codeInsight/unwrapAndRemove/unwrapFinally/finallyCompoundInBlock.kt create mode 100644 idea/testData/codeInsight/unwrapAndRemove/unwrapFinally/finallyCompoundInBlock.kt.after create mode 100644 idea/testData/codeInsight/unwrapAndRemove/unwrapFinally/finallyCompoundInReturn.kt create mode 100644 idea/testData/codeInsight/unwrapAndRemove/unwrapFinally/finallySimpleInReturn.kt create mode 100644 idea/testData/codeInsight/unwrapAndRemove/unwrapTry/tryCompoundInBlock.kt create mode 100644 idea/testData/codeInsight/unwrapAndRemove/unwrapTry/tryCompoundInBlock.kt.after create mode 100644 idea/testData/codeInsight/unwrapAndRemove/unwrapTry/tryCompoundInReturn.kt create mode 100644 idea/testData/codeInsight/unwrapAndRemove/unwrapTry/trySimpleInReturn.kt create mode 100644 idea/testData/codeInsight/unwrapAndRemove/unwrapTry/trySimpleInReturn.kt.after diff --git a/generators/org/jetbrains/jet/generators/tests/GenerateTests.java b/generators/org/jetbrains/jet/generators/tests/GenerateTests.java index 89d576bba48..d0922dcbd7d 100644 --- a/generators/org/jetbrains/jet/generators/tests/GenerateTests.java +++ b/generators/org/jetbrains/jet/generators/tests/GenerateTests.java @@ -379,6 +379,11 @@ public class GenerateTests { testModel("idea/testData/codeInsight/unwrapAndRemove/unwrapElse", "doTestElseUnwrapper"), testModel("idea/testData/codeInsight/unwrapAndRemove/removeElse", "doTestElseRemover"), testModel("idea/testData/codeInsight/unwrapAndRemove/unwrapLoop", "doTestLoopUnwrapper"), + testModel("idea/testData/codeInsight/unwrapAndRemove/unwrapTry", "doTestTryUnwrapper"), + testModel("idea/testData/codeInsight/unwrapAndRemove/unwrapCatch", "doTestCatchUnwrapper"), + testModel("idea/testData/codeInsight/unwrapAndRemove/removeCatch", "doTestCatchRemover"), + testModel("idea/testData/codeInsight/unwrapAndRemove/unwrapFinally", "doTestFinallyUnwrapper"), + testModel("idea/testData/codeInsight/unwrapAndRemove/removeFinally", "doTestFinallyRemover"), testModel("idea/testData/codeInsight/unwrapAndRemove/unwrapLambda", "doTestLambdaUnwrapper") ); } diff --git a/idea/src/org/jetbrains/jet/plugin/codeInsight/unwrap/KoitlinUnwrappers.java b/idea/src/org/jetbrains/jet/plugin/codeInsight/unwrap/KoitlinUnwrappers.java index fe5c517be1c..52d4a760487 100644 --- a/idea/src/org/jetbrains/jet/plugin/codeInsight/unwrap/KoitlinUnwrappers.java +++ b/idea/src/org/jetbrains/jet/plugin/codeInsight/unwrap/KoitlinUnwrappers.java @@ -76,4 +76,77 @@ public class KoitlinUnwrappers { return target instanceof JetLoopExpression ? ((JetLoopExpression) target).getBody() : null; } } + + public static class KotlinTryUnwrapper extends KotlinComponentUnwrapper { + public KotlinTryUnwrapper(String key) { + super(key); + } + + @Override + @Nullable + protected JetExpression getExpressionToUnwrap(@NotNull JetElement target) { + return target instanceof JetTryExpression ? ((JetTryExpression) target).getTryBlock() : null; + } + } + + public static class KotlinCatchUnwrapper extends KotlinComponentUnwrapper { + public KotlinCatchUnwrapper(String key) { + super(key); + } + + @NotNull + @Override + protected JetElement getEnclosingElement(@NotNull JetElement element) { + return (JetElement)element.getParent(); + } + + @Override + protected JetExpression getExpressionToUnwrap(@NotNull JetElement target) { + return target instanceof JetCatchClause ? ((JetCatchClause) target).getCatchBody() : null; + } + } + + public static class KotlinCatchRemover extends KotlinRemover { + public KotlinCatchRemover(String key) { + super(key); + } + + @Override + public boolean isApplicableTo(PsiElement e) { + return e instanceof JetCatchClause; + } + } + + public static class KotlinFinallyUnwrapper extends KotlinComponentUnwrapper { + public KotlinFinallyUnwrapper(String key) { + super(key); + } + + @Override + public boolean isApplicableTo(PsiElement e) { + return super.isApplicableTo(e) && getEnclosingElement((JetElement)e).getParent() instanceof JetBlockExpression; + } + + @NotNull + @Override + protected JetElement getEnclosingElement(@NotNull JetElement element) { + return (JetElement)element.getParent(); + } + + @Override + protected JetExpression getExpressionToUnwrap(@NotNull JetElement target) { + return target instanceof JetFinallySection ? ((JetFinallySection) target).getFinalExpression() : null; + } + } + + public static class KotlinFinallyRemover extends KotlinRemover { + public KotlinFinallyRemover(String key) { + super(key); + } + + @Override + public boolean isApplicableTo(PsiElement e) { + return e instanceof JetFinallySection; + } + } } diff --git a/idea/src/org/jetbrains/jet/plugin/codeInsight/unwrap/KotlinComponentUnwrapper.java b/idea/src/org/jetbrains/jet/plugin/codeInsight/unwrap/KotlinComponentUnwrapper.java index be72bcaf98a..54e8e5d5316 100644 --- a/idea/src/org/jetbrains/jet/plugin/codeInsight/unwrap/KotlinComponentUnwrapper.java +++ b/idea/src/org/jetbrains/jet/plugin/codeInsight/unwrap/KotlinComponentUnwrapper.java @@ -31,21 +31,28 @@ public abstract class KotlinComponentUnwrapper extends KotlinUnwrapRemoveBase { @Nullable protected abstract JetExpression getExpressionToUnwrap(@NotNull JetElement target); + @NotNull + protected JetElement getEnclosingElement(@NotNull JetElement element) { + return element; + } + @Override public boolean isApplicableTo(PsiElement e) { if (!(e instanceof JetElement)) return false; JetExpression expressionToUnwrap = getExpressionToUnwrap((JetElement) e); - return expressionToUnwrap != null && canExtractExpression(expressionToUnwrap, (JetElement) e.getParent()); + return expressionToUnwrap != null && canExtractExpression(expressionToUnwrap, + (JetElement) getEnclosingElement((JetElement) e).getParent()); } @Override protected void doUnwrap(PsiElement element, Context context) throws IncorrectOperationException { - JetExpression targetExpression = (JetExpression) element; - JetExpression expressionToUnwrap = getExpressionToUnwrap(targetExpression); + JetElement targetElement = (JetElement) element; + JetExpression expressionToUnwrap = getExpressionToUnwrap(targetElement); assert expressionToUnwrap != null; - context.extractFromExpression(expressionToUnwrap, targetExpression); - context.delete(targetExpression); + JetElement enclosingElement = getEnclosingElement(targetElement); + context.extractFromExpression(expressionToUnwrap, enclosingElement); + context.delete(enclosingElement); } } diff --git a/idea/src/org/jetbrains/jet/plugin/codeInsight/unwrap/KotlinRemover.java b/idea/src/org/jetbrains/jet/plugin/codeInsight/unwrap/KotlinRemover.java new file mode 100644 index 00000000000..4522986eb46 --- /dev/null +++ b/idea/src/org/jetbrains/jet/plugin/codeInsight/unwrap/KotlinRemover.java @@ -0,0 +1,31 @@ +/* + * 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.unwrap; + +import com.intellij.psi.PsiElement; +import com.intellij.util.IncorrectOperationException; + +public abstract class KotlinRemover extends KotlinUnwrapRemoveBase { + public KotlinRemover(String key) { + super(key); + } + + @Override + protected void doUnwrap(PsiElement element, Context context) throws IncorrectOperationException { + context.delete(element); + } +} diff --git a/idea/src/org/jetbrains/jet/plugin/codeInsight/unwrap/KotlinUnwrapDescriptor.java b/idea/src/org/jetbrains/jet/plugin/codeInsight/unwrap/KotlinUnwrapDescriptor.java index d3f661f6433..a105ac0d978 100644 --- a/idea/src/org/jetbrains/jet/plugin/codeInsight/unwrap/KotlinUnwrapDescriptor.java +++ b/idea/src/org/jetbrains/jet/plugin/codeInsight/unwrap/KotlinUnwrapDescriptor.java @@ -27,6 +27,11 @@ public class KotlinUnwrapDescriptor extends UnwrapDescriptorBase { new KoitlinUnwrappers.KotlinElseRemover("remove.else"), new KoitlinUnwrappers.KotlinElseUnwrapper("unwrap.else"), new KoitlinUnwrappers.KotlinLoopUnwrapper("unwrap.expression"), + new KoitlinUnwrappers.KotlinTryUnwrapper("unwrap.expression"), + new KoitlinUnwrappers.KotlinCatchUnwrapper("unwrap.expression"), + new KoitlinUnwrappers.KotlinCatchRemover("remove.expression"), + new KoitlinUnwrappers.KotlinFinallyUnwrapper("unwrap.expression"), + new KoitlinUnwrappers.KotlinFinallyRemover("remove.expression"), new KotlinLambdaUnwrapper("unwrap.expression"), }; } diff --git a/idea/testData/codeInsight/unwrapAndRemove/removeCatch/catch.kt b/idea/testData/codeInsight/unwrapAndRemove/removeCatch/catch.kt new file mode 100644 index 00000000000..d34c09620f6 --- /dev/null +++ b/idea/testData/codeInsight/unwrapAndRemove/removeCatch/catch.kt @@ -0,0 +1,15 @@ +// OPTION: 1 +fun foo(n: Int): Int { + return try { + n / 0 + } + catch (e: ArithmeticException) { + -1 + } + catch (e: Exception) { + -2 + } + finally { + + } +} diff --git a/idea/testData/codeInsight/unwrapAndRemove/removeCatch/catch.kt.after b/idea/testData/codeInsight/unwrapAndRemove/removeCatch/catch.kt.after new file mode 100644 index 00000000000..cd1400f4005 --- /dev/null +++ b/idea/testData/codeInsight/unwrapAndRemove/removeCatch/catch.kt.after @@ -0,0 +1,12 @@ +// OPTION: 1 +fun foo(n: Int): Int { + return try { + n / 0 + } + catch (e: Exception) { + -2 + } + finally { + + } +} diff --git a/idea/testData/codeInsight/unwrapAndRemove/removeFinally/finallyInBlock.kt b/idea/testData/codeInsight/unwrapAndRemove/removeFinally/finallyInBlock.kt new file mode 100644 index 00000000000..5a5db2ee401 --- /dev/null +++ b/idea/testData/codeInsight/unwrapAndRemove/removeFinally/finallyInBlock.kt @@ -0,0 +1,18 @@ +// OPTION: 1 +fun foo(n: Int): Int { + try { + n / 0 + } + catch (e: ArithmeticException) { + val m = -1 + m + } + catch (e: Exception) { + -2 + } + finally { + println("finally") + } + + return 0 +} diff --git a/idea/testData/codeInsight/unwrapAndRemove/removeFinally/finallyInBlock.kt.after b/idea/testData/codeInsight/unwrapAndRemove/removeFinally/finallyInBlock.kt.after new file mode 100644 index 00000000000..3ff07da9dd7 --- /dev/null +++ b/idea/testData/codeInsight/unwrapAndRemove/removeFinally/finallyInBlock.kt.after @@ -0,0 +1,15 @@ +// OPTION: 1 +fun foo(n: Int): Int { + try { + n / 0 + } + catch (e: ArithmeticException) { + val m = -1 + m + } + catch (e: Exception) { + -2 + } + + return 0 +} diff --git a/idea/testData/codeInsight/unwrapAndRemove/removeFinally/finallyInReturn.kt b/idea/testData/codeInsight/unwrapAndRemove/removeFinally/finallyInReturn.kt new file mode 100644 index 00000000000..f5058f8b146 --- /dev/null +++ b/idea/testData/codeInsight/unwrapAndRemove/removeFinally/finallyInReturn.kt @@ -0,0 +1,15 @@ +// OPTION: 0 +fun foo(n: Int): Int { + return try { + n / 0 + } + catch (e: ArithmeticException) { + -1 + } + catch (e: Exception) { + -2 + } + finally { + println("finally") + } +} diff --git a/idea/testData/codeInsight/unwrapAndRemove/removeFinally/finallyInReturn.kt.after b/idea/testData/codeInsight/unwrapAndRemove/removeFinally/finallyInReturn.kt.after new file mode 100644 index 00000000000..cf503cb3327 --- /dev/null +++ b/idea/testData/codeInsight/unwrapAndRemove/removeFinally/finallyInReturn.kt.after @@ -0,0 +1,12 @@ +// OPTION: 0 +fun foo(n: Int): Int { + return try { + n / 0 + } + catch (e: ArithmeticException) { + -1 + } + catch (e: Exception) { + -2 + } +} diff --git a/idea/testData/codeInsight/unwrapAndRemove/unwrapCatch/catchCompoundInBlock.kt b/idea/testData/codeInsight/unwrapAndRemove/unwrapCatch/catchCompoundInBlock.kt new file mode 100644 index 00000000000..b0ced8a8791 --- /dev/null +++ b/idea/testData/codeInsight/unwrapAndRemove/unwrapCatch/catchCompoundInBlock.kt @@ -0,0 +1,18 @@ +// OPTION: 0 +fun foo(n: Int): Int { + try { + n / 0 + } + catch (e: ArithmeticException) { + val m = -1 + m + } + catch (e: Exception) { + -2 + } + finally { + + } + + return 0 +} diff --git a/idea/testData/codeInsight/unwrapAndRemove/unwrapCatch/catchCompoundInBlock.kt.after b/idea/testData/codeInsight/unwrapAndRemove/unwrapCatch/catchCompoundInBlock.kt.after new file mode 100644 index 00000000000..c5bfbd423e9 --- /dev/null +++ b/idea/testData/codeInsight/unwrapAndRemove/unwrapCatch/catchCompoundInBlock.kt.after @@ -0,0 +1,7 @@ +// OPTION: 0 +fun foo(n: Int): Int { + val m = -1 + m + + return 0 +} diff --git a/idea/testData/codeInsight/unwrapAndRemove/unwrapCatch/catchCompoundInReturn.kt b/idea/testData/codeInsight/unwrapAndRemove/unwrapCatch/catchCompoundInReturn.kt new file mode 100644 index 00000000000..b00f7d3e42c --- /dev/null +++ b/idea/testData/codeInsight/unwrapAndRemove/unwrapCatch/catchCompoundInReturn.kt @@ -0,0 +1,16 @@ +// IS_APPLICABLE: false +fun foo(n: Int): Int { + return try { + n / 0 + } + catch (e: ArithmeticException) { + val m = -1 + m + } + catch (e: Exception) { + -2 + } + finally { + + } +} diff --git a/idea/testData/codeInsight/unwrapAndRemove/unwrapCatch/catchSimpleInReturn.kt b/idea/testData/codeInsight/unwrapAndRemove/unwrapCatch/catchSimpleInReturn.kt new file mode 100644 index 00000000000..a0ee0916d9e --- /dev/null +++ b/idea/testData/codeInsight/unwrapAndRemove/unwrapCatch/catchSimpleInReturn.kt @@ -0,0 +1,15 @@ +// OPTION: 0 +fun foo(n: Int): Int { + return try { + n / 0 + } + catch (e: ArithmeticException) { + -1 + } + catch (e: Exception) { + -2 + } + finally { + + } +} diff --git a/idea/testData/codeInsight/unwrapAndRemove/unwrapCatch/catchSimpleInReturn.kt.after b/idea/testData/codeInsight/unwrapAndRemove/unwrapCatch/catchSimpleInReturn.kt.after new file mode 100644 index 00000000000..d9cdb7d3d57 --- /dev/null +++ b/idea/testData/codeInsight/unwrapAndRemove/unwrapCatch/catchSimpleInReturn.kt.after @@ -0,0 +1,4 @@ +// OPTION: 0 +fun foo(n: Int): Int { + return -1 +} diff --git a/idea/testData/codeInsight/unwrapAndRemove/unwrapFinally/finallyCompoundInBlock.kt b/idea/testData/codeInsight/unwrapAndRemove/unwrapFinally/finallyCompoundInBlock.kt new file mode 100644 index 00000000000..eafab6dcd4b --- /dev/null +++ b/idea/testData/codeInsight/unwrapAndRemove/unwrapFinally/finallyCompoundInBlock.kt @@ -0,0 +1,18 @@ +// OPTION: 0 +fun foo(n: Int): Int { + try { + n / 0 + } + catch (e: ArithmeticException) { + -1 + } + catch (e: Exception) { + -2 + } + finally { + val s = "finally" + println(s) + } + + return 0 +} diff --git a/idea/testData/codeInsight/unwrapAndRemove/unwrapFinally/finallyCompoundInBlock.kt.after b/idea/testData/codeInsight/unwrapAndRemove/unwrapFinally/finallyCompoundInBlock.kt.after new file mode 100644 index 00000000000..3d853eed449 --- /dev/null +++ b/idea/testData/codeInsight/unwrapAndRemove/unwrapFinally/finallyCompoundInBlock.kt.after @@ -0,0 +1,7 @@ +// OPTION: 0 +fun foo(n: Int): Int { + val s = "finally" + println(s) + + return 0 +} diff --git a/idea/testData/codeInsight/unwrapAndRemove/unwrapFinally/finallyCompoundInReturn.kt b/idea/testData/codeInsight/unwrapAndRemove/unwrapFinally/finallyCompoundInReturn.kt new file mode 100644 index 00000000000..a0ab13ebc85 --- /dev/null +++ b/idea/testData/codeInsight/unwrapAndRemove/unwrapFinally/finallyCompoundInReturn.kt @@ -0,0 +1,16 @@ +// IS_APPLICABLE: false +fun foo(n: Int): Int { + return try { + n / 0 + } + catch (e: ArithmeticException) { + -1 + } + catch (e: Exception) { + -2 + } + finally { + val s = "finally" + println(s) + } +} diff --git a/idea/testData/codeInsight/unwrapAndRemove/unwrapFinally/finallySimpleInReturn.kt b/idea/testData/codeInsight/unwrapAndRemove/unwrapFinally/finallySimpleInReturn.kt new file mode 100644 index 00000000000..4b732e94b07 --- /dev/null +++ b/idea/testData/codeInsight/unwrapAndRemove/unwrapFinally/finallySimpleInReturn.kt @@ -0,0 +1,15 @@ +// IS_APPLICABLE: false +fun foo(n: Int): Int { + return try { + n / 0 + } + catch (e: ArithmeticException) { + -1 + } + catch (e: Exception) { + -2 + } + finally { + println("finally") + } +} diff --git a/idea/testData/codeInsight/unwrapAndRemove/unwrapTry/tryCompoundInBlock.kt b/idea/testData/codeInsight/unwrapAndRemove/unwrapTry/tryCompoundInBlock.kt new file mode 100644 index 00000000000..7ab7aac30fd --- /dev/null +++ b/idea/testData/codeInsight/unwrapAndRemove/unwrapTry/tryCompoundInBlock.kt @@ -0,0 +1,11 @@ +// OPTION: 1 +fun foo(n : Int): Int { + try { + val m = n + 1 + m/0 + } catch (e: Exception) { + -1 + } + + return 0 +} diff --git a/idea/testData/codeInsight/unwrapAndRemove/unwrapTry/tryCompoundInBlock.kt.after b/idea/testData/codeInsight/unwrapAndRemove/unwrapTry/tryCompoundInBlock.kt.after new file mode 100644 index 00000000000..6240f7e1d2c --- /dev/null +++ b/idea/testData/codeInsight/unwrapAndRemove/unwrapTry/tryCompoundInBlock.kt.after @@ -0,0 +1,7 @@ +// OPTION: 1 +fun foo(n : Int): Int { + val m = n + 1 + m/0 + + return 0 +} diff --git a/idea/testData/codeInsight/unwrapAndRemove/unwrapTry/tryCompoundInReturn.kt b/idea/testData/codeInsight/unwrapAndRemove/unwrapTry/tryCompoundInReturn.kt new file mode 100644 index 00000000000..2390c58ba98 --- /dev/null +++ b/idea/testData/codeInsight/unwrapAndRemove/unwrapTry/tryCompoundInReturn.kt @@ -0,0 +1,9 @@ +// IS_APPLICABLE: false +fun foo(n : Int): Int { + return try { + val m = n + 1 + m/0 + } catch (e: Exception) { + -1 + } +} diff --git a/idea/testData/codeInsight/unwrapAndRemove/unwrapTry/trySimpleInReturn.kt b/idea/testData/codeInsight/unwrapAndRemove/unwrapTry/trySimpleInReturn.kt new file mode 100644 index 00000000000..3b53ecdb503 --- /dev/null +++ b/idea/testData/codeInsight/unwrapAndRemove/unwrapTry/trySimpleInReturn.kt @@ -0,0 +1,8 @@ +// OPTION: 0 +fun foo(n : Int): Int { + return try { + n/0 + } catch (e: Exception) { + -1 + } +} diff --git a/idea/testData/codeInsight/unwrapAndRemove/unwrapTry/trySimpleInReturn.kt.after b/idea/testData/codeInsight/unwrapAndRemove/unwrapTry/trySimpleInReturn.kt.after new file mode 100644 index 00000000000..3135d2b7da7 --- /dev/null +++ b/idea/testData/codeInsight/unwrapAndRemove/unwrapTry/trySimpleInReturn.kt.after @@ -0,0 +1,4 @@ +// OPTION: 0 +fun foo(n : Int): Int { + return n/0 +} diff --git a/idea/tests/org/jetbrains/jet/plugin/codeInsight/unwrap/AbstractUnwrapRemoveTest.java b/idea/tests/org/jetbrains/jet/plugin/codeInsight/unwrap/AbstractUnwrapRemoveTest.java index fdb85ac02f2..964b1a8940a 100644 --- a/idea/tests/org/jetbrains/jet/plugin/codeInsight/unwrap/AbstractUnwrapRemoveTest.java +++ b/idea/tests/org/jetbrains/jet/plugin/codeInsight/unwrap/AbstractUnwrapRemoveTest.java @@ -46,6 +46,26 @@ public abstract class AbstractUnwrapRemoveTest extends LightCodeInsightTestCase doTest(path, KoitlinUnwrappers.KotlinLoopUnwrapper.class); } + public void doTestTryUnwrapper(@NotNull String path) throws Exception { + doTest(path, KoitlinUnwrappers.KotlinTryUnwrapper.class); + } + + public void doTestCatchUnwrapper(@NotNull String path) throws Exception { + doTest(path, KoitlinUnwrappers.KotlinCatchUnwrapper.class); + } + + public void doTestCatchRemover(@NotNull String path) throws Exception { + doTest(path, KoitlinUnwrappers.KotlinCatchRemover.class); + } + + public void doTestFinallyUnwrapper(@NotNull String path) throws Exception { + doTest(path, KoitlinUnwrappers.KotlinFinallyUnwrapper.class); + } + + public void doTestFinallyRemover(@NotNull String path) throws Exception { + doTest(path, KoitlinUnwrappers.KotlinFinallyRemover.class); + } + public void doTestLambdaUnwrapper(@NotNull String path) throws Exception { doTest(path, KotlinLambdaUnwrapper.class); } diff --git a/idea/tests/org/jetbrains/jet/plugin/codeInsight/unwrap/UnwrapRemoveTestGenerated.java b/idea/tests/org/jetbrains/jet/plugin/codeInsight/unwrap/UnwrapRemoveTestGenerated.java index 79a7e9fd9b4..92c013c37e9 100644 --- a/idea/tests/org/jetbrains/jet/plugin/codeInsight/unwrap/UnwrapRemoveTestGenerated.java +++ b/idea/tests/org/jetbrains/jet/plugin/codeInsight/unwrap/UnwrapRemoveTestGenerated.java @@ -30,7 +30,7 @@ import org.jetbrains.jet.plugin.codeInsight.unwrap.AbstractUnwrapRemoveTest; /** This class is generated by {@link org.jetbrains.jet.generators.tests.GenerateTests}. DO NOT MODIFY MANUALLY */ @SuppressWarnings("all") -@InnerTestClasses({UnwrapRemoveTestGenerated.UnwrapThen.class, UnwrapRemoveTestGenerated.UnwrapElse.class, UnwrapRemoveTestGenerated.RemoveElse.class, UnwrapRemoveTestGenerated.UnwrapLoop.class, UnwrapRemoveTestGenerated.UnwrapLambda.class}) +@InnerTestClasses({UnwrapRemoveTestGenerated.UnwrapThen.class, UnwrapRemoveTestGenerated.UnwrapElse.class, UnwrapRemoveTestGenerated.RemoveElse.class, UnwrapRemoveTestGenerated.UnwrapLoop.class, UnwrapRemoveTestGenerated.UnwrapTry.class, UnwrapRemoveTestGenerated.UnwrapCatch.class, UnwrapRemoveTestGenerated.RemoveCatch.class, UnwrapRemoveTestGenerated.UnwrapFinally.class, UnwrapRemoveTestGenerated.RemoveFinally.class, UnwrapRemoveTestGenerated.UnwrapLambda.class}) public class UnwrapRemoveTestGenerated extends AbstractUnwrapRemoveTest { @TestMetadata("idea/testData/codeInsight/unwrapAndRemove/unwrapThen") public static class UnwrapThen extends AbstractUnwrapRemoveTest { @@ -114,6 +114,106 @@ public class UnwrapRemoveTestGenerated extends AbstractUnwrapRemoveTest { } + @TestMetadata("idea/testData/codeInsight/unwrapAndRemove/unwrapTry") + public static class UnwrapTry extends AbstractUnwrapRemoveTest { + public void testAllFilesPresentInUnwrapTry() throws Exception { + JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.GenerateTests", new File("idea/testData/codeInsight/unwrapAndRemove/unwrapTry"), Pattern.compile("^(.+)\\.kt$"), true); + } + + @TestMetadata("tryCompoundInBlock.kt") + public void testTryCompoundInBlock() throws Exception { + doTestTryUnwrapper("idea/testData/codeInsight/unwrapAndRemove/unwrapTry/tryCompoundInBlock.kt"); + } + + @TestMetadata("tryCompoundInReturn.kt") + public void testTryCompoundInReturn() throws Exception { + doTestTryUnwrapper("idea/testData/codeInsight/unwrapAndRemove/unwrapTry/tryCompoundInReturn.kt"); + } + + @TestMetadata("trySimpleInReturn.kt") + public void testTrySimpleInReturn() throws Exception { + doTestTryUnwrapper("idea/testData/codeInsight/unwrapAndRemove/unwrapTry/trySimpleInReturn.kt"); + } + + } + + @TestMetadata("idea/testData/codeInsight/unwrapAndRemove/unwrapCatch") + public static class UnwrapCatch extends AbstractUnwrapRemoveTest { + public void testAllFilesPresentInUnwrapCatch() throws Exception { + JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.GenerateTests", new File("idea/testData/codeInsight/unwrapAndRemove/unwrapCatch"), Pattern.compile("^(.+)\\.kt$"), true); + } + + @TestMetadata("catchCompoundInBlock.kt") + public void testCatchCompoundInBlock() throws Exception { + doTestCatchUnwrapper("idea/testData/codeInsight/unwrapAndRemove/unwrapCatch/catchCompoundInBlock.kt"); + } + + @TestMetadata("catchCompoundInReturn.kt") + public void testCatchCompoundInReturn() throws Exception { + doTestCatchUnwrapper("idea/testData/codeInsight/unwrapAndRemove/unwrapCatch/catchCompoundInReturn.kt"); + } + + @TestMetadata("catchSimpleInReturn.kt") + public void testCatchSimpleInReturn() throws Exception { + doTestCatchUnwrapper("idea/testData/codeInsight/unwrapAndRemove/unwrapCatch/catchSimpleInReturn.kt"); + } + + } + + @TestMetadata("idea/testData/codeInsight/unwrapAndRemove/removeCatch") + public static class RemoveCatch extends AbstractUnwrapRemoveTest { + public void testAllFilesPresentInRemoveCatch() throws Exception { + JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.GenerateTests", new File("idea/testData/codeInsight/unwrapAndRemove/removeCatch"), Pattern.compile("^(.+)\\.kt$"), true); + } + + @TestMetadata("catch.kt") + public void testCatch() throws Exception { + doTestCatchRemover("idea/testData/codeInsight/unwrapAndRemove/removeCatch/catch.kt"); + } + + } + + @TestMetadata("idea/testData/codeInsight/unwrapAndRemove/unwrapFinally") + public static class UnwrapFinally extends AbstractUnwrapRemoveTest { + public void testAllFilesPresentInUnwrapFinally() throws Exception { + JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.GenerateTests", new File("idea/testData/codeInsight/unwrapAndRemove/unwrapFinally"), Pattern.compile("^(.+)\\.kt$"), true); + } + + @TestMetadata("finallyCompoundInBlock.kt") + public void testFinallyCompoundInBlock() throws Exception { + doTestFinallyUnwrapper("idea/testData/codeInsight/unwrapAndRemove/unwrapFinally/finallyCompoundInBlock.kt"); + } + + @TestMetadata("finallyCompoundInReturn.kt") + public void testFinallyCompoundInReturn() throws Exception { + doTestFinallyUnwrapper("idea/testData/codeInsight/unwrapAndRemove/unwrapFinally/finallyCompoundInReturn.kt"); + } + + @TestMetadata("finallySimpleInReturn.kt") + public void testFinallySimpleInReturn() throws Exception { + doTestFinallyUnwrapper("idea/testData/codeInsight/unwrapAndRemove/unwrapFinally/finallySimpleInReturn.kt"); + } + + } + + @TestMetadata("idea/testData/codeInsight/unwrapAndRemove/removeFinally") + public static class RemoveFinally extends AbstractUnwrapRemoveTest { + public void testAllFilesPresentInRemoveFinally() throws Exception { + JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.GenerateTests", new File("idea/testData/codeInsight/unwrapAndRemove/removeFinally"), Pattern.compile("^(.+)\\.kt$"), true); + } + + @TestMetadata("finallyInBlock.kt") + public void testFinallyInBlock() throws Exception { + doTestFinallyRemover("idea/testData/codeInsight/unwrapAndRemove/removeFinally/finallyInBlock.kt"); + } + + @TestMetadata("finallyInReturn.kt") + public void testFinallyInReturn() throws Exception { + doTestFinallyRemover("idea/testData/codeInsight/unwrapAndRemove/removeFinally/finallyInReturn.kt"); + } + + } + @TestMetadata("idea/testData/codeInsight/unwrapAndRemove/unwrapLambda") public static class UnwrapLambda extends AbstractUnwrapRemoveTest { public void testAllFilesPresentInUnwrapLambda() throws Exception { @@ -178,6 +278,11 @@ public class UnwrapRemoveTestGenerated extends AbstractUnwrapRemoveTest { suite.addTestSuite(UnwrapElse.class); suite.addTestSuite(RemoveElse.class); suite.addTestSuite(UnwrapLoop.class); + suite.addTestSuite(UnwrapTry.class); + suite.addTestSuite(UnwrapCatch.class); + suite.addTestSuite(RemoveCatch.class); + suite.addTestSuite(UnwrapFinally.class); + suite.addTestSuite(RemoveFinally.class); suite.addTestSuite(UnwrapLambda.class); return suite; } From d019c23395fd34c7ea72143d5aef2c0b1ba4c3bd Mon Sep 17 00:00:00 2001 From: Alexey Sedunov Date: Wed, 19 Jun 2013 16:12:30 +0400 Subject: [PATCH 181/291] Implement general expresion remover --- .../jet/generators/tests/GenerateTests.java | 1 + .../codeInsight/unwrap/KoitlinUnwrappers.java | 11 ++++++ .../unwrap/KotlinUnwrapDescriptor.java | 1 + .../removeExpression/ifInBlock.kt | 10 ++++++ .../removeExpression/ifInBlock.kt.after | 5 +++ .../ifInExpressionInReturn.kt | 9 +++++ .../ifInExpressionInReturn.kt.after | 3 ++ .../removeExpression/ifInReturn.kt | 8 +++++ .../removeExpression/ifInReturn.kt.after | 3 ++ .../removeExpression/tryInBlock.kt | 10 ++++++ .../removeExpression/tryInBlock.kt.after | 5 +++ .../removeExpression/tryInReturn.kt | 8 +++++ .../removeExpression/tryInReturn.kt.after | 3 ++ .../unwrap/AbstractUnwrapRemoveTest.java | 4 +++ .../unwrap/UnwrapRemoveTestGenerated.java | 36 ++++++++++++++++++- 15 files changed, 116 insertions(+), 1 deletion(-) create mode 100644 idea/testData/codeInsight/unwrapAndRemove/removeExpression/ifInBlock.kt create mode 100644 idea/testData/codeInsight/unwrapAndRemove/removeExpression/ifInBlock.kt.after create mode 100644 idea/testData/codeInsight/unwrapAndRemove/removeExpression/ifInExpressionInReturn.kt create mode 100644 idea/testData/codeInsight/unwrapAndRemove/removeExpression/ifInExpressionInReturn.kt.after create mode 100644 idea/testData/codeInsight/unwrapAndRemove/removeExpression/ifInReturn.kt create mode 100644 idea/testData/codeInsight/unwrapAndRemove/removeExpression/ifInReturn.kt.after create mode 100644 idea/testData/codeInsight/unwrapAndRemove/removeExpression/tryInBlock.kt create mode 100644 idea/testData/codeInsight/unwrapAndRemove/removeExpression/tryInBlock.kt.after create mode 100644 idea/testData/codeInsight/unwrapAndRemove/removeExpression/tryInReturn.kt create mode 100644 idea/testData/codeInsight/unwrapAndRemove/removeExpression/tryInReturn.kt.after diff --git a/generators/org/jetbrains/jet/generators/tests/GenerateTests.java b/generators/org/jetbrains/jet/generators/tests/GenerateTests.java index d0922dcbd7d..4bced467dec 100644 --- a/generators/org/jetbrains/jet/generators/tests/GenerateTests.java +++ b/generators/org/jetbrains/jet/generators/tests/GenerateTests.java @@ -375,6 +375,7 @@ public class GenerateTests { "idea/tests/", "UnwrapRemoveTestGenerated", AbstractUnwrapRemoveTest.class, + testModel("idea/testData/codeInsight/unwrapAndRemove/removeExpression", "doTestExpressionRemover"), testModel("idea/testData/codeInsight/unwrapAndRemove/unwrapThen", "doTestThenUnwrapper"), testModel("idea/testData/codeInsight/unwrapAndRemove/unwrapElse", "doTestElseUnwrapper"), testModel("idea/testData/codeInsight/unwrapAndRemove/removeElse", "doTestElseRemover"), diff --git a/idea/src/org/jetbrains/jet/plugin/codeInsight/unwrap/KoitlinUnwrappers.java b/idea/src/org/jetbrains/jet/plugin/codeInsight/unwrap/KoitlinUnwrappers.java index 52d4a760487..09efdafaf22 100644 --- a/idea/src/org/jetbrains/jet/plugin/codeInsight/unwrap/KoitlinUnwrappers.java +++ b/idea/src/org/jetbrains/jet/plugin/codeInsight/unwrap/KoitlinUnwrappers.java @@ -26,6 +26,17 @@ public class KoitlinUnwrappers { private KoitlinUnwrappers() { } + public static class KotlinExpressionRemover extends KotlinRemover { + public KotlinExpressionRemover(String key) { + super(key); + } + + @Override + public boolean isApplicableTo(PsiElement e) { + return e instanceof JetExpression && e.getParent() instanceof JetBlockExpression; + } + } + public static class KotlinElseUnwrapper extends KotlinComponentUnwrapper { public KotlinElseUnwrapper(String key) { super(key); diff --git a/idea/src/org/jetbrains/jet/plugin/codeInsight/unwrap/KotlinUnwrapDescriptor.java b/idea/src/org/jetbrains/jet/plugin/codeInsight/unwrap/KotlinUnwrapDescriptor.java index a105ac0d978..27be42c648a 100644 --- a/idea/src/org/jetbrains/jet/plugin/codeInsight/unwrap/KotlinUnwrapDescriptor.java +++ b/idea/src/org/jetbrains/jet/plugin/codeInsight/unwrap/KotlinUnwrapDescriptor.java @@ -23,6 +23,7 @@ public class KotlinUnwrapDescriptor extends UnwrapDescriptorBase { @Override protected Unwrapper[] createUnwrappers() { return new Unwrapper[] { + new KoitlinUnwrappers.KotlinExpressionRemover("remove.expression"), new KoitlinUnwrappers.KotlinThenUnwrapper("unwrap.expression"), new KoitlinUnwrappers.KotlinElseRemover("remove.else"), new KoitlinUnwrappers.KotlinElseUnwrapper("unwrap.else"), diff --git a/idea/testData/codeInsight/unwrapAndRemove/removeExpression/ifInBlock.kt b/idea/testData/codeInsight/unwrapAndRemove/removeExpression/ifInBlock.kt new file mode 100644 index 00000000000..4e42512cfd1 --- /dev/null +++ b/idea/testData/codeInsight/unwrapAndRemove/removeExpression/ifInBlock.kt @@ -0,0 +1,10 @@ +// OPTION: 0 +fun foo(n : Int): Int { + if (n > 0) { + 1 + } else { + -1 + } + + return 0 +} diff --git a/idea/testData/codeInsight/unwrapAndRemove/removeExpression/ifInBlock.kt.after b/idea/testData/codeInsight/unwrapAndRemove/removeExpression/ifInBlock.kt.after new file mode 100644 index 00000000000..ed009ef6d14 --- /dev/null +++ b/idea/testData/codeInsight/unwrapAndRemove/removeExpression/ifInBlock.kt.after @@ -0,0 +1,5 @@ +// OPTION: 0 +fun foo(n : Int): Int { + + return 0 +} diff --git a/idea/testData/codeInsight/unwrapAndRemove/removeExpression/ifInExpressionInReturn.kt b/idea/testData/codeInsight/unwrapAndRemove/removeExpression/ifInExpressionInReturn.kt new file mode 100644 index 00000000000..3526de57020 --- /dev/null +++ b/idea/testData/codeInsight/unwrapAndRemove/removeExpression/ifInExpressionInReturn.kt @@ -0,0 +1,9 @@ +// OPTION: 3 +fun foo(n : Int): Int { + return 10 + + if (n > 0) { + 1 + } else { + -1 + } +} diff --git a/idea/testData/codeInsight/unwrapAndRemove/removeExpression/ifInExpressionInReturn.kt.after b/idea/testData/codeInsight/unwrapAndRemove/removeExpression/ifInExpressionInReturn.kt.after new file mode 100644 index 00000000000..eb7c581f4cc --- /dev/null +++ b/idea/testData/codeInsight/unwrapAndRemove/removeExpression/ifInExpressionInReturn.kt.after @@ -0,0 +1,3 @@ +// OPTION: 3 +fun foo(n : Int): Int { +} diff --git a/idea/testData/codeInsight/unwrapAndRemove/removeExpression/ifInReturn.kt b/idea/testData/codeInsight/unwrapAndRemove/removeExpression/ifInReturn.kt new file mode 100644 index 00000000000..842780a3fd0 --- /dev/null +++ b/idea/testData/codeInsight/unwrapAndRemove/removeExpression/ifInReturn.kt @@ -0,0 +1,8 @@ +// OPTION: 3 +fun foo(n : Int): Int { + return if (n > 0) { + 1 + } else { + -1 + } +} diff --git a/idea/testData/codeInsight/unwrapAndRemove/removeExpression/ifInReturn.kt.after b/idea/testData/codeInsight/unwrapAndRemove/removeExpression/ifInReturn.kt.after new file mode 100644 index 00000000000..eb7c581f4cc --- /dev/null +++ b/idea/testData/codeInsight/unwrapAndRemove/removeExpression/ifInReturn.kt.after @@ -0,0 +1,3 @@ +// OPTION: 3 +fun foo(n : Int): Int { +} diff --git a/idea/testData/codeInsight/unwrapAndRemove/removeExpression/tryInBlock.kt b/idea/testData/codeInsight/unwrapAndRemove/removeExpression/tryInBlock.kt new file mode 100644 index 00000000000..b866dbe27a8 --- /dev/null +++ b/idea/testData/codeInsight/unwrapAndRemove/removeExpression/tryInBlock.kt @@ -0,0 +1,10 @@ +// OPTION: 0 +fun foo(n : Int): Int { + try { + n/0 + } catch (e: Exception) { + -1 + } + + return 0 +} diff --git a/idea/testData/codeInsight/unwrapAndRemove/removeExpression/tryInBlock.kt.after b/idea/testData/codeInsight/unwrapAndRemove/removeExpression/tryInBlock.kt.after new file mode 100644 index 00000000000..ed009ef6d14 --- /dev/null +++ b/idea/testData/codeInsight/unwrapAndRemove/removeExpression/tryInBlock.kt.after @@ -0,0 +1,5 @@ +// OPTION: 0 +fun foo(n : Int): Int { + + return 0 +} diff --git a/idea/testData/codeInsight/unwrapAndRemove/removeExpression/tryInReturn.kt b/idea/testData/codeInsight/unwrapAndRemove/removeExpression/tryInReturn.kt new file mode 100644 index 00000000000..e8892e5dcce --- /dev/null +++ b/idea/testData/codeInsight/unwrapAndRemove/removeExpression/tryInReturn.kt @@ -0,0 +1,8 @@ +// OPTION: 1 +fun foo(n : Int): Int { + return try { + n/0 + } catch (e: Exception) { + -1 + } +} diff --git a/idea/testData/codeInsight/unwrapAndRemove/removeExpression/tryInReturn.kt.after b/idea/testData/codeInsight/unwrapAndRemove/removeExpression/tryInReturn.kt.after new file mode 100644 index 00000000000..6ecc87566f0 --- /dev/null +++ b/idea/testData/codeInsight/unwrapAndRemove/removeExpression/tryInReturn.kt.after @@ -0,0 +1,3 @@ +// OPTION: 1 +fun foo(n : Int): Int { +} diff --git a/idea/tests/org/jetbrains/jet/plugin/codeInsight/unwrap/AbstractUnwrapRemoveTest.java b/idea/tests/org/jetbrains/jet/plugin/codeInsight/unwrap/AbstractUnwrapRemoveTest.java index 964b1a8940a..1b2c2880188 100644 --- a/idea/tests/org/jetbrains/jet/plugin/codeInsight/unwrap/AbstractUnwrapRemoveTest.java +++ b/idea/tests/org/jetbrains/jet/plugin/codeInsight/unwrap/AbstractUnwrapRemoveTest.java @@ -30,6 +30,10 @@ import java.io.File; import java.util.List; public abstract class AbstractUnwrapRemoveTest extends LightCodeInsightTestCase { + public void doTestExpressionRemover(@NotNull String path) throws Exception { + doTest(path, KoitlinUnwrappers.KotlinExpressionRemover.class); + } + public void doTestThenUnwrapper(@NotNull String path) throws Exception { doTest(path, KoitlinUnwrappers.KotlinThenUnwrapper.class); } diff --git a/idea/tests/org/jetbrains/jet/plugin/codeInsight/unwrap/UnwrapRemoveTestGenerated.java b/idea/tests/org/jetbrains/jet/plugin/codeInsight/unwrap/UnwrapRemoveTestGenerated.java index 92c013c37e9..670b6b8962b 100644 --- a/idea/tests/org/jetbrains/jet/plugin/codeInsight/unwrap/UnwrapRemoveTestGenerated.java +++ b/idea/tests/org/jetbrains/jet/plugin/codeInsight/unwrap/UnwrapRemoveTestGenerated.java @@ -30,8 +30,41 @@ import org.jetbrains.jet.plugin.codeInsight.unwrap.AbstractUnwrapRemoveTest; /** This class is generated by {@link org.jetbrains.jet.generators.tests.GenerateTests}. DO NOT MODIFY MANUALLY */ @SuppressWarnings("all") -@InnerTestClasses({UnwrapRemoveTestGenerated.UnwrapThen.class, UnwrapRemoveTestGenerated.UnwrapElse.class, UnwrapRemoveTestGenerated.RemoveElse.class, UnwrapRemoveTestGenerated.UnwrapLoop.class, UnwrapRemoveTestGenerated.UnwrapTry.class, UnwrapRemoveTestGenerated.UnwrapCatch.class, UnwrapRemoveTestGenerated.RemoveCatch.class, UnwrapRemoveTestGenerated.UnwrapFinally.class, UnwrapRemoveTestGenerated.RemoveFinally.class, UnwrapRemoveTestGenerated.UnwrapLambda.class}) +@InnerTestClasses({UnwrapRemoveTestGenerated.RemoveExpression.class, UnwrapRemoveTestGenerated.UnwrapThen.class, UnwrapRemoveTestGenerated.UnwrapElse.class, UnwrapRemoveTestGenerated.RemoveElse.class, UnwrapRemoveTestGenerated.UnwrapLoop.class, UnwrapRemoveTestGenerated.UnwrapTry.class, UnwrapRemoveTestGenerated.UnwrapCatch.class, UnwrapRemoveTestGenerated.RemoveCatch.class, UnwrapRemoveTestGenerated.UnwrapFinally.class, UnwrapRemoveTestGenerated.RemoveFinally.class, UnwrapRemoveTestGenerated.UnwrapLambda.class}) public class UnwrapRemoveTestGenerated extends AbstractUnwrapRemoveTest { + @TestMetadata("idea/testData/codeInsight/unwrapAndRemove/removeExpression") + public static class RemoveExpression extends AbstractUnwrapRemoveTest { + public void testAllFilesPresentInRemoveExpression() throws Exception { + JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.GenerateTests", new File("idea/testData/codeInsight/unwrapAndRemove/removeExpression"), Pattern.compile("^(.+)\\.kt$"), true); + } + + @TestMetadata("ifInBlock.kt") + public void testIfInBlock() throws Exception { + doTestExpressionRemover("idea/testData/codeInsight/unwrapAndRemove/removeExpression/ifInBlock.kt"); + } + + @TestMetadata("ifInExpressionInReturn.kt") + public void testIfInExpressionInReturn() throws Exception { + doTestExpressionRemover("idea/testData/codeInsight/unwrapAndRemove/removeExpression/ifInExpressionInReturn.kt"); + } + + @TestMetadata("ifInReturn.kt") + public void testIfInReturn() throws Exception { + doTestExpressionRemover("idea/testData/codeInsight/unwrapAndRemove/removeExpression/ifInReturn.kt"); + } + + @TestMetadata("tryInBlock.kt") + public void testTryInBlock() throws Exception { + doTestExpressionRemover("idea/testData/codeInsight/unwrapAndRemove/removeExpression/tryInBlock.kt"); + } + + @TestMetadata("tryInReturn.kt") + public void testTryInReturn() throws Exception { + doTestExpressionRemover("idea/testData/codeInsight/unwrapAndRemove/removeExpression/tryInReturn.kt"); + } + + } + @TestMetadata("idea/testData/codeInsight/unwrapAndRemove/unwrapThen") public static class UnwrapThen extends AbstractUnwrapRemoveTest { public void testAllFilesPresentInUnwrapThen() throws Exception { @@ -274,6 +307,7 @@ public class UnwrapRemoveTestGenerated extends AbstractUnwrapRemoveTest { public static Test suite() { TestSuite suite = new TestSuite("UnwrapRemoveTestGenerated"); + suite.addTestSuite(RemoveExpression.class); suite.addTestSuite(UnwrapThen.class); suite.addTestSuite(UnwrapElse.class); suite.addTestSuite(RemoveElse.class); From 8f7d6236822912b193579083412780fd33865efe Mon Sep 17 00:00:00 2001 From: Alexey Sedunov Date: Fri, 21 Jun 2013 16:48:37 +0400 Subject: [PATCH 182/291] Rename: Fix spelling mistake --- .../unwrap/KotlinUnwrapDescriptor.java | 20 +++++++++---------- ...nUnwrappers.java => KotlinUnwrappers.java} | 4 ++-- .../unwrap/AbstractUnwrapRemoveTest.java | 20 +++++++++---------- 3 files changed, 22 insertions(+), 22 deletions(-) rename idea/src/org/jetbrains/jet/plugin/codeInsight/unwrap/{KoitlinUnwrappers.java => KotlinUnwrappers.java} (98%) diff --git a/idea/src/org/jetbrains/jet/plugin/codeInsight/unwrap/KotlinUnwrapDescriptor.java b/idea/src/org/jetbrains/jet/plugin/codeInsight/unwrap/KotlinUnwrapDescriptor.java index 27be42c648a..5ff0b888ab5 100644 --- a/idea/src/org/jetbrains/jet/plugin/codeInsight/unwrap/KotlinUnwrapDescriptor.java +++ b/idea/src/org/jetbrains/jet/plugin/codeInsight/unwrap/KotlinUnwrapDescriptor.java @@ -23,16 +23,16 @@ public class KotlinUnwrapDescriptor extends UnwrapDescriptorBase { @Override protected Unwrapper[] createUnwrappers() { return new Unwrapper[] { - new KoitlinUnwrappers.KotlinExpressionRemover("remove.expression"), - new KoitlinUnwrappers.KotlinThenUnwrapper("unwrap.expression"), - new KoitlinUnwrappers.KotlinElseRemover("remove.else"), - new KoitlinUnwrappers.KotlinElseUnwrapper("unwrap.else"), - new KoitlinUnwrappers.KotlinLoopUnwrapper("unwrap.expression"), - new KoitlinUnwrappers.KotlinTryUnwrapper("unwrap.expression"), - new KoitlinUnwrappers.KotlinCatchUnwrapper("unwrap.expression"), - new KoitlinUnwrappers.KotlinCatchRemover("remove.expression"), - new KoitlinUnwrappers.KotlinFinallyUnwrapper("unwrap.expression"), - new KoitlinUnwrappers.KotlinFinallyRemover("remove.expression"), + new KotlinUnwrappers.KotlinExpressionRemover("remove.expression"), + new KotlinUnwrappers.KotlinThenUnwrapper("unwrap.expression"), + new KotlinUnwrappers.KotlinElseRemover("remove.else"), + new KotlinUnwrappers.KotlinElseUnwrapper("unwrap.else"), + new KotlinUnwrappers.KotlinLoopUnwrapper("unwrap.expression"), + new KotlinUnwrappers.KotlinTryUnwrapper("unwrap.expression"), + new KotlinUnwrappers.KotlinCatchUnwrapper("unwrap.expression"), + new KotlinUnwrappers.KotlinCatchRemover("remove.expression"), + new KotlinUnwrappers.KotlinFinallyUnwrapper("unwrap.expression"), + new KotlinUnwrappers.KotlinFinallyRemover("remove.expression"), new KotlinLambdaUnwrapper("unwrap.expression"), }; } diff --git a/idea/src/org/jetbrains/jet/plugin/codeInsight/unwrap/KoitlinUnwrappers.java b/idea/src/org/jetbrains/jet/plugin/codeInsight/unwrap/KotlinUnwrappers.java similarity index 98% rename from idea/src/org/jetbrains/jet/plugin/codeInsight/unwrap/KoitlinUnwrappers.java rename to idea/src/org/jetbrains/jet/plugin/codeInsight/unwrap/KotlinUnwrappers.java index 09efdafaf22..c3f18edd16c 100644 --- a/idea/src/org/jetbrains/jet/plugin/codeInsight/unwrap/KoitlinUnwrappers.java +++ b/idea/src/org/jetbrains/jet/plugin/codeInsight/unwrap/KotlinUnwrappers.java @@ -22,8 +22,8 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.jet.lang.psi.*; -public class KoitlinUnwrappers { - private KoitlinUnwrappers() { +public class KotlinUnwrappers { + private KotlinUnwrappers() { } public static class KotlinExpressionRemover extends KotlinRemover { diff --git a/idea/tests/org/jetbrains/jet/plugin/codeInsight/unwrap/AbstractUnwrapRemoveTest.java b/idea/tests/org/jetbrains/jet/plugin/codeInsight/unwrap/AbstractUnwrapRemoveTest.java index 1b2c2880188..eebcba41899 100644 --- a/idea/tests/org/jetbrains/jet/plugin/codeInsight/unwrap/AbstractUnwrapRemoveTest.java +++ b/idea/tests/org/jetbrains/jet/plugin/codeInsight/unwrap/AbstractUnwrapRemoveTest.java @@ -31,43 +31,43 @@ import java.util.List; public abstract class AbstractUnwrapRemoveTest extends LightCodeInsightTestCase { public void doTestExpressionRemover(@NotNull String path) throws Exception { - doTest(path, KoitlinUnwrappers.KotlinExpressionRemover.class); + doTest(path, KotlinUnwrappers.KotlinExpressionRemover.class); } public void doTestThenUnwrapper(@NotNull String path) throws Exception { - doTest(path, KoitlinUnwrappers.KotlinThenUnwrapper.class); + doTest(path, KotlinUnwrappers.KotlinThenUnwrapper.class); } public void doTestElseUnwrapper(@NotNull String path) throws Exception { - doTest(path, KoitlinUnwrappers.KotlinElseUnwrapper.class); + doTest(path, KotlinUnwrappers.KotlinElseUnwrapper.class); } public void doTestElseRemover(@NotNull String path) throws Exception { - doTest(path, KoitlinUnwrappers.KotlinElseRemover.class); + doTest(path, KotlinUnwrappers.KotlinElseRemover.class); } public void doTestLoopUnwrapper(@NotNull String path) throws Exception { - doTest(path, KoitlinUnwrappers.KotlinLoopUnwrapper.class); + doTest(path, KotlinUnwrappers.KotlinLoopUnwrapper.class); } public void doTestTryUnwrapper(@NotNull String path) throws Exception { - doTest(path, KoitlinUnwrappers.KotlinTryUnwrapper.class); + doTest(path, KotlinUnwrappers.KotlinTryUnwrapper.class); } public void doTestCatchUnwrapper(@NotNull String path) throws Exception { - doTest(path, KoitlinUnwrappers.KotlinCatchUnwrapper.class); + doTest(path, KotlinUnwrappers.KotlinCatchUnwrapper.class); } public void doTestCatchRemover(@NotNull String path) throws Exception { - doTest(path, KoitlinUnwrappers.KotlinCatchRemover.class); + doTest(path, KotlinUnwrappers.KotlinCatchRemover.class); } public void doTestFinallyUnwrapper(@NotNull String path) throws Exception { - doTest(path, KoitlinUnwrappers.KotlinFinallyUnwrapper.class); + doTest(path, KotlinUnwrappers.KotlinFinallyUnwrapper.class); } public void doTestFinallyRemover(@NotNull String path) throws Exception { - doTest(path, KoitlinUnwrappers.KotlinFinallyRemover.class); + doTest(path, KotlinUnwrappers.KotlinFinallyRemover.class); } public void doTestLambdaUnwrapper(@NotNull String path) throws Exception { From 2cce4c575abe30cb819f2d43e0672ec34d2f2114 Mon Sep 17 00:00:00 2001 From: Zalim Bashorov Date: Sat, 15 Jun 2013 16:12:02 +0400 Subject: [PATCH 183/291] Fixed the comment of the native vararg test. --- js/js.translator/testFiles/native/cases/vararg.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/js/js.translator/testFiles/native/cases/vararg.kt b/js/js.translator/testFiles/native/cases/vararg.kt index 1486d25e137..0f54b78bece 100644 --- a/js/js.translator/testFiles/native/cases/vararg.kt +++ b/js/js.translator/testFiles/native/cases/vararg.kt @@ -83,7 +83,7 @@ fun box(): String { return "failed when test calling order when using spread operator without args" if (!(testCallOrder(1, 2, 3, 4))) - return "failed when test calling order when using spread operator without args" + return "failed when test calling order when using spread operator with some args" val baz: Bar? = Bar(1) if (!(baz!!)?.test(0, 1, 1)) From d64a896c123362c93a1fb94cc3e3df3067c112dd Mon Sep 17 00:00:00 2001 From: develar Date: Sat, 15 Jun 2013 16:12:02 +0400 Subject: [PATCH 184/291] Used idea SmartList and SingletonList in some cases instead ArrayList. Removed unused imports. --- .../k2js/translate/expression/TryTranslator.java | 9 +++------ .../functions/basic/CallStandardMethodIntrinsic.java | 5 ++--- .../reference/AbstractCallExpressionTranslator.java | 5 ++--- .../jetbrains/k2js/translate/utils/TranslationUtils.java | 8 +++++++- 4 files changed, 14 insertions(+), 13 deletions(-) diff --git a/js/js.translator/src/org/jetbrains/k2js/translate/expression/TryTranslator.java b/js/js.translator/src/org/jetbrains/k2js/translate/expression/TryTranslator.java index 39560690b50..31271315769 100644 --- a/js/js.translator/src/org/jetbrains/k2js/translate/expression/TryTranslator.java +++ b/js/js.translator/src/org/jetbrains/k2js/translate/expression/TryTranslator.java @@ -16,11 +16,8 @@ package org.jetbrains.k2js.translate.expression; -import com.google.common.collect.Lists; -import com.google.dart.compiler.backend.js.ast.JsBlock; -import com.google.dart.compiler.backend.js.ast.JsCatch; -import com.google.dart.compiler.backend.js.ast.JsName; -import com.google.dart.compiler.backend.js.ast.JsTry; +import com.google.dart.compiler.backend.js.ast.*; +import com.intellij.util.SmartList; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.jet.lang.psi.*; @@ -70,7 +67,7 @@ public final class TryTranslator extends AbstractTranslator { @NotNull private List translateCatches() { - List result = Lists.newArrayList(); + List result = new SmartList(); for (JetCatchClause catchClause : expression.getCatchClauses()) { result.add(translateCatchClause(catchClause)); } diff --git a/js/js.translator/src/org/jetbrains/k2js/translate/intrinsic/functions/basic/CallStandardMethodIntrinsic.java b/js/js.translator/src/org/jetbrains/k2js/translate/intrinsic/functions/basic/CallStandardMethodIntrinsic.java index ff66136a255..17365062675 100644 --- a/js/js.translator/src/org/jetbrains/k2js/translate/intrinsic/functions/basic/CallStandardMethodIntrinsic.java +++ b/js/js.translator/src/org/jetbrains/k2js/translate/intrinsic/functions/basic/CallStandardMethodIntrinsic.java @@ -16,10 +16,10 @@ package org.jetbrains.k2js.translate.intrinsic.functions.basic; -import com.google.common.collect.Lists; import com.google.dart.compiler.backend.js.ast.JsExpression; import com.google.dart.compiler.backend.js.ast.JsInvocation; import com.google.dart.compiler.backend.js.ast.JsNameRef; +import com.intellij.util.SmartList; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.k2js.translate.context.TranslationContext; @@ -60,8 +60,7 @@ public final class CallStandardMethodIntrinsic extends FunctionIntrinsic { @NotNull private static List composeArguments(@Nullable JsExpression receiver, @NotNull List arguments) { if (receiver != null) { - List args = Lists.newArrayList(); - args.add(receiver); + List args = new SmartList(receiver); args.addAll(arguments); return args; } diff --git a/js/js.translator/src/org/jetbrains/k2js/translate/reference/AbstractCallExpressionTranslator.java b/js/js.translator/src/org/jetbrains/k2js/translate/reference/AbstractCallExpressionTranslator.java index 98e7b2b58b3..5d5719f7b84 100644 --- a/js/js.translator/src/org/jetbrains/k2js/translate/reference/AbstractCallExpressionTranslator.java +++ b/js/js.translator/src/org/jetbrains/k2js/translate/reference/AbstractCallExpressionTranslator.java @@ -30,7 +30,6 @@ import org.jetbrains.k2js.translate.context.TranslationContext; import org.jetbrains.k2js.translate.general.AbstractTranslator; import org.jetbrains.k2js.translate.general.Translation; -import java.util.Arrays; import java.util.Collections; import java.util.List; @@ -69,13 +68,13 @@ public abstract class AbstractCallExpressionTranslator extends AbstractTranslato } if (actualArgument instanceof DefaultValueArgument) { JetExpression defaultArgument = getDefaultArgument(bindingContext(), parameterDescriptor); - return Arrays.asList(Translation.translateAsExpression(defaultArgument, context())); + return Collections.singletonList(Translation.translateAsExpression(defaultArgument, context())); } assert actualArgument instanceof ExpressionValueArgument; assert valueArguments.size() == 1; JetExpression argumentExpression = valueArguments.get(0).getArgumentExpression(); assert argumentExpression != null; - return Arrays.asList(Translation.translateAsExpression(argumentExpression, context())); + return Collections.singletonList(Translation.translateAsExpression(argumentExpression, context())); } @NotNull diff --git a/js/js.translator/src/org/jetbrains/k2js/translate/utils/TranslationUtils.java b/js/js.translator/src/org/jetbrains/k2js/translate/utils/TranslationUtils.java index c507cfafd4f..7a31a388f7a 100644 --- a/js/js.translator/src/org/jetbrains/k2js/translate/utils/TranslationUtils.java +++ b/js/js.translator/src/org/jetbrains/k2js/translate/utils/TranslationUtils.java @@ -17,6 +17,7 @@ package org.jetbrains.k2js.translate.utils; import com.google.dart.compiler.backend.js.ast.*; +import com.intellij.util.SmartList; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor; @@ -28,6 +29,7 @@ import org.jetbrains.k2js.translate.context.TranslationContext; import org.jetbrains.k2js.translate.general.Translation; import java.util.ArrayList; +import java.util.Collections; import java.util.List; import static org.jetbrains.k2js.translate.utils.BindingUtils.getFunctionDescriptorForOperationExpression; @@ -76,7 +78,11 @@ public final class TranslationUtils { @NotNull public static List translateArgumentList(@NotNull TranslationContext context, @NotNull List jetArguments) { - List jsArguments = new ArrayList(); + if (jetArguments.isEmpty()) { + return Collections.emptyList(); + } + + List jsArguments = new SmartList(); for (ValueArgument argument : jetArguments) { jsArguments.add(translateArgument(context, argument)); } From bc043fb9644ae566e675a9a08e77f797b7c60d5e Mon Sep 17 00:00:00 2001 From: develar Date: Thu, 24 Jan 2013 09:55:59 +0400 Subject: [PATCH 185/291] Used convenient JsNameRef ctor instead setQualifier for create JsNameRef with name and qualifier. --- .../k2js/translate/utils/TranslationUtils.java | 13 ++----------- 1 file changed, 2 insertions(+), 11 deletions(-) diff --git a/js/js.translator/src/org/jetbrains/k2js/translate/utils/TranslationUtils.java b/js/js.translator/src/org/jetbrains/k2js/translate/utils/TranslationUtils.java index 7a31a388f7a..a2b8ab346f6 100644 --- a/js/js.translator/src/org/jetbrains/k2js/translate/utils/TranslationUtils.java +++ b/js/js.translator/src/org/jetbrains/k2js/translate/utils/TranslationUtils.java @@ -34,7 +34,6 @@ import java.util.List; import static org.jetbrains.k2js.translate.utils.BindingUtils.getFunctionDescriptorForOperationExpression; import static org.jetbrains.k2js.translate.utils.JsAstUtils.assignment; -import static org.jetbrains.k2js.translate.utils.JsAstUtils.setQualifier; public final class TranslationUtils { private TranslationUtils() { @@ -123,18 +122,10 @@ public final class TranslationUtils { } @NotNull - public static JsNameRef getQualifiedReference(@NotNull TranslationContext context, - @NotNull DeclarationDescriptor descriptor) { - JsName name = context.getNameForDescriptor(descriptor); - JsNameRef reference = name.makeRef(); - JsNameRef qualifier = context.getQualifierForDescriptor(descriptor); - if (qualifier != null) { - setQualifier(reference, qualifier); - } - return reference; + public static JsNameRef getQualifiedReference(@NotNull TranslationContext context, @NotNull DeclarationDescriptor descriptor) { + return new JsNameRef(context.getNameForDescriptor(descriptor), context.getQualifierForDescriptor(descriptor)); } - @NotNull public static List translateExpressionList(@NotNull TranslationContext context, @NotNull List expressions) { From 9cd22942e2c064393854d49d17dc82aab331a1aa Mon Sep 17 00:00:00 2001 From: develar Date: Fri, 21 Jun 2013 16:21:28 +0400 Subject: [PATCH 186/291] Translate when as if-else instead for loop. --- .../test/semantics/PatternMatchingTest.java | 4 + .../translate/context/DynamicContext.java | 5 +- .../expression/ExpressionVisitor.java | 6 +- .../translate/expression/WhenTranslator.java | 190 ++++++++---------- .../foreach/IteratorForTranslator.java | 2 +- .../k2js/translate/general/Translation.java | 2 +- .../translate/utils/TranslationUtils.java | 21 ++ .../patternMatching/cases/whenWithOnlyElse.kt | 9 + 8 files changed, 124 insertions(+), 115 deletions(-) create mode 100644 js/js.translator/testFiles/patternMatching/cases/whenWithOnlyElse.kt diff --git a/js/js.tests/test/org/jetbrains/k2js/test/semantics/PatternMatchingTest.java b/js/js.tests/test/org/jetbrains/k2js/test/semantics/PatternMatchingTest.java index 039af65cdb9..8a2de753ab0 100644 --- a/js/js.tests/test/org/jetbrains/k2js/test/semantics/PatternMatchingTest.java +++ b/js/js.tests/test/org/jetbrains/k2js/test/semantics/PatternMatchingTest.java @@ -81,4 +81,8 @@ public final class PatternMatchingTest extends SingleFileTranslationTest { public void testWhenWithoutExpression() throws Exception { fooBoxTest(); } + + public void testWhenWithOnlyElse() throws Exception { + fooBoxTest(); + } } \ No newline at end of file diff --git a/js/js.translator/src/org/jetbrains/k2js/translate/context/DynamicContext.java b/js/js.translator/src/org/jetbrains/k2js/translate/context/DynamicContext.java index 0fd7f29bb8f..a59539d32d7 100644 --- a/js/js.translator/src/org/jetbrains/k2js/translate/context/DynamicContext.java +++ b/js/js.translator/src/org/jetbrains/k2js/translate/context/DynamicContext.java @@ -66,10 +66,11 @@ public final class DynamicContext { return TemporaryVariable.create(temporaryName, initExpression); } + //TODO: replace return type to make it more readable @NotNull - public Pair createTemporary(@Nullable JsExpression initExpression) { + public Pair createTemporary(@Nullable JsExpression initExpression) { JsVar var = new JsVar(currentScope.declareTemporary(), initExpression); - return new Pair(var, var.getName().makeRef()); + return Pair.create(var, (JsExpression) new JsNameRef(var.getName())); } @NotNull diff --git a/js/js.translator/src/org/jetbrains/k2js/translate/expression/ExpressionVisitor.java b/js/js.translator/src/org/jetbrains/k2js/translate/expression/ExpressionVisitor.java index bc190e3f32d..a39eefdeded 100644 --- a/js/js.translator/src/org/jetbrains/k2js/translate/expression/ExpressionVisitor.java +++ b/js/js.translator/src/org/jetbrains/k2js/translate/expression/ExpressionVisitor.java @@ -89,7 +89,9 @@ public final class ExpressionVisitor extends TranslatorVisitor { assert statement instanceof JetExpression : "Elements in JetBlockExpression " + "should be of type JetExpression"; JsNode jsNode = statement.accept(this, blockContext); - jsBlock.getStatements().add(convertToStatement(jsNode)); + if (jsNode != null) { + jsBlock.getStatements().add(convertToStatement(jsNode)); + } } return jsBlock; } @@ -286,7 +288,7 @@ public final class ExpressionVisitor extends TranslatorVisitor { } @Override - @NotNull + @Nullable public JsNode visitWhenExpression(@NotNull JetWhenExpression expression, @NotNull TranslationContext context) { return Translation.translateWhenExpression(expression, context); diff --git a/js/js.translator/src/org/jetbrains/k2js/translate/expression/WhenTranslator.java b/js/js.translator/src/org/jetbrains/k2js/translate/expression/WhenTranslator.java index 6d4071b6d96..31fccce0a60 100644 --- a/js/js.translator/src/org/jetbrains/k2js/translate/expression/WhenTranslator.java +++ b/js/js.translator/src/org/jetbrains/k2js/translate/expression/WhenTranslator.java @@ -16,115 +16,113 @@ package org.jetbrains.k2js.translate.expression; -import com.google.common.collect.Lists; import com.google.dart.compiler.backend.js.ast.*; +import com.intellij.openapi.util.Pair; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.jet.lang.psi.*; -import org.jetbrains.k2js.translate.context.TemporaryVariable; import org.jetbrains.k2js.translate.context.TranslationContext; import org.jetbrains.k2js.translate.general.AbstractTranslator; import org.jetbrains.k2js.translate.general.Translation; +import org.jetbrains.k2js.translate.utils.BindingUtils; +import org.jetbrains.k2js.translate.utils.TranslationUtils; import org.jetbrains.k2js.translate.utils.mutator.AssignToExpressionMutator; import org.jetbrains.k2js.translate.utils.mutator.LastExpressionMutator; -import java.util.ArrayList; import java.util.List; -import static org.jetbrains.k2js.translate.utils.JsAstUtils.*; +import static org.jetbrains.k2js.translate.utils.JsAstUtils.convertToStatement; +import static org.jetbrains.k2js.translate.utils.JsAstUtils.negated; public final class WhenTranslator extends AbstractTranslator { - - @NotNull + @Nullable public static JsNode translate(@NotNull JetWhenExpression expression, @NotNull TranslationContext context) { WhenTranslator translator = new WhenTranslator(expression, context); - return translator.translate(); + + if (BindingUtils.isStatement(context.bindingContext(), expression)) { + translator.translateAsStatement(context.dynamicContext().jsBlock().getStatements()); + return null; + } + + return translator.translateAsExpression(); } @NotNull private final JetWhenExpression whenExpression; - @Nullable - private final TemporaryVariable expressionToMatch; - @NotNull - private final TemporaryVariable dummyCounter; - @NotNull - private final TemporaryVariable result; - private int currentEntryNumber = 0; + @Nullable + private final Pair expressionToMatch; + + @Nullable + private Pair result; private WhenTranslator(@NotNull JetWhenExpression expression, @NotNull TranslationContext context) { super(context); - this.whenExpression = expression; - JsExpression expressionToMatch = translateExpressionToMatch(whenExpression); - this.expressionToMatch = expressionToMatch != null ? context.declareTemporary(expressionToMatch) : null; - this.dummyCounter = context.declareTemporary(program().getNumberLiteral(0)); - this.result = context.declareTemporary(JsLiteral.NULL); + + whenExpression = expression; + + JetExpression subject = expression.getSubjectExpression(); + if (subject != null) { + expressionToMatch = TranslationUtils.createTemporaryIfNeed(Translation.translateAsExpression(subject, context()), context); + } + else { + expressionToMatch = null; + } } - @NotNull - JsNode translate() { - JsFor resultingFor = generateDummyFor(); - resultingFor.setBody(new JsBlock(translateEntries())); - context().addStatementToCurrentBlock(resultingFor); - return result.reference(); + @Nullable + private JsNode translateAsExpression() { + result = context().dynamicContext().createTemporary(null); + translateAsStatement(context().dynamicContext().jsBlock().getStatements()); + return result.second; } - @NotNull - private List translateEntries() { - List entries = new ArrayList(); + private void translateAsStatement(List statements) { + addTempVarsStatement(statements); + + JsIf prevIf = null; for (JetWhenEntry entry : whenExpression.getEntries()) { - entries.add(surroundWithDummyIf(translateEntry(entry))); + JsStatement statement = withReturnValueCaptured(translateEntryExpression(entry)); + if (entry.isElse()) { + if (prevIf == null) { + statements.add(statement); + } + else { + prevIf.setElseStatement(statement); + } + break; + } + + JsIf ifStatement = new JsIf(translateConditions(entry), statement); + if (prevIf == null) { + statements.add(ifStatement); + } + else { + prevIf.setElseStatement(ifStatement); + } + prevIf = ifStatement; } - return entries; } - @NotNull - private JsStatement surroundWithDummyIf(@NotNull JsStatement entryStatement) { - JsNumberLiteral jsEntryNumber = program().getNumberLiteral(this.currentEntryNumber); - JsExpression stepNumberEqualsCurrentEntryNumber = equality(dummyCounter.reference(), jsEntryNumber); - currentEntryNumber++; - return new JsIf(stepNumberEqualsCurrentEntryNumber, entryStatement, null); - } - - @NotNull - private JsFor generateDummyFor() { - return new JsFor(generateInitExpressions(), generateConditionStatement(), generateIncrementStatement()); - } - - @NotNull - private JsExpression generateInitExpressions() { - List initExpressions = Lists.newArrayList(dummyCounter.assignmentExpression()); - if (expressionToMatch != null) { - initExpressions.add(expressionToMatch.assignmentExpression()); + private void addTempVarsStatement(List statements) { + JsVars vars = new JsVars(); + if (expressionToMatch != null && expressionToMatch.first != null) { + vars.add(expressionToMatch.first); } - return newSequence(initExpressions); - } - - @NotNull - private JsBinaryOperation generateConditionStatement() { - JsNumberLiteral entriesNumber = program().getNumberLiteral(whenExpression.getEntries().size()); - return new JsBinaryOperation(JsBinaryOperator.LT, dummyCounter.reference(), entriesNumber); - } - - @NotNull - private JsPrefixOperation generateIncrementStatement() { - return new JsPrefixOperation(JsUnaryOperator.INC, dummyCounter.reference()); - } - - @NotNull - private JsStatement translateEntry(@NotNull JetWhenEntry entry) { - JsStatement statementToExecute = withReturnValueCaptured(translateEntryExpression(entry)); - if (entry.isElse()) { - return statementToExecute; + if (result != null) { + vars.add(result.first); + } + + if (!vars.isEmpty()) { + statements.add(vars); } - JsExpression condition = translateConditions(entry); - return new JsIf(condition, addDummyBreakIfNeed(statementToExecute), null); } @NotNull - JsStatement withReturnValueCaptured(@NotNull JsNode node) { - return convertToStatement(LastExpressionMutator.mutateLastExpression(node, - new AssignToExpressionMutator(result.reference()))); + private JsStatement withReturnValueCaptured(@NotNull JsNode node) { + return result == null + ? convertToStatement(node) + : LastExpressionMutator.mutateLastExpression(node, new AssignToExpressionMutator(result.second)); } @NotNull @@ -136,32 +134,20 @@ public final class WhenTranslator extends AbstractTranslator { @NotNull private JsExpression translateConditions(@NotNull JetWhenEntry entry) { - List conditions = new ArrayList(); - for (JetWhenCondition condition : entry.getConditions()) { - conditions.add(translateCondition(condition)); - } - return anyOfThemIsTrue(conditions); - } + JetWhenCondition[] conditions = entry.getConditions(); - @NotNull - private static JsExpression anyOfThemIsTrue(List conditions) { - assert !conditions.isEmpty() : "When entry (not else) should have at least one condition"; - JsExpression current = null; - for (JsExpression condition : conditions) { - current = addCaseCondition(current, condition); - } - assert current != null; - return current; - } + assert conditions.length > 0 : "When entry (not else) should have at least one condition"; - @NotNull - private static JsExpression addCaseCondition(@Nullable JsExpression current, @NotNull JsExpression condition) { - if (current == null) { - return condition; + if (conditions.length == 1) { + return translateCondition(conditions[0]); } - else { - return or(current, condition); + + JsExpression result = translateCondition(conditions[0]); + for (int i = 1; i < conditions.length; i++) { + result = new JsBinaryOperation(JsBinaryOperator.OR, translateCondition(conditions[i]), result); } + + return result; } @NotNull @@ -172,11 +158,6 @@ public final class WhenTranslator extends AbstractTranslator { throw new AssertionError("Unsupported when condition " + condition.getClass()); } - @NotNull - private static JsStatement addDummyBreakIfNeed(@NotNull JsStatement statement) { - return statement instanceof JsReturn ? statement : new JsBlock(statement, new JsBreak()); - } - @NotNull private JsExpression translatePatternCondition(@NotNull JetWhenCondition condition) { JsExpression patternMatchExpression = translateWhenConditionToBooleanExpression(condition); @@ -224,7 +205,7 @@ public final class WhenTranslator extends AbstractTranslator { @Nullable private JsExpression getExpressionToMatch() { - return expressionToMatch != null ? expressionToMatch.reference() : null; + return expressionToMatch != null ? expressionToMatch.second : null; } private static boolean isNegated(@NotNull JetWhenCondition condition) { @@ -233,13 +214,4 @@ public final class WhenTranslator extends AbstractTranslator { } return false; } - - @Nullable - private JsExpression translateExpressionToMatch(@NotNull JetWhenExpression expression) { - JetExpression subject = expression.getSubjectExpression(); - if (subject == null) { - return null; - } - return Translation.translateAsExpression(subject, context()); - } } diff --git a/js/js.translator/src/org/jetbrains/k2js/translate/expression/foreach/IteratorForTranslator.java b/js/js.translator/src/org/jetbrains/k2js/translate/expression/foreach/IteratorForTranslator.java index 16372cd99c0..437ad5c8685 100644 --- a/js/js.translator/src/org/jetbrains/k2js/translate/expression/foreach/IteratorForTranslator.java +++ b/js/js.translator/src/org/jetbrains/k2js/translate/expression/foreach/IteratorForTranslator.java @@ -33,7 +33,7 @@ import static org.jetbrains.k2js.translate.utils.PsiUtils.getLoopRange; public final class IteratorForTranslator extends ForTranslator { @NotNull - private final Pair iterator; + private final Pair iterator; @NotNull public static JsStatement doTranslate(@NotNull JetForExpression expression, diff --git a/js/js.translator/src/org/jetbrains/k2js/translate/general/Translation.java b/js/js.translator/src/org/jetbrains/k2js/translate/general/Translation.java index 4308f2c4fde..f474310c1a4 100644 --- a/js/js.translator/src/org/jetbrains/k2js/translate/general/Translation.java +++ b/js/js.translator/src/org/jetbrains/k2js/translate/general/Translation.java @@ -118,7 +118,7 @@ public final class Translation { return convertToStatement(translateExpression(expression, context)); } - @NotNull + @Nullable public static JsNode translateWhenExpression(@NotNull JetWhenExpression expression, @NotNull TranslationContext context) { return WhenTranslator.translate(expression, context); diff --git a/js/js.translator/src/org/jetbrains/k2js/translate/utils/TranslationUtils.java b/js/js.translator/src/org/jetbrains/k2js/translate/utils/TranslationUtils.java index a2b8ab346f6..5a200ca1e8d 100644 --- a/js/js.translator/src/org/jetbrains/k2js/translate/utils/TranslationUtils.java +++ b/js/js.translator/src/org/jetbrains/k2js/translate/utils/TranslationUtils.java @@ -17,6 +17,7 @@ package org.jetbrains.k2js.translate.utils; import com.google.dart.compiler.backend.js.ast.*; +import com.intellij.openapi.util.Pair; import com.intellij.util.SmartList; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -74,6 +75,7 @@ public final class TranslationUtils { JsBinaryOperator operator = isNegated ? JsBinaryOperator.NEQ : JsBinaryOperator.EQ; return new JsBinaryOperation(operator, expressionToCheck, JsLiteral.NULL); } + @NotNull public static List translateArgumentList(@NotNull TranslationContext context, @NotNull List jetArguments) { @@ -168,4 +170,23 @@ public final class TranslationUtils { return false; } + + public static boolean isCacheNeeded(@NotNull JsExpression expression) { + return !(expression instanceof JsLiteral) && + (!(expression instanceof JsNameRef) || ((JsNameRef) expression).getQualifier() != null); + } + + @NotNull + public static Pair createTemporaryIfNeed( + @NotNull JsExpression expression, + @NotNull TranslationContext context + ) { + // don't create temp variable for simple expression + if (isCacheNeeded(expression)) { + return context.dynamicContext().createTemporary(expression); + } + else { + return Pair.create(null, expression); + } + } } diff --git a/js/js.translator/testFiles/patternMatching/cases/whenWithOnlyElse.kt b/js/js.translator/testFiles/patternMatching/cases/whenWithOnlyElse.kt new file mode 100644 index 00000000000..2339c758d84 --- /dev/null +++ b/js/js.translator/testFiles/patternMatching/cases/whenWithOnlyElse.kt @@ -0,0 +1,9 @@ +package foo + +fun box(): Boolean { + var a = 0 + when (a) { + else -> a = 2 + } + return a == 2 +} From fa10a3289d89a04cf9c6b354b062acc3c6ee5631 Mon Sep 17 00:00:00 2001 From: develar Date: Fri, 21 Jun 2013 16:21:28 +0400 Subject: [PATCH 187/291] Use PrimitiveHashMap and PrimitiveHashSet when possible. Kotlin.AbstractList splitted to AbstractCollection and AbstractList. --- .../translate/reference/CallTranslator.java | 42 ++++++++++++---- js/js.translator/testFiles/kotlin_lib.js | 48 +++++++++++------- js/js.translator/testFiles/maps.js | 50 +++++++++++++++++-- 3 files changed, 108 insertions(+), 32 deletions(-) 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 cec4259636f..eeed6a3cb09 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 @@ -16,18 +16,25 @@ package org.jetbrains.k2js.translate.reference; -import com.google.dart.compiler.backend.js.ast.*; +import com.google.dart.compiler.backend.js.ast.JsExpression; +import com.google.dart.compiler.backend.js.ast.JsInvocation; +import com.google.dart.compiler.backend.js.ast.JsNameRef; +import com.google.dart.compiler.backend.js.ast.JsNew; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.jet.lang.descriptors.*; -import org.jetbrains.jet.lang.resolve.calls.util.ExpressionAsFunctionDescriptor; import org.jetbrains.jet.lang.resolve.calls.model.ResolvedCall; import org.jetbrains.jet.lang.resolve.calls.model.VariableAsFunctionResolvedCall; +import org.jetbrains.jet.lang.resolve.calls.util.ExpressionAsFunctionDescriptor; +import org.jetbrains.jet.lang.resolve.name.Name; +import org.jetbrains.jet.lang.types.JetType; import org.jetbrains.k2js.translate.context.TranslationContext; import org.jetbrains.k2js.translate.general.AbstractTranslator; import org.jetbrains.k2js.translate.intrinsic.functions.basic.FunctionIntrinsic; +import org.jetbrains.k2js.translate.intrinsic.functions.patterns.NamePredicate; import org.jetbrains.k2js.translate.utils.AnnotationsUtils; import org.jetbrains.k2js.translate.utils.ErrorReportingUtils; +import org.jetbrains.k2js.translate.utils.JsDescriptorUtils; import java.util.ArrayList; import java.util.List; @@ -145,20 +152,37 @@ public final class CallTranslator extends AbstractTranslator { @NotNull private JsExpression constructorCall() { - JsExpression constructorReference = translateAsFunctionWithNoThisObject(descriptor); - JsExpression constructorCall = createConstructorCallExpression(constructorReference); - assert constructorCall instanceof HasArguments : "Constructor call should be expression with arguments."; - ((HasArguments) constructorCall).getArguments().addAll(arguments); - return constructorCall; + JsExpression constructorReference; + ClassDescriptor classDescriptor = (ClassDescriptor) descriptor.getContainingDeclaration(); + boolean isSet = false; + if (AnnotationsUtils.isLibraryObject(classDescriptor) && + (classDescriptor.getName().asString().equals("HashMap") || (isSet = classDescriptor.getName().asString().equals("HashSet")))) { + JetType keyType = resolvedCall.getTypeArguments().values().iterator().next(); + Name keyTypeName = JsDescriptorUtils.getNameIfStandardType(keyType); + String collectionClassName; + if (keyTypeName != null && (NamePredicate.PRIMITIVE_NUMBERS.apply(keyTypeName) || keyTypeName.asString().equals("String"))) { + collectionClassName = isSet ? "PrimitiveHashSet" : "PrimitiveHashMap"; + } + else { + collectionClassName = isSet ? "ComplexHashSet" : "ComplexHashMap"; + } + + constructorReference = context().namer().kotlin(collectionClassName); + } + else { + constructorReference = translateAsFunctionWithNoThisObject(descriptor); + } + + return createConstructorCallExpression(constructorReference); } @NotNull private JsExpression createConstructorCallExpression(@NotNull JsExpression constructorReference) { if (context().isEcma5() && !AnnotationsUtils.isNativeObject(resolvedCall.getCandidateDescriptor())) { - return new JsInvocation(constructorReference); + return new JsInvocation(constructorReference, arguments); } else { - return new JsNew(constructorReference); + return new JsNew(constructorReference, arguments); } } diff --git a/js/js.translator/testFiles/kotlin_lib.js b/js/js.translator/testFiles/kotlin_lib.js index cf4b0008f47..b325a5aa63b 100644 --- a/js/js.translator/testFiles/kotlin_lib.js +++ b/js/js.translator/testFiles/kotlin_lib.js @@ -75,6 +75,7 @@ var kotlin = {set:function (receiver, key, value) { Kotlin.Exception = Kotlin.$createClass(); Kotlin.RuntimeException = Kotlin.$createClass(Kotlin.Exception); + Kotlin.IndexOutOfBounds = Kotlin.$createClass(Kotlin.Exception); Kotlin.NullPointerException = Kotlin.$createClass(Kotlin.Exception); Kotlin.NoSuchElementException = Kotlin.$createClass(Kotlin.Exception); Kotlin.IllegalArgumentException = Kotlin.$createClass(Kotlin.Exception); @@ -139,34 +140,28 @@ var kotlin = {set:function (receiver, key, value) { Kotlin.Collection = Kotlin.$createClass(); - Kotlin.AbstractList = Kotlin.$createClass(Kotlin.Collection, { - iterator: function () { - return Kotlin.$new(ListIterator)(this); - }, - isEmpty: function () { - return this.size() === 0; + Kotlin.AbstractCollection = Kotlin.$createClass(Kotlin.Collection, { + size: function () { + return this.$size; }, addAll: function (collection) { var it = collection.iterator(); - var i = this.$size; + var i = this.size(); while (i-- > 0) { this.add(it.next()); } }, - remove: function (o) { - var index = this.indexOf(o); - if (index !== -1) { - this.removeAt(index); - } + isEmpty: function () { + return this.size() === 0; }, - contains: function (o) { - return this.indexOf(o) !== -1; + iterator: function () { + return Kotlin.$new(ArrayIterator)(this.toArray()); }, equals: function (o) { - if (this.$size === o.$size) { + if (this.size() === o.size()) { var iterator1 = this.iterator(); var iterator2 = o.iterator(); - var i = this.$size; + var i = this.size(); while (i-- > 0) { if (!Kotlin.equals(iterator1.next(), iterator2.next())) { return false; @@ -197,6 +192,21 @@ var kotlin = {set:function (receiver, key, value) { } }); + Kotlin.AbstractList = Kotlin.$createClass(Kotlin.AbstractCollection, { + iterator: function () { + return Kotlin.$new(ListIterator)(this); + }, + remove: function (o) { + var index = this.indexOf(o); + if (index !== -1) { + this.removeAt(index); + } + }, + contains: function (o) { + return this.indexOf(o) !== -1; + } + }); + //TODO: should be JS Array-like (https://developer.mozilla.org/en-US/docs/JavaScript/Guide/Predefined_Core_Objects#Working_with_Array-like_objects) Kotlin.ArrayList = Kotlin.$createClass(Kotlin.AbstractList, { initialize: function () { @@ -211,9 +221,6 @@ var kotlin = {set:function (receiver, key, value) { this.checkRange(index); this.array[index] = value; }, - toArray: function () { - return this.array.slice(0, this.$size); - }, size: function () { return this.$size; }, @@ -252,6 +259,9 @@ var kotlin = {set:function (receiver, key, value) { } return -1; }, + toArray: function () { + return this.array.slice(0, this.$size); + }, toString: function () { return "[" + this.array.join(", ") + "]"; }, diff --git a/js/js.translator/testFiles/maps.js b/js/js.translator/testFiles/maps.js index 5a358b4d112..75d078d4363 100644 --- a/js/js.translator/testFiles/maps.js +++ b/js/js.translator/testFiles/maps.js @@ -298,7 +298,7 @@ this.values = function () { var values = this._values(); - var i = values.length + var i = values.length; var result = Kotlin.$new(Kotlin.ArrayList)(); while (i--) { result.add(values[i]); @@ -371,7 +371,7 @@ }; this.keySet = function () { - var res = Kotlin.$new(Kotlin.HashSet)(); + var res = Kotlin.$new(Kotlin.ComplexHashSet)(); var keys = this._keys(); var i = keys.length; while (i--) { @@ -475,7 +475,7 @@ Kotlin.ComplexHashMap = Kotlin.HashMap; throw Kotlin.$new(Kotlin.UnsupportedOperationException)(); }, keySet: function () { - var result = Kotlin.$new(Kotlin.HashSet)(); + var result = Kotlin.$new(Kotlin.PrimitiveHashSet)(); var map = this.map; for (var key in map) { if (map.hasOwnProperty(key)) { @@ -494,6 +494,46 @@ Kotlin.ComplexHashMap = Kotlin.HashMap; }); }()); +Kotlin.Set = Kotlin.$createClass(Kotlin.Collection); + +Kotlin.PrimitiveHashSet = Kotlin.$createClass(Kotlin.AbstractCollection, { + initialize: function () { + this.$size = 0; + this.map = {}; + }, + contains: function (key) { + return this.map[key] === true; + }, + add: function (element) { + var prevElement = this.map[element]; + this.map[element] = true; + if (prevElement === true) { + return false; + } + else { + this.$size++; + return true; + } + }, + remove: function (element) { + if (this.map[element] === true) { + delete this.map[element]; + this.$size--; + return true; + } + else { + return false; + } + }, + clear: function () { + this.$size = 0; + this.map = {}; + }, + toArray: function () { + return Kotlin.keys(this.map); + } +}); + (function () { function HashSet(hashingFunction, equalityFunction) { var hashTable = new Kotlin.HashTable(hashingFunction, equalityFunction); @@ -614,7 +654,9 @@ Kotlin.ComplexHashMap = Kotlin.HashMap; }; } - Kotlin.HashSet = Kotlin.$createClass({initialize: function () { + Kotlin.HashSet = Kotlin.$createClass(Kotlin.Set, {initialize: function () { HashSet.call(this); }}); + + Kotlin.ComplexHashSet = Kotlin.HashSet; }()); From 9d1e319f0febb4cf036d74fe2cd110450e0113a8 Mon Sep 17 00:00:00 2001 From: Zalim Bashorov Date: Fri, 21 Jun 2013 16:21:28 +0400 Subject: [PATCH 188/291] JS backend: implemented PrimitiveHashMap#putAll. --- js/js.translator/testFiles/maps.js | 8 +++++++- libraries/stdlib/test/js/MapJsTest.kt | 1 + 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/js/js.translator/testFiles/maps.js b/js/js.translator/testFiles/maps.js index 75d078d4363..ffc18118fc2 100644 --- a/js/js.translator/testFiles/maps.js +++ b/js/js.translator/testFiles/maps.js @@ -472,7 +472,13 @@ Kotlin.ComplexHashMap = Kotlin.HashMap; this.map = {}; }, putAll: function (fromMap) { - throw Kotlin.$new(Kotlin.UnsupportedOperationException)(); + var map = fromMap.map; + for (var key in map) { + if (map.hasOwnProperty(key)) { + this.map[key] = map[key]; + this.$size++; + } + } }, keySet: function () { var result = Kotlin.$new(Kotlin.PrimitiveHashSet)(); diff --git a/libraries/stdlib/test/js/MapJsTest.kt b/libraries/stdlib/test/js/MapJsTest.kt index 3132b0878f3..5c564f92208 100644 --- a/libraries/stdlib/test/js/MapJsTest.kt +++ b/libraries/stdlib/test/js/MapJsTest.kt @@ -5,6 +5,7 @@ import kotlin.test.* import java.util.* import org.junit.Test as test +// TODO: Write test generator for testing `Map` implementations. class MapJsTest { //TODO: replace `array(...).toList()` to `listOf(...)` val KEYS = array("zero", "one", "two", "three").toList() From 7f1f2aa6413b7a4285f68cc3a91efd7c1e307ec9 Mon Sep 17 00:00:00 2001 From: develar Date: Fri, 21 Jun 2013 16:21:28 +0400 Subject: [PATCH 189/291] Dropped get_hasNext (hasNext property) from js library files. --- js/js.translator/testFiles/kotlin_lib.js | 12 +++--------- js/js.translator/testFiles/kotlin_lib_ecma5.js | 9 +++------ js/js.translator/testFiles/maps.js | 8 ++++---- 3 files changed, 10 insertions(+), 19 deletions(-) diff --git a/js/js.translator/testFiles/kotlin_lib.js b/js/js.translator/testFiles/kotlin_lib.js index b325a5aa63b..d376e093b3e 100644 --- a/js/js.translator/testFiles/kotlin_lib.js +++ b/js/js.translator/testFiles/kotlin_lib.js @@ -116,9 +116,6 @@ var kotlin = {set:function (receiver, key, value) { next: function () { return this.array[this.index++]; }, - get_hasNext: function () { - return this.index < this.size; - }, hasNext: function () { return this.index < this.size; } @@ -132,9 +129,6 @@ var kotlin = {set:function (receiver, key, value) { }, next: function () { return this.list.get(this.index++); - }, - get_hasNext: function () { - return this.index < this.size; } }); @@ -379,8 +373,8 @@ var kotlin = {set:function (receiver, key, value) { this.set_i(this.$i + this.$increment); return value; }, - get_hasNext: function () { - return this.$increment > 0 ? this.$next <= this.$end : this.$next >= this.$end; + hasNext: function () { + return this.get_count() > 0; } }); @@ -449,7 +443,7 @@ var kotlin = {set:function (receiver, key, value) { throw Kotlin.Exception(); } var max = it.next(); - while (it.get_hasNext()) { + while (it.hasNext()) { var el = it.next(); if (comp.compare(max, el) < 0) { max = el; diff --git a/js/js.translator/testFiles/kotlin_lib_ecma5.js b/js/js.translator/testFiles/kotlin_lib_ecma5.js index bee9e704943..cea232dfba6 100644 --- a/js/js.translator/testFiles/kotlin_lib_ecma5.js +++ b/js/js.translator/testFiles/kotlin_lib_ecma5.js @@ -175,12 +175,9 @@ var Kotlin = Object.create(null); initializer = value; } else if (name.indexOf("get_") === 0) { - // our std lib contains collision: hasNext property vs hasNext as function, we prefer function (actually, it does work) - var getterName = name.substring(4); - if (!descriptors.hasOwnProperty(getterName)) { - descriptors[getterName] = {get: value}; - descriptors[name] = {value: value}; - } + descriptors[name.substring(4)] = {get: value}; + // std lib code can refers to + descriptors[name] = {value: value}; } else if (name.indexOf("set_") === 0) { descriptors[name.substring(4)] = {set: value}; diff --git a/js/js.translator/testFiles/maps.js b/js/js.translator/testFiles/maps.js index ffc18118fc2..e9d381b5e04 100644 --- a/js/js.translator/testFiles/maps.js +++ b/js/js.translator/testFiles/maps.js @@ -404,7 +404,7 @@ Kotlin.ComplexHashMap = Kotlin.HashMap; next: function () { return this.map[this.keys[this.index++]]; }, - get_hasNext: function () { + hasNext: function () { return this.index < this.size; } }); @@ -595,8 +595,8 @@ Kotlin.PrimitiveHashSet = Kotlin.$createClass(Kotlin.AbstractCollection, { var iter1 = this.iterator(); var iter2 = o.iterator(); while (true) { - var hn1 = iter1.get_hasNext(); - var hn2 = iter2.get_hasNext(); + var hn1 = iter1.hasNext(); + var hn2 = iter2.hasNext(); if (hn1 != hn2) return false; if (!hn2) return true; @@ -614,7 +614,7 @@ Kotlin.PrimitiveHashSet = Kotlin.$createClass(Kotlin.AbstractCollection, { var builder = "["; var iter = this.iterator(); var first = true; - while (iter.get_hasNext()) { + while (iter.hasNext()) { if (first) first = false; else From 69dffe8358cf4bae72fd71a1c7db8e34e12c1145 Mon Sep 17 00:00:00 2001 From: Nikolay Krasko Date: Fri, 21 Jun 2013 19:42:56 +0400 Subject: [PATCH 190/291] Optimize searching for kotlin classes --- .../caches/JetGotoClassContributor.java | 29 ++++++++++--------- .../jet/plugin/caches/JetShortNamesCache.java | 4 +-- .../IDELightClassGenerationSupport.java | 15 +++++----- 3 files changed, 24 insertions(+), 24 deletions(-) diff --git a/idea/src/org/jetbrains/jet/plugin/caches/JetGotoClassContributor.java b/idea/src/org/jetbrains/jet/plugin/caches/JetGotoClassContributor.java index ac98c103b4a..0efcf63a3b2 100644 --- a/idea/src/org/jetbrains/jet/plugin/caches/JetGotoClassContributor.java +++ b/idea/src/org/jetbrains/jet/plugin/caches/JetGotoClassContributor.java @@ -21,9 +21,13 @@ import com.intellij.navigation.NavigationItem; import com.intellij.openapi.project.Project; import com.intellij.psi.PsiClass; import com.intellij.psi.search.GlobalSearchScope; +import com.intellij.psi.search.PsiShortNamesCache; import com.intellij.util.ArrayUtil; import org.jetbrains.annotations.NotNull; -import org.jetbrains.jet.lang.psi.*; +import org.jetbrains.jet.lang.psi.JetClass; +import org.jetbrains.jet.lang.psi.JetClassOrObject; +import org.jetbrains.jet.lang.psi.JetNamedDeclaration; +import org.jetbrains.jet.lang.psi.JetPsiUtil; import org.jetbrains.jet.lang.resolve.name.FqName; import org.jetbrains.jet.plugin.stubindex.JetShortClassNameIndex; @@ -54,17 +58,21 @@ public class JetGotoClassContributor implements GotoClassContributor { @NotNull @Override public String[] getNames(Project project, boolean includeNonProjectItems) { - return JetShortNamesCache.getKotlinInstance(project).getAllClassNames(); + return ArrayUtil.toObjectArray(JetShortClassNameIndex.getInstance().getAllKeys(project), String.class); } @NotNull @Override public NavigationItem[] getItemsByName(String name, String pattern, Project project, boolean includeNonProjectItems) { - GlobalSearchScope scope = GlobalSearchScope.allScope(project); - PsiClass[] classes = JetShortNamesCache.getKotlinInstance(project).getClassesByName(name, scope); + GlobalSearchScope scope = includeNonProjectItems ? GlobalSearchScope.allScope(project) : GlobalSearchScope.projectScope(project); + Collection classesOrObjects = JetShortClassNameIndex.getInstance().get(name, project, scope); + if (classesOrObjects.isEmpty()) { + return NavigationItem.EMPTY_NAVIGATION_ITEM_ARRAY; + } + + PsiClass[] classes = PsiShortNamesCache.getInstance(project).getClassesByName(name, scope); Collection javaQualifiedNames = new HashSet(); - for (PsiClass aClass : classes) { String qualifiedName = aClass.getQualifiedName(); if (qualifiedName != null) { @@ -73,23 +81,16 @@ public class JetGotoClassContributor implements GotoClassContributor { } List items = new ArrayList(); - Collection classesOrObjects = JetShortClassNameIndex.getInstance().get(name, project, scope); - for (JetClassOrObject classOrObject : classesOrObjects) { FqName fqName = JetPsiUtil.getFQName(classOrObject); if (fqName == null || javaQualifiedNames.contains(fqName.toString())) { + // Elements will be added by Java class contributor continue; } - if (classOrObject instanceof JetObjectDeclaration) { - // items.add((JetObjectDeclaration) classOrObject); - } - else if (classOrObject instanceof JetClass) { + if (classOrObject instanceof JetClass) { items.add(classOrObject); } - else { - assert false; - } } return ArrayUtil.toObjectArray(items, NavigationItem.class); diff --git a/idea/src/org/jetbrains/jet/plugin/caches/JetShortNamesCache.java b/idea/src/org/jetbrains/jet/plugin/caches/JetShortNamesCache.java index 38abadfafcf..2d6005d82b8 100644 --- a/idea/src/org/jetbrains/jet/plugin/caches/JetShortNamesCache.java +++ b/idea/src/org/jetbrains/jet/plugin/caches/JetShortNamesCache.java @@ -86,7 +86,7 @@ public class JetShortNamesCache extends PsiShortNamesCache { // .namespace classes can not be indexed, since they have no explicit declarations IDELightClassGenerationSupport lightClassGenerationSupport = IDELightClassGenerationSupport.getInstanceForIDE(project); - Set packageClassShortNames = lightClassGenerationSupport.getAllPackageClasses(GlobalSearchScope.allScope(project)).keySet(); + Set packageClassShortNames = lightClassGenerationSupport.getAllPossiblePackageClasses(GlobalSearchScope.allScope(project)).keySet(); classNames.addAll(packageClassShortNames); return ArrayUtil.toStringArray(classNames); @@ -101,7 +101,7 @@ public class JetShortNamesCache extends PsiShortNamesCache { List result = new ArrayList(); IDELightClassGenerationSupport lightClassGenerationSupport = IDELightClassGenerationSupport.getInstanceForIDE(project); - MultiMap packageClasses = lightClassGenerationSupport.getAllPackageClasses(scope); + MultiMap packageClasses = lightClassGenerationSupport.getAllPossiblePackageClasses(scope); // .namespace classes can not be indexed, since they have no explicit declarations Collection fqNames = packageClasses.get(name); 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 75365972681..5d6342d5ec3 100644 --- a/idea/src/org/jetbrains/jet/plugin/caches/resolve/IDELightClassGenerationSupport.java +++ b/idea/src/org/jetbrains/jet/plugin/caches/resolve/IDELightClassGenerationSupport.java @@ -37,7 +37,9 @@ import org.jetbrains.jet.lang.psi.JetPsiUtil; import org.jetbrains.jet.lang.resolve.java.PackageClassUtils; import org.jetbrains.jet.lang.resolve.name.FqName; import org.jetbrains.jet.plugin.libraries.JetSourceNavigationHelper; -import org.jetbrains.jet.plugin.stubindex.*; +import org.jetbrains.jet.plugin.stubindex.JetAllPackagesIndex; +import org.jetbrains.jet.plugin.stubindex.JetClassByPackageIndex; +import org.jetbrains.jet.plugin.stubindex.JetFullClassNameIndex; import org.jetbrains.jet.util.QualifiedNamesUtil; import java.util.Collection; @@ -131,18 +133,15 @@ public class IDELightClassGenerationSupport extends LightClassGenerationSupport } @NotNull - public MultiMap getAllPackageClasses(@NotNull GlobalSearchScope scope) { + public MultiMap getAllPossiblePackageClasses(@NotNull GlobalSearchScope scope) { Collection packageFqNames = JetAllPackagesIndex.getInstance().getAllKeys(project); MultiMap result = new MultiMap(); for (String packageFqName : packageFqNames) { - Collection files = findFilesForPackage(new FqName(packageFqName), scope); - if (!files.isEmpty()) { - FqName packageClassFqName = PackageClassUtils.getPackageClassFqName(new FqName(packageFqName)); - result.putValue(packageClassFqName.shortName().asString(), packageClassFqName); - } - + FqName packageClassFqName = PackageClassUtils.getPackageClassFqName(new FqName(packageFqName)); + result.putValue(packageClassFqName.shortName().asString(), packageClassFqName); } + return result; } } From 9b3115a10b33be2caccf2bf70c1905a5491184d3 Mon Sep 17 00:00:00 2001 From: Alexander Udalov Date: Mon, 24 Jun 2013 23:09:33 +0400 Subject: [PATCH 191/291] Fix EA-47308 Don't always cast PsiFile to JetFile, first check if it really is a Kotlin source --- .../org/jetbrains/jet/plugin/quickfix/CastExpressionFix.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/idea/src/org/jetbrains/jet/plugin/quickfix/CastExpressionFix.java b/idea/src/org/jetbrains/jet/plugin/quickfix/CastExpressionFix.java index d58f92e6ebd..eeb30199411 100644 --- a/idea/src/org/jetbrains/jet/plugin/quickfix/CastExpressionFix.java +++ b/idea/src/org/jetbrains/jet/plugin/quickfix/CastExpressionFix.java @@ -58,9 +58,10 @@ public class CastExpressionFix extends JetIntentionAction { @Override public boolean isAvailable(@NotNull Project project, Editor editor, PsiFile file) { + if (!super.isAvailable(project, editor, file)) return false; BindingContext context = AnalyzerFacadeWithCache.analyzeFileWithCache((JetFile) file).getBindingContext(); JetType expressionType = context.get(BindingContext.EXPRESSION_TYPE, element); - return super.isAvailable(project, editor, file) && expressionType != null && JetTypeChecker.INSTANCE.isSubtypeOf(type, expressionType); + return expressionType != null && JetTypeChecker.INSTANCE.isSubtypeOf(type, expressionType); } @Override From 68b0ad53c409085a51f40cd4239b7f9f88ab61ab Mon Sep 17 00:00:00 2001 From: Alexander Udalov Date: Mon, 24 Jun 2013 23:18:44 +0400 Subject: [PATCH 192/291] Regression test for KT-24 #KT-24 Obsolete --- .../codegen/box/innerNested/nestedClassInObject.kt | 10 ++++++++++ .../generated/BlackBoxCodegenTestGenerated.java | 5 +++++ 2 files changed, 15 insertions(+) create mode 100644 compiler/testData/codegen/box/innerNested/nestedClassInObject.kt diff --git a/compiler/testData/codegen/box/innerNested/nestedClassInObject.kt b/compiler/testData/codegen/box/innerNested/nestedClassInObject.kt new file mode 100644 index 00000000000..ec3f72d4b20 --- /dev/null +++ b/compiler/testData/codegen/box/innerNested/nestedClassInObject.kt @@ -0,0 +1,10 @@ +object A { + class B + class C +} + +fun box(): String { + val b = A.B() + val c = A.C() + 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 c7d3a2c1a75..bc16ba9d43e 100644 --- a/compiler/tests/org/jetbrains/jet/codegen/generated/BlackBoxCodegenTestGenerated.java +++ b/compiler/tests/org/jetbrains/jet/codegen/generated/BlackBoxCodegenTestGenerated.java @@ -2340,6 +2340,11 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest { doTest("compiler/testData/codegen/box/innerNested/kt3132.kt"); } + @TestMetadata("nestedClassInObject.kt") + public void testNestedClassInObject() throws Exception { + doTest("compiler/testData/codegen/box/innerNested/nestedClassInObject.kt"); + } + @TestMetadata("nestedClassObject.kt") public void testNestedClassObject() throws Exception { doTest("compiler/testData/codegen/box/innerNested/nestedClassObject.kt"); From db41329e671f18ae1c7e21ad0806e2fd10f2a1af Mon Sep 17 00:00:00 2001 From: Alexander Udalov Date: Tue, 25 Jun 2013 17:59:30 +0400 Subject: [PATCH 193/291] Exclude KT-3574 from Android tests due to jet.Nothing bug --- .../tests/org/jetbrains/jet/compiler/android/SpecialFiles.java | 1 + 1 file changed, 1 insertion(+) diff --git a/compiler/android-tests/tests/org/jetbrains/jet/compiler/android/SpecialFiles.java b/compiler/android-tests/tests/org/jetbrains/jet/compiler/android/SpecialFiles.java index c2cfb870baa..7b24dd1222b 100644 --- a/compiler/android-tests/tests/org/jetbrains/jet/compiler/android/SpecialFiles.java +++ b/compiler/android-tests/tests/org/jetbrains/jet/compiler/android/SpecialFiles.java @@ -72,6 +72,7 @@ public class SpecialFiles { excludedFiles.add("kt344.kt"); // Bug excludedFiles.add("comparisonWithNullCallsFun.kt"); // java.lang.NoClassDefFoundError: jet.Nothing + excludedFiles.add("kt3574.kt"); // java.lang.NoClassDefFoundError: jet.Nothing } private SpecialFiles() { From 356c32893bbb0de32ec4d032b3350a5a8a7a5753 Mon Sep 17 00:00:00 2001 From: Alexander Udalov Date: Tue, 25 Jun 2013 18:11:17 +0400 Subject: [PATCH 194/291] Don't use 'iinc' instruction on byte/short/char variables Android run-time verifier complains when there's any possibility that a byte/short/char local variable could contain a value not fitting into the type's limits. --- .../org/jetbrains/jet/codegen/AsmUtil.java | 10 +- .../jet/codegen/ExpressionCodegen.java | 145 +++++++++--------- .../jet/codegen/intrinsics/Increment.java | 12 +- .../primitiveTypes/incrementByteCharShort.kt | 22 +++ .../BlackBoxCodegenTestGenerated.java | 5 + 5 files changed, 112 insertions(+), 82 deletions(-) create mode 100644 compiler/testData/codegen/box/primitiveTypes/incrementByteCharShort.kt diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/AsmUtil.java b/compiler/backend/src/org/jetbrains/jet/codegen/AsmUtil.java index 9116696fa30..5a0d5d17f80 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/AsmUtil.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/AsmUtil.java @@ -433,25 +433,23 @@ public class AsmUtil { } } - public static Type genIncrement(Type expectedType, int myDelta, InstructionAdapter v) { + public static void genIncrement(Type expectedType, int myDelta, InstructionAdapter v) { if (expectedType == Type.LONG_TYPE) { - //noinspection UnnecessaryBoxing v.lconst(myDelta); } else if (expectedType == Type.FLOAT_TYPE) { - //noinspection UnnecessaryBoxing v.fconst(myDelta); } else if (expectedType == Type.DOUBLE_TYPE) { - //noinspection UnnecessaryBoxing v.dconst(myDelta); } else { v.iconst(myDelta); - expectedType = Type.INT_TYPE; + v.add(Type.INT_TYPE); + StackValue.coerce(Type.INT_TYPE, expectedType, v); + return; } v.add(expectedType); - return expectedType; } public static Type genNegate(Type expectedType, InstructionAdapter v) { diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java index 66971d59270..e0026290b71 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java @@ -3057,89 +3057,92 @@ public class ExpressionCodegen extends JetVisitor implem v.mark(ok); return StackValue.onStack(base.type); } + DeclarationDescriptor op = bindingContext.get(BindingContext.REFERENCE_TARGET, expression.getOperationReference()); - if (op instanceof FunctionDescriptor) { - Type asmType = expressionType(expression); - DeclarationDescriptor cls = op.getContainingDeclaration(); - 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().asString().equals("inc") ? 1 : -1; - return StackValue.postIncrement(index, increment); - } - } - gen(operand, asmType); // old value - generateIncrement(op, asmType, operand, receiver); // increment in-place - return StackValue.onStack(asmType); // old value - } - else { - ResolvedCall resolvedCall = - bindingContext.get(BindingContext.RESOLVED_CALL, expression.getOperationReference()); - assert resolvedCall != null; + if (!(op instanceof FunctionDescriptor)) { + throw new UnsupportedOperationException("Don't know how to generate this postfix expression: " + op); + } - Callable callable = resolveToCallable((FunctionDescriptor) op, false); + Type asmType = expressionType(expression); + DeclarationDescriptor cls = op.getContainingDeclaration(); - StackValue value = gen(expression.getBaseExpression()); - value.dupReceiver(v); + int increment; + if (op.getName().asString().equals("inc")) { + increment = 1; + } + else if (op.getName().asString().equals("dec")) { + increment = -1; + } + else { + throw new UnsupportedOperationException("Unsupported postfix operation: " + op); + } - Type type = expressionType(expression.getBaseExpression()); - value.put(type, v); - - switch (value.receiverSize()) { - case 0: - dup(v, type); - break; - - case 1: - if (type.getSize() == 2) { - v.dup2X1(); - } - else { - v.dupX1(); - } - break; - - case 2: - if (type.getSize() == 2) { - v.dup2X2(); - } - else { - v.dupX2(); - } - break; - - case -1: - throw new UnsupportedOperationException(); - } - - CallableMethod callableMethod = (CallableMethod) callable; - callableMethod.invokeWithNotNullAssertion(v, state, resolvedCall); - - value.store(callableMethod.getReturnType(), v); - return StackValue.onStack(type); + if (isPrimitiveNumberClassDescriptor(cls)) { + receiver.put(receiver.type, v); + JetExpression operand = expression.getBaseExpression(); + if (operand instanceof JetReferenceExpression && asmType == Type.INT_TYPE) { + int index = indexOfLocal((JetReferenceExpression) operand); + if (index >= 0) { + return StackValue.postIncrement(index, increment); } } + gen(operand, asmType); // old value + generateIncrement(increment, asmType, operand, receiver); // increment in-place + return StackValue.onStack(asmType); // old value + } + else { + ResolvedCall resolvedCall = + bindingContext.get(BindingContext.RESOLVED_CALL, expression.getOperationReference()); + assert resolvedCall != null; + + Callable callable = resolveToCallable((FunctionDescriptor) op, false); + + StackValue value = gen(expression.getBaseExpression()); + value.dupReceiver(v); + + Type type = expressionType(expression.getBaseExpression()); + value.put(type, v); + + switch (value.receiverSize()) { + case 0: + dup(v, type); + break; + + case 1: + if (type.getSize() == 2) { + v.dup2X1(); + } + else { + v.dupX1(); + } + break; + + case 2: + if (type.getSize() == 2) { + v.dup2X2(); + } + else { + v.dupX2(); + } + break; + + case -1: + throw new UnsupportedOperationException(); + } + + CallableMethod callableMethod = (CallableMethod) callable; + callableMethod.invokeWithNotNullAssertion(v, state, resolvedCall); + + value.store(callableMethod.getReturnType(), v); + return StackValue.onStack(type); } - throw new UnsupportedOperationException("Don't know how to generate this postfix expression"); } - private void generateIncrement(DeclarationDescriptor op, Type asmType, JetExpression operand, StackValue receiver) { - int increment = op.getName().asString().equals("inc") ? 1 : -1; - if (operand instanceof JetReferenceExpression) { - int index = indexOfLocal((JetReferenceExpression) operand); - if (index >= 0 && isIntPrimitive(asmType)) { - v.iinc(index, increment); - return; - } - } + private void generateIncrement(int increment, Type asmType, JetExpression operand, StackValue receiver) { StackValue value = genQualified(receiver, operand); value.dupReceiver(v); value.put(asmType, v); - asmType = genIncrement(asmType, increment, v); + genIncrement(asmType, increment, v); value.store(asmType, v); } diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/Increment.java b/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/Increment.java index 89ecc7e31c5..f358295e8ef 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/Increment.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/Increment.java @@ -29,7 +29,8 @@ import org.jetbrains.jet.lang.psi.JetReferenceExpression; import java.util.List; -import static org.jetbrains.jet.codegen.AsmUtil.*; +import static org.jetbrains.jet.codegen.AsmUtil.genIncrement; +import static org.jetbrains.jet.codegen.AsmUtil.unboxType; public class Increment implements IntrinsicMethod { private final int myDelta; @@ -57,9 +58,9 @@ public class Increment implements IntrinsicMethod { while (operand instanceof JetParenthesizedExpression) { operand = ((JetParenthesizedExpression) operand).getExpression(); } - if (operand instanceof JetReferenceExpression) { + if (operand instanceof JetReferenceExpression && expectedType == Type.INT_TYPE) { int index = codegen.indexOfLocal((JetReferenceExpression) operand); - if (index >= 0 && isIntPrimitive(expectedType)) { + if (index >= 0) { return StackValue.preIncrement(index, myDelta); } } @@ -68,12 +69,13 @@ public class Increment implements IntrinsicMethod { value.dupReceiver(v); value.put(expectedType, v); - value.store(genIncrement(expectedType, myDelta, v), v); + genIncrement(expectedType, myDelta, v); + value.store(expectedType, v); value.put(expectedType, v); } else { receiver.put(expectedType, v); - StackValue.coerce(genIncrement(expectedType, myDelta, v), expectedType, v); + genIncrement(expectedType, myDelta, v); } return StackValue.onStack(expectedType); } diff --git a/compiler/testData/codegen/box/primitiveTypes/incrementByteCharShort.kt b/compiler/testData/codegen/box/primitiveTypes/incrementByteCharShort.kt new file mode 100644 index 00000000000..59b3f12b2ef --- /dev/null +++ b/compiler/testData/codegen/box/primitiveTypes/incrementByteCharShort.kt @@ -0,0 +1,22 @@ +fun byteArg(b: Byte) {} +fun charArg(c: Char) {} +fun shortArg(s: Short) {} + +fun box(): String { + var b = 42.toByte() + b++ + ++b + byteArg(b) + + var c = 'x' + c++ + ++c + charArg(c) + + var s = 239.toShort() + s++ + ++s + shortArg(s) + + 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 bc16ba9d43e..784f1355c8f 100644 --- a/compiler/tests/org/jetbrains/jet/codegen/generated/BlackBoxCodegenTestGenerated.java +++ b/compiler/tests/org/jetbrains/jet/codegen/generated/BlackBoxCodegenTestGenerated.java @@ -3339,6 +3339,11 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest { doTest("compiler/testData/codegen/box/primitiveTypes/ea35963.kt"); } + @TestMetadata("incrementByteCharShort.kt") + public void testIncrementByteCharShort() throws Exception { + doTest("compiler/testData/codegen/box/primitiveTypes/incrementByteCharShort.kt"); + } + @TestMetadata("intLiteralIsNotNull.kt") public void testIntLiteralIsNotNull() throws Exception { doTest("compiler/testData/codegen/box/primitiveTypes/intLiteralIsNotNull.kt"); From fea85476b73aa2f078abdf4a671571e4c77ae665 Mon Sep 17 00:00:00 2001 From: Alexander Udalov Date: Tue, 25 Jun 2013 18:13:20 +0400 Subject: [PATCH 195/291] Cast int to byte/short/char in for loop generation Similar to the previous commit, don't use iinc or iadd+istore where the value can overflow the byte/short/char limits. This fixes Android tests --- .../jet/codegen/ExpressionCodegen.java | 42 +++++-------------- 1 file changed, 11 insertions(+), 31 deletions(-) diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java index e0026290b71..f587b0bc31a 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java @@ -930,37 +930,13 @@ public class ExpressionCodegen extends JetVisitor implem checkPostCondition(loopExit); } - int sort = asmElementType.getSort(); - switch (sort) { - case Type.INT: - case Type.CHAR: - case Type.BYTE: - case Type.SHORT: - v.iinc(loopParameterVar, 1); - break; - - case Type.LONG: - v.load(loopParameterVar, asmElementType); - v.lconst(1); - v.add(asmElementType); - v.store(loopParameterVar, asmElementType); - break; - - case Type.FLOAT: - case Type.DOUBLE: - v.load(loopParameterVar, asmElementType); - if (sort == Type.DOUBLE) { - v.dconst(1.0); - } - else { - v.fconst(1.0f); - } - v.add(asmElementType); - v.store(loopParameterVar, asmElementType); - break; - - default: - throw new IllegalStateException("Unexpected range element type: " + asmElementType); + if (asmElementType == Type.INT_TYPE) { + v.iinc(loopParameterVar, 1); + } + else { + v.load(loopParameterVar, asmElementType); + genIncrement(asmElementType, 1, v); + v.store(loopParameterVar, asmElementType); } } } @@ -1149,6 +1125,10 @@ public class ExpressionCodegen extends JetVisitor implem v.load(incrementVar, asmElementType); v.add(asmElementType); + if (asmElementType == Type.BYTE_TYPE || asmElementType == Type.SHORT_TYPE || asmElementType == Type.CHAR_TYPE) { + StackValue.coerce(Type.INT_TYPE, asmElementType, v); + } + v.store(loopParameterVar, asmElementType); } } From 50eb14c5258fc37c936306952d67bfdd243ca592 Mon Sep 17 00:00:00 2001 From: Evgeny Gerashchenko Date: Thu, 6 Jun 2013 23:29:14 +0400 Subject: [PATCH 196/291] Rendering member kind for constructor. --- .../jet/renderer/DescriptorRendererImpl.java | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/compiler/frontend/src/org/jetbrains/jet/renderer/DescriptorRendererImpl.java b/compiler/frontend/src/org/jetbrains/jet/renderer/DescriptorRendererImpl.java index b4d9afbf8a5..66e319058d5 100644 --- a/compiler/frontend/src/org/jetbrains/jet/renderer/DescriptorRendererImpl.java +++ b/compiler/frontend/src/org/jetbrains/jet/renderer/DescriptorRendererImpl.java @@ -355,7 +355,7 @@ public class DescriptorRendererImpl implements DescriptorRenderer { return !callable.getOverriddenDescriptors().isEmpty(); } - private void renderOverrideAndMemberKind(@NotNull CallableMemberDescriptor callableMember, @NotNull StringBuilder builder) { + private void renderOverride(@NotNull CallableMemberDescriptor callableMember, @NotNull StringBuilder builder) { if (!modifiers) return; if (overridesSomething(callableMember)) { if (overrideRenderingPolicy != OverrideRenderingPolicy.RENDER_OPEN) { @@ -365,6 +365,10 @@ public class DescriptorRendererImpl implements DescriptorRenderer { } } } + } + + private void renderMemberKind(CallableMemberDescriptor callableMember, StringBuilder builder) { + if (!modifiers) return; if (verbose && callableMember.getKind() != CallableMemberDescriptor.Kind.DECLARATION) { builder.append("/*").append(callableMember.getKind().name().toLowerCase()).append("*/ "); } @@ -460,7 +464,8 @@ public class DescriptorRendererImpl implements DescriptorRenderer { renderAnnotations(function, builder); renderVisibility(function.getVisibility(), builder); renderModalityForCallable(function, builder); - renderOverrideAndMemberKind(function, builder); + renderOverride(function, builder); + renderMemberKind(function, builder); builder.append(renderKeyword("fun")).append(" "); renderTypeParameters(function.getTypeParameters(), builder, true); @@ -483,6 +488,7 @@ public class DescriptorRendererImpl implements DescriptorRenderer { private void renderConstructor(@NotNull ConstructorDescriptor constructor, @NotNull StringBuilder builder) { renderAnnotations(constructor, builder); renderVisibility(constructor.getVisibility(), builder); + renderMemberKind(constructor, builder); builder.append(renderKeyword("constructor")).append(" "); @@ -582,7 +588,8 @@ public class DescriptorRendererImpl implements DescriptorRenderer { renderAnnotations(property, builder); renderVisibility(property.getVisibility(), builder); renderModalityForCallable(property, builder); - renderOverrideAndMemberKind(property, builder); + renderOverride(property, builder); + renderMemberKind(property, builder); renderValVarPrefix(property, builder); } From 5e2c3fcb50acb558e87df2bcbbd43149690e8063 Mon Sep 17 00:00:00 2001 From: Evgeny Gerashchenko Date: Thu, 6 Jun 2013 23:30:03 +0400 Subject: [PATCH 197/291] Loading SAM adapters for constructors. --- .../jet/codegen/ExpressionCodegen.java | 2 +- .../resolver/JavaConstructorResolver.java | 15 +++ .../java/sam/SingleAbstractMethodUtils.java | 96 +++++++++++++++---- .../impl/ConstructorDescriptorImpl.java | 7 +- .../jet/lang/resolve/BindingContext.java | 2 +- .../adapter/Constructor.java | 6 ++ .../adapter/Constructor.txt | 6 ++ .../jvm/compiler/LoadJavaTestGenerated.java | 5 + 8 files changed, 116 insertions(+), 23 deletions(-) create mode 100644 compiler/testData/loadJava/compiledJava/singleAbstractMethod/adapter/Constructor.java create mode 100644 compiler/testData/loadJava/compiledJava/singleAbstractMethod/adapter/Constructor.txt diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java index f587b0bc31a..feb52803e97 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java @@ -1897,7 +1897,7 @@ public class ExpressionCodegen extends JetVisitor implem } SimpleFunctionDescriptor original = ((SimpleFunctionDescriptor) fun).getOriginal(); if (original.getKind() == CallableMemberDescriptor.Kind.SYNTHESIZED) { - return bindingContext.get(SAM_ADAPTER_FUNCTION_TO_ORIGINAL, original); + return (SimpleFunctionDescriptor) bindingContext.get(SAM_ADAPTER_FUNCTION_TO_ORIGINAL, original); // TODO support constructor } if (original.getKind() == CallableMemberDescriptor.Kind.FAKE_OVERRIDE) { for (FunctionDescriptor overridden : original.getOverriddenDescriptors()) { diff --git a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/resolver/JavaConstructorResolver.java b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/resolver/JavaConstructorResolver.java index 812e92143cd..03943e0f754 100644 --- a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/resolver/JavaConstructorResolver.java +++ b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/resolver/JavaConstructorResolver.java @@ -18,6 +18,7 @@ package org.jetbrains.jet.lang.resolve.java.resolver; import com.google.common.collect.Lists; import com.intellij.psi.*; +import com.intellij.util.containers.ContainerUtil; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.jet.lang.descriptors.*; @@ -31,6 +32,7 @@ import org.jetbrains.jet.lang.resolve.java.*; import org.jetbrains.jet.lang.resolve.java.kotlinSignature.AlternativeMethodSignatureData; import org.jetbrains.jet.lang.resolve.java.kt.JetConstructorAnnotation; import org.jetbrains.jet.lang.resolve.java.provider.ClassPsiDeclarationProvider; +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; import org.jetbrains.jet.lang.types.JetType; @@ -149,6 +151,7 @@ public final class JavaConstructorResolver { ConstructorDescriptor constructor = resolveConstructor(psiClass, isStatic, psiConstructor, containingClass); if (constructor != null) { constructors.add(constructor); + ContainerUtil.addIfNotNull(constructors, resolveSamAdapter(constructor)); } } } @@ -218,4 +221,16 @@ public final class JavaConstructorResolver { trace.record(BindingContext.CONSTRUCTOR, psiConstructor, constructorDescriptor); return constructorDescriptor; } + + @Nullable + private ConstructorDescriptor resolveSamAdapter(@NotNull ConstructorDescriptor original) { + if (SingleAbstractMethodUtils.isSamAdapterNecessary(original)) { + ConstructorDescriptor adapterFunction = SingleAbstractMethodUtils.createSamAdapterConstructor(original); + + trace.record(BindingContext.SAM_ADAPTER_FUNCTION_TO_ORIGINAL, adapterFunction, original); + trace.record(BindingContext.SOURCE_DESCRIPTOR_FOR_SYNTHESIZED, adapterFunction, original); + return adapterFunction; + } + return null; + } } \ No newline at end of file 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 791161d5abc..7134388ac38 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 @@ -21,6 +21,7 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.jet.lang.descriptors.*; import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor; +import org.jetbrains.jet.lang.descriptors.impl.ConstructorDescriptorImpl; import org.jetbrains.jet.lang.descriptors.impl.SimpleFunctionDescriptorImpl; import org.jetbrains.jet.lang.descriptors.impl.TypeParameterDescriptorImpl; import org.jetbrains.jet.lang.descriptors.impl.ValueParameterDescriptorImpl; @@ -174,7 +175,7 @@ public class SingleAbstractMethodUtils { return getFunctionTypeForSamType(type) != null; } - public static boolean isSamAdapterNecessary(@NotNull SimpleFunctionDescriptor fun) { + public static boolean isSamAdapterNecessary(@NotNull FunctionDescriptor fun) { for (ValueParameterDescriptor param : fun.getValueParameters()) { if (isSamType(param.getType())) { return true; @@ -184,20 +185,77 @@ public class SingleAbstractMethodUtils { } @NotNull - public static SimpleFunctionDescriptor createSamAdapterFunction(@NotNull SimpleFunctionDescriptor original) { - SimpleFunctionDescriptorImpl result = new SimpleFunctionDescriptorImpl( + public static SimpleFunctionDescriptor createSamAdapterFunction(@NotNull final SimpleFunctionDescriptor original) { + final SimpleFunctionDescriptorImpl result = new SimpleFunctionDescriptorImpl( original.getContainingDeclaration(), original.getAnnotations(), original.getName(), CallableMemberDescriptor.Kind.SYNTHESIZED ); + FunctionInitializer initializer = new FunctionInitializer() { + @Override + public void initialize( + @NotNull List typeParameters, + @NotNull List valueParameters, + @Nullable JetType returnType + ) { + result.initialize( + null, + original.getExpectedThisObject(), + typeParameters, + valueParameters, + returnType, + original.getModality(), + original.getVisibility(), + false + ); + } + }; + return initSamAdapter(original, result, initializer); + } - TypeParameters typeParameters = recreateAndInitializeTypeParameters(original.getTypeParameters(), result); + @NotNull + public static ConstructorDescriptor createSamAdapterConstructor(@NotNull final ConstructorDescriptor original) { + final ConstructorDescriptorImpl result = new ConstructorDescriptorImpl( + original.getContainingDeclaration(), + original.getAnnotations(), + original.isPrimary(), + CallableMemberDescriptor.Kind.SYNTHESIZED + ); + FunctionInitializer initializer = new FunctionInitializer() { + @Override + public void initialize( + @NotNull List typeParameters, + @NotNull List valueParameters, + @Nullable JetType returnType + ) { + result.initialize( + typeParameters, + valueParameters, + original.getVisibility(), + original.getExpectedThisObject() == ReceiverParameterDescriptor.NO_RECEIVER_PARAMETER + ); + } + }; + return initSamAdapter(original, result, initializer); + } + + private static F initSamAdapter( + @NotNull F original, + @NotNull F adapter, + @NotNull FunctionInitializer initializer + ) { + TypeParameters typeParameters = recreateAndInitializeTypeParameters(original.getTypeParameters(), adapter); JetType returnTypeUnsubstituted = original.getReturnType(); - assert returnTypeUnsubstituted != null : original; - JetType returnType = typeParameters.substitutor.substitute(returnTypeUnsubstituted, Variance.OUT_VARIANCE); - assert returnType != null : "couldn't substitute type: " + returnType + ", substitutor = " + typeParameters.substitutor; + JetType returnType; + if (returnTypeUnsubstituted == null) { // return type may be null for not yet initialized constructors + returnType = null; + } + else { + returnType = typeParameters.substitutor.substitute(returnTypeUnsubstituted, Variance.OUT_VARIANCE); + assert returnType != null : "couldn't substitute type: " + returnType + ", substitutor = " + typeParameters.substitutor; + } List valueParameters = Lists.newArrayList(); for (ValueParameterDescriptor originalParam : original.getValueParameters()) { @@ -208,22 +266,12 @@ public class SingleAbstractMethodUtils { assert newType != null : "couldn't substitute type: " + newTypeUnsubstituted + ", substitutor = " + typeParameters.substitutor; ValueParameterDescriptor newParam = new ValueParameterDescriptorImpl( - result, originalParam.getIndex(), originalParam.getAnnotations(), originalParam.getName(), newType, false, null); + adapter, originalParam.getIndex(), originalParam.getAnnotations(), originalParam.getName(), newType, false, null); valueParameters.add(newParam); } - result.initialize( - null, - original.getExpectedThisObject(), - typeParameters.descriptors, - valueParameters, - returnType, - original.getModality(), - original.getVisibility(), - false - ); - - return result; + initializer.initialize(typeParameters.descriptors, valueParameters, returnType); + return adapter; } @NotNull @@ -273,4 +321,12 @@ public class SingleAbstractMethodUtils { this.substitutor = substitutor; } } + + private static abstract class FunctionInitializer { + public abstract void initialize( + @NotNull List typeParameters, + @NotNull List valueParameters, + @Nullable JetType returnType + ); + } } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/impl/ConstructorDescriptorImpl.java b/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/impl/ConstructorDescriptorImpl.java index abe1d6f6d50..e0560aea197 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/impl/ConstructorDescriptorImpl.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/impl/ConstructorDescriptorImpl.java @@ -22,6 +22,7 @@ import org.jetbrains.jet.lang.descriptors.*; import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor; import org.jetbrains.jet.lang.resolve.DescriptorUtils; import org.jetbrains.jet.lang.resolve.name.Name; +import org.jetbrains.jet.lang.types.JetType; import java.util.Collections; import java.util.List; @@ -36,7 +37,11 @@ public class ConstructorDescriptorImpl extends FunctionDescriptorImpl implements private static final Name NAME = Name.special(""); public ConstructorDescriptorImpl(@NotNull ClassDescriptor containingDeclaration, @NotNull List annotations, boolean isPrimary) { - super(containingDeclaration, annotations, NAME, Kind.DECLARATION); + this(containingDeclaration, annotations, isPrimary, Kind.DECLARATION); + } + + public ConstructorDescriptorImpl(@NotNull ClassDescriptor containingDeclaration, @NotNull List annotations, boolean isPrimary, Kind kind) { + super(containingDeclaration, annotations, NAME, kind); this.isPrimary = isPrimary; } 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 b84fa9060f8..dbc1d85ee1d 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/BindingContext.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/BindingContext.java @@ -265,7 +265,7 @@ public interface BindingContext { WritableSlice IS_DECLARED_IN_JAVA = Slices.createSimpleSlice(); WritableSlice SAM_CONSTRUCTOR_TO_INTERFACE = Slices.createSimpleSlice(); - WritableSlice SAM_ADAPTER_FUNCTION_TO_ORIGINAL = Slices.createSimpleSlice(); + WritableSlice SAM_ADAPTER_FUNCTION_TO_ORIGINAL = Slices.createSimpleSlice(); WritableSlice SOURCE_DESCRIPTOR_FOR_SYNTHESIZED = Slices.createSimpleSlice(); @SuppressWarnings("UnusedDeclaration") diff --git a/compiler/testData/loadJava/compiledJava/singleAbstractMethod/adapter/Constructor.java b/compiler/testData/loadJava/compiledJava/singleAbstractMethod/adapter/Constructor.java new file mode 100644 index 00000000000..527ec3102bd --- /dev/null +++ b/compiler/testData/loadJava/compiledJava/singleAbstractMethod/adapter/Constructor.java @@ -0,0 +1,6 @@ +package test; + +public class Constructor { + public Constructor(Runnable r) { + } +} diff --git a/compiler/testData/loadJava/compiledJava/singleAbstractMethod/adapter/Constructor.txt b/compiler/testData/loadJava/compiledJava/singleAbstractMethod/adapter/Constructor.txt new file mode 100644 index 00000000000..a9b54f026fc --- /dev/null +++ b/compiler/testData/loadJava/compiledJava/singleAbstractMethod/adapter/Constructor.txt @@ -0,0 +1,6 @@ +package test + +public open class Constructor : java.lang.Object { + public /*synthesized*/ constructor Constructor(/*0*/ p0: (() -> jet.Unit)?) + public constructor Constructor(/*0*/ p0: java.lang.Runnable?) +} diff --git a/compiler/tests/org/jetbrains/jet/jvm/compiler/LoadJavaTestGenerated.java b/compiler/tests/org/jetbrains/jet/jvm/compiler/LoadJavaTestGenerated.java index 5d88070a54a..65c21f08fae 100644 --- a/compiler/tests/org/jetbrains/jet/jvm/compiler/LoadJavaTestGenerated.java +++ b/compiler/tests/org/jetbrains/jet/jvm/compiler/LoadJavaTestGenerated.java @@ -1239,6 +1239,11 @@ public class LoadJavaTestGenerated extends AbstractLoadJavaTest { doTestCompiledJava("compiler/testData/loadJava/compiledJava/singleAbstractMethod/adapter/Basic.java"); } + @TestMetadata("Constructor.java") + public void testConstructor() throws Exception { + doTestCompiledJava("compiler/testData/loadJava/compiledJava/singleAbstractMethod/adapter/Constructor.java"); + } + @TestMetadata("DeepSamLoop.java") public void testDeepSamLoop() throws Exception { doTestCompiledJava("compiler/testData/loadJava/compiledJava/singleAbstractMethod/adapter/DeepSamLoop.java"); From 4980dacd33944a39bfbbf3a0ca657e5986d6aaea Mon Sep 17 00:00:00 2001 From: Evgeny Gerashchenko Date: Fri, 7 Jun 2013 18:15:43 +0400 Subject: [PATCH 198/291] Supported calls of SAM adapters for constructors. --- .../jet/codegen/ExpressionCodegen.java | 17 +++++++++-------- .../boxWithJava/samAdapters/constructor.java | 11 +++++++++++ .../boxWithJava/samAdapters/constructor.kt | 5 +++++ .../BlackBoxWithJavaCodegenTestGenerated.java | 5 +++++ 4 files changed, 30 insertions(+), 8 deletions(-) create mode 100644 compiler/testData/codegen/boxWithJava/samAdapters/constructor.java create mode 100644 compiler/testData/codegen/boxWithJava/samAdapters/constructor.kt diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java index feb52803e97..3cc14ad907f 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java @@ -1891,17 +1891,17 @@ public class ExpressionCodegen extends JetVisitor implem } @Nullable - private SimpleFunctionDescriptor getOriginalIfSamAdapter(@NotNull CallableDescriptor fun) { - if (!(fun instanceof SimpleFunctionDescriptor)) { + private FunctionDescriptor getOriginalIfSamAdapter(@NotNull CallableDescriptor fun) { + if (!(fun instanceof FunctionDescriptor)) { return null; } - SimpleFunctionDescriptor original = ((SimpleFunctionDescriptor) fun).getOriginal(); + FunctionDescriptor original = ((FunctionDescriptor) fun).getOriginal(); if (original.getKind() == CallableMemberDescriptor.Kind.SYNTHESIZED) { - return (SimpleFunctionDescriptor) bindingContext.get(SAM_ADAPTER_FUNCTION_TO_ORIGINAL, original); // TODO support constructor + return bindingContext.get(SAM_ADAPTER_FUNCTION_TO_ORIGINAL, original); } if (original.getKind() == CallableMemberDescriptor.Kind.FAKE_OVERRIDE) { for (FunctionDescriptor overridden : original.getOverriddenDescriptors()) { - SimpleFunctionDescriptor originalIfSamAdapter = getOriginalIfSamAdapter(overridden); + FunctionDescriptor originalIfSamAdapter = getOriginalIfSamAdapter(overridden); if (originalIfSamAdapter != null) { return originalIfSamAdapter; } @@ -2059,7 +2059,7 @@ public class ExpressionCodegen extends JetVisitor implem return typeMapper.mapToFunctionInvokeCallableMethod(createInvoke(fd)); } else { - SimpleFunctionDescriptor originalOfSamAdapter = getOriginalIfSamAdapter(fd); + SimpleFunctionDescriptor originalOfSamAdapter = (SimpleFunctionDescriptor) getOriginalIfSamAdapter(fd); return typeMapper.mapToCallableMethod(originalOfSamAdapter != null ? originalOfSamAdapter : fd, superCall, isCallInsideSameClassAsDeclared(fd, context), isCallInsideSameModuleAsDeclared(fd, context), @@ -2293,7 +2293,7 @@ public class ExpressionCodegen extends JetVisitor implem int mask = 0; - SimpleFunctionDescriptor originalOfSamAdapter = getOriginalIfSamAdapter(fd); + FunctionDescriptor originalOfSamAdapter = getOriginalIfSamAdapter(fd); for (ValueParameterDescriptor valueParameter : fd.getValueParameters()) { ResolvedValueArgument resolvedValueArgument = valueArguments.get(valueParameter.getIndex()); @@ -3263,7 +3263,8 @@ public class ExpressionCodegen extends JetVisitor implem //See StackValue.receiver for more info pushClosureOnStack(closure, resolvedCall.getThisObject().exists() || resolvedCall.getReceiverArgument().exists()); - CallableMethod method = typeMapper.mapToCallableMethod(constructorDescriptor); + ConstructorDescriptor originalOfSamAdapter = (ConstructorDescriptor) getOriginalIfSamAdapter(constructorDescriptor); + CallableMethod method = typeMapper.mapToCallableMethod(originalOfSamAdapter == null ? constructorDescriptor : originalOfSamAdapter); invokeMethodWithArguments(method, resolvedCall, null, StackValue.none()); return StackValue.onStack(type); diff --git a/compiler/testData/codegen/boxWithJava/samAdapters/constructor.java b/compiler/testData/codegen/boxWithJava/samAdapters/constructor.java new file mode 100644 index 00000000000..c47e8ab052e --- /dev/null +++ b/compiler/testData/codegen/boxWithJava/samAdapters/constructor.java @@ -0,0 +1,11 @@ +class JavaClass { + private Runnable r; + + public JavaClass(Runnable r) { + this.r = r; + } + + public void run() { + r.run(); + } +} \ No newline at end of file diff --git a/compiler/testData/codegen/boxWithJava/samAdapters/constructor.kt b/compiler/testData/codegen/boxWithJava/samAdapters/constructor.kt new file mode 100644 index 00000000000..15128cc1a13 --- /dev/null +++ b/compiler/testData/codegen/boxWithJava/samAdapters/constructor.kt @@ -0,0 +1,5 @@ +fun box(): String { + var v = "FAIL" + JavaClass { v = "OK" }.run() + return v +} \ No newline at end of file diff --git a/compiler/tests/org/jetbrains/jet/codegen/generated/BlackBoxWithJavaCodegenTestGenerated.java b/compiler/tests/org/jetbrains/jet/codegen/generated/BlackBoxWithJavaCodegenTestGenerated.java index 92d64318f91..803f18aef84 100644 --- a/compiler/tests/org/jetbrains/jet/codegen/generated/BlackBoxWithJavaCodegenTestGenerated.java +++ b/compiler/tests/org/jetbrains/jet/codegen/generated/BlackBoxWithJavaCodegenTestGenerated.java @@ -145,6 +145,11 @@ public class BlackBoxWithJavaCodegenTestGenerated extends AbstractBlackBoxCodege doTestWithJava("compiler/testData/codegen/boxWithJava/samAdapters/comparator.kt"); } + @TestMetadata("constructor.kt") + public void testConstructor() throws Exception { + doTestWithJava("compiler/testData/codegen/boxWithJava/samAdapters/constructor.kt"); + } + @TestMetadata("fileFilter.kt") public void testFileFilter() throws Exception { doTestWithJava("compiler/testData/codegen/boxWithJava/samAdapters/fileFilter.kt"); From cfc99b941a1607349b49575a46aa08a2950ef94a Mon Sep 17 00:00:00 2001 From: Evgeny Gerashchenko Date: Fri, 7 Jun 2013 19:51:22 +0400 Subject: [PATCH 199/291] Added test for ambiguous SAM adapters within one class. --- .../tests/j+k/ambiguousSamAdapters.kt | 18 ++++++++++++++++++ .../adapter/AmbiguousAdapters.java | 11 +++++++++++ .../adapter/AmbiguousAdapters.txt | 9 +++++++++ .../checkers/JetDiagnosticsTestGenerated.java | 5 +++++ .../jvm/compiler/LoadJavaTestGenerated.java | 5 +++++ 5 files changed, 48 insertions(+) create mode 100644 compiler/testData/diagnostics/tests/j+k/ambiguousSamAdapters.kt create mode 100644 compiler/testData/loadJava/compiledJava/singleAbstractMethod/adapter/AmbiguousAdapters.java create mode 100644 compiler/testData/loadJava/compiledJava/singleAbstractMethod/adapter/AmbiguousAdapters.txt diff --git a/compiler/testData/diagnostics/tests/j+k/ambiguousSamAdapters.kt b/compiler/testData/diagnostics/tests/j+k/ambiguousSamAdapters.kt new file mode 100644 index 00000000000..3862b810009 --- /dev/null +++ b/compiler/testData/diagnostics/tests/j+k/ambiguousSamAdapters.kt @@ -0,0 +1,18 @@ +// FILE: A.java +import java.io.Closeable; + +public class A { + public static void foo(Runnable r) { + } + + public static void foo(Closeable c) { + } +} + +// FILE: test.kt + +fun main() { + A.foo { "Hello!" } + A.foo(Runnable { "Hello!" }) +} + diff --git a/compiler/testData/loadJava/compiledJava/singleAbstractMethod/adapter/AmbiguousAdapters.java b/compiler/testData/loadJava/compiledJava/singleAbstractMethod/adapter/AmbiguousAdapters.java new file mode 100644 index 00000000000..a30e22636d6 --- /dev/null +++ b/compiler/testData/loadJava/compiledJava/singleAbstractMethod/adapter/AmbiguousAdapters.java @@ -0,0 +1,11 @@ +package test; + +import java.io.Closeable; + +public class AmbiguousAdapters { + public void foo(Runnable r) { + } + + public void foo(Closeable c) { + } +} diff --git a/compiler/testData/loadJava/compiledJava/singleAbstractMethod/adapter/AmbiguousAdapters.txt b/compiler/testData/loadJava/compiledJava/singleAbstractMethod/adapter/AmbiguousAdapters.txt new file mode 100644 index 00000000000..8285524a2cb --- /dev/null +++ b/compiler/testData/loadJava/compiledJava/singleAbstractMethod/adapter/AmbiguousAdapters.txt @@ -0,0 +1,9 @@ +package test + +public open class AmbiguousAdapters : java.lang.Object { + public constructor AmbiguousAdapters() + public open /*synthesized*/ fun foo(/*0*/ p0: (() -> jet.Unit)?): jet.Unit + public open /*synthesized*/ fun foo(/*0*/ p0: (() -> jet.Unit)?): jet.Unit + public open fun foo(/*0*/ p0: java.io.Closeable?): jet.Unit + public open fun foo(/*0*/ p0: java.lang.Runnable?): jet.Unit +} diff --git a/compiler/tests/org/jetbrains/jet/checkers/JetDiagnosticsTestGenerated.java b/compiler/tests/org/jetbrains/jet/checkers/JetDiagnosticsTestGenerated.java index 0ea7d1a1d8c..4c08680cbe5 100644 --- a/compiler/tests/org/jetbrains/jet/checkers/JetDiagnosticsTestGenerated.java +++ b/compiler/tests/org/jetbrains/jet/checkers/JetDiagnosticsTestGenerated.java @@ -3224,6 +3224,11 @@ public class JetDiagnosticsTestGenerated extends AbstractDiagnosticsTestWithEage JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.GenerateTests", new File("compiler/testData/diagnostics/tests/j+k"), Pattern.compile("^(.+)\\.kt$"), true); } + @TestMetadata("ambiguousSamAdapters.kt") + public void testAmbiguousSamAdapters() throws Exception { + doTest("compiler/testData/diagnostics/tests/j+k/ambiguousSamAdapters.kt"); + } + @TestMetadata("innerNestedClassFromJava.kt") public void testInnerNestedClassFromJava() throws Exception { doTest("compiler/testData/diagnostics/tests/j+k/innerNestedClassFromJava.kt"); diff --git a/compiler/tests/org/jetbrains/jet/jvm/compiler/LoadJavaTestGenerated.java b/compiler/tests/org/jetbrains/jet/jvm/compiler/LoadJavaTestGenerated.java index 65c21f08fae..544c3e4295a 100644 --- a/compiler/tests/org/jetbrains/jet/jvm/compiler/LoadJavaTestGenerated.java +++ b/compiler/tests/org/jetbrains/jet/jvm/compiler/LoadJavaTestGenerated.java @@ -1234,6 +1234,11 @@ public class LoadJavaTestGenerated extends AbstractLoadJavaTest { JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.GenerateTests", new File("compiler/testData/loadJava/compiledJava/singleAbstractMethod/adapter"), Pattern.compile("^(.+)\\.java$"), true); } + @TestMetadata("AmbiguousAdapters.java") + public void testAmbiguousAdapters() throws Exception { + doTestCompiledJava("compiler/testData/loadJava/compiledJava/singleAbstractMethod/adapter/AmbiguousAdapters.java"); + } + @TestMetadata("Basic.java") public void testBasic() throws Exception { doTestCompiledJava("compiler/testData/loadJava/compiledJava/singleAbstractMethod/adapter/Basic.java"); From e8d0022406258634acebf76ae47626efab1753dd Mon Sep 17 00:00:00 2001 From: Evgeny Gerashchenko Date: Tue, 11 Jun 2013 20:04:27 +0400 Subject: [PATCH 200/291] Typo. --- .../jetbrains/jet/codegen/ExpressionCodegen.java | 16 ++++++++-------- .../jet/codegen/ImplementationBodyCodegen.java | 4 ++-- .../jet/codegen/context/CodegenContext.java | 4 ++-- 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java index 3cc14ad907f..8ec6fe63a3c 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java @@ -1629,7 +1629,7 @@ public class ExpressionCodegen extends JetVisitor implem expression.getReferencedNameElementType() == JetTokens.FIELD_IDENTIFIER && contextKind() != OwnerKind.TRAIT_IMPL; JetExpression r = getReceiverForSelector(expression); boolean isSuper = r instanceof JetSuperExpression; - propertyDescriptor = accessablePropertyDescriptor(propertyDescriptor); + propertyDescriptor = accessiblePropertyDescriptor(propertyDescriptor); StackValue iValue = intermediateValueForProperty(propertyDescriptor, directToField, isSuper ? (JetSuperExpression) r : null); if (directToField) { @@ -1800,7 +1800,7 @@ public class ExpressionCodegen extends JetVisitor implem } } - propertyDescriptor = accessablePropertyDescriptor(propertyDescriptor); + propertyDescriptor = accessiblePropertyDescriptor(propertyDescriptor); if (propertyDescriptor.getGetter() != null) { callableGetter = typeMapper @@ -1865,7 +1865,7 @@ public class ExpressionCodegen extends JetVisitor implem throw new UnsupportedOperationException("unknown type of callee descriptor: " + funDescriptor); } - funDescriptor = accessableFunctionDescriptor((FunctionDescriptor) funDescriptor); + funDescriptor = accessibleFunctionDescriptor((FunctionDescriptor) funDescriptor); if (funDescriptor instanceof ConstructorDescriptor) { return generateNewCall(expression, resolvedCall, receiver); @@ -1944,13 +1944,13 @@ public class ExpressionCodegen extends JetVisitor implem } @NotNull - private PropertyDescriptor accessablePropertyDescriptor(PropertyDescriptor propertyDescriptor) { - return context.accessablePropertyDescriptor(propertyDescriptor); + private PropertyDescriptor accessiblePropertyDescriptor(PropertyDescriptor propertyDescriptor) { + return context.accessiblePropertyDescriptor(propertyDescriptor); } @NotNull - protected FunctionDescriptor accessableFunctionDescriptor(FunctionDescriptor fd) { - return context.accessableFunctionDescriptor(fd); + protected FunctionDescriptor accessibleFunctionDescriptor(FunctionDescriptor fd) { + return context.accessibleFunctionDescriptor(fd); } @NotNull @@ -1972,7 +1972,7 @@ public class ExpressionCodegen extends JetVisitor implem } } - fd = accessableFunctionDescriptor(fd); + fd = accessibleFunctionDescriptor(fd); Callable callable = resolveToCallable(fd, superCall); if (callable instanceof CallableMethod) { diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/ImplementationBodyCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/ImplementationBodyCodegen.java index bcdd7a43ffe..d448c99aed9 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/ImplementationBodyCodegen.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/ImplementationBodyCodegen.java @@ -996,7 +996,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { if (state.getClassBuilderMode() == ClassBuilderMode.FULL) { ConstructorDescriptor constructorDescriptor = DescriptorUtils.getConstructorOfSingletonObject(fieldTypeDescriptor); ExpressionCodegen codegen = createOrGetClInitCodegen(); - FunctionDescriptor fd = codegen.accessableFunctionDescriptor(constructorDescriptor); + FunctionDescriptor fd = codegen.accessibleFunctionDescriptor(constructorDescriptor); generateMethodCallTo(fd, codegen.v); field.store(field.type, codegen.v); } @@ -1112,7 +1112,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { //generate object$ parentCodegen.genInitSingleton(descriptor, StackValue.singleton(descriptor, typeMapper)); parentCodegen.generateInitializers(parentCodegen.createOrGetClInitCodegen(), - myClass.getDeclarations(), bindingContext, state); + myClass.getDeclarations(), bindingContext, state); } else { generateInitializers(codegen, myClass.getDeclarations(), bindingContext, state); } diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/context/CodegenContext.java b/compiler/backend/src/org/jetbrains/jet/codegen/context/CodegenContext.java index 32bd32ac879..aaef6ff3338 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/context/CodegenContext.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/context/CodegenContext.java @@ -317,12 +317,12 @@ public abstract class CodegenContext { } @NotNull - public PropertyDescriptor accessablePropertyDescriptor(PropertyDescriptor propertyDescriptor) { + public PropertyDescriptor accessiblePropertyDescriptor(PropertyDescriptor propertyDescriptor) { return (PropertyDescriptor) accessibleDescriptorIfNeeded(propertyDescriptor, true); } @NotNull - public FunctionDescriptor accessableFunctionDescriptor(FunctionDescriptor fd) { + public FunctionDescriptor accessibleFunctionDescriptor(FunctionDescriptor fd) { return (FunctionDescriptor) accessibleDescriptorIfNeeded(fd, true); } From fe77c3edb90dd0fe40642c2470a284b51ad6c771 Mon Sep 17 00:00:00 2001 From: Evgeny Gerashchenko Date: Tue, 11 Jun 2013 20:37:09 +0400 Subject: [PATCH 201/291] Replaced signed decimal with hex. Eliminated querying canonical path. --- .../src/org/jetbrains/jet/codegen/NamespaceCodegen.java | 2 +- .../codegen/topLevelMemberInvocation/extensionFunction/1.kt | 4 ++-- .../topLevelMemberInvocation/functionDifferentPackage/1.kt | 4 ++-- .../functionInMultiFileNamespace/1.kt | 4 ++-- .../codegen/topLevelMemberInvocation/functionSamePackage/1.kt | 4 ++-- .../testData/codegen/topLevelMemberInvocation/property/1.kt | 4 ++-- .../codegen/topLevelMemberInvocation/propertyWithGetter/1.kt | 4 ++-- 7 files changed, 13 insertions(+), 13 deletions(-) diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/NamespaceCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/NamespaceCodegen.java index 2a47158c56b..5240f42a922 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/NamespaceCodegen.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/NamespaceCodegen.java @@ -277,7 +277,7 @@ public class NamespaceCodegen extends MemberCodegen { substringTo = name.length(); } - int pathHashCode = FileUtil.toSystemDependentName(file.getVirtualFile().getCanonicalPath()).hashCode(); + String pathHashCode = Integer.toHexString(FileUtil.toSystemDependentName(file.getVirtualFile().getPath()).hashCode()); // dollar sign in the end is to prevent synthetic class from having "Test" or other parseable suffix // path hashCode to prevent same name / different path collision diff --git a/compiler/testData/codegen/topLevelMemberInvocation/extensionFunction/1.kt b/compiler/testData/codegen/topLevelMemberInvocation/extensionFunction/1.kt index f57bee466e0..d9de048329c 100644 --- a/compiler/testData/codegen/topLevelMemberInvocation/extensionFunction/1.kt +++ b/compiler/testData/codegen/topLevelMemberInvocation/extensionFunction/1.kt @@ -4,5 +4,5 @@ fun test2() { 1.test1() } -// 2 INVOKESTATIC _DefaultPackage\$src\$1\$[\-]*[0-9]*\.test1 \(I\)V -// 1 INVOKESTATIC _DefaultPackage\$src\$1\$[\-]*[0-9]*\.test2 \(\)V \ No newline at end of file +// 2 INVOKESTATIC _DefaultPackage\$src\$1\$[0-9a-f]+\.test1 \(I\)V +// 1 INVOKESTATIC _DefaultPackage\$src\$1\$[0-9a-f]+\.test2 \(\)V \ No newline at end of file diff --git a/compiler/testData/codegen/topLevelMemberInvocation/functionDifferentPackage/1.kt b/compiler/testData/codegen/topLevelMemberInvocation/functionDifferentPackage/1.kt index 43df2e3d042..3112e3b54c5 100644 --- a/compiler/testData/codegen/topLevelMemberInvocation/functionDifferentPackage/1.kt +++ b/compiler/testData/codegen/topLevelMemberInvocation/functionDifferentPackage/1.kt @@ -2,5 +2,5 @@ package a fun test1() {} -// 2 INVOKESTATIC a/APackage\$src\$1\$[\-]*[0-9]*\.test1 \(\)V -// 1 INVOKESTATIC b/BPackage\$src\$2\$[\-]*[0-9]*\.test2 \(\)V \ No newline at end of file +// 2 INVOKESTATIC a/APackage\$src\$1\$[0-9a-f]+\.test1 \(\)V +// 1 INVOKESTATIC b/BPackage\$src\$2\$[0-9a-f]+\.test2 \(\)V \ No newline at end of file diff --git a/compiler/testData/codegen/topLevelMemberInvocation/functionInMultiFileNamespace/1.kt b/compiler/testData/codegen/topLevelMemberInvocation/functionInMultiFileNamespace/1.kt index 01364d196e6..411d63895e8 100644 --- a/compiler/testData/codegen/topLevelMemberInvocation/functionInMultiFileNamespace/1.kt +++ b/compiler/testData/codegen/topLevelMemberInvocation/functionInMultiFileNamespace/1.kt @@ -1,4 +1,4 @@ fun test1() {} -// 2 INVOKESTATIC _DefaultPackage\$src\$1\$[\-]*[0-9]*\.test1 \(\)V -// 1 INVOKESTATIC _DefaultPackage\$src\$2\$[\-]*[0-9]*\.test2 \(\)V \ No newline at end of file +// 2 INVOKESTATIC _DefaultPackage\$src\$1\$[0-9a-f]+\.test1 \(\)V +// 1 INVOKESTATIC _DefaultPackage\$src\$2\$[0-9a-f]+\.test2 \(\)V \ No newline at end of file diff --git a/compiler/testData/codegen/topLevelMemberInvocation/functionSamePackage/1.kt b/compiler/testData/codegen/topLevelMemberInvocation/functionSamePackage/1.kt index 26e8ae92fb0..febbd8f35ff 100644 --- a/compiler/testData/codegen/topLevelMemberInvocation/functionSamePackage/1.kt +++ b/compiler/testData/codegen/topLevelMemberInvocation/functionSamePackage/1.kt @@ -4,5 +4,5 @@ fun test2() { test1() } -// 2 INVOKESTATIC _DefaultPackage\$src\$1\$[\-]*[0-9]*\.test1 \(\)V -// 1 INVOKESTATIC _DefaultPackage\$src\$1\$[\-]*[0-9]*\.test2 \(\)V \ No newline at end of file +// 2 INVOKESTATIC _DefaultPackage\$src\$1\$[0-9a-f]+\.test1 \(\)V +// 1 INVOKESTATIC _DefaultPackage\$src\$1\$[0-9a-f]+\.test2 \(\)V \ No newline at end of file diff --git a/compiler/testData/codegen/topLevelMemberInvocation/property/1.kt b/compiler/testData/codegen/topLevelMemberInvocation/property/1.kt index ca7b4efb10d..b8e7ff8e1ff 100644 --- a/compiler/testData/codegen/topLevelMemberInvocation/property/1.kt +++ b/compiler/testData/codegen/topLevelMemberInvocation/property/1.kt @@ -2,5 +2,5 @@ package a val prop = 1 -// 2 INVOKESTATIC a/APackage\$src\$1\$[\-]*[0-9]*\.getProp \(\)I -// 1 GETSTATIC a/APackage\$src\$1\$[\-]*[0-9]*\.prop \: I \ No newline at end of file +// 2 INVOKESTATIC a/APackage\$src\$1\$[0-9a-f]+\.getProp \(\)I +// 1 GETSTATIC a/APackage\$src\$1\$[0-9a-f]+\.prop \: I \ No newline at end of file diff --git a/compiler/testData/codegen/topLevelMemberInvocation/propertyWithGetter/1.kt b/compiler/testData/codegen/topLevelMemberInvocation/propertyWithGetter/1.kt index a60672a7b5c..9fbe6945525 100644 --- a/compiler/testData/codegen/topLevelMemberInvocation/propertyWithGetter/1.kt +++ b/compiler/testData/codegen/topLevelMemberInvocation/propertyWithGetter/1.kt @@ -5,5 +5,5 @@ val prop: Int = 0 return $prop + 1 } -// 2 INVOKESTATIC a/APackage\$src\$1\$[\-]*[0-9]*\.getProp \(\)I -// 1 GETSTATIC a/APackage\$src\$1\$[\-]*[0-9]*\.prop \: I \ No newline at end of file +// 2 INVOKESTATIC a/APackage\$src\$1\$[0-9a-f]+\.getProp \(\)I +// 1 GETSTATIC a/APackage\$src\$1\$[0-9a-f]+\.prop \: I \ No newline at end of file From 0f067f042f3c8bf839251dacb1b212232ec027e0 Mon Sep 17 00:00:00 2001 From: Evgeny Gerashchenko Date: Thu, 13 Jun 2013 15:30:40 +0400 Subject: [PATCH 202/291] Using more specific class. --- .../src/org/jetbrains/jet/codegen/ExpressionCodegen.java | 6 ++++-- .../src/org/jetbrains/jet/codegen/SamWrapperCodegen.java | 5 +++-- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java index 8ec6fe63a3c..bd8ac50d7b3 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java @@ -54,6 +54,7 @@ import org.jetbrains.jet.lang.resolve.java.AsmTypeConstants; import org.jetbrains.jet.lang.resolve.java.JvmAbi; import org.jetbrains.jet.lang.resolve.java.JvmClassName; import org.jetbrains.jet.lang.resolve.java.JvmPrimitiveType; +import org.jetbrains.jet.lang.resolve.java.descriptor.ClassDescriptorFromJvmBytecode; import org.jetbrains.jet.lang.resolve.java.sam.SingleAbstractMethodUtils; import org.jetbrains.jet.lang.resolve.name.Name; import org.jetbrains.jet.lang.resolve.scopes.receivers.*; @@ -1883,7 +1884,8 @@ public class ExpressionCodegen extends JetVisitor implem BindingContext.SAM_CONSTRUCTOR_TO_INTERFACE, ((SimpleFunctionDescriptor) funDescriptor).getOriginal()); if (samInterface != null) { - return invokeSamConstructor(expression, resolvedCall, (SimpleFunctionDescriptor) funDescriptor, samInterface); + return invokeSamConstructor(expression, resolvedCall, (SimpleFunctionDescriptor) funDescriptor, + (ClassDescriptorFromJvmBytecode) samInterface); } } @@ -1914,7 +1916,7 @@ public class ExpressionCodegen extends JetVisitor implem JetCallExpression expression, ResolvedCall resolvedCall, SimpleFunctionDescriptor funDescriptor, - ClassDescriptor samInterface + ClassDescriptorFromJvmBytecode samInterface ) { ResolvedValueArgument argument = resolvedCall.getValueArgumentsByIndex().get(0); if (!(argument instanceof ExpressionValueArgument)) { diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/SamWrapperCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/SamWrapperCodegen.java index 950b4543c73..a5994abd07e 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/SamWrapperCodegen.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/SamWrapperCodegen.java @@ -34,6 +34,7 @@ import org.jetbrains.jet.lang.psi.JetExpression; import org.jetbrains.jet.lang.resolve.BindingContext; import org.jetbrains.jet.lang.resolve.calls.model.ResolvedCall; import org.jetbrains.jet.lang.resolve.java.JvmClassName; +import org.jetbrains.jet.lang.resolve.java.descriptor.ClassDescriptorFromJvmBytecode; import org.jetbrains.jet.lang.resolve.java.sam.SingleAbstractMethodUtils; import org.jetbrains.jet.lang.resolve.name.Name; import org.jetbrains.jet.lang.types.JetType; @@ -47,9 +48,9 @@ import static org.jetbrains.jet.lang.resolve.java.AsmTypeConstants.OBJECT_TYPE; public class SamWrapperCodegen extends GenerationStateAware { private static final String FUNCTION_FIELD_NAME = "function"; - @NotNull private final ClassDescriptor samInterface; + @NotNull private final ClassDescriptorFromJvmBytecode samInterface; - public SamWrapperCodegen(@NotNull GenerationState state, @NotNull ClassDescriptor samInterface) { + public SamWrapperCodegen(@NotNull GenerationState state, @NotNull ClassDescriptorFromJvmBytecode samInterface) { super(state); this.samInterface = samInterface; } From ba2dae4db716f86d92c556a130b90feb0b963a78 Mon Sep 17 00:00:00 2001 From: Evgeny Gerashchenko Date: Thu, 13 Jun 2013 16:25:09 +0400 Subject: [PATCH 203/291] Removed obsolete comment. --- .../backend/src/org/jetbrains/jet/codegen/NamespaceCodegen.java | 1 - 1 file changed, 1 deletion(-) diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/NamespaceCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/NamespaceCodegen.java index 5240f42a922..08157beac9c 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/NamespaceCodegen.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/NamespaceCodegen.java @@ -279,7 +279,6 @@ public class NamespaceCodegen extends MemberCodegen { String pathHashCode = Integer.toHexString(FileUtil.toSystemDependentName(file.getVirtualFile().getPath()).hashCode()); - // dollar sign in the end is to prevent synthetic class from having "Test" or other parseable suffix // path hashCode to prevent same name / different path collision return namespaceInternalName + "$src$" + replaceSpecialSymbols(name.substring(substringFrom, substringTo)) + "$" + pathHashCode; } From 8a9ec0f3ce5ed6bde51dc8b8fc99f4314a85e3e4 Mon Sep 17 00:00:00 2001 From: Evgeny Gerashchenko Date: Thu, 13 Jun 2013 18:38:39 +0400 Subject: [PATCH 204/291] Added comment. --- .../backend/src/org/jetbrains/jet/codegen/NamespaceCodegen.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/NamespaceCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/NamespaceCodegen.java index 08157beac9c..7eaf6447306 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/NamespaceCodegen.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/NamespaceCodegen.java @@ -277,6 +277,8 @@ public class NamespaceCodegen extends MemberCodegen { substringTo = name.length(); } + // Conversion to system-dependent name seems to be unnecessary, but it's hard to check now: + // it was introduced when fixing KT-2839, which appeared again (KT-3639). String pathHashCode = Integer.toHexString(FileUtil.toSystemDependentName(file.getVirtualFile().getPath()).hashCode()); // path hashCode to prevent same name / different path collision From 7d514bf081419254bd9807bc6ca726b25c52487f Mon Sep 17 00:00:00 2001 From: Evgeny Gerashchenko Date: Thu, 13 Jun 2013 18:42:36 +0400 Subject: [PATCH 205/291] Simplified code. --- .../jet/codegen/NamespaceCodegen.java | 18 +++++++----------- 1 file changed, 7 insertions(+), 11 deletions(-) diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/NamespaceCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/NamespaceCodegen.java index 7eaf6447306..446d64f0a40 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/NamespaceCodegen.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/NamespaceCodegen.java @@ -22,6 +22,7 @@ import com.intellij.openapi.progress.ProcessCanceledException; import com.intellij.openapi.util.io.FileUtil; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.psi.PsiFile; +import com.intellij.util.PathUtil; import org.jetbrains.annotations.NotNull; import org.jetbrains.asm4.AnnotationVisitor; import org.jetbrains.asm4.MethodVisitor; @@ -35,11 +36,13 @@ import org.jetbrains.jet.lang.descriptors.impl.SimpleFunctionDescriptorImpl; import org.jetbrains.jet.lang.diagnostics.DiagnosticUtils; import org.jetbrains.jet.lang.psi.*; import org.jetbrains.jet.lang.resolve.BindingContext; -import org.jetbrains.jet.lang.resolve.java.*; +import org.jetbrains.jet.lang.resolve.java.JvmAbi; +import org.jetbrains.jet.lang.resolve.java.JvmClassName; +import org.jetbrains.jet.lang.resolve.java.JvmStdlibNames; +import org.jetbrains.jet.lang.resolve.java.PackageClassUtils; import org.jetbrains.jet.lang.resolve.name.FqName; import org.jetbrains.jet.lang.resolve.name.Name; -import java.io.File; import java.util.Collection; import java.util.Collections; import java.util.List; @@ -268,21 +271,14 @@ public class NamespaceCodegen extends MemberCodegen { @NotNull private static String getMultiFileNamespaceInternalName(@NotNull String namespaceInternalName, @NotNull PsiFile file) { - String name = FileUtil.toSystemDependentName(file.getName()); - - int substringFrom = name.lastIndexOf(File.separator) + 1; - - int substringTo = name.lastIndexOf('.'); - if (substringTo == -1) { - substringTo = name.length(); - } + String fileName = FileUtil.getNameWithoutExtension(PathUtil.getFileName(file.getName())); // Conversion to system-dependent name seems to be unnecessary, but it's hard to check now: // it was introduced when fixing KT-2839, which appeared again (KT-3639). String pathHashCode = Integer.toHexString(FileUtil.toSystemDependentName(file.getVirtualFile().getPath()).hashCode()); // path hashCode to prevent same name / different path collision - return namespaceInternalName + "$src$" + replaceSpecialSymbols(name.substring(substringFrom, substringTo)) + "$" + pathHashCode; + return namespaceInternalName + "$src$" + replaceSpecialSymbols(fileName) + "$" + pathHashCode; } private static String replaceSpecialSymbols(@NotNull String str) { From 0fbf203ff70a036d1b8b04734032c9dab17b91e2 Mon Sep 17 00:00:00 2001 From: Evgeny Gerashchenko Date: Thu, 13 Jun 2013 19:30:21 +0400 Subject: [PATCH 206/291] Extracted method. --- .../src/org/jetbrains/jet/codegen/CodegenUtil.java | 8 ++++++++ .../src/org/jetbrains/jet/codegen/NamespaceCodegen.java | 7 ++----- 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/CodegenUtil.java b/compiler/backend/src/org/jetbrains/jet/codegen/CodegenUtil.java index 57605e9648f..4d1ca0eb5eb 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/CodegenUtil.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/CodegenUtil.java @@ -17,6 +17,8 @@ package org.jetbrains.jet.codegen; import com.intellij.openapi.util.Condition; +import com.intellij.openapi.util.io.FileUtil; +import com.intellij.psi.PsiFile; import com.intellij.util.containers.ContainerUtil; import com.intellij.util.containers.Stack; import org.jetbrains.annotations.NotNull; @@ -286,4 +288,10 @@ public class CodegenUtil { return ((ImplementationBodyCodegen) classBodyCodegen.getParentCodegen()); } + + static int getPathHashCode(@NotNull PsiFile file) { + // Conversion to system-dependent name seems to be unnecessary, but it's hard to check now: + // it was introduced when fixing KT-2839, which appeared again (KT-3639). + return FileUtil.toSystemDependentName(file.getVirtualFile().getPath()).hashCode(); + } } diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/NamespaceCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/NamespaceCodegen.java index 446d64f0a40..1cfe73b0f10 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/NamespaceCodegen.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/NamespaceCodegen.java @@ -273,12 +273,9 @@ public class NamespaceCodegen extends MemberCodegen { private static String getMultiFileNamespaceInternalName(@NotNull String namespaceInternalName, @NotNull PsiFile file) { String fileName = FileUtil.getNameWithoutExtension(PathUtil.getFileName(file.getName())); - // Conversion to system-dependent name seems to be unnecessary, but it's hard to check now: - // it was introduced when fixing KT-2839, which appeared again (KT-3639). - String pathHashCode = Integer.toHexString(FileUtil.toSystemDependentName(file.getVirtualFile().getPath()).hashCode()); - // path hashCode to prevent same name / different path collision - return namespaceInternalName + "$src$" + replaceSpecialSymbols(fileName) + "$" + pathHashCode; + return namespaceInternalName + "$src$" + replaceSpecialSymbols(fileName) + "$" + Integer.toHexString( + CodegenUtil.getPathHashCode(file)); } private static String replaceSpecialSymbols(@NotNull String str) { From 7ef4c8cfa8c1d4c3bae6ba0e2c719c5f2f6b254a Mon Sep 17 00:00:00 2001 From: Evgeny Gerashchenko Date: Thu, 13 Jun 2013 19:36:26 +0400 Subject: [PATCH 207/291] Generating SAM wrapper class per source file. --- .../jet/codegen/ExpressionCodegen.java | 3 +- .../jet/codegen/SamWrapperClasses.java | 52 +++++++++++++++++ .../jet/codegen/SamWrapperCodegen.java | 57 ++++++++----------- .../jet/codegen/state/GenerationState.java | 8 +++ .../codegen/box/sam/sameWrapperClass.kt | 7 +++ .../samWrappersDifferentFiles/1/wrapped.kt | 4 ++ .../samWrappersDifferentFiles/2/wrapped.kt | 4 ++ .../samWrappersDifferentFiles/box.kt | 6 ++ .../BlackBoxCodegenTestGenerated.java | 5 ++ ...BlackBoxMultiFileCodegenTestGenerated.java | 5 ++ 10 files changed, 118 insertions(+), 33 deletions(-) create mode 100644 compiler/backend/src/org/jetbrains/jet/codegen/SamWrapperClasses.java create mode 100644 compiler/testData/codegen/box/sam/sameWrapperClass.kt create mode 100644 compiler/testData/codegen/boxMultiFile/samWrappersDifferentFiles/1/wrapped.kt create mode 100644 compiler/testData/codegen/boxMultiFile/samWrappersDifferentFiles/2/wrapped.kt create mode 100644 compiler/testData/codegen/boxMultiFile/samWrappersDifferentFiles/box.kt diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java index bd8ac50d7b3..b7cc9516fc1 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java @@ -1931,7 +1931,8 @@ public class ExpressionCodegen extends JetVisitor implem return genClosure(((JetFunctionLiteralExpression) argumentExpression).getFunctionLiteral(), samInterface); } else { - JvmClassName className = new SamWrapperCodegen(state, samInterface).genWrapper(expression, argumentExpression); + JvmClassName className = + state.getSamWrapperClasses().getSamWrapperClass(samInterface, (JetFile) expression.getContainingFile()); v.anew(className.getAsmType()); v.dup(); diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/SamWrapperClasses.java b/compiler/backend/src/org/jetbrains/jet/codegen/SamWrapperClasses.java new file mode 100644 index 00000000000..874ac019ee8 --- /dev/null +++ b/compiler/backend/src/org/jetbrains/jet/codegen/SamWrapperClasses.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.codegen; + +import com.google.common.collect.Maps; +import com.intellij.openapi.util.Factory; +import com.intellij.openapi.util.Pair; +import com.intellij.util.containers.ContainerUtil; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.jet.codegen.state.GenerationState; +import org.jetbrains.jet.lang.descriptors.ClassDescriptor; +import org.jetbrains.jet.lang.psi.JetExpression; +import org.jetbrains.jet.lang.psi.JetFile; +import org.jetbrains.jet.lang.resolve.java.JvmClassName; +import org.jetbrains.jet.lang.resolve.java.descriptor.ClassDescriptorFromJvmBytecode; + +import java.util.Map; + +public class SamWrapperClasses { + private final GenerationState state; + + private final Map, JvmClassName> samInterfaceToWrapperClass = Maps.newHashMap(); + + public SamWrapperClasses(GenerationState state) { + this.state = state; + } + + @NotNull + public JvmClassName getSamWrapperClass(@NotNull final ClassDescriptorFromJvmBytecode samInterface, @NotNull final JetFile file) { + return ContainerUtil.getOrCreate(samInterfaceToWrapperClass, Pair.create(samInterface, file), + new Factory() { + @Override + public JvmClassName create() { + return new SamWrapperCodegen(state, samInterface).genWrapper(file); + } + }); + } +} diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/SamWrapperCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/SamWrapperCodegen.java index a5994abd07e..a5e14687a70 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/SamWrapperCodegen.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/SamWrapperCodegen.java @@ -20,25 +20,23 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.asm4.MethodVisitor; import org.jetbrains.asm4.Type; import org.jetbrains.asm4.commons.InstructionAdapter; -import org.jetbrains.jet.codegen.binding.CodegenBinding; import org.jetbrains.jet.codegen.context.CodegenContext; import org.jetbrains.jet.codegen.state.GenerationState; import org.jetbrains.jet.codegen.state.GenerationStateAware; import org.jetbrains.jet.codegen.state.JetTypeMapperMode; -import org.jetbrains.jet.lang.descriptors.CallableDescriptor; -import org.jetbrains.jet.lang.descriptors.ClassDescriptor; import org.jetbrains.jet.lang.descriptors.FunctionDescriptor; +import org.jetbrains.jet.lang.descriptors.NamespaceDescriptor; import org.jetbrains.jet.lang.descriptors.SimpleFunctionDescriptor; -import org.jetbrains.jet.lang.psi.JetCallExpression; -import org.jetbrains.jet.lang.psi.JetExpression; +import org.jetbrains.jet.lang.psi.JetFile; import org.jetbrains.jet.lang.resolve.BindingContext; -import org.jetbrains.jet.lang.resolve.calls.model.ResolvedCall; +import org.jetbrains.jet.lang.resolve.DescriptorUtils; import org.jetbrains.jet.lang.resolve.java.JvmClassName; +import org.jetbrains.jet.lang.resolve.java.PackageClassUtils; import org.jetbrains.jet.lang.resolve.java.descriptor.ClassDescriptorFromJvmBytecode; import org.jetbrains.jet.lang.resolve.java.sam.SingleAbstractMethodUtils; +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.lang.KotlinBuiltIns; import static org.jetbrains.asm4.Opcodes.*; import static org.jetbrains.jet.codegen.AsmUtil.NO_FLAG_PACKAGE_PRIVATE; @@ -55,33 +53,18 @@ public class SamWrapperCodegen extends GenerationStateAware { this.samInterface = samInterface; } - public JvmClassName genWrapper(JetCallExpression callExpression, JetExpression argumentExpression) { - // Example: we generate SAM constructor call Comparator(f), where f: (Int, Int) -> Int - + public JvmClassName genWrapper(@NotNull JetFile file) { // Name for generated class, in form of whatever$1 - JvmClassName name = bindingContext.get(CodegenBinding.FQN_FOR_SAM_CONSTRUCTOR, callExpression); - assert name != null : "internal class name not found for " + callExpression.getText(); + JvmClassName name = JvmClassName.byInternalName(getWrapperName(file)); - // e.g. (Int, Int) -> Int - JetType functionType = bindingContext.get(BindingContext.EXPRESSION_TYPE, argumentExpression); - assert functionType != null && KotlinBuiltIns.getInstance().isFunctionType(functionType) : - "not a function type of " + argumentExpression.getText() + ": " + functionType; + // e.g. (T, T) -> Int + JetType functionType = samInterface.getFunctionTypeForSamInterface(); + assert functionType != null : samInterface.toString(); + // e.g. compare(T, T) + SimpleFunctionDescriptor interfaceFunction = SingleAbstractMethodUtils.getAbstractMethodOfSamInterface(samInterface); - // SAM constructor call - ResolvedCall resolvedCall = - bindingContext.get(BindingContext.RESOLVED_CALL, callExpression.getCalleeExpression()); - assert resolvedCall != null : "couldn't find resolved call for " + callExpression.getText(); - - // e.g. Comparator - JetType resultType = resolvedCall.getResultingDescriptor().getReturnType(); - assert resultType != null && resultType.getConstructor() == samInterface.getTypeConstructor() : - "unexpected result type: " + resultType; - - // e.g. compare(Int, Int) - SimpleFunctionDescriptor interfaceFunction = SingleAbstractMethodUtils.getAbstractMethodOfSamType(resultType); - - ClassBuilder cv = state.getFactory().newVisitor(name.getInternalName(), callExpression.getContainingFile()); - cv.defineClass(callExpression, + ClassBuilder cv = state.getFactory().newVisitor(name.getInternalName(), file); + cv.defineClass(file, V1_6, ACC_FINAL, name.getInternalName(), @@ -89,7 +72,7 @@ public class SamWrapperCodegen extends GenerationStateAware { OBJECT_TYPE.getInternalName(), new String[]{JvmClassName.byClassDescriptor(samInterface).getInternalName()} ); - cv.visitSource(callExpression.getContainingFile().getName(), null); + cv.visitSource(file.getName(), null); // e.g. ASM type for Function2 Type functionAsmType = state.getTypeMapper().mapType(functionType, JetTypeMapperMode.VALUE); @@ -149,4 +132,14 @@ public class SamWrapperCodegen extends GenerationStateAware { StackValue functionField = StackValue.field(functionType, JvmClassName.byType(ownerType), FUNCTION_FIELD_NAME, false); codegen.genDelegate(interfaceFunction, invokeFunction, functionField); } + + private String getWrapperName(@NotNull JetFile containingFile) { + NamespaceDescriptor namespace = state.getBindingContext().get(BindingContext.FILE_TO_NAMESPACE, containingFile); + assert namespace != null : "couldn't find namespace for file: " + containingFile.getVirtualFile(); + FqName fqName = DescriptorUtils.getFQName(namespace).toSafe(); + String packageInternalName = JvmClassName.byFqNameWithoutInnerClasses( + PackageClassUtils.getPackageClassFqName(fqName)).getInternalName(); + return packageInternalName + "$sam$" + samInterface.getName().asString() + + "$" + Integer.toHexString(CodegenUtil.getPathHashCode(containingFile)); // TODO add class FQ name hash + } } diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/state/GenerationState.java b/compiler/backend/src/org/jetbrains/jet/codegen/state/GenerationState.java index 1ae5760d4a5..671a889855a 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/state/GenerationState.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/state/GenerationState.java @@ -56,6 +56,9 @@ public class GenerationState { @NotNull private final IntrinsicMethods intrinsics; + @NotNull + private final SamWrapperClasses samWrapperClasses = new SamWrapperClasses(this); + @NotNull private final BindingTrace bindingTrace; @@ -154,6 +157,11 @@ public class GenerationState { return intrinsics; } + @NotNull + public SamWrapperClasses getSamWrapperClasses() { + return samWrapperClasses; + } + public boolean isGenerateNotNullAssertions() { return generateNotNullAssertions; } diff --git a/compiler/testData/codegen/box/sam/sameWrapperClass.kt b/compiler/testData/codegen/box/sam/sameWrapperClass.kt new file mode 100644 index 00000000000..aa83e109082 --- /dev/null +++ b/compiler/testData/codegen/box/sam/sameWrapperClass.kt @@ -0,0 +1,7 @@ +fun box(): String { + val f = { } + val class1 = Runnable(f).getClass() + val class2 = Runnable(f).getClass() + + return if (class1 == class2) "OK" else "$class1 $class2" +} \ No newline at end of file diff --git a/compiler/testData/codegen/boxMultiFile/samWrappersDifferentFiles/1/wrapped.kt b/compiler/testData/codegen/boxMultiFile/samWrappersDifferentFiles/1/wrapped.kt new file mode 100644 index 00000000000..733fce7706e --- /dev/null +++ b/compiler/testData/codegen/boxMultiFile/samWrappersDifferentFiles/1/wrapped.kt @@ -0,0 +1,4 @@ +fun getWrapped1(): Runnable { + val f = { } + return Runnable(f) +} diff --git a/compiler/testData/codegen/boxMultiFile/samWrappersDifferentFiles/2/wrapped.kt b/compiler/testData/codegen/boxMultiFile/samWrappersDifferentFiles/2/wrapped.kt new file mode 100644 index 00000000000..4abed42b27f --- /dev/null +++ b/compiler/testData/codegen/boxMultiFile/samWrappersDifferentFiles/2/wrapped.kt @@ -0,0 +1,4 @@ +fun getWrapped2(): Runnable { + val f = { } + return Runnable(f) +} diff --git a/compiler/testData/codegen/boxMultiFile/samWrappersDifferentFiles/box.kt b/compiler/testData/codegen/boxMultiFile/samWrappersDifferentFiles/box.kt new file mode 100644 index 00000000000..86dca7f11b8 --- /dev/null +++ b/compiler/testData/codegen/boxMultiFile/samWrappersDifferentFiles/box.kt @@ -0,0 +1,6 @@ +fun box(): String { + val class1 = getWrapped1().getClass() + val class2 = getWrapped2().getClass() + + return if (class1 != class2) "OK" else "Same class: $class1" +} \ 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 784f1355c8f..ade9d8142e4 100644 --- a/compiler/tests/org/jetbrains/jet/codegen/generated/BlackBoxCodegenTestGenerated.java +++ b/compiler/tests/org/jetbrains/jet/codegen/generated/BlackBoxCodegenTestGenerated.java @@ -3756,6 +3756,11 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest { doTest("compiler/testData/codegen/box/sam/runnableAccessingClosure2.kt"); } + @TestMetadata("sameWrapperClass.kt") + public void testSameWrapperClass() throws Exception { + doTest("compiler/testData/codegen/box/sam/sameWrapperClass.kt"); + } + @TestMetadata("syntheticVsReal.kt") public void testSyntheticVsReal() throws Exception { doTest("compiler/testData/codegen/box/sam/syntheticVsReal.kt"); diff --git a/compiler/tests/org/jetbrains/jet/codegen/generated/BlackBoxMultiFileCodegenTestGenerated.java b/compiler/tests/org/jetbrains/jet/codegen/generated/BlackBoxMultiFileCodegenTestGenerated.java index 84c13b424a5..533525829da 100644 --- a/compiler/tests/org/jetbrains/jet/codegen/generated/BlackBoxMultiFileCodegenTestGenerated.java +++ b/compiler/tests/org/jetbrains/jet/codegen/generated/BlackBoxMultiFileCodegenTestGenerated.java @@ -71,6 +71,11 @@ public class BlackBoxMultiFileCodegenTestGenerated extends AbstractBlackBoxCodeg doTestMultiFile("compiler/testData/codegen/boxMultiFile/nestedPackages"); } + @TestMetadata("samWrappersDifferentFiles") + public void testSamWrappersDifferentFiles() throws Exception { + doTestMultiFile("compiler/testData/codegen/boxMultiFile/samWrappersDifferentFiles"); + } + @TestMetadata("sameFileName") public void testSameFileName() throws Exception { doTestMultiFile("compiler/testData/codegen/boxMultiFile/sameFileName"); From be029436758e08f3e06e8ec5c3d4fac1d827b8a8 Mon Sep 17 00:00:00 2001 From: Evgeny Gerashchenko Date: Thu, 13 Jun 2013 19:55:12 +0400 Subject: [PATCH 208/291] Considering SAM interface FQ name in hash. --- .../jetbrains/jet/codegen/SamWrapperCodegen.java | 4 ++-- .../samWrappers/differentFqNames.java | 5 +++++ .../boxWithJava/samWrappers/differentFqNames.kt | 7 +++++++ .../BlackBoxWithJavaCodegenTestGenerated.java | 16 +++++++++++++++- 4 files changed, 29 insertions(+), 3 deletions(-) create mode 100644 compiler/testData/codegen/boxWithJava/samWrappers/differentFqNames.java create mode 100644 compiler/testData/codegen/boxWithJava/samWrappers/differentFqNames.kt diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/SamWrapperCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/SamWrapperCodegen.java index a5e14687a70..1e90036254c 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/SamWrapperCodegen.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/SamWrapperCodegen.java @@ -139,7 +139,7 @@ public class SamWrapperCodegen extends GenerationStateAware { FqName fqName = DescriptorUtils.getFQName(namespace).toSafe(); String packageInternalName = JvmClassName.byFqNameWithoutInnerClasses( PackageClassUtils.getPackageClassFqName(fqName)).getInternalName(); - return packageInternalName + "$sam$" + samInterface.getName().asString() + - "$" + Integer.toHexString(CodegenUtil.getPathHashCode(containingFile)); // TODO add class FQ name hash + return packageInternalName + "$sam$" + samInterface.getName().asString() + "$" + + Integer.toHexString(CodegenUtil.getPathHashCode(containingFile) * 31 + DescriptorUtils.getFQName(samInterface).hashCode()); } } diff --git a/compiler/testData/codegen/boxWithJava/samWrappers/differentFqNames.java b/compiler/testData/codegen/boxWithJava/samWrappers/differentFqNames.java new file mode 100644 index 00000000000..c6f8175bd8b --- /dev/null +++ b/compiler/testData/codegen/boxWithJava/samWrappers/differentFqNames.java @@ -0,0 +1,5 @@ +class Custom { + public interface Runnable { + void run2(); + } +} \ No newline at end of file diff --git a/compiler/testData/codegen/boxWithJava/samWrappers/differentFqNames.kt b/compiler/testData/codegen/boxWithJava/samWrappers/differentFqNames.kt new file mode 100644 index 00000000000..ffc5045d17d --- /dev/null +++ b/compiler/testData/codegen/boxWithJava/samWrappers/differentFqNames.kt @@ -0,0 +1,7 @@ +fun box(): String { + val f = { } + val class1 = Runnable(f).getClass() + val class2 = Custom.Runnable(f).getClass() + + return if (class1 != class2) "OK" else "Same class: $class1" +} \ No newline at end of file diff --git a/compiler/tests/org/jetbrains/jet/codegen/generated/BlackBoxWithJavaCodegenTestGenerated.java b/compiler/tests/org/jetbrains/jet/codegen/generated/BlackBoxWithJavaCodegenTestGenerated.java index 803f18aef84..ad0e4845f5a 100644 --- a/compiler/tests/org/jetbrains/jet/codegen/generated/BlackBoxWithJavaCodegenTestGenerated.java +++ b/compiler/tests/org/jetbrains/jet/codegen/generated/BlackBoxWithJavaCodegenTestGenerated.java @@ -31,7 +31,7 @@ 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/boxWithJava") -@InnerTestClasses({BlackBoxWithJavaCodegenTestGenerated.CallableReference.class, BlackBoxWithJavaCodegenTestGenerated.Enum.class, BlackBoxWithJavaCodegenTestGenerated.Functions.class, BlackBoxWithJavaCodegenTestGenerated.Property.class, BlackBoxWithJavaCodegenTestGenerated.SamAdapters.class, BlackBoxWithJavaCodegenTestGenerated.StaticFun.class, BlackBoxWithJavaCodegenTestGenerated.Visibility.class}) +@InnerTestClasses({BlackBoxWithJavaCodegenTestGenerated.CallableReference.class, BlackBoxWithJavaCodegenTestGenerated.Enum.class, BlackBoxWithJavaCodegenTestGenerated.Functions.class, BlackBoxWithJavaCodegenTestGenerated.Property.class, BlackBoxWithJavaCodegenTestGenerated.SamAdapters.class, BlackBoxWithJavaCodegenTestGenerated.SamWrappers.class, BlackBoxWithJavaCodegenTestGenerated.StaticFun.class, BlackBoxWithJavaCodegenTestGenerated.Visibility.class}) public class BlackBoxWithJavaCodegenTestGenerated extends AbstractBlackBoxCodegenTest { public void testAllFilesPresentInBoxWithJava() throws Exception { JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.GenerateTests", new File("compiler/testData/codegen/boxWithJava"), Pattern.compile("^(.+)\\.kt$"), true); @@ -182,6 +182,19 @@ public class BlackBoxWithJavaCodegenTestGenerated extends AbstractBlackBoxCodege } + @TestMetadata("compiler/testData/codegen/boxWithJava/samWrappers") + public static class SamWrappers extends AbstractBlackBoxCodegenTest { + public void testAllFilesPresentInSamWrappers() throws Exception { + JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.GenerateTests", new File("compiler/testData/codegen/boxWithJava/samWrappers"), Pattern.compile("^(.+)\\.kt$"), true); + } + + @TestMetadata("differentFqNames.kt") + public void testDifferentFqNames() throws Exception { + doTestWithJava("compiler/testData/codegen/boxWithJava/samWrappers/differentFqNames.kt"); + } + + } + @TestMetadata("compiler/testData/codegen/boxWithJava/staticFun") public static class StaticFun extends AbstractBlackBoxCodegenTest { public void testAllFilesPresentInStaticFun() throws Exception { @@ -344,6 +357,7 @@ public class BlackBoxWithJavaCodegenTestGenerated extends AbstractBlackBoxCodege suite.addTestSuite(Functions.class); suite.addTestSuite(Property.class); suite.addTestSuite(SamAdapters.class); + suite.addTestSuite(SamWrappers.class); suite.addTestSuite(StaticFun.class); suite.addTest(Visibility.innerSuite()); return suite; From 2e2061d9b6fd937807ba69bd09ec9733dc1b93fc Mon Sep 17 00:00:00 2001 From: Evgeny Gerashchenko Date: Sat, 22 Jun 2013 14:59:57 +0400 Subject: [PATCH 209/291] Clarified comment. --- compiler/backend/src/org/jetbrains/jet/codegen/CodegenUtil.java | 1 + 1 file changed, 1 insertion(+) diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/CodegenUtil.java b/compiler/backend/src/org/jetbrains/jet/codegen/CodegenUtil.java index 4d1ca0eb5eb..740e2574d9e 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/CodegenUtil.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/CodegenUtil.java @@ -292,6 +292,7 @@ public class CodegenUtil { static int getPathHashCode(@NotNull PsiFile file) { // Conversion to system-dependent name seems to be unnecessary, but it's hard to check now: // it was introduced when fixing KT-2839, which appeared again (KT-3639). + // If you try to remove it, run tests on Windows. return FileUtil.toSystemDependentName(file.getVirtualFile().getPath()).hashCode(); } } From ee9fcff9caea43073f19180c1fe4b043d2fb89d8 Mon Sep 17 00:00:00 2001 From: Evgeny Gerashchenko Date: Thu, 13 Jun 2013 20:16:47 +0400 Subject: [PATCH 210/291] Supported non-literal arguments for SAM adapters. --- .../jet/codegen/ExpressionCodegen.java | 21 ++++++++++++------- .../nonLiteralAndLiteralRunnable.java | 6 ++++++ .../nonLiteralAndLiteralRunnable.kt | 6 ++++++ .../samAdapters/nonLiteralComparator.java | 7 +++++++ .../samAdapters/nonLiteralComparator.kt | 10 +++++++++ .../samAdapters/nonLiteralInConstructor.java | 11 ++++++++++ .../samAdapters/nonLiteralInConstructor.kt | 6 ++++++ .../samAdapters/nonLiteralRunnable.java | 5 +++++ .../samAdapters/nonLiteralRunnable.kt | 6 ++++++ .../BlackBoxWithJavaCodegenTestGenerated.java | 20 ++++++++++++++++++ 10 files changed, 90 insertions(+), 8 deletions(-) create mode 100644 compiler/testData/codegen/boxWithJava/samAdapters/nonLiteralAndLiteralRunnable.java create mode 100644 compiler/testData/codegen/boxWithJava/samAdapters/nonLiteralAndLiteralRunnable.kt create mode 100644 compiler/testData/codegen/boxWithJava/samAdapters/nonLiteralComparator.java create mode 100644 compiler/testData/codegen/boxWithJava/samAdapters/nonLiteralComparator.kt create mode 100644 compiler/testData/codegen/boxWithJava/samAdapters/nonLiteralInConstructor.java create mode 100644 compiler/testData/codegen/boxWithJava/samAdapters/nonLiteralInConstructor.kt create mode 100644 compiler/testData/codegen/boxWithJava/samAdapters/nonLiteralRunnable.java create mode 100644 compiler/testData/codegen/boxWithJava/samAdapters/nonLiteralRunnable.kt diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java index b7cc9516fc1..32a661118b1 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java @@ -1884,8 +1884,7 @@ public class ExpressionCodegen extends JetVisitor implem BindingContext.SAM_CONSTRUCTOR_TO_INTERFACE, ((SimpleFunctionDescriptor) funDescriptor).getOriginal()); if (samInterface != null) { - return invokeSamConstructor(expression, resolvedCall, (SimpleFunctionDescriptor) funDescriptor, - (ClassDescriptorFromJvmBytecode) samInterface); + return invokeSamConstructor(expression, resolvedCall, (ClassDescriptorFromJvmBytecode) samInterface); } } @@ -1915,7 +1914,6 @@ public class ExpressionCodegen extends JetVisitor implem private StackValue invokeSamConstructor( JetCallExpression expression, ResolvedCall resolvedCall, - SimpleFunctionDescriptor funDescriptor, ClassDescriptorFromJvmBytecode samInterface ) { ResolvedValueArgument argument = resolvedCall.getValueArgumentsByIndex().get(0); @@ -1926,18 +1924,26 @@ public class ExpressionCodegen extends JetVisitor implem ValueArgument valueArgument = ((ExpressionValueArgument) argument).getValueArgument(); assert valueArgument != null : "getValueArgument() is null for " + expression.getText(); JetExpression argumentExpression = valueArgument.getArgumentExpression(); + assert argumentExpression != null : "getArgumentExpression() is null for " + expression.getText(); + return genSamInterfaceValue(argumentExpression, samInterface); + } + + private StackValue genSamInterfaceValue( + @NotNull JetExpression argumentExpression, + @NotNull ClassDescriptorFromJvmBytecode samInterface + ) { if (argumentExpression instanceof JetFunctionLiteralExpression) { return genClosure(((JetFunctionLiteralExpression) argumentExpression).getFunctionLiteral(), samInterface); } else { JvmClassName className = - state.getSamWrapperClasses().getSamWrapperClass(samInterface, (JetFile) expression.getContainingFile()); + state.getSamWrapperClasses().getSamWrapperClass(samInterface, (JetFile) argumentExpression.getContainingFile()); v.anew(className.getAsmType()); v.dup(); - JetType functionType = funDescriptor.getValueParameters().get(0).getType(); + JetType functionType = samInterface.getFunctionTypeForSamInterface(); gen(argumentExpression, typeMapper.mapType(functionType)); v.invokespecial(className.getInternalName(), "", @@ -2309,10 +2315,9 @@ public class ExpressionCodegen extends JetVisitor implem if (originalOfSamAdapter != null) { JetType samAdapterType = originalOfSamAdapter.getValueParameters().get(valueParameter.getIndex()).getType(); if (SingleAbstractMethodUtils.isSamType(samAdapterType)) { - ClassDescriptor samInterface = (ClassDescriptor) samAdapterType.getConstructor().getDeclarationDescriptor(); + ClassDescriptorFromJvmBytecode samInterface = (ClassDescriptorFromJvmBytecode) samAdapterType.getConstructor().getDeclarationDescriptor(); - // TODO support not literals - genClosure(((JetFunctionLiteralExpression) argumentExpression).getFunctionLiteral(), samInterface); + genSamInterfaceValue(argumentExpression, samInterface); continue; } } diff --git a/compiler/testData/codegen/boxWithJava/samAdapters/nonLiteralAndLiteralRunnable.java b/compiler/testData/codegen/boxWithJava/samAdapters/nonLiteralAndLiteralRunnable.java new file mode 100644 index 00000000000..b740457a32c --- /dev/null +++ b/compiler/testData/codegen/boxWithJava/samAdapters/nonLiteralAndLiteralRunnable.java @@ -0,0 +1,6 @@ +class JavaClass { + public static void run(Runnable r1, Runnable r2) { + r1.run(); + r2.run(); + } +} \ No newline at end of file diff --git a/compiler/testData/codegen/boxWithJava/samAdapters/nonLiteralAndLiteralRunnable.kt b/compiler/testData/codegen/boxWithJava/samAdapters/nonLiteralAndLiteralRunnable.kt new file mode 100644 index 00000000000..433f6d04e4b --- /dev/null +++ b/compiler/testData/codegen/boxWithJava/samAdapters/nonLiteralAndLiteralRunnable.kt @@ -0,0 +1,6 @@ +fun box(): String { + var v = "FAIL" + val f = { v = "O" } + JavaClass.run(f, { v += "K" }) + return v +} \ No newline at end of file diff --git a/compiler/testData/codegen/boxWithJava/samAdapters/nonLiteralComparator.java b/compiler/testData/codegen/boxWithJava/samAdapters/nonLiteralComparator.java new file mode 100644 index 00000000000..1d6843c1a82 --- /dev/null +++ b/compiler/testData/codegen/boxWithJava/samAdapters/nonLiteralComparator.java @@ -0,0 +1,7 @@ +import java.util.*; + +class JavaClass { + public static void sortIntList(List list, Comparator comparator) { + Collections.sort(list, comparator); + } +} \ No newline at end of file diff --git a/compiler/testData/codegen/boxWithJava/samAdapters/nonLiteralComparator.kt b/compiler/testData/codegen/boxWithJava/samAdapters/nonLiteralComparator.kt new file mode 100644 index 00000000000..084a31ab8f4 --- /dev/null +++ b/compiler/testData/codegen/boxWithJava/samAdapters/nonLiteralComparator.kt @@ -0,0 +1,10 @@ +import java.util.* + +fun box(): String { + val list = ArrayList(Arrays.asList(3, 2, 4, 8, 1, 5)) + val expected = ArrayList(Arrays.asList(8, 5, 4, 3, 2, 1)) + + val f = { (a: Int, b: Int) -> b - a } + JavaClass.sortIntList(list, f) + return if (list == expected) "OK" else list.toString() +} \ No newline at end of file diff --git a/compiler/testData/codegen/boxWithJava/samAdapters/nonLiteralInConstructor.java b/compiler/testData/codegen/boxWithJava/samAdapters/nonLiteralInConstructor.java new file mode 100644 index 00000000000..c47e8ab052e --- /dev/null +++ b/compiler/testData/codegen/boxWithJava/samAdapters/nonLiteralInConstructor.java @@ -0,0 +1,11 @@ +class JavaClass { + private Runnable r; + + public JavaClass(Runnable r) { + this.r = r; + } + + public void run() { + r.run(); + } +} \ No newline at end of file diff --git a/compiler/testData/codegen/boxWithJava/samAdapters/nonLiteralInConstructor.kt b/compiler/testData/codegen/boxWithJava/samAdapters/nonLiteralInConstructor.kt new file mode 100644 index 00000000000..9d2e9a4f8b7 --- /dev/null +++ b/compiler/testData/codegen/boxWithJava/samAdapters/nonLiteralInConstructor.kt @@ -0,0 +1,6 @@ +fun box(): String { + var v = "FAIL" + val f = { v = "OK" } + JavaClass(f).run() + return v +} \ No newline at end of file diff --git a/compiler/testData/codegen/boxWithJava/samAdapters/nonLiteralRunnable.java b/compiler/testData/codegen/boxWithJava/samAdapters/nonLiteralRunnable.java new file mode 100644 index 00000000000..3860797a795 --- /dev/null +++ b/compiler/testData/codegen/boxWithJava/samAdapters/nonLiteralRunnable.java @@ -0,0 +1,5 @@ +class JavaClass { + public static void run(Runnable r) { + r.run(); + } +} \ No newline at end of file diff --git a/compiler/testData/codegen/boxWithJava/samAdapters/nonLiteralRunnable.kt b/compiler/testData/codegen/boxWithJava/samAdapters/nonLiteralRunnable.kt new file mode 100644 index 00000000000..093a7879ce5 --- /dev/null +++ b/compiler/testData/codegen/boxWithJava/samAdapters/nonLiteralRunnable.kt @@ -0,0 +1,6 @@ +fun box(): String { + var v = "FAIL" + val f = { v = "OK" } + JavaClass.run(f) + return v +} \ No newline at end of file diff --git a/compiler/tests/org/jetbrains/jet/codegen/generated/BlackBoxWithJavaCodegenTestGenerated.java b/compiler/tests/org/jetbrains/jet/codegen/generated/BlackBoxWithJavaCodegenTestGenerated.java index ad0e4845f5a..7459f66bff5 100644 --- a/compiler/tests/org/jetbrains/jet/codegen/generated/BlackBoxWithJavaCodegenTestGenerated.java +++ b/compiler/tests/org/jetbrains/jet/codegen/generated/BlackBoxWithJavaCodegenTestGenerated.java @@ -155,6 +155,26 @@ public class BlackBoxWithJavaCodegenTestGenerated extends AbstractBlackBoxCodege doTestWithJava("compiler/testData/codegen/boxWithJava/samAdapters/fileFilter.kt"); } + @TestMetadata("nonLiteralAndLiteralRunnable.kt") + public void testNonLiteralAndLiteralRunnable() throws Exception { + doTestWithJava("compiler/testData/codegen/boxWithJava/samAdapters/nonLiteralAndLiteralRunnable.kt"); + } + + @TestMetadata("nonLiteralComparator.kt") + public void testNonLiteralComparator() throws Exception { + doTestWithJava("compiler/testData/codegen/boxWithJava/samAdapters/nonLiteralComparator.kt"); + } + + @TestMetadata("nonLiteralInConstructor.kt") + public void testNonLiteralInConstructor() throws Exception { + doTestWithJava("compiler/testData/codegen/boxWithJava/samAdapters/nonLiteralInConstructor.kt"); + } + + @TestMetadata("nonLiteralRunnable.kt") + public void testNonLiteralRunnable() throws Exception { + doTestWithJava("compiler/testData/codegen/boxWithJava/samAdapters/nonLiteralRunnable.kt"); + } + @TestMetadata("severalSamParameters.kt") public void testSeveralSamParameters() throws Exception { doTestWithJava("compiler/testData/codegen/boxWithJava/samAdapters/severalSamParameters.kt"); From d78f36a780b29621e672e5d0888eee0a872b0afa Mon Sep 17 00:00:00 2001 From: Evgeny Gerashchenko Date: Thu, 13 Jun 2013 20:35:09 +0400 Subject: [PATCH 211/291] Minor. Renamed test. --- .../{cantCallInherited.java => inheritedSimple.java} | 0 .../{cantCallInherited.kt => inheritedSimple.kt} | 0 .../BlackBoxWithJavaCodegenTestGenerated.java | 10 +++++----- 3 files changed, 5 insertions(+), 5 deletions(-) rename compiler/testData/codegen/boxWithJava/samAdapters/{cantCallInherited.java => inheritedSimple.java} (100%) rename compiler/testData/codegen/boxWithJava/samAdapters/{cantCallInherited.kt => inheritedSimple.kt} (100%) diff --git a/compiler/testData/codegen/boxWithJava/samAdapters/cantCallInherited.java b/compiler/testData/codegen/boxWithJava/samAdapters/inheritedSimple.java similarity index 100% rename from compiler/testData/codegen/boxWithJava/samAdapters/cantCallInherited.java rename to compiler/testData/codegen/boxWithJava/samAdapters/inheritedSimple.java diff --git a/compiler/testData/codegen/boxWithJava/samAdapters/cantCallInherited.kt b/compiler/testData/codegen/boxWithJava/samAdapters/inheritedSimple.kt similarity index 100% rename from compiler/testData/codegen/boxWithJava/samAdapters/cantCallInherited.kt rename to compiler/testData/codegen/boxWithJava/samAdapters/inheritedSimple.kt diff --git a/compiler/tests/org/jetbrains/jet/codegen/generated/BlackBoxWithJavaCodegenTestGenerated.java b/compiler/tests/org/jetbrains/jet/codegen/generated/BlackBoxWithJavaCodegenTestGenerated.java index 7459f66bff5..5b1c2e481f1 100644 --- a/compiler/tests/org/jetbrains/jet/codegen/generated/BlackBoxWithJavaCodegenTestGenerated.java +++ b/compiler/tests/org/jetbrains/jet/codegen/generated/BlackBoxWithJavaCodegenTestGenerated.java @@ -135,11 +135,6 @@ public class BlackBoxWithJavaCodegenTestGenerated extends AbstractBlackBoxCodege JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.GenerateTests", new File("compiler/testData/codegen/boxWithJava/samAdapters"), Pattern.compile("^(.+)\\.kt$"), true); } - @TestMetadata("cantCallInherited.kt") - public void testCantCallInherited() throws Exception { - doTestWithJava("compiler/testData/codegen/boxWithJava/samAdapters/cantCallInherited.kt"); - } - @TestMetadata("comparator.kt") public void testComparator() throws Exception { doTestWithJava("compiler/testData/codegen/boxWithJava/samAdapters/comparator.kt"); @@ -155,6 +150,11 @@ public class BlackBoxWithJavaCodegenTestGenerated extends AbstractBlackBoxCodege doTestWithJava("compiler/testData/codegen/boxWithJava/samAdapters/fileFilter.kt"); } + @TestMetadata("inheritedSimple.kt") + public void testInheritedSimple() throws Exception { + doTestWithJava("compiler/testData/codegen/boxWithJava/samAdapters/inheritedSimple.kt"); + } + @TestMetadata("nonLiteralAndLiteralRunnable.kt") public void testNonLiteralAndLiteralRunnable() throws Exception { doTestWithJava("compiler/testData/codegen/boxWithJava/samAdapters/nonLiteralAndLiteralRunnable.kt"); From eb7dc87225e6f8f96c84dbed24b613b82842c721 Mon Sep 17 00:00:00 2001 From: Evgeny Gerashchenko Date: Thu, 13 Jun 2013 20:40:31 +0400 Subject: [PATCH 212/291] Ignore SAM adapters when finding abstract members. --- .../java/sam/SingleAbstractMethodUtils.java | 5 +++-- .../lang/resolve/calls/CallResolverUtil.java | 16 +++++++++++++++- .../resolve/calls/tasks/TaskPrioritizer.java | 19 +++---------------- .../adapter/InheritedSimple.java | 10 ++++++++++ .../adapter/InheritedSimple.txt | 19 +++++++++++++++++++ .../jvm/compiler/LoadJavaTestGenerated.java | 5 +++++ 6 files changed, 55 insertions(+), 19 deletions(-) create mode 100644 compiler/testData/loadJava/compiledJava/singleAbstractMethod/adapter/InheritedSimple.java create mode 100644 compiler/testData/loadJava/compiledJava/singleAbstractMethod/adapter/InheritedSimple.txt 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 7134388ac38..09df97a0c74 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 @@ -25,6 +25,7 @@ import org.jetbrains.jet.lang.descriptors.impl.ConstructorDescriptorImpl; import org.jetbrains.jet.lang.descriptors.impl.SimpleFunctionDescriptorImpl; import org.jetbrains.jet.lang.descriptors.impl.TypeParameterDescriptorImpl; import org.jetbrains.jet.lang.descriptors.impl.ValueParameterDescriptorImpl; +import org.jetbrains.jet.lang.resolve.calls.CallResolverUtil; 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; @@ -45,8 +46,8 @@ public class SingleAbstractMethodUtils { List abstractMembers = Lists.newArrayList(); for (DeclarationDescriptor member : type.getMemberScope().getAllDescriptors()) { if (member instanceof CallableMemberDescriptor && - ((CallableMemberDescriptor) member).getModality() == Modality.ABSTRACT && - ((CallableMemberDescriptor) member).getKind() != CallableMemberDescriptor.Kind.SYNTHESIZED) { + ((CallableMemberDescriptor) member).getModality() == Modality.ABSTRACT && + !CallResolverUtil.isOrOverridesSynthesized((CallableMemberDescriptor) member)) { abstractMembers.add((CallableMemberDescriptor) member); } } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/CallResolverUtil.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/CallResolverUtil.java index f9467fffa71..fedaced4525 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/CallResolverUtil.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/CallResolverUtil.java @@ -35,7 +35,6 @@ import org.jetbrains.jet.lang.resolve.calls.model.ResolvedCallWithTrace; import org.jetbrains.jet.lang.resolve.calls.model.ResolvedValueArgument; import org.jetbrains.jet.lang.resolve.calls.tasks.ResolutionCandidate; import org.jetbrains.jet.lang.types.*; -import org.jetbrains.jet.lang.types.checker.JetTypeChecker; import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns; import java.util.Collections; @@ -171,4 +170,19 @@ public class CallResolverUtil { receiverType.getAnnotations(), receiverType.getConstructor(), receiverType.isNullable(), fakeTypeArguments, ErrorUtils.createErrorScope("Error scope for erased receiver type", /*throwExceptions=*/true)); } + + public static boolean isOrOverridesSynthesized(@NotNull CallableMemberDescriptor descriptor) { + if (descriptor.getKind() == CallableMemberDescriptor.Kind.SYNTHESIZED) { + return true; + } + if (descriptor.getKind() == CallableMemberDescriptor.Kind.FAKE_OVERRIDE) { + for (CallableMemberDescriptor overridden : descriptor.getOverriddenDescriptors()) { + if (!isOrOverridesSynthesized(overridden)) { + return false; + } + } + return true; + } + return false; + } } 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 85db61fa34f..26ace9a4d62 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 @@ -41,6 +41,7 @@ import java.util.Collections; import java.util.List; import static org.jetbrains.jet.lang.resolve.DescriptorUtils.isClassObject; +import static org.jetbrains.jet.lang.resolve.calls.CallResolverUtil.*; import static org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverValue.NO_RECEIVER; public class TaskPrioritizer { @@ -106,22 +107,8 @@ public class TaskPrioritizer { private boolean isSynthesized(ResolutionCandidate call) { D descriptor = call.getDescriptor(); - return descriptor instanceof CallableMemberDescriptor && isOrOverridesSynthesized((CallableMemberDescriptor) descriptor); - } - - private boolean isOrOverridesSynthesized(CallableMemberDescriptor descriptor) { - if (descriptor.getKind() == CallableMemberDescriptor.Kind.SYNTHESIZED) { - return true; - } - if (descriptor.getKind() == CallableMemberDescriptor.Kind.FAKE_OVERRIDE) { - for (CallableMemberDescriptor overridden : descriptor.getOverriddenDescriptors()) { - if (!isOrOverridesSynthesized(overridden)) { - return false; - } - } - return true; - } - return false; + return descriptor instanceof CallableMemberDescriptor && + isOrOverridesSynthesized((CallableMemberDescriptor) descriptor); } }; diff --git a/compiler/testData/loadJava/compiledJava/singleAbstractMethod/adapter/InheritedSimple.java b/compiler/testData/loadJava/compiledJava/singleAbstractMethod/adapter/InheritedSimple.java new file mode 100644 index 00000000000..66c7a3c1988 --- /dev/null +++ b/compiler/testData/loadJava/compiledJava/singleAbstractMethod/adapter/InheritedSimple.java @@ -0,0 +1,10 @@ +package test; + +public interface InheritedSimple { + public interface Super { + void foo(Runnable r); + } + + public interface Sub extends Super { + } +} \ No newline at end of file diff --git a/compiler/testData/loadJava/compiledJava/singleAbstractMethod/adapter/InheritedSimple.txt b/compiler/testData/loadJava/compiledJava/singleAbstractMethod/adapter/InheritedSimple.txt new file mode 100644 index 00000000000..10534b8b49e --- /dev/null +++ b/compiler/testData/loadJava/compiledJava/singleAbstractMethod/adapter/InheritedSimple.txt @@ -0,0 +1,19 @@ +package test + +public trait InheritedSimple : java.lang.Object { + + public trait Sub : test.InheritedSimple.Super { + public abstract override /*1*/ /*fake_override*/ fun foo(/*0*/ p0: (() -> jet.Unit)?): jet.Unit + public abstract override /*1*/ /*fake_override*/ fun foo(/*0*/ p0: java.lang.Runnable?): jet.Unit + } + + public trait Super : java.lang.Object { + public abstract /*synthesized*/ fun foo(/*0*/ p0: (() -> jet.Unit)?): jet.Unit + public abstract fun foo(/*0*/ p0: java.lang.Runnable?): jet.Unit + } +} + +package InheritedSimple { + public /*synthesized*/ fun Sub(/*0*/ function: (java.lang.Runnable?) -> jet.Unit): test.InheritedSimple.Sub + public /*synthesized*/ fun Super(/*0*/ function: (java.lang.Runnable?) -> jet.Unit): test.InheritedSimple.Super +} diff --git a/compiler/tests/org/jetbrains/jet/jvm/compiler/LoadJavaTestGenerated.java b/compiler/tests/org/jetbrains/jet/jvm/compiler/LoadJavaTestGenerated.java index 544c3e4295a..36030874f3d 100644 --- a/compiler/tests/org/jetbrains/jet/jvm/compiler/LoadJavaTestGenerated.java +++ b/compiler/tests/org/jetbrains/jet/jvm/compiler/LoadJavaTestGenerated.java @@ -1254,6 +1254,11 @@ public class LoadJavaTestGenerated extends AbstractLoadJavaTest { doTestCompiledJava("compiler/testData/loadJava/compiledJava/singleAbstractMethod/adapter/DeepSamLoop.java"); } + @TestMetadata("InheritedSimple.java") + public void testInheritedSimple() throws Exception { + doTestCompiledJava("compiler/testData/loadJava/compiledJava/singleAbstractMethod/adapter/InheritedSimple.java"); + } + @TestMetadata("NonTrivialFunctionType.java") public void testNonTrivialFunctionType() throws Exception { doTestCompiledJava("compiler/testData/loadJava/compiledJava/singleAbstractMethod/adapter/NonTrivialFunctionType.java"); From 9668360df37d5772fff6c9794530dafb2ae3e667 Mon Sep 17 00:00:00 2001 From: Evgeny Gerashchenko Date: Fri, 14 Jun 2013 15:01:06 +0400 Subject: [PATCH 213/291] Not showing "empty if" when it has comment inside. --- .idea/inspectionProfiles/idea_default.xml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.idea/inspectionProfiles/idea_default.xml b/.idea/inspectionProfiles/idea_default.xml index 2b82dfd963c..42c64a58316 100644 --- a/.idea/inspectionProfiles/idea_default.xml +++ b/.idea/inspectionProfiles/idea_default.xml @@ -59,6 +59,9 @@ + +

" + htmlContent + "

"; + } } diff --git a/idea/src/org/jetbrains/jet/plugin/highlighter/JetHighlighter.java b/idea/src/org/jetbrains/jet/plugin/highlighter/JetHighlighter.java index 8987e291e12..f9bb1e3a895 100644 --- a/idea/src/org/jetbrains/jet/plugin/highlighter/JetHighlighter.java +++ b/idea/src/org/jetbrains/jet/plugin/highlighter/JetHighlighter.java @@ -85,7 +85,7 @@ public class JetHighlighter extends SyntaxHighlighterBase { keys1.put(JetTokens.BLOCK_COMMENT, JetHighlightingColors.BLOCK_COMMENT); keys1.put(JetTokens.DOC_COMMENT, JetHighlightingColors.DOC_COMMENT); - fillMap(keys1, KDocTokens.CONTENT_TOKENS, JetHighlightingColors.DOC_COMMENT); + fillMap(keys1, KDocTokens.KDOC_HIGHLIGHT_TOKENS, JetHighlightingColors.DOC_COMMENT); keys1.put(KDocTokens.TAG_NAME, JetHighlightingColors.KDOC_TAG); keys2.put(KDocTokens.TAG_NAME, JetHighlightingColors.DOC_COMMENT); diff --git a/idea/testData/editor/quickDoc/MethodFromStdLib.kt b/idea/testData/editor/quickDoc/MethodFromStdLib.kt new file mode 100644 index 00000000000..3cd05d8b360 --- /dev/null +++ b/idea/testData/editor/quickDoc/MethodFromStdLib.kt @@ -0,0 +1,5 @@ +fun test() { + listOf(1, 2, 4).filter { it > 0 } +} + +// INFO: public fun <T> jet.Collection<T>.filter(predicate: (T) → jet.Boolean): jet.List<T> defined in kotlin

Returns a list containing all elements which match the given *predicate*

\ No newline at end of file diff --git a/idea/testData/editor/quickDoc/OnClassDeclarationWithNoPackage.kt b/idea/testData/editor/quickDoc/OnClassDeclarationWithNoPackage.kt new file mode 100644 index 00000000000..2364066228c --- /dev/null +++ b/idea/testData/editor/quickDoc/OnClassDeclarationWithNoPackage.kt @@ -0,0 +1,6 @@ +/** + * Usefull comment + */ +class Some + +// INFO: internal final class Some defined in root package

Usefull comment

\ No newline at end of file diff --git a/idea/testData/editor/quickDoc/OnFunctionDeclarationWithPackage.kt b/idea/testData/editor/quickDoc/OnFunctionDeclarationWithPackage.kt new file mode 100644 index 00000000000..eaa85a06877 --- /dev/null +++ b/idea/testData/editor/quickDoc/OnFunctionDeclarationWithPackage.kt @@ -0,0 +1,15 @@ +package test + +/** + + * + * + * Test function + + * + * @param first - Some + * @param second - Other + */ +fun testFun(first: String, second: Int) = 12 + +// INFO: internal fun testFun(first: jet.String, second: jet.Int): jet.Int defined in test

Test function


@param - first - Some
@param - second - Other

\ No newline at end of file diff --git a/idea/testData/editor/quickDoc/OnMethodUsage.kt b/idea/testData/editor/quickDoc/OnMethodUsage.kt new file mode 100644 index 00000000000..529988e3239 --- /dev/null +++ b/idea/testData/editor/quickDoc/OnMethodUsage.kt @@ -0,0 +1,15 @@ +/** + Some documentation + + @param a - Some int + * @param b: String + */ +fun testMethod(a: Int, b: String) { + +} + +fun test() { + testMethod(1, "value") +} + +// INFO: internal fun testMethod(a: jet.Int, b: jet.String): jet.Unit defined in root package

Some documentation

@param - a - Some int
@param - b: String

\ No newline at end of file diff --git a/idea/tests/org/jetbrains/jet/editor/quickDoc/AbstractJetQuickDocProviderTest.java b/idea/tests/org/jetbrains/jet/editor/quickDoc/AbstractJetQuickDocProviderTest.java new file mode 100644 index 00000000000..fa21406adde --- /dev/null +++ b/idea/tests/org/jetbrains/jet/editor/quickDoc/AbstractJetQuickDocProviderTest.java @@ -0,0 +1,51 @@ +/* + * 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.quickDoc; + +import com.intellij.codeInsight.documentation.DocumentationManager; +import com.intellij.codeInsight.navigation.CtrlMouseHandler; +import com.intellij.psi.PsiElement; +import com.intellij.testFramework.LightProjectDescriptor; +import com.intellij.testFramework.fixtures.LightCodeInsightFixtureTestCase; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.jet.InTextDirectivesUtils; +import org.jetbrains.jet.plugin.ProjectDescriptorWithStdlibSources; + +import java.util.List; + +public abstract class AbstractJetQuickDocProviderTest extends LightCodeInsightFixtureTestCase { + public void doTest(@NotNull String path) throws Exception { + myFixture.configureByFile(path); + + PsiElement element = myFixture.getFile().findElementAt(myFixture.getEditor().getCaretModel().getOffset()); + assertNotNull("Can't find element at caret in file: " + path, element); + + DocumentationManager documentationManager = DocumentationManager.getInstance(myFixture.getProject()); + PsiElement targetElement = documentationManager.findTargetElement(myFixture.getEditor(), myFixture.getFile()); + + List directives = InTextDirectivesUtils.findLinesWithPrefixesRemoved(myFixture.getFile().getText(), "INFO:"); + assertTrue("Documentation to check should be added to test file with // INFO: directive " + path, 1 == directives.size()); + + assertEquals(directives.get(0), CtrlMouseHandler.getInfo(targetElement, element)); + } + + @NotNull + @Override + protected LightProjectDescriptor getProjectDescriptor() { + return ProjectDescriptorWithStdlibSources.INSTANCE; + } +} diff --git a/idea/tests/org/jetbrains/jet/editor/quickDoc/JetQuickDocProviderTestGenerated.java b/idea/tests/org/jetbrains/jet/editor/quickDoc/JetQuickDocProviderTestGenerated.java new file mode 100644 index 00000000000..e0c6c8f15e0 --- /dev/null +++ b/idea/tests/org/jetbrains/jet/editor/quickDoc/JetQuickDocProviderTestGenerated.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.editor.quickDoc; + +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.editor.quickDoc.AbstractJetQuickDocProviderTest; + +/** This class is generated by {@link org.jetbrains.jet.generators.tests.GenerateTests}. DO NOT MODIFY MANUALLY */ +@SuppressWarnings("all") +@TestMetadata("idea/testData/editor/quickDoc") +public class JetQuickDocProviderTestGenerated extends AbstractJetQuickDocProviderTest { + public void testAllFilesPresentInQuickDoc() throws Exception { + JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.GenerateTests", new File("idea/testData/editor/quickDoc"), Pattern.compile("^(.+)\\.kt$"), true); + } + + @TestMetadata("MethodFromStdLib.kt") + public void testMethodFromStdLib() throws Exception { + doTest("idea/testData/editor/quickDoc/MethodFromStdLib.kt"); + } + + @TestMetadata("OnClassDeclarationWithNoPackage.kt") + public void testOnClassDeclarationWithNoPackage() throws Exception { + doTest("idea/testData/editor/quickDoc/OnClassDeclarationWithNoPackage.kt"); + } + + @TestMetadata("OnFunctionDeclarationWithPackage.kt") + public void testOnFunctionDeclarationWithPackage() throws Exception { + doTest("idea/testData/editor/quickDoc/OnFunctionDeclarationWithPackage.kt"); + } + + @TestMetadata("OnMethodUsage.kt") + public void testOnMethodUsage() throws Exception { + doTest("idea/testData/editor/quickDoc/OnMethodUsage.kt"); + } + +} From 03053711f42f2c0da7fa2e38b0db5d8f626c3aa2 Mon Sep 17 00:00:00 2001 From: Nikolay Krasko Date: Tue, 2 Jul 2013 18:28:04 +0400 Subject: [PATCH 266/291] Refactoring: Move CompleteSession class to upper level --- .../plugin/completion/CompletionSession.java | 293 ++++++++++++++++++ .../completion/JetCompletionContributor.java | 270 +--------------- 2 files changed, 294 insertions(+), 269 deletions(-) create mode 100644 idea/src/org/jetbrains/jet/plugin/completion/CompletionSession.java diff --git a/idea/src/org/jetbrains/jet/plugin/completion/CompletionSession.java b/idea/src/org/jetbrains/jet/plugin/completion/CompletionSession.java new file mode 100644 index 00000000000..c211cf22bb1 --- /dev/null +++ b/idea/src/org/jetbrains/jet/plugin/completion/CompletionSession.java @@ -0,0 +1,293 @@ +/* + * 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.completion; + +import com.google.common.base.Predicate; +import com.google.common.collect.Collections2; +import com.intellij.codeInsight.completion.CompletionParameters; +import com.intellij.codeInsight.completion.CompletionResultSet; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.Condition; +import com.intellij.openapi.util.Conditions; +import com.intellij.psi.PsiElement; +import com.intellij.psi.search.GlobalSearchScope; +import com.intellij.psi.util.PsiTreeUtil; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; +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.lazy.ResolveSession; +import org.jetbrains.jet.lang.resolve.lazy.ResolveSessionUtils; +import org.jetbrains.jet.lang.resolve.scopes.JetScope; +import org.jetbrains.jet.lexer.JetTokens; +import org.jetbrains.jet.plugin.caches.JetShortNamesCache; +import org.jetbrains.jet.plugin.codeInsight.TipsManager; +import org.jetbrains.jet.plugin.completion.weigher.JetCompletionSorting; +import org.jetbrains.jet.plugin.project.WholeProjectAnalyzerFacade; +import org.jetbrains.jet.plugin.references.JetSimpleNameReference; + +import java.util.Collection; + +class CompletionSession { + @Nullable + private final DeclarationDescriptor inDescriptor; + private final int customInvocationCount; + private final CompletionParameters parameters; + private final JetCompletionResultSet jetResult; + private final JetSimpleNameReference jetReference; + + public CompletionSession( + @NotNull CompletionParameters parameters, + @NotNull CompletionResultSet result, + @NotNull JetSimpleNameReference jetReference, + @NotNull PsiElement position + ) { + + this(parameters, result, jetReference, position, parameters.getInvocationCount()); + } + + public CompletionSession( + @NotNull CompletionParameters parameters, + @NotNull CompletionResultSet result, + @NotNull JetSimpleNameReference jetReference, + @NotNull PsiElement position, + int customInvocationCount + ) { + this.parameters = parameters; + this.jetReference = jetReference; + this.customInvocationCount = customInvocationCount; + + ResolveSession resolveSession = WholeProjectAnalyzerFacade.getLazyResolveSessionForFile((JetFile) position.getContainingFile()); + BindingContext expressionBindingContext = ResolveSessionUtils.resolveToExpression(resolveSession, jetReference.getExpression()); + JetScope scope = expressionBindingContext.get(BindingContext.RESOLUTION_SCOPE, jetReference.getExpression()); + + inDescriptor = scope != null ? scope.getContainingDeclaration() : null; + + this.jetResult = new JetCompletionResultSet( + JetCompletionSorting.addJetSorting(parameters, result), + resolveSession, + expressionBindingContext, new Condition() { + @Override + public boolean value(DeclarationDescriptor descriptor) { + return isVisibleDescriptor(descriptor); + } + }); + } + + void completeForReference() { + if (isOnlyKeywordCompletion(getPosition())) { + return; + } + + if (shouldRunOnlyTypeCompletion()) { + if (customInvocationCount >= 1) { + JetTypesCompletionHelper.addJetTypes(parameters, jetResult); + } + else { + addReferenceVariants(new Condition() { + @Override + public boolean value(DeclarationDescriptor descriptor) { + return isPartOfTypeDeclaration(descriptor); + } + }); + } + + return; + } + + addReferenceVariants(Conditions.alwaysTrue()); + + String prefix = jetResult.getResult().getPrefixMatcher().getPrefix(); + + // Try to avoid computing not-imported descriptors for empty prefix + if (prefix.isEmpty()) { + if (customInvocationCount < 2) { + return; + } + + if (PsiTreeUtil.getParentOfType(jetReference.getExpression(), JetDotQualifiedExpression.class) == null) { + return; + } + } + + if (shouldRunTopLevelCompletion()) { + JetTypesCompletionHelper.addJetTypes(parameters, jetResult); + addJetTopLevelFunctions(); + addJetTopLevelObjects(); + } + + if (shouldRunExtensionsCompletion()) { + addJetExtensions(); + } + } + + private static boolean isOnlyKeywordCompletion(PsiElement position) { + return PsiTreeUtil.getParentOfType(position, JetModifierList.class) != null; + } + + private void addJetExtensions() { + Project project = getPosition().getProject(); + JetShortNamesCache namesCache = JetShortNamesCache.getKotlinInstance(project); + + Collection jetCallableExtensions = namesCache.getJetCallableExtensions( + jetResult.getShortNameFilter(), + jetReference.getExpression(), + getResolveSession(), + GlobalSearchScope.allScope(project)); + + jetResult.addAllElements(jetCallableExtensions); + } + + public static boolean isPartOfTypeDeclaration(@NotNull DeclarationDescriptor descriptor) { + if (descriptor instanceof NamespaceDescriptor || descriptor instanceof TypeParameterDescriptor) { + return true; + } + + if (descriptor instanceof ClassDescriptor) { + ClassDescriptor classDescriptor = (ClassDescriptor) descriptor; + ClassKind kind = classDescriptor.getKind(); + return !(kind == ClassKind.OBJECT || kind == ClassKind.CLASS_OBJECT); + } + + return false; + } + + private void addJetTopLevelFunctions() { + String actualPrefix = jetResult.getResult().getPrefixMatcher().getPrefix(); + Project project = getPosition().getProject(); + + JetShortNamesCache namesCache = JetShortNamesCache.getKotlinInstance(project); + GlobalSearchScope scope = GlobalSearchScope.allScope(project); + Collection functionNames = namesCache.getAllTopLevelFunctionNames(); + + // TODO: Fix complete extension not only on contains + for (String name : functionNames) { + if (name.contains(actualPrefix)) { + jetResult.addAllElements(namesCache.getTopLevelFunctionDescriptorsByName( + name, jetReference.getExpression(), getResolveSession(), scope)); + } + } + } + + private void addJetTopLevelObjects() { + Project project = getPosition().getProject(); + JetShortNamesCache namesCache = JetShortNamesCache.getKotlinInstance(project); + GlobalSearchScope scope = GlobalSearchScope.allScope(project); + Collection objectNames = namesCache.getAllTopLevelObjectNames(); + + for (String name : objectNames) { + if (jetResult.getResult().getPrefixMatcher().prefixMatches(name)) { + jetResult.addAllElements(namesCache.getTopLevelObjectsByName(name, jetReference.getExpression(), getResolveSession(), scope)); + } + } + } + + private boolean shouldRunOnlyTypeCompletion() { + // Check that completion in the type annotation context and if there's a qualified + // expression we are at first of it + JetTypeReference typeReference = PsiTreeUtil.getParentOfType(getPosition(), JetTypeReference.class); + if (typeReference != null) { + JetSimpleNameExpression firstPartReference = PsiTreeUtil.findChildOfType(typeReference, JetSimpleNameExpression.class); + return firstPartReference == jetReference.getExpression(); + } + + return false; + } + + private boolean shouldRunTopLevelCompletion() { + if (customInvocationCount == 0) { + return false; + } + + PsiElement element = getPosition(); + if (getPosition().getNode().getElementType() == JetTokens.IDENTIFIER) { + if (element.getParent() instanceof JetSimpleNameExpression) { + JetSimpleNameExpression nameExpression = (JetSimpleNameExpression)element.getParent(); + + // Top level completion should be executed for simple name which is not in qualified expression + if (PsiTreeUtil.getParentOfType(nameExpression, JetQualifiedExpression.class) != null) { + return false; + } + + // Don't call top level completion in qualified named position of user type + PsiElement parent = nameExpression.getParent(); + if (parent instanceof JetUserType && ((JetUserType) parent).getQualifier() != null) { + return false; + } + + return true; + } + } + + return false; + } + + private boolean shouldRunExtensionsCompletion() { + return !(customInvocationCount == 0 && jetResult.getResult().getPrefixMatcher().getPrefix().length() < 3); + } + + private void addReferenceVariants(@NotNull final Condition filterCondition) { + Collection descriptors = TipsManager.getReferenceVariants( + jetReference.getExpression(), getExpressionBindingContext()); + + Collection filterDescriptors = Collections2.filter(descriptors, new Predicate() { + @Override + public boolean apply(@Nullable DeclarationDescriptor descriptor) { + return descriptor != null && filterCondition.value(descriptor); + } + }); + + jetResult.addAllElements(filterDescriptors); + } + + private boolean isVisibleDescriptor(DeclarationDescriptor descriptor) { + if (customInvocationCount >= 2) { + // Show everything if user insist on showing completion list + return true; + } + + if (descriptor instanceof DeclarationDescriptorWithVisibility) { + if (inDescriptor != null) { + //noinspection ConstantConditions + return Visibilities.isVisible((DeclarationDescriptorWithVisibility) descriptor, inDescriptor); + } + } + + return true; + } + + private BindingContext getExpressionBindingContext() { + return jetResult.getBindingContext(); + } + + private ResolveSession getResolveSession() { + return jetResult.getResolveSession(); + } + + private PsiElement getPosition() { + return parameters.getPosition(); + } + + public JetCompletionResultSet getJetResult() { + return jetResult; + } + + public int getCustomInvocationCount() { + return customInvocationCount; + } +} diff --git a/idea/src/org/jetbrains/jet/plugin/completion/JetCompletionContributor.java b/idea/src/org/jetbrains/jet/plugin/completion/JetCompletionContributor.java index 9e4736cd1e3..4e4584f6194 100644 --- a/idea/src/org/jetbrains/jet/plugin/completion/JetCompletionContributor.java +++ b/idea/src/org/jetbrains/jet/plugin/completion/JetCompletionContributor.java @@ -16,35 +16,16 @@ package org.jetbrains.jet.plugin.completion; -import com.google.common.base.Predicate; -import com.google.common.collect.Collections2; import com.intellij.codeInsight.completion.*; -import com.intellij.openapi.project.Project; -import com.intellij.openapi.util.Condition; -import com.intellij.openapi.util.Conditions; import com.intellij.patterns.PlatformPatterns; import com.intellij.psi.PsiElement; import com.intellij.psi.PsiReference; -import com.intellij.psi.search.GlobalSearchScope; -import com.intellij.psi.util.PsiTreeUtil; import com.intellij.util.ProcessingContext; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import org.jetbrains.jet.plugin.codeInsight.TipsManager; -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.lazy.ResolveSession; -import org.jetbrains.jet.lang.resolve.lazy.ResolveSessionUtils; -import org.jetbrains.jet.lang.resolve.scopes.JetScope; -import org.jetbrains.jet.lexer.JetTokens; -import org.jetbrains.jet.plugin.caches.JetShortNamesCache; -import org.jetbrains.jet.plugin.completion.weigher.JetCompletionSorting; -import org.jetbrains.jet.plugin.project.WholeProjectAnalyzerFacade; +import org.jetbrains.jet.lang.psi.JetFile; import org.jetbrains.jet.plugin.references.JetSimpleNameReference; -import java.util.Collection; - public class JetCompletionContributor extends CompletionContributor { public JetCompletionContributor() { extend(CompletionType.BASIC, PlatformPatterns.psiElement(), @@ -100,253 +81,4 @@ public class JetCompletionContributor extends CompletionContributor { return null; } - - private static class CompletionSession { - @Nullable - private final DeclarationDescriptor inDescriptor; - private final int customInvocationCount; - private final CompletionParameters parameters; - private final JetCompletionResultSet jetResult; - private final JetSimpleNameReference jetReference; - - public CompletionSession( - @NotNull CompletionParameters parameters, - @NotNull CompletionResultSet result, - @NotNull JetSimpleNameReference jetReference, - @NotNull PsiElement position - ) { - - this(parameters, result, jetReference, position, parameters.getInvocationCount()); - } - - public CompletionSession( - @NotNull CompletionParameters parameters, - @NotNull CompletionResultSet result, - @NotNull JetSimpleNameReference jetReference, - @NotNull PsiElement position, - int customInvocationCount - ) { - this.parameters = parameters; - this.jetReference = jetReference; - this.customInvocationCount = customInvocationCount; - - ResolveSession resolveSession = WholeProjectAnalyzerFacade.getLazyResolveSessionForFile((JetFile) position.getContainingFile()); - BindingContext expressionBindingContext = ResolveSessionUtils.resolveToExpression(resolveSession, jetReference.getExpression()); - JetScope scope = expressionBindingContext.get(BindingContext.RESOLUTION_SCOPE, jetReference.getExpression()); - - inDescriptor = scope != null ? scope.getContainingDeclaration() : null; - - this.jetResult = new JetCompletionResultSet( - JetCompletionSorting.addJetSorting(parameters, result), - resolveSession, - expressionBindingContext, new Condition() { - @Override - public boolean value(DeclarationDescriptor descriptor) { - return isVisibleDescriptor(descriptor); - } - }); - } - - void completeForReference() { - if (isOnlyKeywordCompletion(getPosition())) { - return; - } - - if (shouldRunOnlyTypeCompletion()) { - if (customInvocationCount >= 1) { - JetTypesCompletionHelper.addJetTypes(parameters, jetResult); - } - else { - addReferenceVariants(new Condition() { - @Override - public boolean value(DeclarationDescriptor descriptor) { - return isPartOfTypeDeclaration(descriptor); - } - }); - } - - return; - } - - addReferenceVariants(Conditions.alwaysTrue()); - - String prefix = jetResult.getResult().getPrefixMatcher().getPrefix(); - - // Try to avoid computing not-imported descriptors for empty prefix - if (prefix.isEmpty()) { - if (customInvocationCount < 2) { - return; - } - - if (PsiTreeUtil.getParentOfType(jetReference.getExpression(), JetDotQualifiedExpression.class) == null) { - return; - } - } - - if (shouldRunTopLevelCompletion()) { - JetTypesCompletionHelper.addJetTypes(parameters, jetResult); - addJetTopLevelFunctions(); - addJetTopLevelObjects(); - } - - if (shouldRunExtensionsCompletion()) { - addJetExtensions(); - } - } - - private static boolean isOnlyKeywordCompletion(PsiElement position) { - return PsiTreeUtil.getParentOfType(position, JetModifierList.class) != null; - } - - private void addJetExtensions() { - Project project = getPosition().getProject(); - JetShortNamesCache namesCache = JetShortNamesCache.getKotlinInstance(project); - - Collection jetCallableExtensions = namesCache.getJetCallableExtensions( - jetResult.getShortNameFilter(), - jetReference.getExpression(), - getResolveSession(), - GlobalSearchScope.allScope(project)); - - jetResult.addAllElements(jetCallableExtensions); - } - - public static boolean isPartOfTypeDeclaration(@NotNull DeclarationDescriptor descriptor) { - if (descriptor instanceof NamespaceDescriptor || descriptor instanceof TypeParameterDescriptor) { - return true; - } - - if (descriptor instanceof ClassDescriptor) { - ClassDescriptor classDescriptor = (ClassDescriptor) descriptor; - ClassKind kind = classDescriptor.getKind(); - return !(kind == ClassKind.OBJECT || kind == ClassKind.CLASS_OBJECT); - } - - return false; - } - - private void addJetTopLevelFunctions() { - String actualPrefix = jetResult.getResult().getPrefixMatcher().getPrefix(); - Project project = getPosition().getProject(); - - JetShortNamesCache namesCache = JetShortNamesCache.getKotlinInstance(project); - GlobalSearchScope scope = GlobalSearchScope.allScope(project); - Collection functionNames = namesCache.getAllTopLevelFunctionNames(); - - // TODO: Fix complete extension not only on contains - for (String name : functionNames) { - if (name.contains(actualPrefix)) { - jetResult.addAllElements(namesCache.getTopLevelFunctionDescriptorsByName( - name, jetReference.getExpression(), getResolveSession(), scope)); - } - } - } - - private void addJetTopLevelObjects() { - Project project = getPosition().getProject(); - JetShortNamesCache namesCache = JetShortNamesCache.getKotlinInstance(project); - GlobalSearchScope scope = GlobalSearchScope.allScope(project); - Collection objectNames = namesCache.getAllTopLevelObjectNames(); - - for (String name : objectNames) { - if (jetResult.getResult().getPrefixMatcher().prefixMatches(name)) { - jetResult.addAllElements(namesCache.getTopLevelObjectsByName(name, jetReference.getExpression(), getResolveSession(), scope)); - } - } - } - - private boolean shouldRunOnlyTypeCompletion() { - // Check that completion in the type annotation context and if there's a qualified - // expression we are at first of it - JetTypeReference typeReference = PsiTreeUtil.getParentOfType(getPosition(), JetTypeReference.class); - if (typeReference != null) { - JetSimpleNameExpression firstPartReference = PsiTreeUtil.findChildOfType(typeReference, JetSimpleNameExpression.class); - return firstPartReference == jetReference.getExpression(); - } - - return false; - } - - private boolean shouldRunTopLevelCompletion() { - if (customInvocationCount == 0) { - return false; - } - - PsiElement element = getPosition(); - if (getPosition().getNode().getElementType() == JetTokens.IDENTIFIER) { - if (element.getParent() instanceof JetSimpleNameExpression) { - JetSimpleNameExpression nameExpression = (JetSimpleNameExpression)element.getParent(); - - // Top level completion should be executed for simple name which is not in qualified expression - if (PsiTreeUtil.getParentOfType(nameExpression, JetQualifiedExpression.class) != null) { - return false; - } - - // Don't call top level completion in qualified named position of user type - PsiElement parent = nameExpression.getParent(); - if (parent instanceof JetUserType && ((JetUserType) parent).getQualifier() != null) { - return false; - } - - return true; - } - } - - return false; - } - - private boolean shouldRunExtensionsCompletion() { - return !(customInvocationCount == 0 && jetResult.getResult().getPrefixMatcher().getPrefix().length() < 3); - } - - private void addReferenceVariants(@NotNull final Condition filterCondition) { - Collection descriptors = TipsManager.getReferenceVariants( - jetReference.getExpression(), getExpressionBindingContext()); - - Collection filterDescriptors = Collections2.filter(descriptors, new Predicate() { - @Override - public boolean apply(@Nullable DeclarationDescriptor descriptor) { - return descriptor != null && filterCondition.value(descriptor); - } - }); - - jetResult.addAllElements(filterDescriptors); - } - - private boolean isVisibleDescriptor(DeclarationDescriptor descriptor) { - if (customInvocationCount >= 2) { - // Show everything if user insist on showing completion list - return true; - } - - if (descriptor instanceof DeclarationDescriptorWithVisibility) { - if (inDescriptor != null) { - //noinspection ConstantConditions - return Visibilities.isVisible((DeclarationDescriptorWithVisibility) descriptor, inDescriptor); - } - } - - return true; - } - - private BindingContext getExpressionBindingContext() { - return jetResult.getBindingContext(); - } - - private ResolveSession getResolveSession() { - return jetResult.getResolveSession(); - } - - private PsiElement getPosition() { - return parameters.getPosition(); - } - - public JetCompletionResultSet getJetResult() { - return jetResult; - } - - public int getCustomInvocationCount() { - return customInvocationCount; - } - } } From 86274466c5b5a225f8a821c1620bad7e202a357a Mon Sep 17 00:00:00 2001 From: Nikolay Krasko Date: Tue, 2 Jul 2013 18:28:04 +0400 Subject: [PATCH 267/291] Add ability to search kotlin classes in selected scope --- .../jet/plugin/caches/JetShortNamesCache.java | 10 ++++++---- .../plugin/completion/JetTypesCompletionHelper.java | 3 ++- .../jetbrains/jet/plugin/quickfix/AutoImportFix.java | 2 +- 3 files changed, 9 insertions(+), 6 deletions(-) diff --git a/idea/src/org/jetbrains/jet/plugin/caches/JetShortNamesCache.java b/idea/src/org/jetbrains/jet/plugin/caches/JetShortNamesCache.java index 2d6005d82b8..3872b09ae6e 100644 --- a/idea/src/org/jetbrains/jet/plugin/caches/JetShortNamesCache.java +++ b/idea/src/org/jetbrains/jet/plugin/caches/JetShortNamesCache.java @@ -348,23 +348,25 @@ public class JetShortNamesCache extends PsiShortNamesCache { public Collection getJetClassesDescriptors( @NotNull Condition acceptedShortNameCondition, - @NotNull KotlinCodeAnalyzer analyzer + @NotNull KotlinCodeAnalyzer analyzer, + @NotNull GlobalSearchScope searchScope ) { Collection classDescriptors = new ArrayList(); for (String fqName : JetFullClassNameIndex.getInstance().getAllKeys(project)) { FqName classFQName = new FqName(fqName); if (acceptedShortNameCondition.value(classFQName.shortName().asString())) { - classDescriptors.addAll(getJetClassesDescriptorsByFQName(analyzer, classFQName)); + classDescriptors.addAll(getJetClassesDescriptorsByFQName(analyzer, classFQName, searchScope)); } } return classDescriptors; } - private Collection getJetClassesDescriptorsByFQName(@NotNull KotlinCodeAnalyzer analyzer, @NotNull FqName classFQName) { + private Collection getJetClassesDescriptorsByFQName( + @NotNull KotlinCodeAnalyzer analyzer, @NotNull FqName classFQName, @NotNull GlobalSearchScope searchScope) { Collection jetClassOrObjects = JetFullClassNameIndex.getInstance().get( - classFQName.asString(), project, GlobalSearchScope.allScope(project)); + classFQName.asString(), project, searchScope); if (jetClassOrObjects.isEmpty()) { // This fqn is absent in caches, dead or not in scope diff --git a/idea/src/org/jetbrains/jet/plugin/completion/JetTypesCompletionHelper.java b/idea/src/org/jetbrains/jet/plugin/completion/JetTypesCompletionHelper.java index efc3211a77c..29fba8b8ce4 100644 --- a/idea/src/org/jetbrains/jet/plugin/completion/JetTypesCompletionHelper.java +++ b/idea/src/org/jetbrains/jet/plugin/completion/JetTypesCompletionHelper.java @@ -20,6 +20,7 @@ import com.intellij.codeInsight.completion.*; import com.intellij.codeInsight.lookup.LookupElement; import com.intellij.openapi.project.Project; import com.intellij.psi.PsiClass; +import com.intellij.psi.search.GlobalSearchScope; import com.intellij.util.Consumer; import org.jetbrains.annotations.NotNull; import org.jetbrains.jet.asJava.KotlinLightClass; @@ -46,7 +47,7 @@ public class JetTypesCompletionHelper { Project project = parameters.getOriginalFile().getProject(); JetShortNamesCache namesCache = JetShortNamesCache.getKotlinInstance(project); jetCompletionResult.addAllElements(namesCache.getJetClassesDescriptors( - jetCompletionResult.getShortNameFilter(), jetCompletionResult.getResolveSession())); + jetCompletionResult.getShortNameFilter(), jetCompletionResult.getResolveSession(), GlobalSearchScope.allScope(project))); if (!KotlinFrameworkDetector.isJsKotlinModule((JetFile) parameters.getOriginalFile())) { addAdaptedJavaCompletion(parameters, jetCompletionResult); diff --git a/idea/src/org/jetbrains/jet/plugin/quickfix/AutoImportFix.java b/idea/src/org/jetbrains/jet/plugin/quickfix/AutoImportFix.java index 24cedb60bb1..582906ee11a 100644 --- a/idea/src/org/jetbrains/jet/plugin/quickfix/AutoImportFix.java +++ b/idea/src/org/jetbrains/jet/plugin/quickfix/AutoImportFix.java @@ -213,7 +213,7 @@ public class AutoImportFix extends JetHintAction implem public boolean value(String s) { return typeName.equals(s); } - }, resolveSession); + }, resolveSession, GlobalSearchScope.allScope(project)); return Collections2.transform(descriptors, new Function() { @Override From f0a10b70c13031b8a51f26867796b431a92f285d Mon Sep 17 00:00:00 2001 From: Nikolay Krasko Date: Thu, 4 Jul 2013 16:36:51 +0400 Subject: [PATCH 268/291] Fix wrong unnecessary completion for the case of force completion #KT-1187 Fixed --- .../jetbrains/jet/plugin/caches/JetShortNamesCache.java | 3 ++- .../basic/common/DoNotCompleteForErrorReceivers.kt | 1 + .../basic/common/DoNotCompleteForErrorReceiversForce.kt | 8 ++++++++ .../jet/completion/JetBasicJSCompletionTestGenerated.java | 5 +++++ .../completion/JetBasicJavaCompletionTestGenerated.java | 5 +++++ 5 files changed, 21 insertions(+), 1 deletion(-) create mode 100644 idea/testData/completion/basic/common/DoNotCompleteForErrorReceiversForce.kt diff --git a/idea/src/org/jetbrains/jet/plugin/caches/JetShortNamesCache.java b/idea/src/org/jetbrains/jet/plugin/caches/JetShortNamesCache.java index 3872b09ae6e..4565ff78205 100644 --- a/idea/src/org/jetbrains/jet/plugin/caches/JetShortNamesCache.java +++ b/idea/src/org/jetbrains/jet/plugin/caches/JetShortNamesCache.java @@ -45,6 +45,7 @@ import org.jetbrains.jet.lang.resolve.lazy.ResolveSessionUtils; import org.jetbrains.jet.lang.resolve.name.FqName; import org.jetbrains.jet.lang.resolve.name.Name; import org.jetbrains.jet.lang.resolve.scopes.JetScope; +import org.jetbrains.jet.lang.types.ErrorUtils; import org.jetbrains.jet.lang.types.JetType; import org.jetbrains.jet.lang.types.expressions.ExpressionTypingUtils; import org.jetbrains.jet.plugin.caches.resolve.IDELightClassGenerationSupport; @@ -308,7 +309,7 @@ public class JetShortNamesCache extends PsiShortNamesCache { JetType expressionType = context.get(BindingContext.EXPRESSION_TYPE, receiverExpression); JetScope scope = context.get(BindingContext.RESOLUTION_SCOPE, receiverExpression); - if (expressionType != null && scope != null) { + if (expressionType != null && scope != null && !ErrorUtils.isErrorType(expressionType)) { Collection extensionFunctionsNames = getAllJetExtensionFunctionsNames(searchScope); Set functionFQNs = new java.util.HashSet(); diff --git a/idea/testData/completion/basic/common/DoNotCompleteForErrorReceivers.kt b/idea/testData/completion/basic/common/DoNotCompleteForErrorReceivers.kt index 19006b4d1f8..f623ee069b5 100644 --- a/idea/testData/completion/basic/common/DoNotCompleteForErrorReceivers.kt +++ b/idea/testData/completion/basic/common/DoNotCompleteForErrorReceivers.kt @@ -4,4 +4,5 @@ fun anyfun() { a.b.c.d.e.f. } +// TIME: 1 // NUMBER: 0 \ No newline at end of file diff --git a/idea/testData/completion/basic/common/DoNotCompleteForErrorReceiversForce.kt b/idea/testData/completion/basic/common/DoNotCompleteForErrorReceiversForce.kt new file mode 100644 index 00000000000..e2d9d3a115f --- /dev/null +++ b/idea/testData/completion/basic/common/DoNotCompleteForErrorReceiversForce.kt @@ -0,0 +1,8 @@ +/// KT-1187 Wrong unnecessary completion + +fun anyfun() { + a.b.c.d.e.f. +} + +// TIME: 2 +// NUMBER: 0 \ 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 d842aa95c82..c5a058ae5d1 100644 --- a/idea/tests/org/jetbrains/jet/completion/JetBasicJSCompletionTestGenerated.java +++ b/idea/tests/org/jetbrains/jet/completion/JetBasicJSCompletionTestGenerated.java @@ -104,6 +104,11 @@ public class JetBasicJSCompletionTestGenerated extends AbstractJetJSCompletionTe doTest("idea/testData/completion/basic/common/DoNotCompleteForErrorReceivers.kt"); } + @TestMetadata("DoNotCompleteForErrorReceiversForce.kt") + public void testDoNotCompleteForErrorReceiversForce() throws Exception { + doTest("idea/testData/completion/basic/common/DoNotCompleteForErrorReceiversForce.kt"); + } + @TestMetadata("ExtendClassName.kt") public void testExtendClassName() throws Exception { doTest("idea/testData/completion/basic/common/ExtendClassName.kt"); diff --git a/idea/tests/org/jetbrains/jet/completion/JetBasicJavaCompletionTestGenerated.java b/idea/tests/org/jetbrains/jet/completion/JetBasicJavaCompletionTestGenerated.java index 8dad2867c6c..8a8c8e48997 100644 --- a/idea/tests/org/jetbrains/jet/completion/JetBasicJavaCompletionTestGenerated.java +++ b/idea/tests/org/jetbrains/jet/completion/JetBasicJavaCompletionTestGenerated.java @@ -104,6 +104,11 @@ public class JetBasicJavaCompletionTestGenerated extends AbstractJavaCompletionT doTest("idea/testData/completion/basic/common/DoNotCompleteForErrorReceivers.kt"); } + @TestMetadata("DoNotCompleteForErrorReceiversForce.kt") + public void testDoNotCompleteForErrorReceiversForce() throws Exception { + doTest("idea/testData/completion/basic/common/DoNotCompleteForErrorReceiversForce.kt"); + } + @TestMetadata("ExtendClassName.kt") public void testExtendClassName() throws Exception { doTest("idea/testData/completion/basic/common/ExtendClassName.kt"); From 37e4402822c4de59b82ed9e5b4c3c6aa783c6848 Mon Sep 17 00:00:00 2001 From: Nikolay Krasko Date: Thu, 4 Jul 2013 16:52:48 +0400 Subject: [PATCH 269/291] Complete only imported classes on auto-typing and first completion and set up invocation count --- .../plugin/completion/CompletionSession.java | 31 +++------ .../completion/JetCompletionContributor.java | 63 ++++++++++++------- .../JetExtensionReceiverTypeContributor.java | 38 +++++------ .../completion/JetPackagesContributor.java | 24 +++---- .../completion/JetTypesCompletionHelper.java | 4 +- .../basic/common/ExtensionForProperty.kt | 7 ++- .../basic/common/ExtensionFunReceiverForce.kt | 11 ++++ .../basic/common/ExtensionInsideFunction.kt | 22 +++++++ .../basic/common/InParametersTypes.kt | 14 +++++ .../basic/common/InParametersTypesForce.kt | 14 +++++ .../basic/java/AutoForceCompletion.kt | 4 ++ .../completion/basic/java/PropertyMetadata.kt | 2 +- .../basic/js/AutoForceCompletion.kt | 4 ++ .../JetBasicJSCompletionTestGenerated.java | 25 ++++++++ .../JetBasicJavaCompletionTestGenerated.java | 25 ++++++++ 15 files changed, 200 insertions(+), 88 deletions(-) create mode 100644 idea/testData/completion/basic/common/ExtensionFunReceiverForce.kt create mode 100644 idea/testData/completion/basic/common/ExtensionInsideFunction.kt create mode 100644 idea/testData/completion/basic/common/InParametersTypes.kt create mode 100644 idea/testData/completion/basic/common/InParametersTypesForce.kt create mode 100644 idea/testData/completion/basic/java/AutoForceCompletion.kt create mode 100644 idea/testData/completion/basic/js/AutoForceCompletion.kt diff --git a/idea/src/org/jetbrains/jet/plugin/completion/CompletionSession.java b/idea/src/org/jetbrains/jet/plugin/completion/CompletionSession.java index c211cf22bb1..3fc63bd2e59 100644 --- a/idea/src/org/jetbrains/jet/plugin/completion/CompletionSession.java +++ b/idea/src/org/jetbrains/jet/plugin/completion/CompletionSession.java @@ -20,6 +20,7 @@ import com.google.common.base.Predicate; import com.google.common.collect.Collections2; import com.intellij.codeInsight.completion.CompletionParameters; import com.intellij.codeInsight.completion.CompletionResultSet; +import com.intellij.codeInsight.completion.JavaCompletionContributor; import com.intellij.openapi.project.Project; import com.intellij.openapi.util.Condition; import com.intellij.openapi.util.Conditions; @@ -43,10 +44,9 @@ import org.jetbrains.jet.plugin.references.JetSimpleNameReference; import java.util.Collection; -class CompletionSession { +public class CompletionSession { @Nullable private final DeclarationDescriptor inDescriptor; - private final int customInvocationCount; private final CompletionParameters parameters; private final JetCompletionResultSet jetResult; private final JetSimpleNameReference jetReference; @@ -57,20 +57,8 @@ class CompletionSession { @NotNull JetSimpleNameReference jetReference, @NotNull PsiElement position ) { - - this(parameters, result, jetReference, position, parameters.getInvocationCount()); - } - - public CompletionSession( - @NotNull CompletionParameters parameters, - @NotNull CompletionResultSet result, - @NotNull JetSimpleNameReference jetReference, - @NotNull PsiElement position, - int customInvocationCount - ) { this.parameters = parameters; this.jetReference = jetReference; - this.customInvocationCount = customInvocationCount; ResolveSession resolveSession = WholeProjectAnalyzerFacade.getLazyResolveSessionForFile((JetFile) position.getContainingFile()); BindingContext expressionBindingContext = ResolveSessionUtils.resolveToExpression(resolveSession, jetReference.getExpression()); @@ -95,7 +83,7 @@ class CompletionSession { } if (shouldRunOnlyTypeCompletion()) { - if (customInvocationCount >= 1) { + if (parameters.getInvocationCount() >= 2) { JetTypesCompletionHelper.addJetTypes(parameters, jetResult); } else { @@ -105,6 +93,7 @@ class CompletionSession { return isPartOfTypeDeclaration(descriptor); } }); + JavaCompletionContributor.advertiseSecondCompletion(parameters.getPosition().getProject(), jetResult.getResult()); } return; @@ -116,7 +105,7 @@ class CompletionSession { // Try to avoid computing not-imported descriptors for empty prefix if (prefix.isEmpty()) { - if (customInvocationCount < 2) { + if (parameters.getInvocationCount() < 2) { return; } @@ -210,7 +199,7 @@ class CompletionSession { } private boolean shouldRunTopLevelCompletion() { - if (customInvocationCount == 0) { + if (parameters.getInvocationCount() < 2) { return false; } @@ -238,7 +227,7 @@ class CompletionSession { } private boolean shouldRunExtensionsCompletion() { - return !(customInvocationCount == 0 && jetResult.getResult().getPrefixMatcher().getPrefix().length() < 3); + return !(parameters.getInvocationCount() <= 1 && jetResult.getResult().getPrefixMatcher().getPrefix().length() < 3); } private void addReferenceVariants(@NotNull final Condition filterCondition) { @@ -256,7 +245,7 @@ class CompletionSession { } private boolean isVisibleDescriptor(DeclarationDescriptor descriptor) { - if (customInvocationCount >= 2) { + if (parameters.getInvocationCount() >= 2) { // Show everything if user insist on showing completion list return true; } @@ -287,7 +276,7 @@ class CompletionSession { return jetResult; } - public int getCustomInvocationCount() { - return customInvocationCount; + public CompletionParameters getParameters() { + return parameters; } } diff --git a/idea/src/org/jetbrains/jet/plugin/completion/JetCompletionContributor.java b/idea/src/org/jetbrains/jet/plugin/completion/JetCompletionContributor.java index 4e4584f6194..178a8bfaed6 100644 --- a/idea/src/org/jetbrains/jet/plugin/completion/JetCompletionContributor.java +++ b/idea/src/org/jetbrains/jet/plugin/completion/JetCompletionContributor.java @@ -36,33 +36,36 @@ public class JetCompletionContributor extends CompletionContributor { ProcessingContext context, @NotNull CompletionResultSet result ) { - - PsiElement position = parameters.getPosition(); - if (!(position.getContainingFile() instanceof JetFile)) { - return; - } - - JetSimpleNameReference jetReference = getJetReference(parameters); - if (jetReference != null) { - result.restartCompletionWhenNothingMatches(); - CompletionSession session = new CompletionSession(parameters, result, jetReference, position); - - session.completeForReference(); - - if (!session.getJetResult().isSomethingAdded() && session.getCustomInvocationCount() == 0) { - // Rerun completion if nothing was found - session = new CompletionSession(parameters, result, jetReference, position, 1); - - session.completeForReference(); - } - } - - // Prevent from adding reference variants from standard reference contributor - result.stopHere(); + doSimpleReferenceCompletion(parameters, result); } }); } + public static void doSimpleReferenceCompletion(CompletionParameters parameters, CompletionResultSet result) { + PsiElement position = parameters.getPosition(); + + if (!(position.getContainingFile() instanceof JetFile)) { + return; + } + + JetSimpleNameReference jetReference = getJetReference(parameters); + if (jetReference != null) { + result.restartCompletionWhenNothingMatches(); + + CompletionSession session = new CompletionSession(parameters, result, jetReference, position); + session.completeForReference(); + + if (!session.getJetResult().isSomethingAdded() && session.getParameters().getInvocationCount() < 2) { + // Rerun completion if nothing was found + session = new CompletionSession(parameters.withInvocationCount(2), result, jetReference, position); + session.completeForReference(); + } + + // Prevent from adding reference variants from standard reference contributor + result.stopHere(); + } + } + @Nullable private static JetSimpleNameReference getJetReference(@NotNull CompletionParameters parameters) { PsiElement element = parameters.getPosition(); @@ -81,4 +84,18 @@ public class JetCompletionContributor extends CompletionContributor { return null; } + + @Override + public void beforeCompletion(@NotNull CompletionInitializationContext context) { + if (context.getCompletionType() == CompletionType.BASIC && context.getFile() instanceof JetFile) { + PsiElement position = context.getFile().findElementAt(Math.max(0, context.getStartOffset() - 1)); + + if (JetPackagesContributor.ACTIVATION_PATTERN.accepts(position)) { + context.setDummyIdentifier(JetPackagesContributor.DUMMY_IDENTIFIER); + } + else if (JetExtensionReceiverTypeContributor.ACTIVATION_PATTERN.accepts(position)) { + context.setDummyIdentifier(JetExtensionReceiverTypeContributor.DUMMY_IDENTIFIER); + } + } + } } diff --git a/idea/src/org/jetbrains/jet/plugin/completion/JetExtensionReceiverTypeContributor.java b/idea/src/org/jetbrains/jet/plugin/completion/JetExtensionReceiverTypeContributor.java index 778ea5519f5..3f7a369a7f1 100644 --- a/idea/src/org/jetbrains/jet/plugin/completion/JetExtensionReceiverTypeContributor.java +++ b/idea/src/org/jetbrains/jet/plugin/completion/JetExtensionReceiverTypeContributor.java @@ -22,36 +22,16 @@ import com.intellij.patterns.PlatformPatterns; import com.intellij.psi.PsiElement; import com.intellij.util.ProcessingContext; import org.jetbrains.annotations.NotNull; -import org.jetbrains.jet.lang.psi.JetFile; -import org.jetbrains.jet.lang.resolve.lazy.ResolveSession; import org.jetbrains.jet.lexer.JetTokens; -import org.jetbrains.jet.plugin.project.WholeProjectAnalyzerFacade; /** * Special contributor for getting completion of type for extensions receiver. */ public class JetExtensionReceiverTypeContributor extends CompletionContributor { - private static class ReceiverTypeCompletionProvider extends CompletionProvider { - @Override - protected void addCompletions(@NotNull CompletionParameters parameters, - ProcessingContext context, - @NotNull CompletionResultSet result - ) { - ResolveSession resolveSession = WholeProjectAnalyzerFacade.getLazyResolveSessionForFile( - (JetFile) parameters.getPosition().getContainingFile()); - JetCompletionResultSet jetCompletionResultSet = new JetCompletionResultSet( - result, resolveSession, resolveSession.getBindingContext()); + static final String DUMMY_IDENTIFIER = "KotlinExtensionDummy.fake() {}"; - if (parameters.getInvocationCount() > 0) { - JetTypesCompletionHelper.addJetTypes(parameters, jetCompletionResultSet); - } - - result.stopHere(); - } - } - - private static final ElementPattern ACTIVATION_PATTERN = + static final ElementPattern ACTIVATION_PATTERN = // TODO: Check for fun with generic type parameters PlatformPatterns.psiElement().afterLeaf( JetTokens.FUN_KEYWORD.toString(), @@ -59,7 +39,17 @@ public class JetExtensionReceiverTypeContributor extends CompletionContributor { JetTokens.VAR_KEYWORD.toString()); public JetExtensionReceiverTypeContributor() { - extend(CompletionType.BASIC, ACTIVATION_PATTERN, new ReceiverTypeCompletionProvider()); - extend(CompletionType.CLASS_NAME, ACTIVATION_PATTERN, new ReceiverTypeCompletionProvider()); + extend(CompletionType.BASIC, ACTIVATION_PATTERN, new CompletionProvider() { + @Override + protected void addCompletions( + @NotNull CompletionParameters parameters, ProcessingContext context, @NotNull CompletionResultSet result + ) { + if (parameters.getInvocationCount() > 0) { + JetCompletionContributor.doSimpleReferenceCompletion(parameters, result); + } + + result.stopHere(); + } + }); } } diff --git a/idea/src/org/jetbrains/jet/plugin/completion/JetPackagesContributor.java b/idea/src/org/jetbrains/jet/plugin/completion/JetPackagesContributor.java index d900b8c8777..7e60b010acf 100644 --- a/idea/src/org/jetbrains/jet/plugin/completion/JetPackagesContributor.java +++ b/idea/src/org/jetbrains/jet/plugin/completion/JetPackagesContributor.java @@ -18,18 +18,18 @@ package org.jetbrains.jet.plugin.completion; import com.intellij.codeInsight.completion.*; import com.intellij.codeInsight.lookup.LookupElement; +import com.intellij.patterns.ElementPattern; import com.intellij.patterns.PlatformPatterns; import com.intellij.psi.PsiElement; import com.intellij.psi.PsiReference; -import com.intellij.psi.util.PsiTreeUtil; import com.intellij.util.ProcessingContext; import org.jetbrains.annotations.NotNull; -import org.jetbrains.jet.plugin.codeInsight.TipsManager; import org.jetbrains.jet.lang.psi.JetFile; import org.jetbrains.jet.lang.psi.JetNamespaceHeader; import org.jetbrains.jet.lang.resolve.BindingContext; import org.jetbrains.jet.lang.resolve.lazy.ResolveSession; import org.jetbrains.jet.lang.resolve.lazy.ResolveSessionUtils; +import org.jetbrains.jet.plugin.codeInsight.TipsManager; import org.jetbrains.jet.plugin.project.WholeProjectAnalyzerFacade; import org.jetbrains.jet.plugin.references.JetSimpleNameReference; @@ -39,10 +39,14 @@ import org.jetbrains.jet.plugin.references.JetSimpleNameReference; */ public class JetPackagesContributor extends CompletionContributor { - private static final String DUMMY_IDENTIFIER = "___package___"; + static final String DUMMY_IDENTIFIER = "___package___"; + + static final ElementPattern ACTIVATION_PATTERN = + PlatformPatterns.psiElement().inside(JetNamespaceHeader.class); + public JetPackagesContributor() { - extend(CompletionType.BASIC, PlatformPatterns.psiElement(), + extend(CompletionType.BASIC, ACTIVATION_PATTERN, new CompletionProvider() { @Override protected void addCompletions(@NotNull CompletionParameters parameters, ProcessingContext context, @@ -53,11 +57,6 @@ public class JetPackagesContributor extends CompletionContributor { return; } - JetNamespaceHeader namespaceHeader = PsiTreeUtil.getParentOfType(position, JetNamespaceHeader.class); - if (namespaceHeader == null) { - return; - } - PsiReference ref = parameters.getPosition().getContainingFile().findReferenceAt(parameters.getOffset()); if (ref instanceof JetSimpleNameReference) { @@ -88,11 +87,4 @@ public class JetPackagesContributor extends CompletionContributor { } }); } - - @Override - public void beforeCompletion(@NotNull CompletionInitializationContext context) { - // Will need to filter this dummy identifier to avoid showing it in completion - context.setDummyIdentifier(DUMMY_IDENTIFIER); - // context.setDummyIdentifier(CompletionInitializationContext.DUMMY_IDENTIFIER); - } } diff --git a/idea/src/org/jetbrains/jet/plugin/completion/JetTypesCompletionHelper.java b/idea/src/org/jetbrains/jet/plugin/completion/JetTypesCompletionHelper.java index 29fba8b8ce4..dfa655bf92f 100644 --- a/idea/src/org/jetbrains/jet/plugin/completion/JetTypesCompletionHelper.java +++ b/idea/src/org/jetbrains/jet/plugin/completion/JetTypesCompletionHelper.java @@ -42,6 +42,8 @@ public class JetTypesCompletionHelper { @NotNull CompletionParameters parameters, @NotNull JetCompletionResultSet jetCompletionResult ) { + assert parameters.getInvocationCount() >= 2: "Method should be used only for force completion. In other case complete classes from scope"; + jetCompletionResult.addAllElements(KotlinBuiltIns.getInstance().getNonPhysicalClasses()); Project project = parameters.getOriginalFile().getProject(); @@ -57,7 +59,7 @@ public class JetTypesCompletionHelper { /** * Add java elements with performing conversion to kotlin elements if necessary. */ - static void addAdaptedJavaCompletion( + private static void addAdaptedJavaCompletion( @NotNull CompletionParameters parameters, @NotNull final JetCompletionResultSet jetCompletionResult ) { diff --git a/idea/testData/completion/basic/common/ExtensionForProperty.kt b/idea/testData/completion/basic/common/ExtensionForProperty.kt index d89b58a6a81..e943ea36aed 100644 --- a/idea/testData/completion/basic/common/ExtensionForProperty.kt +++ b/idea/testData/completion/basic/common/ExtensionForProperty.kt @@ -1,8 +1,11 @@ class Test { - val Str + val St } // TIME: 1 // EXIST: String~(jet) -// EXIST: StringBuilder +// EXIST: IllegalStateException +// EXIST_JAVA_ONLY: StringBuilder // EXIST_JAVA_ONLY: StringBuffer +// ABSENT: HTMLStyleElement +// ABSENT: Statement@Statement~(java.sql) diff --git a/idea/testData/completion/basic/common/ExtensionFunReceiverForce.kt b/idea/testData/completion/basic/common/ExtensionFunReceiverForce.kt new file mode 100644 index 00000000000..e58e0b8ff6b --- /dev/null +++ b/idea/testData/completion/basic/common/ExtensionFunReceiverForce.kt @@ -0,0 +1,11 @@ +class Test { + val St +} + +// TIME: 2 +// EXIST: String~(jet) +// EXIST: IllegalStateException +// EXIST: StringBuilder +// EXIST_JAVA_ONLY: StringBuffer +// EXIST_JS_ONLY: HTMLStyleElement +// EXIST_JAVA_ONLY: Statement@Statement~(java.sql) diff --git a/idea/testData/completion/basic/common/ExtensionInsideFunction.kt b/idea/testData/completion/basic/common/ExtensionInsideFunction.kt new file mode 100644 index 00000000000..0abe4c1c584 --- /dev/null +++ b/idea/testData/completion/basic/common/ExtensionInsideFunction.kt @@ -0,0 +1,22 @@ +class StrSome { + class StrOther + + fun more() { + class StrInFun + + fun Str + } +} + +class StrMore { + class StrAbsent +} + +// TIME: 1 +// EXIST: String~(jet) +// EXIST: StrSome +// EXIST: StrMore +// EXIST: StrInFun +// EXIST_JAVA_ONLY: StringBuilder +// EXIST_JAVA_ONLY: StringBuffer +// ABSENT: StrAbsent \ No newline at end of file diff --git a/idea/testData/completion/basic/common/InParametersTypes.kt b/idea/testData/completion/basic/common/InParametersTypes.kt new file mode 100644 index 00000000000..30e9c5ff74d --- /dev/null +++ b/idea/testData/completion/basic/common/InParametersTypes.kt @@ -0,0 +1,14 @@ +class SomeClass { + class SomeInternal + + fun some(a : S) +} + +// TIME: 1 +// EXIST: SomeClass, SomeInternal +// EXIST: String~(jet) +// EXIST: IllegalStateException +// EXIST_JAVA_ONLY: StringBuilder +// EXIST_JAVA_ONLY: StringBuffer +// ABSENT: HTMLStyleElement +// ABSENT: Statement@Statement~(java.sql) \ No newline at end of file diff --git a/idea/testData/completion/basic/common/InParametersTypesForce.kt b/idea/testData/completion/basic/common/InParametersTypesForce.kt new file mode 100644 index 00000000000..3494cd6674a --- /dev/null +++ b/idea/testData/completion/basic/common/InParametersTypesForce.kt @@ -0,0 +1,14 @@ +class SomeClass { + class SomeInternal + + fun some(a : S) +} + +// TIME: 2 +// EXIST: SomeClass, SomeInternal +// EXIST: String~(jet) +// EXIST: IllegalStateException +// EXIST: StringBuilder +// EXIST_JAVA_ONLY: StringBuffer +// EXIST_JS_ONLY: HTMLStyleElement +// EXIST_JAVA_ONLY: Statement@Statement~(java.sql) \ No newline at end of file diff --git a/idea/testData/completion/basic/java/AutoForceCompletion.kt b/idea/testData/completion/basic/java/AutoForceCompletion.kt new file mode 100644 index 00000000000..8737bea6d24 --- /dev/null +++ b/idea/testData/completion/basic/java/AutoForceCompletion.kt @@ -0,0 +1,4 @@ +fun some(a : Statement) + +// TIME: 1 +// EXIST: Statement@Statement~(java.sql) \ No newline at end of file diff --git a/idea/testData/completion/basic/java/PropertyMetadata.kt b/idea/testData/completion/basic/java/PropertyMetadata.kt index 9ff24e328e8..6d19763b980 100644 --- a/idea/testData/completion/basic/java/PropertyMetadata.kt +++ b/idea/testData/completion/basic/java/PropertyMetadata.kt @@ -8,4 +8,4 @@ fun firstFun() { // TIME: 1 // EXIST: PropertyMetadata@PropertyMetadata~(jet) // EXIST: PropertyMetadataImpl@PropertyMetadataImpl~(jet) -// NUMBER: 4 +// NUMBER: 2 diff --git a/idea/testData/completion/basic/js/AutoForceCompletion.kt b/idea/testData/completion/basic/js/AutoForceCompletion.kt new file mode 100644 index 00000000000..1caa404a088 --- /dev/null +++ b/idea/testData/completion/basic/js/AutoForceCompletion.kt @@ -0,0 +1,4 @@ +fun some(a : HTMLStyle) + +// TIME: 1 +// EXIST: HTMLStyleElement diff --git a/idea/tests/org/jetbrains/jet/completion/JetBasicJSCompletionTestGenerated.java b/idea/tests/org/jetbrains/jet/completion/JetBasicJSCompletionTestGenerated.java index c5a058ae5d1..b0adf6cbd8c 100644 --- a/idea/tests/org/jetbrains/jet/completion/JetBasicJSCompletionTestGenerated.java +++ b/idea/tests/org/jetbrains/jet/completion/JetBasicJSCompletionTestGenerated.java @@ -129,6 +129,16 @@ public class JetBasicJSCompletionTestGenerated extends AbstractJetJSCompletionTe doTest("idea/testData/completion/basic/common/ExtensionFunReceiver.kt"); } + @TestMetadata("ExtensionFunReceiverForce.kt") + public void testExtensionFunReceiverForce() throws Exception { + doTest("idea/testData/completion/basic/common/ExtensionFunReceiverForce.kt"); + } + + @TestMetadata("ExtensionInsideFunction.kt") + public void testExtensionInsideFunction() throws Exception { + doTest("idea/testData/completion/basic/common/ExtensionInsideFunction.kt"); + } + @TestMetadata("ExtensionWithAdditionalTypeParameters.kt") public void testExtensionWithAdditionalTypeParameters() throws Exception { doTest("idea/testData/completion/basic/common/ExtensionWithAdditionalTypeParameters.kt"); @@ -254,6 +264,16 @@ public class JetBasicJSCompletionTestGenerated extends AbstractJetJSCompletionTe doTest("idea/testData/completion/basic/common/InPackageBegin.kt"); } + @TestMetadata("InParametersTypes.kt") + public void testInParametersTypes() throws Exception { + doTest("idea/testData/completion/basic/common/InParametersTypes.kt"); + } + + @TestMetadata("InParametersTypesForce.kt") + public void testInParametersTypesForce() throws Exception { + doTest("idea/testData/completion/basic/common/InParametersTypesForce.kt"); + } + @TestMetadata("InTypeAnnotation.kt") public void testInTypeAnnotation() throws Exception { doTest("idea/testData/completion/basic/common/InTypeAnnotation.kt"); @@ -426,6 +446,11 @@ public class JetBasicJSCompletionTestGenerated extends AbstractJetJSCompletionTe JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.GenerateTests", new File("idea/testData/completion/basic/js"), Pattern.compile("^(.+)\\.kt$"), true); } + @TestMetadata("AutoForceCompletion.kt") + public void testAutoForceCompletion() throws Exception { + doTest("idea/testData/completion/basic/js/AutoForceCompletion.kt"); + } + @TestMetadata("InPackage.kt") public void testInPackage() throws Exception { doTest("idea/testData/completion/basic/js/InPackage.kt"); diff --git a/idea/tests/org/jetbrains/jet/completion/JetBasicJavaCompletionTestGenerated.java b/idea/tests/org/jetbrains/jet/completion/JetBasicJavaCompletionTestGenerated.java index 8a8c8e48997..3aea26c832e 100644 --- a/idea/tests/org/jetbrains/jet/completion/JetBasicJavaCompletionTestGenerated.java +++ b/idea/tests/org/jetbrains/jet/completion/JetBasicJavaCompletionTestGenerated.java @@ -129,6 +129,16 @@ public class JetBasicJavaCompletionTestGenerated extends AbstractJavaCompletionT doTest("idea/testData/completion/basic/common/ExtensionFunReceiver.kt"); } + @TestMetadata("ExtensionFunReceiverForce.kt") + public void testExtensionFunReceiverForce() throws Exception { + doTest("idea/testData/completion/basic/common/ExtensionFunReceiverForce.kt"); + } + + @TestMetadata("ExtensionInsideFunction.kt") + public void testExtensionInsideFunction() throws Exception { + doTest("idea/testData/completion/basic/common/ExtensionInsideFunction.kt"); + } + @TestMetadata("ExtensionWithAdditionalTypeParameters.kt") public void testExtensionWithAdditionalTypeParameters() throws Exception { doTest("idea/testData/completion/basic/common/ExtensionWithAdditionalTypeParameters.kt"); @@ -254,6 +264,16 @@ public class JetBasicJavaCompletionTestGenerated extends AbstractJavaCompletionT doTest("idea/testData/completion/basic/common/InPackageBegin.kt"); } + @TestMetadata("InParametersTypes.kt") + public void testInParametersTypes() throws Exception { + doTest("idea/testData/completion/basic/common/InParametersTypes.kt"); + } + + @TestMetadata("InParametersTypesForce.kt") + public void testInParametersTypesForce() throws Exception { + doTest("idea/testData/completion/basic/common/InParametersTypesForce.kt"); + } + @TestMetadata("InTypeAnnotation.kt") public void testInTypeAnnotation() throws Exception { doTest("idea/testData/completion/basic/common/InTypeAnnotation.kt"); @@ -426,6 +446,11 @@ public class JetBasicJavaCompletionTestGenerated extends AbstractJavaCompletionT JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.GenerateTests", new File("idea/testData/completion/basic/java"), Pattern.compile("^(.+)\\.kt$"), true); } + @TestMetadata("AutoForceCompletion.kt") + public void testAutoForceCompletion() throws Exception { + doTest("idea/testData/completion/basic/java/AutoForceCompletion.kt"); + } + @TestMetadata("ExtensionFromStandardLibrary.kt") public void testExtensionFromStandardLibrary() throws Exception { doTest("idea/testData/completion/basic/java/ExtensionFromStandardLibrary.kt"); From 54e1cf0879208c5edb5897fbf0c370bbf35f6c60 Mon Sep 17 00:00:00 2001 From: Svetlana Isakova Date: Tue, 2 Jul 2013 21:19:28 +0400 Subject: [PATCH 270/291] removed incorrect code from resolve tests Resolve tests had a functionality that for primary constructor parameters class A(val x: Int, y: Int) `$x` was resolved to property descriptor while `x` was resolved to value parameter descriptor. But it worked incorrect (see tests changes) and was senseless because 'x' in code always resolves to property descriptor. So it was dropped. --- .../PrimaryConstructorParameters.resolve | 26 ++++++++------ .../resolve/PrimaryConstructors.resolve | 10 +++--- .../jet/resolve/ExpectedResolveData.java | 35 +++---------------- 3 files changed, 24 insertions(+), 47 deletions(-) diff --git a/compiler/testData/resolve/PrimaryConstructorParameters.resolve b/compiler/testData/resolve/PrimaryConstructorParameters.resolve index 7e571f43347..2d398d0acdd 100644 --- a/compiler/testData/resolve/PrimaryConstructorParameters.resolve +++ b/compiler/testData/resolve/PrimaryConstructorParameters.resolve @@ -1,21 +1,25 @@ class C(~x~x : Int, ~y~val y : Int) : Base(`x`x /*parameter*/), Base1 by Base1(`x`x) { - var z = `x`x // parameter - get() = `$x`x // property + var zx = `x`x // parameter + get() = `!`x // inaccessible + + var zy = `y`y // parameter + get() = `y`y // property { - val z = `x`x // parameter + val wx = `x`x + val wy = `y`y } - val foo = `$y`y + val fx = `x`x + val fy = `y`y - this() : this(1, 2) { - val z = x // inaccessible - val zz = `$y`y // property - } - - fun f() : Int { - return `$x`x // property + fun test() { + val ux = `!`x // inaccessible + val uy = `y`y // property } } +class D(~a~a: Int) { + val a = `a`a +} \ No newline at end of file diff --git a/compiler/testData/resolve/PrimaryConstructors.resolve b/compiler/testData/resolve/PrimaryConstructors.resolve index 851d2f3321d..74a50a58f68 100644 --- a/compiler/testData/resolve/PrimaryConstructors.resolve +++ b/compiler/testData/resolve/PrimaryConstructors.resolve @@ -1,20 +1,20 @@ class A(~a~val a : Int) { - ~b~val b = `$a`a - ~f~fun f() = `$a`a + ~b~val b = `a`a + ~f~fun f() = `a`a } fun test() { ~va~val a = A() - `va`a.`$a`a`:kotlin::Int` + `va`a.`a`a`:kotlin::Int` a.`b`b`:kotlin::Int` a.`f`f()`:kotlin::Int` } class Foo(~bar~var bar : Int, ~barr~barr : Int, ~barrr~val barrr : Int) { { - `$bar`bar = 1 + `bar`bar = 1 `barr`barr = 1 - `$barrr`barrr = 1 + `barrr`barrr = 1 } } diff --git a/compiler/tests/org/jetbrains/jet/resolve/ExpectedResolveData.java b/compiler/tests/org/jetbrains/jet/resolve/ExpectedResolveData.java index 3d0dd6e488d..98f243d90a8 100644 --- a/compiler/tests/org/jetbrains/jet/resolve/ExpectedResolveData.java +++ b/compiler/tests/org/jetbrains/jet/resolve/ExpectedResolveData.java @@ -27,10 +27,7 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.jet.analyzer.AnalyzeExhaust; import org.jetbrains.jet.cli.jvm.compiler.JetCoreEnvironment; -import org.jetbrains.jet.lang.descriptors.ClassDescriptor; -import org.jetbrains.jet.lang.descriptors.ClassifierDescriptor; -import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor; -import org.jetbrains.jet.lang.descriptors.TypeParameterDescriptor; +import org.jetbrains.jet.lang.descriptors.*; import org.jetbrains.jet.lang.diagnostics.Diagnostic; import org.jetbrains.jet.lang.diagnostics.DiagnosticUtils; import org.jetbrains.jet.lang.diagnostics.Errors; @@ -239,9 +236,6 @@ public abstract class ExpectedResolveData { } PsiElement expected = nameToDeclaration.get(name); - if (expected == null && name.startsWith("$")) { - expected = nameToDeclaration.get(name.substring(1)); - } if (expected == null) { expected = nameToPsiElement.get(name); } @@ -281,30 +275,9 @@ public abstract class ExpectedResolveData { } assertNotNull(element.getText(), reference); - if (expected instanceof JetParameter || actual instanceof JetParameter) { - DeclarationDescriptor expectedDescriptor; - if (name.startsWith("$")) { - expectedDescriptor = bindingContext.get(BindingContext.PRIMARY_CONSTRUCTOR_PARAMETER, (JetParameter) expected); - } - else { - expectedDescriptor = bindingContext.get(BindingContext.DECLARATION_TO_DESCRIPTOR, expected); - if (expectedDescriptor == null) { - expectedDescriptor = bindingContext.get(BindingContext.CONSTRUCTOR, (JetElement) expected); - } - } - - - DeclarationDescriptor actualDescriptor = bindingContext.get(REFERENCE_TARGET, reference); - - assertEquals( - "Reference `" + name + "`" + renderReferenceInContext(reference) + " is resolved into " + actualName + ".", - expectedDescriptor, actualDescriptor); - } - else { - assertEquals( - "Reference `" + name + "`" + renderReferenceInContext(reference) + " is resolved into " + actualName + ".", - expected.getText(), actual != null ? actual.getText() : null); - } + assertEquals( + "Reference `" + name + "`" + renderReferenceInContext(reference) + " is resolved into " + actualName + ".", + expected, actual); } for (Map.Entry entry : positionToType.entrySet()) { From 9347a48df8bab84786e945d154963d7c9a0bfb8c Mon Sep 17 00:00:00 2001 From: Svetlana Isakova Date: Tue, 2 Jul 2013 21:50:11 +0400 Subject: [PATCH 271/291] restored priorities members with invoke have more priority than extensions --- .../calls/tasks/ResolutionTaskHolder.java | 6 ++ .../resolve/calls/tasks/TaskPrioritizer.java | 75 +++++++++++-------- .../memberWithInvokeVsNonLocal.resolve | 8 ++ .../jet/resolve/JetResolveTestGenerated.java | 5 ++ 4 files changed, 62 insertions(+), 32 deletions(-) create mode 100644 compiler/testData/resolve/candidatesPriority/memberWithInvokeVsNonLocal.resolve diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/tasks/ResolutionTaskHolder.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/tasks/ResolutionTaskHolder.java index b9162fa9ff5..5533913bb59 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/tasks/ResolutionTaskHolder.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/tasks/ResolutionTaskHolder.java @@ -63,6 +63,12 @@ public class ResolutionTaskHolder { } } + public void addCandidates(@NotNull List>> candidatesList) { + for (Collection> candidates : candidatesList) { + addCandidates(candidates); + } + } + public List> getTasks() { if (tasks == null) { tasks = Lists.newArrayList(); 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 099d599d790..908c9d2ea68 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 @@ -89,16 +89,16 @@ public class TaskPrioritizer { } ResolutionTaskHolder result = new ResolutionTaskHolder(functionReference, context, new MyPriorityProvider(context)); - for (CallableDescriptorCollector callableDescriptorCollector : callableDescriptorCollectors) { - doComputeTasks(scope, explicitReceiver, name, result, context, callableDescriptorCollector); - } + doComputeTasks(scope, explicitReceiver, name, result, context, callableDescriptorCollectors); return result.getTasks(); } - private static void doComputeTasks(@NotNull JetScope scope, @NotNull ReceiverValue receiver, + private static void doComputeTasks( + @NotNull JetScope scope, @NotNull ReceiverValue receiver, @NotNull Name name, @NotNull ResolutionTaskHolder result, - @NotNull BasicCallResolutionContext context, @NotNull CallableDescriptorCollector callableDescriptorCollector) { - + @NotNull BasicCallResolutionContext context, + @NotNull List> callableDescriptorCollectors + ) { ProgressIndicatorProvider.checkCanceled(); AutoCastServiceImpl autoCastService = new AutoCastServiceImpl(context.dataFlowInfo, context.trace.getBindingContext()); @@ -110,42 +110,53 @@ public class TaskPrioritizer { if (receiver.exists()) { List variantsForExplicitReceiver = autoCastService.getVariantsForReceiver(receiver); - Collection> members = Lists.newArrayList(); - for (ReceiverValue variant : variantsForExplicitReceiver) { - Collection membersForThisVariant = callableDescriptorCollector.getMembersByName(variant.getType(), name); - convertWithReceivers(membersForThisVariant, Collections.singletonList(variant), - Collections.singletonList(NO_RECEIVER), members, hasExplicitThisObject); + for (CallableDescriptorCollector callableDescriptorCollector : callableDescriptorCollectors) { + Collection> members = Lists.newArrayList(); + for (ReceiverValue variant : variantsForExplicitReceiver) { + Collection membersForThisVariant = callableDescriptorCollector.getMembersByName(variant.getType(), name); + convertWithReceivers(membersForThisVariant, Collections.singletonList(variant), + Collections.singletonList(NO_RECEIVER), members, hasExplicitThisObject); + } + result.addCandidates(members); } - result.addCandidates(members); - - for (ReceiverValue implicitReceiver : implicitReceivers) { - Collection memberExtensions = callableDescriptorCollector.getNonMembersByName( - implicitReceiver.getType().getMemberScope(), name); - List variantsForImplicitReceiver = autoCastService.getVariantsForReceiver(implicitReceiver); - result.addCandidates(convertWithReceivers(memberExtensions, variantsForImplicitReceiver, - variantsForExplicitReceiver, hasExplicitThisObject)); + for (CallableDescriptorCollector callableDescriptorCollector : callableDescriptorCollectors) { + for (ReceiverValue implicitReceiver : implicitReceivers) { + Collection memberExtensions = callableDescriptorCollector.getNonMembersByName( + implicitReceiver.getType().getMemberScope(), name); + List variantsForImplicitReceiver = autoCastService.getVariantsForReceiver(implicitReceiver); + result.addCandidates(convertWithReceivers(memberExtensions, variantsForImplicitReceiver, + variantsForExplicitReceiver, hasExplicitThisObject)); + } + Collection> extensionFunctions = convertWithImpliedThis( + scope, variantsForExplicitReceiver, callableDescriptorCollector.getNonMembersByName(scope, name)); + result.addCandidates(extensionFunctions); } - - Collection> extensionFunctions = convertWithImpliedThis( - scope, variantsForExplicitReceiver, callableDescriptorCollector.getNonMembersByName(scope, name)); - result.addCandidates(extensionFunctions); } else { - Collection> functions = convertWithImpliedThis(scope, Collections.singletonList(receiver), callableDescriptorCollector - .getNonExtensionsByName(scope, name)); + List>> localsList = Lists.newArrayList(); + List>> nonlocalsList = Lists.newArrayList(); + for (CallableDescriptorCollector callableDescriptorCollector : callableDescriptorCollectors) { - List> nonlocals = Lists.newArrayList(); - List> locals = Lists.newArrayList(); - //noinspection unchecked,RedundantTypeArguments - TaskPrioritizer.splitLexicallyLocalDescriptors(functions, scope.getContainingDeclaration(), locals, nonlocals); + Collection> functions = + convertWithImpliedThis(scope, Collections.singletonList(receiver), callableDescriptorCollector + .getNonExtensionsByName(scope, name)); - result.addCandidates(locals); + List> nonlocals = Lists.newArrayList(); + List> locals = Lists.newArrayList(); + //noinspection unchecked,RedundantTypeArguments + TaskPrioritizer.splitLexicallyLocalDescriptors(functions, scope.getContainingDeclaration(), locals, nonlocals); + + localsList.add(locals); + nonlocalsList.add(nonlocals); + } + + result.addCandidates(localsList); for (ReceiverValue implicitReceiver : implicitReceivers) { - doComputeTasks(scope, implicitReceiver, name, result, context, callableDescriptorCollector); + doComputeTasks(scope, implicitReceiver, name, result, context, callableDescriptorCollectors); } - result.addCandidates(nonlocals); + result.addCandidates(nonlocalsList); } } diff --git a/compiler/testData/resolve/candidatesPriority/memberWithInvokeVsNonLocal.resolve b/compiler/testData/resolve/candidatesPriority/memberWithInvokeVsNonLocal.resolve new file mode 100644 index 00000000000..ba5f8457364 --- /dev/null +++ b/compiler/testData/resolve/candidatesPriority/memberWithInvokeVsNonLocal.resolve @@ -0,0 +1,8 @@ +annotation class data + +public class BinaryResponse(~data~val data: () -> String) { + fun writeResponse() { + + `data`data() + } +} diff --git a/compiler/tests/org/jetbrains/jet/resolve/JetResolveTestGenerated.java b/compiler/tests/org/jetbrains/jet/resolve/JetResolveTestGenerated.java index 5b23f67300b..dc85ba28418 100644 --- a/compiler/tests/org/jetbrains/jet/resolve/JetResolveTestGenerated.java +++ b/compiler/tests/org/jetbrains/jet/resolve/JetResolveTestGenerated.java @@ -228,6 +228,11 @@ public class JetResolveTestGenerated extends AbstractResolveTest { doTest("compiler/testData/resolve/candidatesPriority/memberVsLocalExtension.resolve"); } + @TestMetadata("memberWithInvokeVsNonLocal.resolve") + public void testMemberWithInvokeVsNonLocal() throws Exception { + doTest("compiler/testData/resolve/candidatesPriority/memberWithInvokeVsNonLocal.resolve"); + } + @TestMetadata("receiverVsThisObject.resolve") public void testReceiverVsThisObject() throws Exception { doTest("compiler/testData/resolve/candidatesPriority/receiverVsThisObject.resolve"); From cf5c5dba3dc602aa91b9be68fdc2a00b494d9aeb Mon Sep 17 00:00:00 2001 From: Svetlana Isakova Date: Thu, 4 Jul 2013 14:14:35 +0400 Subject: [PATCH 272/291] KT-3189 Function invoke is called with no reason prioritize tasks specially for invoke #KT-3189 Fixed #KT-3190 Fixed #KT-3297 Fixed --- .../resolve/calls/tasks/TaskPrioritizer.java | 246 +++++++++++++----- .../box/functions/{ => invoke}/invoke.kt | 0 .../codegen/box/functions/invoke/kt3189.kt | 15 ++ .../codegen/box/functions/invoke/kt3190.kt | 24 ++ .../codegen/box/functions/invoke/kt3297.kt | 17 ++ .../tests/resolve/invoke/invokeAsExtension.kt | 63 +++++ .../tests/resolve/invoke/invokeAsMember.kt | 62 +++++ .../resolve/invoke/invokeAsMemberExtension.kt | 125 +++++++++ ...vokeAsMemberExtensionToExplicitReceiver.kt | 12 + .../checkers/JetDiagnosticsTestGenerated.java | 37 ++- .../BlackBoxCodegenTestGenerated.java | 36 ++- 11 files changed, 567 insertions(+), 70 deletions(-) rename compiler/testData/codegen/box/functions/{ => invoke}/invoke.kt (100%) create mode 100644 compiler/testData/codegen/box/functions/invoke/kt3189.kt create mode 100644 compiler/testData/codegen/box/functions/invoke/kt3190.kt create mode 100644 compiler/testData/codegen/box/functions/invoke/kt3297.kt create mode 100644 compiler/testData/diagnostics/tests/resolve/invoke/invokeAsExtension.kt create mode 100644 compiler/testData/diagnostics/tests/resolve/invoke/invokeAsMember.kt create mode 100644 compiler/testData/diagnostics/tests/resolve/invoke/invokeAsMemberExtension.kt create mode 100644 compiler/testData/diagnostics/tests/resolve/invoke/invokeAsMemberExtensionToExplicitReceiver.kt 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 908c9d2ea68..e2d2788afc7 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 @@ -75,8 +75,12 @@ public class TaskPrioritizer { } @NotNull - public static List> computePrioritizedTasks(@NotNull final BasicCallResolutionContext context, @NotNull Name name, - @NotNull JetReferenceExpression functionReference, @NotNull List> callableDescriptorCollectors) { + public static List> computePrioritizedTasks( + @NotNull BasicCallResolutionContext context, + @NotNull Name name, + @NotNull JetReferenceExpression functionReference, + @NotNull List> callableDescriptorCollectors + ) { ReceiverValue explicitReceiver = context.call.getExplicitReceiver(); JetScope scope; if (explicitReceiver.exists() && explicitReceiver.getType() instanceof NamespaceType) { @@ -89,88 +93,176 @@ public class TaskPrioritizer { } ResolutionTaskHolder result = new ResolutionTaskHolder(functionReference, context, new MyPriorityProvider(context)); - doComputeTasks(scope, explicitReceiver, name, result, context, callableDescriptorCollectors); + TaskPrioritizerContext c = new TaskPrioritizerContext(name, result, context, scope, callableDescriptorCollectors); + doComputeTasks(explicitReceiver, c); return result.getTasks(); } private static void doComputeTasks( - @NotNull JetScope scope, @NotNull ReceiverValue receiver, - @NotNull Name name, @NotNull ResolutionTaskHolder result, - @NotNull BasicCallResolutionContext context, - @NotNull List> callableDescriptorCollectors + @NotNull ReceiverValue receiver, + @NotNull TaskPrioritizerContext c ) { ProgressIndicatorProvider.checkCanceled(); - AutoCastServiceImpl autoCastService = new AutoCastServiceImpl(context.dataFlowInfo, context.trace.getBindingContext()); - List implicitReceivers = JetScopeUtils.getImplicitReceiversHierarchyValues(scope); - boolean hasExplicitThisObject = context.call.getThisObject().exists(); - if (hasExplicitThisObject) { - implicitReceivers.add(context.call.getThisObject()); + boolean resolveInvoke = c.context.call.getThisObject().exists(); + if (resolveInvoke) { + addCandidatesForInvoke(receiver, c); + return; } + List implicitReceivers = JetScopeUtils.getImplicitReceiversHierarchyValues(c.scope); if (receiver.exists()) { - List variantsForExplicitReceiver = autoCastService.getVariantsForReceiver(receiver); - - for (CallableDescriptorCollector callableDescriptorCollector : callableDescriptorCollectors) { - Collection> members = Lists.newArrayList(); - for (ReceiverValue variant : variantsForExplicitReceiver) { - Collection membersForThisVariant = callableDescriptorCollector.getMembersByName(variant.getType(), name); - convertWithReceivers(membersForThisVariant, Collections.singletonList(variant), - Collections.singletonList(NO_RECEIVER), members, hasExplicitThisObject); - } - result.addCandidates(members); - } - - for (CallableDescriptorCollector callableDescriptorCollector : callableDescriptorCollectors) { - for (ReceiverValue implicitReceiver : implicitReceivers) { - Collection memberExtensions = callableDescriptorCollector.getNonMembersByName( - implicitReceiver.getType().getMemberScope(), name); - List variantsForImplicitReceiver = autoCastService.getVariantsForReceiver(implicitReceiver); - result.addCandidates(convertWithReceivers(memberExtensions, variantsForImplicitReceiver, - variantsForExplicitReceiver, hasExplicitThisObject)); - } - Collection> extensionFunctions = convertWithImpliedThis( - scope, variantsForExplicitReceiver, callableDescriptorCollector.getNonMembersByName(scope, name)); - result.addCandidates(extensionFunctions); - } + addCandidatesForExplicitReceiver(receiver, implicitReceivers, c, /*resolveInvoke=*/false); + return; } - else { - List>> localsList = Lists.newArrayList(); - List>> nonlocalsList = Lists.newArrayList(); - for (CallableDescriptorCollector callableDescriptorCollector : callableDescriptorCollectors) { + addCandidatesForNoReceiver(implicitReceivers, c); + } - Collection> functions = - convertWithImpliedThis(scope, Collections.singletonList(receiver), callableDescriptorCollector - .getNonExtensionsByName(scope, name)); + private static void addCandidatesForExplicitReceiver( + @NotNull ReceiverValue receiver, + @NotNull List implicitReceivers, + @NotNull TaskPrioritizerContext c, + boolean resolveInvoke + ) { - List> nonlocals = Lists.newArrayList(); - List> locals = Lists.newArrayList(); - //noinspection unchecked,RedundantTypeArguments - TaskPrioritizer.splitLexicallyLocalDescriptors(functions, scope.getContainingDeclaration(), locals, nonlocals); + List variantsForExplicitReceiver = c.autoCastService.getVariantsForReceiver(receiver); - localsList.add(locals); - nonlocalsList.add(nonlocals); + //members + for (CallableDescriptorCollector callableDescriptorCollector : c.callableDescriptorCollectors) { + Collection> members = Lists.newArrayList(); + for (ReceiverValue variant : variantsForExplicitReceiver) { + Collection membersForThisVariant = callableDescriptorCollector.getMembersByName(variant.getType(), c.name); + convertWithReceivers(membersForThisVariant, Collections.singletonList(variant), + Collections.singletonList(NO_RECEIVER), members, resolveInvoke); } + c.result.addCandidates(members); + } - result.addCandidates(localsList); - + for (CallableDescriptorCollector callableDescriptorCollector : c.callableDescriptorCollectors) { + //member extensions for (ReceiverValue implicitReceiver : implicitReceivers) { - doComputeTasks(scope, implicitReceiver, name, result, context, callableDescriptorCollectors); + addMemberExtensionCandidates(implicitReceiver, variantsForExplicitReceiver, + callableDescriptorCollector, c, resolveInvoke); } - result.addCandidates(nonlocalsList); + //extensions + Collection> extensionFunctions = convertWithImpliedThis( + c.scope, variantsForExplicitReceiver, callableDescriptorCollector.getNonMembersByName(c.scope, c.name)); + c.result.addCandidates(extensionFunctions); } } - private static Collection> convertWithReceivers(Collection descriptors, Iterable thisObjects, - Iterable receiverParameters, boolean hasExplicitThisObject) { + private static void addMemberExtensionCandidates( + @NotNull ReceiverValue implicitReceiver, + @NotNull List variantsForExplicitReceiver, + @NotNull CallableDescriptorCollector callableDescriptorCollector, TaskPrioritizerContext c, + boolean resolveInvoke + ) { + Collection memberExtensions = callableDescriptorCollector.getNonMembersByName( + implicitReceiver.getType().getMemberScope(), c.name); + List variantsForImplicitReceiver = c.autoCastService.getVariantsForReceiver(implicitReceiver); + c.result.addCandidates(convertWithReceivers(memberExtensions, variantsForImplicitReceiver, + variantsForExplicitReceiver, resolveInvoke)); + } + private static void addCandidatesForNoReceiver( + @NotNull List implicitReceivers, + @NotNull TaskPrioritizerContext c + ) { + List>> localsList = Lists.newArrayList(); + List>> nonlocalsList = Lists.newArrayList(); + for (CallableDescriptorCollector callableDescriptorCollector : c.callableDescriptorCollectors) { + + Collection> functions = + convertWithImpliedThis(c.scope, Collections.singletonList(NO_RECEIVER), callableDescriptorCollector + .getNonExtensionsByName(c.scope, c.name)); + + List> nonlocals = Lists.newArrayList(); + List> locals = Lists.newArrayList(); + //noinspection unchecked,RedundantTypeArguments + TaskPrioritizer.splitLexicallyLocalDescriptors(functions, c.scope.getContainingDeclaration(), locals, nonlocals); + + localsList.add(locals); + nonlocalsList.add(nonlocals); + } + + //locals + c.result.addCandidates(localsList); + + //try all implicit receivers as explicit + for (ReceiverValue implicitReceiver : implicitReceivers) { + addCandidatesForExplicitReceiver(implicitReceiver, implicitReceivers, c, /*resolveInvoke=*/false); + } + + //nonlocals + c.result.addCandidates(nonlocalsList); + } + + private static void addCandidatesForInvoke( + @NotNull ReceiverValue explicitReceiver, + @NotNull TaskPrioritizerContext c + ) { + List implicitReceivers = JetScopeUtils.getImplicitReceiversHierarchyValues(c.scope); + + // For 'a.foo()' where foo has function type, + // a is explicitReceiver, foo is variableReceiver. + ReceiverValue variableReceiver = c.context.call.getThisObject(); + assert variableReceiver.exists() : "'Invoke' call hasn't got variable receiver"; + + // For invocation a.foo() explicit receiver 'a' + // can be a receiver for 'foo' variable + // or for 'invoke' function. + + // (1) a.foo + foo.invoke() + if (!explicitReceiver.exists()) { + addCandidatesForExplicitReceiver(variableReceiver, implicitReceivers, c, /*resolveInvoke=*/true); + } + + // (2) foo + a.invoke() + + // 'invoke' is member extension to explicit receiver while variable receiver is 'this object' + //trait A + //trait Foo { fun A.invoke() } + + if (explicitReceiver.exists()) { + //a.foo() + addCandidatesWhenInvokeIsMemberExtensionToExplicitReceiver(variableReceiver, explicitReceiver, c); + return; + } + // with (a) { foo() } + for (ReceiverValue implicitReceiver : implicitReceivers) { + addCandidatesWhenInvokeIsMemberExtensionToExplicitReceiver(variableReceiver, implicitReceiver, c); + } + } + + private static void addCandidatesWhenInvokeIsMemberExtensionToExplicitReceiver( + @NotNull ReceiverValue variableReceiver, + @NotNull ReceiverValue explicitReceiver, + @NotNull TaskPrioritizerContext c + ) { + List variantsForExplicitReceiver = c.autoCastService.getVariantsForReceiver(explicitReceiver); + + for (CallableDescriptorCollector callableDescriptorCollector : c.callableDescriptorCollectors) { + addMemberExtensionCandidates(variableReceiver, variantsForExplicitReceiver, callableDescriptorCollector, c, /*resolveInvoke=*/true); + } + } + + private static Collection> convertWithReceivers( + @NotNull Collection descriptors, + @NotNull Iterable thisObjects, + @NotNull Iterable receiverParameters, + boolean hasExplicitThisObject + ) { Collection> result = Lists.newArrayList(); convertWithReceivers(descriptors, thisObjects, receiverParameters, result, hasExplicitThisObject); return result; } - private static void convertWithReceivers(Collection descriptors, Iterable thisObjects, Iterable receiverParameters, - Collection> result, boolean hasExplicitThisObject) { - + private static void convertWithReceivers( + @NotNull Collection descriptors, + @NotNull Iterable thisObjects, + @NotNull Iterable receiverParameters, + @NotNull Collection> result, + boolean hasExplicitThisObject + ) { for (ReceiverValue thisObject : thisObjects) { for (ReceiverValue receiverParameter : receiverParameters) { for (D extension : descriptors) { @@ -189,7 +281,11 @@ public class TaskPrioritizer { } } - public static Collection> convertWithImpliedThis(JetScope scope, Collection receiverParameters, Collection descriptors) { + public static Collection> convertWithImpliedThis( + @NotNull JetScope scope, + @NotNull Collection receiverParameters, + @NotNull Collection descriptors + ) { Collection> result = Lists.newArrayList(); for (ReceiverValue receiverParameter : receiverParameters) { for (D descriptor : descriptors) { @@ -221,7 +317,10 @@ public class TaskPrioritizer { return result; } - private static boolean setImpliedThis(@NotNull JetScope scope, ResolutionCandidate candidate) { + private static boolean setImpliedThis( + @NotNull JetScope scope, + @NotNull ResolutionCandidate candidate + ) { ReceiverParameterDescriptor expectedThisObject = candidate.getDescriptor().getExpectedThisObject(); if (expectedThisObject == null) return true; List receivers = scope.getImplicitReceiversHierarchy(); @@ -245,9 +344,6 @@ public class TaskPrioritizer { return result.getTasks(); } - private TaskPrioritizer() { - } - private static class MyPriorityProvider implements ResolutionTaskHolder.PriorityProvider> { private final BasicCallResolutionContext context; @@ -279,4 +375,28 @@ public class TaskPrioritizer { isOrOverridesSynthesized((CallableMemberDescriptor) descriptor); } } + + private static class TaskPrioritizerContext { + @NotNull public final Name name; + @NotNull public final ResolutionTaskHolder result; + @NotNull public final BasicCallResolutionContext context; + @NotNull public final JetScope scope; + @NotNull public final List> callableDescriptorCollectors; + @NotNull AutoCastServiceImpl autoCastService; + + private TaskPrioritizerContext( + @NotNull Name name, + @NotNull ResolutionTaskHolder result, + @NotNull BasicCallResolutionContext context, + @NotNull JetScope scope, + @NotNull List> callableDescriptorCollectors + ) { + this.name = name; + this.result = result; + this.context = context; + this.scope = scope; + this.callableDescriptorCollectors = callableDescriptorCollectors; + autoCastService = new AutoCastServiceImpl(context.dataFlowInfo, context.trace.getBindingContext()); + } + } } diff --git a/compiler/testData/codegen/box/functions/invoke.kt b/compiler/testData/codegen/box/functions/invoke/invoke.kt similarity index 100% rename from compiler/testData/codegen/box/functions/invoke.kt rename to compiler/testData/codegen/box/functions/invoke/invoke.kt diff --git a/compiler/testData/codegen/box/functions/invoke/kt3189.kt b/compiler/testData/codegen/box/functions/invoke/kt3189.kt new file mode 100644 index 00000000000..149606d0e51 --- /dev/null +++ b/compiler/testData/codegen/box/functions/invoke/kt3189.kt @@ -0,0 +1,15 @@ +//KT-3189 Function invoke is called with no reason + +fun box(): String { + + val bad = Bad({ 1 }) + + return if (bad.test() == 1) "OK" else "fail" +} + +class Bad(val a: () -> Int) { + + fun test(): Int = a() + + fun invoke(): Int = 2 +} \ No newline at end of file diff --git a/compiler/testData/codegen/box/functions/invoke/kt3190.kt b/compiler/testData/codegen/box/functions/invoke/kt3190.kt new file mode 100644 index 00000000000..b0eb6d488be --- /dev/null +++ b/compiler/testData/codegen/box/functions/invoke/kt3190.kt @@ -0,0 +1,24 @@ +//KT-3190 Compiler crash if function called 'invoke' calls a closure + +fun box(): String { + val test = Cached({ it + 2 }) + return if (test(1) == 3) "OK" else "fail" +} + +class Cached(private val generate: (K)->V): jet.Function1 { + val store = java.util.HashMap() + + // Everything works just fine if 'invoke' method is renamed to, for example, 'get' + override fun invoke(p1: K) = store.getOrPut(p1) { generate(p1) } +} + +//from library +fun MutableMap.getOrPut(key: K, defaultValue: ()-> V) : V { + if (this.containsKey(key)) { + return this.get(key) as V + } else { + val answer = defaultValue() + this.put(key, answer) + return answer + } +} diff --git a/compiler/testData/codegen/box/functions/invoke/kt3297.kt b/compiler/testData/codegen/box/functions/invoke/kt3297.kt new file mode 100644 index 00000000000..bfa9d55a77a --- /dev/null +++ b/compiler/testData/codegen/box/functions/invoke/kt3297.kt @@ -0,0 +1,17 @@ +//KT-3297 Calling the wrong function inside an extension method to the Function0 class + +fun Function0.or(alt: () -> R): R { + try { + return this() + } catch (e: Exception) { + return alt() + } +} + +fun box(): String { + return { + throw RuntimeException("fail") + } or { + "OK" + } +} \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/resolve/invoke/invokeAsExtension.kt b/compiler/testData/diagnostics/tests/resolve/invoke/invokeAsExtension.kt new file mode 100644 index 00000000000..f04620b96b6 --- /dev/null +++ b/compiler/testData/diagnostics/tests/resolve/invoke/invokeAsExtension.kt @@ -0,0 +1,63 @@ +class Foo {} + +fun Foo.invoke() {} + +//no variable +fun test(foo: Foo) { + foo() +} + +//variable as member +trait A { + val foo: Foo +} + + +fun test(a: A) { + a.foo() + + with (a) { + foo() + } +} + +//variable as extension +trait B { +} +val B.foo = Foo() + +fun test(b: B) { + b.foo() + + with (b) { + foo() + } +} + +//variable as member extension +trait C + +trait D { + val C.foo: Foo + + fun test(c: C) { + c.foo() + + with (c) { + foo() + } + } +} + +fun test(d: D, c: C) { + with (d) { + c.foo() + + with (c) { + foo() + } + } +} + +//-------------- +fun with(receiver: T, f: T.() -> R) : R = receiver.f() \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/resolve/invoke/invokeAsMember.kt b/compiler/testData/diagnostics/tests/resolve/invoke/invokeAsMember.kt new file mode 100644 index 00000000000..44c8084cbeb --- /dev/null +++ b/compiler/testData/diagnostics/tests/resolve/invoke/invokeAsMember.kt @@ -0,0 +1,62 @@ +class Foo { + fun invoke() {} +} + +//no variable +fun test(foo: Foo) { + foo() +} + +//variable as member +trait A { + val foo: Foo +} + +fun test(a: A) { + a.foo() + + with (a) { + foo() + } +} + +//variable as extension +trait B {} +val B.foo = Foo() + + +fun test(b: B) { + b.foo() + + with (b) { + foo() + } +} + +//variable as member extension +trait C + +trait D { + val C.foo: Foo + + fun test(c: C) { + c.foo() + + with (c) { + foo() + } + } +} + +fun test(d: D, c: C) { + with (d) { + c.foo() + + with (c) { + foo() + } + } +} + +//-------------- +fun with(receiver: T, f: T.() -> R) : R = receiver.f() \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/resolve/invoke/invokeAsMemberExtension.kt b/compiler/testData/diagnostics/tests/resolve/invoke/invokeAsMemberExtension.kt new file mode 100644 index 00000000000..2f312de73c8 --- /dev/null +++ b/compiler/testData/diagnostics/tests/resolve/invoke/invokeAsMemberExtension.kt @@ -0,0 +1,125 @@ +class Foo + +//no variable +trait A { + fun Foo.invoke() {} + + fun test(foo: Foo) { + foo() + } +} + +//variable as member +trait B { + val foo: Foo +} + +class C { + fun Foo.invoke() {} + + fun test(b: B) { + b.foo() + + with (b) { + foo() + } + } +} + +fun test(c: C, b: B) { + with (c) { + b.foo() + + with (b) { + foo() + } + } +} + + +//variable as extension, +trait D { +} +val D.foo = Foo() + +class E { + fun Foo.invoke() {} + + fun test(d: D) { + d.foo() + + with (d) { + foo() + } + } +} + +fun test(e: E, d: D) { + with (e) { + d.foo() + + with (d) { + foo() + } + } +} + +//variable as member extension +trait F + +trait G { + val F.foo: Foo + fun Foo.invoke() + + fun test(f: F) { + f.foo() + + with (f) { + foo() + } + } +} + +fun test(g: G, f: F) { + with (g) { + f.foo() + + with (f) { + foo() + } + } +} + +//variable as member extension (2) +trait X + +trait U { + val X.foo: Foo +} + +trait V { + fun Foo.invoke() {} + + fun U.test(x: X) { + x.foo() + + with (x) { + foo() + } + } +} + +fun test(u: U, v: V, x: X) { + with (v) { + with (u) { + x.foo() + + with (x) { + foo() + } + } + } +} + +//-------------- +fun with(receiver: T, f: T.() -> R) : R = receiver.f() \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/resolve/invoke/invokeAsMemberExtensionToExplicitReceiver.kt b/compiler/testData/diagnostics/tests/resolve/invoke/invokeAsMemberExtensionToExplicitReceiver.kt new file mode 100644 index 00000000000..1d75d9a9f40 --- /dev/null +++ b/compiler/testData/diagnostics/tests/resolve/invoke/invokeAsMemberExtensionToExplicitReceiver.kt @@ -0,0 +1,12 @@ +trait A +trait Foo { + fun A.invoke() +} + +fun test(a: A, foo: Foo) { + a.foo() +} + +fun test(a: Int, foo: Int.()->Unit) { + a.foo() +} \ 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 3088039f8df..2bbd81a66cc 100644 --- a/compiler/tests/org/jetbrains/jet/checkers/JetDiagnosticsTestGenerated.java +++ b/compiler/tests/org/jetbrains/jet/checkers/JetDiagnosticsTestGenerated.java @@ -4510,6 +4510,7 @@ public class JetDiagnosticsTestGenerated extends AbstractDiagnosticsTestWithEage } @TestMetadata("compiler/testData/diagnostics/tests/resolve") + @InnerTestClasses({Resolve.Invoke.class}) public static class Resolve extends AbstractDiagnosticsTestWithEagerResolve { public void testAllFilesPresentInResolve() throws Exception { JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.GenerateTests", new File("compiler/testData/diagnostics/tests/resolve"), Pattern.compile("^(.+)\\.kt$"), true); @@ -4545,6 +4546,40 @@ public class JetDiagnosticsTestGenerated extends AbstractDiagnosticsTestWithEage doTest("compiler/testData/diagnostics/tests/resolve/resolveWithoutGenerics.kt"); } + @TestMetadata("compiler/testData/diagnostics/tests/resolve/invoke") + public static class Invoke extends AbstractDiagnosticsTestWithEagerResolve { + public void testAllFilesPresentInInvoke() throws Exception { + JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.GenerateTests", new File("compiler/testData/diagnostics/tests/resolve/invoke"), Pattern.compile("^(.+)\\.kt$"), true); + } + + @TestMetadata("invokeAsExtension.kt") + public void testInvokeAsExtension() throws Exception { + doTest("compiler/testData/diagnostics/tests/resolve/invoke/invokeAsExtension.kt"); + } + + @TestMetadata("invokeAsMember.kt") + public void testInvokeAsMember() throws Exception { + doTest("compiler/testData/diagnostics/tests/resolve/invoke/invokeAsMember.kt"); + } + + @TestMetadata("invokeAsMemberExtension.kt") + public void testInvokeAsMemberExtension() throws Exception { + doTest("compiler/testData/diagnostics/tests/resolve/invoke/invokeAsMemberExtension.kt"); + } + + @TestMetadata("invokeAsMemberExtensionToExplicitReceiver.kt") + public void testInvokeAsMemberExtensionToExplicitReceiver() throws Exception { + doTest("compiler/testData/diagnostics/tests/resolve/invoke/invokeAsMemberExtensionToExplicitReceiver.kt"); + } + + } + + public static Test innerSuite() { + TestSuite suite = new TestSuite("Resolve"); + suite.addTestSuite(Resolve.class); + suite.addTestSuite(Invoke.class); + return suite; + } } @TestMetadata("compiler/testData/diagnostics/tests/scopes") @@ -5087,7 +5122,7 @@ public class JetDiagnosticsTestGenerated extends AbstractDiagnosticsTestWithEage suite.addTestSuite(Recovery.class); suite.addTestSuite(Redeclarations.class); suite.addTestSuite(Regressions.class); - suite.addTestSuite(Resolve.class); + suite.addTest(Resolve.innerSuite()); suite.addTestSuite(Scopes.class); suite.addTestSuite(SenselessComparison.class); suite.addTestSuite(Shadowing.class); diff --git a/compiler/tests/org/jetbrains/jet/codegen/generated/BlackBoxCodegenTestGenerated.java b/compiler/tests/org/jetbrains/jet/codegen/generated/BlackBoxCodegenTestGenerated.java index 34ba0c8f1f2..a11f85b39c7 100644 --- a/compiler/tests/org/jetbrains/jet/codegen/generated/BlackBoxCodegenTestGenerated.java +++ b/compiler/tests/org/jetbrains/jet/codegen/generated/BlackBoxCodegenTestGenerated.java @@ -2092,7 +2092,7 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest { } @TestMetadata("compiler/testData/codegen/box/functions") - @InnerTestClasses({Functions.LocalFunctions.class}) + @InnerTestClasses({Functions.Invoke.class, Functions.LocalFunctions.class}) public static class Functions extends AbstractBlackBoxCodegenTest { public void testAllFilesPresentInFunctions() throws Exception { JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.GenerateTests", new File("compiler/testData/codegen/box/functions"), Pattern.compile("^(.+)\\.kt$"), true); @@ -2168,11 +2168,6 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest { doTest("compiler/testData/codegen/box/functions/functionNtoString.kt"); } - @TestMetadata("invoke.kt") - public void testInvoke() throws Exception { - doTest("compiler/testData/codegen/box/functions/invoke.kt"); - } - @TestMetadata("kt1038.kt") public void testKt1038() throws Exception { doTest("compiler/testData/codegen/box/functions/kt1038.kt"); @@ -2268,6 +2263,34 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest { doTest("compiler/testData/codegen/box/functions/nothisnoclosure.kt"); } + @TestMetadata("compiler/testData/codegen/box/functions/invoke") + public static class Invoke extends AbstractBlackBoxCodegenTest { + public void testAllFilesPresentInInvoke() throws Exception { + JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.GenerateTests", new File("compiler/testData/codegen/box/functions/invoke"), Pattern.compile("^(.+)\\.kt$"), true); + } + + @TestMetadata("invoke.kt") + public void testInvoke() throws Exception { + doTest("compiler/testData/codegen/box/functions/invoke/invoke.kt"); + } + + @TestMetadata("kt3189.kt") + public void testKt3189() throws Exception { + doTest("compiler/testData/codegen/box/functions/invoke/kt3189.kt"); + } + + @TestMetadata("kt3190.kt") + public void testKt3190() throws Exception { + doTest("compiler/testData/codegen/box/functions/invoke/kt3190.kt"); + } + + @TestMetadata("kt3297.kt") + public void testKt3297() throws Exception { + doTest("compiler/testData/codegen/box/functions/invoke/kt3297.kt"); + } + + } + @TestMetadata("compiler/testData/codegen/box/functions/localFunctions") public static class LocalFunctions extends AbstractBlackBoxCodegenTest { public void testAllFilesPresentInLocalFunctions() throws Exception { @@ -2284,6 +2307,7 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest { public static Test innerSuite() { TestSuite suite = new TestSuite("Functions"); suite.addTestSuite(Functions.class); + suite.addTestSuite(Invoke.class); suite.addTestSuite(LocalFunctions.class); return suite; } From 9fd8a8d497272b2ad0f0610b4c367e9d2668505c Mon Sep 17 00:00:00 2001 From: Svetlana Isakova Date: Fri, 5 Jul 2013 14:49:49 +0400 Subject: [PATCH 273/291] removed method 'isClassObjectAValue' There are no sensible usages of it. Presence of class object can be determined by 'getClassObjectDescriptor() != null' check --- .../jet/lang/descriptors/ClassifierDescriptor.java | 2 -- .../lang/descriptors/impl/ClassDescriptorImpl.java | 5 ----- .../impl/LazySubstitutingClassDescriptor.java | 5 ----- .../impl/MutableClassDescriptorLite.java | 6 ------ .../impl/TypeParameterDescriptorImpl.java | 5 ----- .../lang/resolve/calls/CallExpressionResolver.java | 13 +++---------- .../calls/autocasts/DataFlowValueFactory.java | 9 +++++++-- .../lazy/descriptors/LazyClassDescriptor.java | 6 ------ .../descriptors/LazyTypeParameterDescriptor.java | 5 ----- 9 files changed, 10 insertions(+), 46 deletions(-) diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/ClassifierDescriptor.java b/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/ClassifierDescriptor.java index 7ddd70998ad..e17dd7a8514 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/ClassifierDescriptor.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/ClassifierDescriptor.java @@ -30,6 +30,4 @@ public interface ClassifierDescriptor extends DeclarationDescriptorNonRoot { @Nullable JetType getClassObjectType(); - - boolean isClassObjectAValue(); } 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 765970371c3..4c186db167b 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 @@ -141,11 +141,6 @@ public class ClassDescriptorImpl extends DeclarationDescriptorNonRootImpl implem return kind; } - @Override - public boolean isClassObjectAValue() { - return true; - } - @Override public R accept(DeclarationDescriptorVisitor visitor, D data) { return visitor.visitClassDescriptor(this, data); diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/impl/LazySubstitutingClassDescriptor.java b/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/impl/LazySubstitutingClassDescriptor.java index 357575ff9cd..901b8b21c58 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/impl/LazySubstitutingClassDescriptor.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/impl/LazySubstitutingClassDescriptor.java @@ -180,11 +180,6 @@ public class LazySubstitutingClassDescriptor implements ClassDescriptor { return original.isInner(); } - @Override - public boolean isClassObjectAValue() { - return original.isClassObjectAValue(); - } - @Override public R accept(DeclarationDescriptorVisitor visitor, D data) { return visitor.visitClassDescriptor(this, data); 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 cdbcddd9a8e..260fbd71bcd 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 @@ -133,12 +133,6 @@ public abstract class MutableClassDescriptorLite extends ClassDescriptorBase { return classObjectType; } - @Override - public boolean isClassObjectAValue() { - return true; - } - - @NotNull @Override public ClassKind getKind() { 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 513e5753afd..36dc836625b 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 @@ -245,11 +245,6 @@ public class TypeParameterDescriptorImpl extends DeclarationDescriptorNonRootImp return classObjectBoundsAsType; } - @Override - public boolean isClassObjectAValue() { - return true; - } - public void addClassObjectBound(@NotNull JetType bound) { checkUninitialized(); classObjectUpperBounds.add(bound); // TODO : Duplicates? diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/CallExpressionResolver.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/CallExpressionResolver.java index 19287f94992..bd28f643ade 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/CallExpressionResolver.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/CallExpressionResolver.java @@ -72,9 +72,6 @@ public class CallExpressionResolver { if (classObjectType != null) { context.trace.record(REFERENCE_TARGET, expression, classifier); JetType result = getExtendedClassObjectType(classObjectType, referencedName, classifier, context); - if (result == null) { - context.trace.report(NO_CLASS_OBJECT.on(expression, classifier)); - } return DataFlowUtils.checkType(result, expression, context); } } @@ -120,7 +117,7 @@ public class CallExpressionResolver { return result[0]; } - @Nullable + @NotNull private JetType getExtendedClassObjectType( @NotNull JetType classObjectType, @NotNull Name referencedName, @@ -135,18 +132,14 @@ public class CallExpressionResolver { NamespaceDescriptor namespace = context.scope.getNamespace(referencedName); if (namespace != null) { + //for enums loaded from java binaries scopes.add(namespace.getMemberScope()); } JetScope scope = new ChainedScope(classifier, scopes.toArray(new JetScope[scopes.size()])); return new NamespaceType(referencedName, scope); } - else if (context.expressionPosition == ExpressionPosition.LHS_OF_DOT || classifier.isClassObjectAValue()) { - return classObjectType; - } - else { - return null; - } + return classObjectType; } private boolean furtherNameLookup( 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 d0069211aef..726764a603d 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,12 @@ public class DataFlowValueFactory { } } - private static final IdentifierInfo NO_IDENTIFIER_INFO = new IdentifierInfo(null, false, false); + private static final IdentifierInfo NO_IDENTIFIER_INFO = new IdentifierInfo(null, false, false) { + @Override + public String toString() { + return "NO_IDENTIFIER_INFO"; + } + }; @NotNull private static IdentifierInfo createInfo(Object id, boolean isStable) { @@ -199,7 +204,7 @@ public class DataFlowValueFactory { } if (declarationDescriptor instanceof ClassDescriptor) { ClassDescriptor classDescriptor = (ClassDescriptor) declarationDescriptor; - return createInfo(classDescriptor, classDescriptor.isClassObjectAValue()); + return createInfo(classDescriptor, classDescriptor.getClassObjectDescriptor() != null); } return NO_IDENTIFIER_INFO; } 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 57079753619..48112f4bc74 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 @@ -275,11 +275,6 @@ public class LazyClassDescriptor extends ClassDescriptorBase implements LazyDesc return classObjectDescriptor == null ? null : classObjectDescriptor.getDefaultType(); } - @Override - public boolean isClassObjectAValue() { - return true; - } - @Override public ClassDescriptor getClassObjectDescriptor() { return classObjectDescriptor.compute(); @@ -395,7 +390,6 @@ public class LazyClassDescriptor extends ClassDescriptorBase implements LazyDesc ForceResolveUtil.forceResolveAllContents(getTypeConstructor()); getUnsubstitutedPrimaryConstructor(); getVisibility(); - isClassObjectAValue(); } private class LazyClassTypeConstructor implements LazyDescriptor, TypeConstructor { diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/lazy/descriptors/LazyTypeParameterDescriptor.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/lazy/descriptors/LazyTypeParameterDescriptor.java index 6619816241a..5429e327436 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/lazy/descriptors/LazyTypeParameterDescriptor.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/lazy/descriptors/LazyTypeParameterDescriptor.java @@ -256,11 +256,6 @@ public class LazyTypeParameterDescriptor implements TypeParameterDescriptor, Laz return null; } - @Override - public boolean isClassObjectAValue() { - return false; - } - @NotNull @Override public DeclarationDescriptor getOriginal() { From d3e6d2d6cdff2ee6b09189cda430b1a430a17ca7 Mon Sep 17 00:00:00 2001 From: Svetlana Isakova Date: Fri, 5 Jul 2013 18:02:28 +0400 Subject: [PATCH 274/291] do not need to check stand-alone class object for class, when it's on the left hand side of dot it is analyzed in 'getIdForImplicitReceiver' (test added) --- .../calls/autocasts/DataFlowValueFactory.java | 4 ---- .../tests/smartCasts/classObjectMember.kt | 22 +++++++++++++++++++ .../checkers/JetDiagnosticsTestGenerated.java | 5 +++++ 3 files changed, 27 insertions(+), 4 deletions(-) create mode 100644 compiler/testData/diagnostics/tests/smartCasts/classObjectMember.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 726764a603d..780169f9878 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 @@ -202,10 +202,6 @@ public class DataFlowValueFactory { if (declarationDescriptor instanceof NamespaceDescriptor) { return createNamespaceInfo(declarationDescriptor); } - if (declarationDescriptor instanceof ClassDescriptor) { - ClassDescriptor classDescriptor = (ClassDescriptor) declarationDescriptor; - return createInfo(classDescriptor, classDescriptor.getClassObjectDescriptor() != null); - } return NO_IDENTIFIER_INFO; } diff --git a/compiler/testData/diagnostics/tests/smartCasts/classObjectMember.kt b/compiler/testData/diagnostics/tests/smartCasts/classObjectMember.kt new file mode 100644 index 00000000000..53bf09c020e --- /dev/null +++ b/compiler/testData/diagnostics/tests/smartCasts/classObjectMember.kt @@ -0,0 +1,22 @@ +open class T { + val x : Int? = null +} + +class A { + class object: T() { + } +} + +class B { + class object: T() { + } +} + +fun test() { + if (A.x != null) { + useInt(A.x) + useInt(B.x) + } +} + +fun useInt(i: Int) = i \ 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 2bbd81a66cc..abb5951ef74 100644 --- a/compiler/tests/org/jetbrains/jet/checkers/JetDiagnosticsTestGenerated.java +++ b/compiler/tests/org/jetbrains/jet/checkers/JetDiagnosticsTestGenerated.java @@ -4867,6 +4867,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("classObjectMember.kt") + public void testClassObjectMember() throws Exception { + doTest("compiler/testData/diagnostics/tests/smartCasts/classObjectMember.kt"); + } + @TestMetadata("combineWithNoSelectorInfo.kt") public void testCombineWithNoSelectorInfo() throws Exception { doTest("compiler/testData/diagnostics/tests/smartCasts/combineWithNoSelectorInfo.kt"); From dddec9ea3ddc293cf7af1a7e5c53887807ffc536 Mon Sep 17 00:00:00 2001 From: "Natalia.Ukhorskaya" Date: Tue, 2 Jul 2013 16:45:20 +0400 Subject: [PATCH 275/291] Resolve enum in annotation arguments --- .../jet/lang/resolve/AnnotationResolver.java | 37 +++++++++++++++++++ .../testData/resolveAnnotations/testFile.kt | 9 ++++- .../AnnotationDescriptorResolveTest.java | 18 +++++++++ 3 files changed, 63 insertions(+), 1 deletion(-) diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/AnnotationResolver.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/AnnotationResolver.java index c8345704670..a078c4fae7e 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/AnnotationResolver.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/AnnotationResolver.java @@ -24,12 +24,14 @@ import org.jetbrains.jet.lang.descriptors.annotations.Annotated; import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor; import org.jetbrains.jet.lang.diagnostics.Errors; import org.jetbrains.jet.lang.psi.*; +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; import org.jetbrains.jet.lang.resolve.calls.model.ResolvedValueArgument; import org.jetbrains.jet.lang.resolve.calls.autocasts.DataFlowInfo; import org.jetbrains.jet.lang.resolve.constants.CompileTimeConstant; +import org.jetbrains.jet.lang.resolve.constants.EnumValue; import org.jetbrains.jet.lang.resolve.scopes.JetScope; import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverValue; import org.jetbrains.jet.lang.types.ErrorUtils; @@ -227,6 +229,31 @@ public class AnnotationResolver { return trace.get(BindingContext.COMPILE_TIME_VALUE, expression); } + @Override + public CompileTimeConstant visitSimpleNameExpression(JetSimpleNameExpression expression, Void data) { + ResolvedCall resolvedCall = + trace.getBindingContext().get(BindingContext.RESOLVED_CALL, expression); + if (resolvedCall != null) { + CallableDescriptor callableDescriptor = resolvedCall.getResultingDescriptor(); + if (callableDescriptor instanceof PropertyDescriptor) { + PropertyDescriptor propertyDescriptor = (PropertyDescriptor) callableDescriptor; + if (isEnumProperty(propertyDescriptor)) { + return new EnumValue(propertyDescriptor); + } + } + } + return null; + } + + @Override + public CompileTimeConstant visitQualifiedExpression(JetQualifiedExpression expression, Void data) { + JetExpression selectorExpression = expression.getSelectorExpression(); + if (selectorExpression != null) { + return selectorExpression.accept(this, null); + } + return super.visitQualifiedExpression(expression, data); + } + @Override public CompileTimeConstant visitJetElement(JetElement element, Void nothing) { // TODO: @@ -237,6 +264,16 @@ public class AnnotationResolver { return expression.accept(visitor, null); } + private static boolean isEnumProperty(@NotNull PropertyDescriptor descriptor) { + if (DescriptorUtils.isKindOf(descriptor.getType(), ClassKind.ENUM_CLASS)) { + DeclarationDescriptor enumClassObject = descriptor.getContainingDeclaration(); + if (DescriptorUtils.isKindOf(enumClassObject, ClassKind.CLASS_OBJECT)) { + return DescriptorUtils.isKindOf(enumClassObject.getContainingDeclaration(), ClassKind.ENUM_CLASS); + } + } + return false; + } + @NotNull public List getResolvedAnnotations(@Nullable JetModifierList modifierList, BindingTrace trace) { if (modifierList == null) { diff --git a/compiler/testData/resolveAnnotations/testFile.kt b/compiler/testData/resolveAnnotations/testFile.kt index c949abc1c20..ab055ef1d93 100644 --- a/compiler/testData/resolveAnnotations/testFile.kt +++ b/compiler/testData/resolveAnnotations/testFile.kt @@ -1,5 +1,7 @@ package test +import test.MyEnum.* + ANNOTATION class MyClass [ANNOTATION]([ANNOTATION] param: Int, [ANNOTATION] val consProp: Int) { ANNOTATION class object { } @@ -36,4 +38,9 @@ val funLiteral = {([ANNOTATION] a: Int) -> a } annotation class AnnString(a: String) -annotation class AnnInt(a: Int) \ No newline at end of file +annotation class AnnInt(a: Int) +annotation class AnnEnum(a: MyEnum) + +enum class MyEnum { + A +} \ No newline at end of file diff --git a/compiler/tests/org/jetbrains/jet/resolve/annotation/AnnotationDescriptorResolveTest.java b/compiler/tests/org/jetbrains/jet/resolve/annotation/AnnotationDescriptorResolveTest.java index 89d4c68a773..92121675578 100644 --- a/compiler/tests/org/jetbrains/jet/resolve/annotation/AnnotationDescriptorResolveTest.java +++ b/compiler/tests/org/jetbrains/jet/resolve/annotation/AnnotationDescriptorResolveTest.java @@ -63,6 +63,24 @@ public class AnnotationDescriptorResolveTest extends JetLiteFixture { doTest(content, expectedAnnotation); } + public void testEnumAnnotation() throws IOException { + String content = getContent("AnnEnum(MyEnum.A)"); + String expectedAnnotation = "AnnEnum[a = MyEnum.A]"; + doTest(content, expectedAnnotation); + } + + public void testQualifiedEnumAnnotation() throws IOException { + String content = getContent("AnnEnum(test.MyEnum.A)"); + String expectedAnnotation = "AnnEnum[a = MyEnum.A]"; + doTest(content, expectedAnnotation); + } + + public void testUnqualifiedEnumAnnotation() throws IOException { + String content = getContent("AnnEnum(A)"); + String expectedAnnotation = "AnnEnum[a = MyEnum.A]"; + doTest(content, expectedAnnotation); + } + private void doTest(@NotNull String content, @NotNull String expectedAnnotation) { NamespaceDescriptor test = getNamespaceDescriptor(content); ClassDescriptor myClass = getClassDescriptor(test, "MyClass"); From 98d3b1e113f2da352d9606d202fb1b3b4728e05f Mon Sep 17 00:00:00 2001 From: "Natalia.Ukhorskaya" Date: Fri, 5 Jul 2013 14:12:55 +0400 Subject: [PATCH 276/291] Resolve arrays in annotation arguments --- .../jet/lang/resolve/AnnotationResolver.java | 25 +++++++++++++++++++ .../jet/lang/resolve/AnnotationUtils.java | 15 +++++++++++ .../testData/resolveAnnotations/testFile.kt | 3 +++ .../AnnotationDescriptorResolveTest.java | 18 +++++++++++++ 4 files changed, 61 insertions(+) diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/AnnotationResolver.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/AnnotationResolver.java index a078c4fae7e..ffda825cae0 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/AnnotationResolver.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/AnnotationResolver.java @@ -30,6 +30,7 @@ import org.jetbrains.jet.lang.resolve.calls.CallResolver; import org.jetbrains.jet.lang.resolve.calls.results.OverloadResolutionResults; import org.jetbrains.jet.lang.resolve.calls.model.ResolvedValueArgument; import org.jetbrains.jet.lang.resolve.calls.autocasts.DataFlowInfo; +import org.jetbrains.jet.lang.resolve.constants.ArrayValue; import org.jetbrains.jet.lang.resolve.constants.CompileTimeConstant; import org.jetbrains.jet.lang.resolve.constants.EnumValue; import org.jetbrains.jet.lang.resolve.scopes.JetScope; @@ -254,6 +255,30 @@ public class AnnotationResolver { return super.visitQualifiedExpression(expression, data); } + @Override + public CompileTimeConstant visitCallExpression(JetCallExpression expression, Void data) { + ResolvedCall call = + trace.getBindingContext().get(BindingContext.RESOLVED_CALL, (expression).getCalleeExpression()); + if (call != null) { + if (AnnotationUtils.isArrayMethodCall(call)) { + CallableDescriptor resultingDescriptor = call.getResultingDescriptor(); + JetType type = resultingDescriptor.getValueParameters().iterator().next().getVarargElementType(); + List> arguments = Lists.newArrayList(); + for (ResolvedValueArgument descriptorToArgument : call.getValueArguments().values()) { + List valueArguments = descriptorToArgument.getArguments(); + for (ValueArgument argument : valueArguments) { + JetExpression argumentExpression = argument.getArgumentExpression(); + if (argumentExpression != null) { + arguments.add(resolveAnnotationArgument(argumentExpression, type, trace)); + } + } + } + return new ArrayValue(arguments, resultingDescriptor.getReturnType()); + } + } + return null; + } + @Override public CompileTimeConstant visitJetElement(JetElement element, Void nothing) { // TODO: diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/AnnotationUtils.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/AnnotationUtils.java index 5ba69ba59c8..339c19c43ed 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/AnnotationUtils.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/AnnotationUtils.java @@ -19,8 +19,10 @@ package org.jetbrains.jet.lang.resolve; import org.jetbrains.annotations.NotNull; import org.jetbrains.jet.lang.descriptors.ClassDescriptor; import org.jetbrains.jet.lang.descriptors.VariableDescriptor; +import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor; import org.jetbrains.jet.lang.psi.JetParameter; import org.jetbrains.jet.lang.psi.JetTypeReference; +import org.jetbrains.jet.lang.resolve.calls.model.ResolvedCall; import org.jetbrains.jet.lang.types.JetType; import org.jetbrains.jet.lang.types.TypeProjection; import org.jetbrains.jet.lang.types.TypeUtils; @@ -87,6 +89,19 @@ public class AnnotationUtils { return false; } + public static boolean isArrayMethodCall(@NotNull ResolvedCall resolvedCall) { + List annotations = resolvedCall.getResultingDescriptor().getOriginal().getAnnotations(); + if (annotations != null) { + for (AnnotationDescriptor annotation : annotations) { + //noinspection ConstantConditions + if ("Intrinsic".equals(annotation.getType().getConstructor().getDeclarationDescriptor().getName().asString())) { + return "kotlin.arrays.array".equals(annotation.getAllValueArguments().values().iterator().next().getValue()); + } + } + } + return false; + } + private static boolean isJavaLangClass(ClassDescriptor descriptor) { return "java.lang.Class".equals(DescriptorUtils.getFQName(descriptor).asString()); } diff --git a/compiler/testData/resolveAnnotations/testFile.kt b/compiler/testData/resolveAnnotations/testFile.kt index ab055ef1d93..8734dd77b8e 100644 --- a/compiler/testData/resolveAnnotations/testFile.kt +++ b/compiler/testData/resolveAnnotations/testFile.kt @@ -40,6 +40,9 @@ val funLiteral = {([ANNOTATION] a: Int) -> a } annotation class AnnString(a: String) annotation class AnnInt(a: Int) annotation class AnnEnum(a: MyEnum) +annotation class AnnIntArray(a: IntArray) +annotation class AnnStringArray(a: Array) +annotation class AnnArrayOfEnum(a: Array) enum class MyEnum { A diff --git a/compiler/tests/org/jetbrains/jet/resolve/annotation/AnnotationDescriptorResolveTest.java b/compiler/tests/org/jetbrains/jet/resolve/annotation/AnnotationDescriptorResolveTest.java index 92121675578..8325b74e56b 100644 --- a/compiler/tests/org/jetbrains/jet/resolve/annotation/AnnotationDescriptorResolveTest.java +++ b/compiler/tests/org/jetbrains/jet/resolve/annotation/AnnotationDescriptorResolveTest.java @@ -81,6 +81,24 @@ public class AnnotationDescriptorResolveTest extends JetLiteFixture { doTest(content, expectedAnnotation); } + public void testIntArrayAnnotation() throws IOException { + String content = getContent("AnnIntArray(intArray(1, 2))"); + String expectedAnnotation = "AnnIntArray[a = [1.toInt(), 2.toInt()]]"; + doTest(content, expectedAnnotation); + } + + public void testStringArrayAnnotation() throws IOException { + String content = getContent("AnnStringArray(array(\"a\"))"); + String expectedAnnotation = "AnnStringArray[a = [\"a\"]]"; + doTest(content, expectedAnnotation); + } + + public void testEnumArrayAnnotation() throws IOException { + String content = getContent("AnnArrayOfEnum(array(MyEnum.A))"); + String expectedAnnotation = "AnnArrayOfEnum[a = [MyEnum.A]]"; + doTest(content, expectedAnnotation); + } + private void doTest(@NotNull String content, @NotNull String expectedAnnotation) { NamespaceDescriptor test = getNamespaceDescriptor(content); ClassDescriptor myClass = getClassDescriptor(test, "MyClass"); From 42f10d77db13e66aef9fd806095fadf19d96b225 Mon Sep 17 00:00:00 2001 From: "Natalia.Ukhorskaya" Date: Fri, 5 Jul 2013 14:14:23 +0400 Subject: [PATCH 277/291] Add annotation argument type in tests --- .../AnnotationDescriptorResolveTest.java | 20 ++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/compiler/tests/org/jetbrains/jet/resolve/annotation/AnnotationDescriptorResolveTest.java b/compiler/tests/org/jetbrains/jet/resolve/annotation/AnnotationDescriptorResolveTest.java index 8325b74e56b..126b50b6f34 100644 --- a/compiler/tests/org/jetbrains/jet/resolve/annotation/AnnotationDescriptorResolveTest.java +++ b/compiler/tests/org/jetbrains/jet/resolve/annotation/AnnotationDescriptorResolveTest.java @@ -28,10 +28,12 @@ import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor; import org.jetbrains.jet.lang.descriptors.impl.AnonymousFunctionDescriptor; import org.jetbrains.jet.lang.psi.JetFile; import org.jetbrains.jet.lang.resolve.BindingContext; +import org.jetbrains.jet.lang.resolve.DescriptorUtils; import org.jetbrains.jet.lang.resolve.name.FqName; import org.jetbrains.jet.lang.resolve.name.Name; import org.jetbrains.jet.lang.resolve.scopes.JetScope; import org.jetbrains.jet.lang.types.TypeProjection; +import org.jetbrains.jet.renderer.DescriptorRenderer; import java.io.File; import java.io.IOException; @@ -53,49 +55,49 @@ public class AnnotationDescriptorResolveTest extends JetLiteFixture { public void testIntAnnotation() throws IOException { String content = getContent("AnnInt(1)"); - String expectedAnnotation = "AnnInt[a = 1.toInt()]"; + String expectedAnnotation = "AnnInt[a = 1.toInt(): jet.Int]"; doTest(content, expectedAnnotation); } public void testStringAnnotation() throws IOException { String content = getContent("AnnString(\"test\")"); - String expectedAnnotation = "AnnString[a = \"test\"]"; + String expectedAnnotation = "AnnString[a = \"test\": jet.String]"; doTest(content, expectedAnnotation); } public void testEnumAnnotation() throws IOException { String content = getContent("AnnEnum(MyEnum.A)"); - String expectedAnnotation = "AnnEnum[a = MyEnum.A]"; + String expectedAnnotation = "AnnEnum[a = MyEnum.A: test.MyEnum]"; doTest(content, expectedAnnotation); } public void testQualifiedEnumAnnotation() throws IOException { String content = getContent("AnnEnum(test.MyEnum.A)"); - String expectedAnnotation = "AnnEnum[a = MyEnum.A]"; + String expectedAnnotation = "AnnEnum[a = MyEnum.A: test.MyEnum]"; doTest(content, expectedAnnotation); } public void testUnqualifiedEnumAnnotation() throws IOException { String content = getContent("AnnEnum(A)"); - String expectedAnnotation = "AnnEnum[a = MyEnum.A]"; + String expectedAnnotation = "AnnEnum[a = MyEnum.A: test.MyEnum]"; doTest(content, expectedAnnotation); } public void testIntArrayAnnotation() throws IOException { String content = getContent("AnnIntArray(intArray(1, 2))"); - String expectedAnnotation = "AnnIntArray[a = [1.toInt(), 2.toInt()]]"; + String expectedAnnotation = "AnnIntArray[a = [1.toInt(), 2.toInt()]: jet.IntArray]"; doTest(content, expectedAnnotation); } public void testStringArrayAnnotation() throws IOException { String content = getContent("AnnStringArray(array(\"a\"))"); - String expectedAnnotation = "AnnStringArray[a = [\"a\"]]"; + String expectedAnnotation = "AnnStringArray[a = [\"a\"]: jet.Array]"; doTest(content, expectedAnnotation); } public void testEnumArrayAnnotation() throws IOException { String content = getContent("AnnArrayOfEnum(array(MyEnum.A))"); - String expectedAnnotation = "AnnArrayOfEnum[a = [MyEnum.A]]"; + String expectedAnnotation = "AnnArrayOfEnum[a = [MyEnum.A]: jet.Array]"; doTest(content, expectedAnnotation); } @@ -331,7 +333,7 @@ public class AnnotationDescriptorResolveTest extends JetLiteFixture { String actual = StringUtil.join(member.getAnnotations(), new Function() { @Override public String fun(AnnotationDescriptor annotationDescriptor) { - return annotationDescriptor.toString(); + return annotationDescriptor.getType().toString() + DescriptorUtils.getSortedValueArguments(annotationDescriptor, DescriptorRenderer.TEXT); } }, " "); assertEquals("Failed to resolve annotation descriptor for " + member.toString(), expectedAnnotation, actual); From 42b0bdc54dfd05f212a696721eb9db16f77361cb Mon Sep 17 00:00:00 2001 From: "Natalia.Ukhorskaya" Date: Fri, 5 Jul 2013 18:15:54 +0400 Subject: [PATCH 278/291] Support varargs in annotation arguments --- .../jet/lang/resolve/AnnotationResolver.java | 56 ++++++++++++------- .../testData/resolveAnnotations/testFile.kt | 2 + .../AnnotationDescriptorResolveTest.java | 12 ++++ 3 files changed, 51 insertions(+), 19 deletions(-) diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/AnnotationResolver.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/AnnotationResolver.java index ffda825cae0..2852d2f0324 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/AnnotationResolver.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/AnnotationResolver.java @@ -38,6 +38,7 @@ import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverValue; import org.jetbrains.jet.lang.types.ErrorUtils; import org.jetbrains.jet.lang.types.JetType; import org.jetbrains.jet.lang.types.expressions.ExpressionTypingServices; +import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns; import javax.inject.Inject; import java.util.Collections; @@ -174,25 +175,48 @@ public class AnnotationResolver { if (results.isSuccess()) { for (Map.Entry descriptorToArgument : results.getResultingCall().getValueArguments().entrySet()) { - // TODO: are varargs supported here? - List valueArguments = descriptorToArgument.getValue().getArguments(); + AnnotationDescriptor annotationDescriptor = trace.getBindingContext().get(BindingContext.ANNOTATION, annotationEntry); + assert annotationDescriptor != null : "Annotation descriptor should be created before resolving arguments for " + annotationEntry.getText(); + ValueParameterDescriptor parameterDescriptor = descriptorToArgument.getKey(); - for (ValueArgument argument : valueArguments) { - JetExpression argumentExpression = argument.getArgumentExpression(); - if (argumentExpression != null) { - CompileTimeConstant compileTimeConstant = - resolveAnnotationArgument(argumentExpression, parameterDescriptor.getType(), trace); - if (compileTimeConstant != null) { - AnnotationDescriptor annotationDescriptor = trace.getBindingContext().get(BindingContext.ANNOTATION, annotationEntry); - assert annotationDescriptor != null : "Annotation descriptor should be created before resolving arguments for " + annotationEntry.getText(); - annotationDescriptor.setValueArgument(parameterDescriptor, compileTimeConstant); - } + + JetType varargElementType = parameterDescriptor.getVarargElementType(); + List> constants = resolveValueArguments(descriptorToArgument.getValue(), parameterDescriptor.getType(), trace); + if (varargElementType == null) { + for (CompileTimeConstant constant : constants) { + annotationDescriptor.setValueArgument(parameterDescriptor, constant); } } + else { + JetType arrayType = KotlinBuiltIns.getInstance().getPrimitiveArrayJetTypeByPrimitiveJetType(varargElementType); + if (arrayType == null) { + arrayType = KotlinBuiltIns.getInstance().getArrayType(varargElementType); + } + annotationDescriptor.setValueArgument(parameterDescriptor, new ArrayValue(constants, arrayType)); + } } } } + @NotNull + private List> resolveValueArguments( + @NotNull ResolvedValueArgument resolvedValueArgument, + @NotNull JetType expectedType, + @NotNull BindingTrace trace + ) { + List> constants = Lists.newArrayList(); + for (ValueArgument argument : resolvedValueArgument.getArguments()) { + JetExpression argumentExpression = argument.getArgumentExpression(); + if (argumentExpression != null) { + CompileTimeConstant constant = resolveAnnotationArgument(argumentExpression, expectedType, trace); + if (constant != null) { + constants.add(constant); + } + } + } + return constants; + } + @Nullable private CompileTimeConstant resolveAnnotationArgument(@NotNull JetExpression expression, @NotNull final JetType expectedType, final BindingTrace trace) { JetVisitor, Void> visitor = new JetVisitor, Void>() { @@ -265,13 +289,7 @@ public class AnnotationResolver { JetType type = resultingDescriptor.getValueParameters().iterator().next().getVarargElementType(); List> arguments = Lists.newArrayList(); for (ResolvedValueArgument descriptorToArgument : call.getValueArguments().values()) { - List valueArguments = descriptorToArgument.getArguments(); - for (ValueArgument argument : valueArguments) { - JetExpression argumentExpression = argument.getArgumentExpression(); - if (argumentExpression != null) { - arguments.add(resolveAnnotationArgument(argumentExpression, type, trace)); - } - } + arguments.addAll(resolveValueArguments(descriptorToArgument, type, trace)); } return new ArrayValue(arguments, resultingDescriptor.getReturnType()); } diff --git a/compiler/testData/resolveAnnotations/testFile.kt b/compiler/testData/resolveAnnotations/testFile.kt index 8734dd77b8e..8f6025b4b10 100644 --- a/compiler/testData/resolveAnnotations/testFile.kt +++ b/compiler/testData/resolveAnnotations/testFile.kt @@ -41,6 +41,8 @@ annotation class AnnString(a: String) annotation class AnnInt(a: Int) annotation class AnnEnum(a: MyEnum) annotation class AnnIntArray(a: IntArray) +annotation class AnnIntVararg(vararg a: Int) +annotation class AnnStringVararg(vararg a: String) annotation class AnnStringArray(a: Array) annotation class AnnArrayOfEnum(a: Array) diff --git a/compiler/tests/org/jetbrains/jet/resolve/annotation/AnnotationDescriptorResolveTest.java b/compiler/tests/org/jetbrains/jet/resolve/annotation/AnnotationDescriptorResolveTest.java index 126b50b6f34..1ad56e3a9a7 100644 --- a/compiler/tests/org/jetbrains/jet/resolve/annotation/AnnotationDescriptorResolveTest.java +++ b/compiler/tests/org/jetbrains/jet/resolve/annotation/AnnotationDescriptorResolveTest.java @@ -89,6 +89,18 @@ public class AnnotationDescriptorResolveTest extends JetLiteFixture { doTest(content, expectedAnnotation); } + public void testIntArrayVarargAnnotation() throws IOException { + String content = getContent("AnnIntVararg(1, 2)"); + String expectedAnnotation = "AnnIntVararg[a = [1.toInt(), 2.toInt()]: jet.IntArray]"; + doTest(content, expectedAnnotation); + } + + public void testStringArrayVarargAnnotation() throws IOException { + String content = getContent("AnnStringVararg(\"a\", \"b\")"); + String expectedAnnotation = "AnnStringVararg[a = [\"a\", \"b\"]: jet.Array]"; + doTest(content, expectedAnnotation); + } + public void testStringArrayAnnotation() throws IOException { String content = getContent("AnnStringArray(array(\"a\"))"); String expectedAnnotation = "AnnStringArray[a = [\"a\"]: jet.Array]"; From bbed2da4ddf32c33fb9c0f71aa47f28029582f23 Mon Sep 17 00:00:00 2001 From: "Natalia.Ukhorskaya" Date: Thu, 4 Jul 2013 16:51:17 +0400 Subject: [PATCH 279/291] Resolve annotations in annotation arguments --- .../jet/lang/resolve/AnnotationResolver.java | 57 ++++++++++++------- .../testData/resolveAnnotations/testFile.kt | 1 + .../AnnotationDescriptorResolveTest.java | 6 ++ 3 files changed, 45 insertions(+), 19 deletions(-) diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/AnnotationResolver.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/AnnotationResolver.java index 2852d2f0324..00b575063f6 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/AnnotationResolver.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/AnnotationResolver.java @@ -30,6 +30,7 @@ import org.jetbrains.jet.lang.resolve.calls.CallResolver; import org.jetbrains.jet.lang.resolve.calls.results.OverloadResolutionResults; import org.jetbrains.jet.lang.resolve.calls.model.ResolvedValueArgument; import org.jetbrains.jet.lang.resolve.calls.autocasts.DataFlowInfo; +import org.jetbrains.jet.lang.resolve.constants.AnnotationValue; import org.jetbrains.jet.lang.resolve.constants.ArrayValue; import org.jetbrains.jet.lang.resolve.constants.CompileTimeConstant; import org.jetbrains.jet.lang.resolve.constants.EnumValue; @@ -173,27 +174,34 @@ public class AnnotationResolver { ) { OverloadResolutionResults results = resolveAnnotationCall(annotationEntry, scope, trace); if (results.isSuccess()) { - for (Map.Entry descriptorToArgument : - results.getResultingCall().getValueArguments().entrySet()) { - AnnotationDescriptor annotationDescriptor = trace.getBindingContext().get(BindingContext.ANNOTATION, annotationEntry); - assert annotationDescriptor != null : "Annotation descriptor should be created before resolving arguments for " + annotationEntry.getText(); + AnnotationDescriptor annotationDescriptor = trace.getBindingContext().get(BindingContext.ANNOTATION, annotationEntry); + assert annotationDescriptor != null : "Annotation descriptor should be created before resolving arguments for " + annotationEntry.getText(); + resolveAnnotationArgument(annotationDescriptor, results.getResultingCall(), trace); + } + } - ValueParameterDescriptor parameterDescriptor = descriptorToArgument.getKey(); + private void resolveAnnotationArgument( + @NotNull AnnotationDescriptor annotationDescriptor, + @NotNull ResolvedCall call, + @NotNull BindingTrace trace + ) { + for (Map.Entry descriptorToArgument : + call.getValueArguments().entrySet()) { + ValueParameterDescriptor parameterDescriptor = descriptorToArgument.getKey(); - JetType varargElementType = parameterDescriptor.getVarargElementType(); - List> constants = resolveValueArguments(descriptorToArgument.getValue(), parameterDescriptor.getType(), trace); - if (varargElementType == null) { - for (CompileTimeConstant constant : constants) { - annotationDescriptor.setValueArgument(parameterDescriptor, constant); - } + JetType varargElementType = parameterDescriptor.getVarargElementType(); + List> constants = resolveValueArguments(descriptorToArgument.getValue(), parameterDescriptor.getType(), trace); + if (varargElementType == null) { + for (CompileTimeConstant constant : constants) { + annotationDescriptor.setValueArgument(parameterDescriptor, constant); } - else { - JetType arrayType = KotlinBuiltIns.getInstance().getPrimitiveArrayJetTypeByPrimitiveJetType(varargElementType); - if (arrayType == null) { - arrayType = KotlinBuiltIns.getInstance().getArrayType(varargElementType); - } - annotationDescriptor.setValueArgument(parameterDescriptor, new ArrayValue(constants, arrayType)); + } + else { + JetType arrayType = KotlinBuiltIns.getInstance().getPrimitiveArrayJetTypeByPrimitiveJetType(varargElementType); + if (arrayType == null) { + arrayType = KotlinBuiltIns.getInstance().getArrayType(varargElementType); } + annotationDescriptor.setValueArgument(parameterDescriptor, new ArrayValue(constants, arrayType)); } } } @@ -210,7 +218,7 @@ public class AnnotationResolver { if (argumentExpression != null) { CompileTimeConstant constant = resolveAnnotationArgument(argumentExpression, expectedType, trace); if (constant != null) { - constants.add(constant); + constants.add(constant); } } } @@ -284,8 +292,8 @@ public class AnnotationResolver { ResolvedCall call = trace.getBindingContext().get(BindingContext.RESOLVED_CALL, (expression).getCalleeExpression()); if (call != null) { + CallableDescriptor resultingDescriptor = call.getResultingDescriptor(); if (AnnotationUtils.isArrayMethodCall(call)) { - CallableDescriptor resultingDescriptor = call.getResultingDescriptor(); JetType type = resultingDescriptor.getValueParameters().iterator().next().getVarargElementType(); List> arguments = Lists.newArrayList(); for (ResolvedValueArgument descriptorToArgument : call.getValueArguments().values()) { @@ -293,6 +301,17 @@ public class AnnotationResolver { } return new ArrayValue(arguments, resultingDescriptor.getReturnType()); } + + if (resultingDescriptor instanceof ConstructorDescriptor) { + JetType constructorReturnType = resultingDescriptor.getReturnType(); + assert constructorReturnType != null : "Constructor should have return type"; + if (DescriptorUtils.isAnnotationClass(constructorReturnType.getConstructor().getDeclarationDescriptor())) { + AnnotationDescriptor descriptor = new AnnotationDescriptor(); + descriptor.setAnnotationType(constructorReturnType); + resolveAnnotationArgument(descriptor, call, trace); + return new AnnotationValue(descriptor); + } + } } return null; } diff --git a/compiler/testData/resolveAnnotations/testFile.kt b/compiler/testData/resolveAnnotations/testFile.kt index 8f6025b4b10..ca0d49d67be 100644 --- a/compiler/testData/resolveAnnotations/testFile.kt +++ b/compiler/testData/resolveAnnotations/testFile.kt @@ -45,6 +45,7 @@ annotation class AnnIntVararg(vararg a: Int) annotation class AnnStringVararg(vararg a: String) annotation class AnnStringArray(a: Array) annotation class AnnArrayOfEnum(a: Array) +annotation class AnnAnn(a: AnnInt) enum class MyEnum { A diff --git a/compiler/tests/org/jetbrains/jet/resolve/annotation/AnnotationDescriptorResolveTest.java b/compiler/tests/org/jetbrains/jet/resolve/annotation/AnnotationDescriptorResolveTest.java index 1ad56e3a9a7..6129e4c616d 100644 --- a/compiler/tests/org/jetbrains/jet/resolve/annotation/AnnotationDescriptorResolveTest.java +++ b/compiler/tests/org/jetbrains/jet/resolve/annotation/AnnotationDescriptorResolveTest.java @@ -113,6 +113,12 @@ public class AnnotationDescriptorResolveTest extends JetLiteFixture { doTest(content, expectedAnnotation); } + public void testAnnotationAnnotation() throws Exception { + String content = getContent("AnnAnn(AnnInt(1))"); + String expectedAnnotation = "AnnAnn[a = AnnInt[a = 1.toInt()]: test.AnnInt]"; + doTest(content, expectedAnnotation); + } + private void doTest(@NotNull String content, @NotNull String expectedAnnotation) { NamespaceDescriptor test = getNamespaceDescriptor(content); ClassDescriptor myClass = getClassDescriptor(test, "MyClass"); From b6bdcb303d34b052076f1dbabbc947ac83834b44 Mon Sep 17 00:00:00 2001 From: "Natalia.Ukhorskaya" Date: Thu, 4 Jul 2013 17:39:15 +0400 Subject: [PATCH 280/291] Resolve java.lang.Class as annotation argument --- .../AnnotationArgumentVisitor.java | 2 + .../jet/lang/resolve/AnnotationResolver.java | 9 ++-- .../jet/lang/resolve/AnnotationUtils.java | 13 +++++ .../resolve/constants/JavaClassValue.java | 52 +++++++++++++++++++ .../testData/resolveAnnotations/testFile.kt | 1 + .../AnnotationDescriptorResolveTest.java | 6 +++ 6 files changed, 79 insertions(+), 4 deletions(-) create mode 100644 compiler/frontend/src/org/jetbrains/jet/lang/resolve/constants/JavaClassValue.java diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/annotations/AnnotationArgumentVisitor.java b/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/annotations/AnnotationArgumentVisitor.java index 06229b57f33..ef2fe79ae12 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/annotations/AnnotationArgumentVisitor.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/descriptors/annotations/AnnotationArgumentVisitor.java @@ -48,4 +48,6 @@ public interface AnnotationArgumentVisitor { R visitArrayValue(ArrayValue value, D data); R visitAnnotationValue(AnnotationValue value, D data); + + R visitJavaClassValue(JavaClassValue value, D data); } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/AnnotationResolver.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/AnnotationResolver.java index 00b575063f6..62a759df815 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/AnnotationResolver.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/AnnotationResolver.java @@ -30,10 +30,7 @@ import org.jetbrains.jet.lang.resolve.calls.CallResolver; import org.jetbrains.jet.lang.resolve.calls.results.OverloadResolutionResults; import org.jetbrains.jet.lang.resolve.calls.model.ResolvedValueArgument; import org.jetbrains.jet.lang.resolve.calls.autocasts.DataFlowInfo; -import org.jetbrains.jet.lang.resolve.constants.AnnotationValue; -import org.jetbrains.jet.lang.resolve.constants.ArrayValue; -import org.jetbrains.jet.lang.resolve.constants.CompileTimeConstant; -import org.jetbrains.jet.lang.resolve.constants.EnumValue; +import org.jetbrains.jet.lang.resolve.constants.*; import org.jetbrains.jet.lang.resolve.scopes.JetScope; import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverValue; import org.jetbrains.jet.lang.types.ErrorUtils; @@ -312,6 +309,10 @@ public class AnnotationResolver { return new AnnotationValue(descriptor); } } + + if (AnnotationUtils.isJavaClassMethodCall(call)) { + return new JavaClassValue(resultingDescriptor.getReturnType()); + } } return null; } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/AnnotationUtils.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/AnnotationUtils.java index 339c19c43ed..947f0a498f2 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/AnnotationUtils.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/AnnotationUtils.java @@ -102,6 +102,19 @@ public class AnnotationUtils { return false; } + public static boolean isJavaClassMethodCall(@NotNull ResolvedCall resolvedCall) { + List annotations = resolvedCall.getResultingDescriptor().getOriginal().getAnnotations(); + if (annotations != null) { + for (AnnotationDescriptor annotation : annotations) { + //noinspection ConstantConditions + if ("Intrinsic".equals(annotation.getType().getConstructor().getDeclarationDescriptor().getName().asString())) { + return "kotlin.javaClass.function".equals(annotation.getAllValueArguments().values().iterator().next().getValue()); + } + } + } + return false; + } + private static boolean isJavaLangClass(ClassDescriptor descriptor) { return "java.lang.Class".equals(DescriptorUtils.getFQName(descriptor).asString()); } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/constants/JavaClassValue.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/constants/JavaClassValue.java new file mode 100644 index 00000000000..5b93e540bd8 --- /dev/null +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/constants/JavaClassValue.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.lang.resolve.constants; + +import org.jetbrains.annotations.NotNull; +import org.jetbrains.jet.lang.descriptors.annotations.AnnotationArgumentVisitor; +import org.jetbrains.jet.lang.types.JetType; +import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns; + +public class JavaClassValue implements CompileTimeConstant { + + private final JetType value; + + public JavaClassValue(JetType value) { + this.value = value; + } + + @Override + public JetType getValue() { + return value.getArguments().iterator().next().getType(); + } + + @NotNull + @Override + public JetType getType(@NotNull KotlinBuiltIns kotlinBuiltIns) { + return value; + } + + @Override + public R accept(AnnotationArgumentVisitor visitor, D data) { + return visitor.visitJavaClassValue(this, data); + } + + @Override + public String toString() { + return getValue() + ".class"; + } +} diff --git a/compiler/testData/resolveAnnotations/testFile.kt b/compiler/testData/resolveAnnotations/testFile.kt index ca0d49d67be..498c7d6d49c 100644 --- a/compiler/testData/resolveAnnotations/testFile.kt +++ b/compiler/testData/resolveAnnotations/testFile.kt @@ -46,6 +46,7 @@ annotation class AnnStringVararg(vararg a: String) annotation class AnnStringArray(a: Array) annotation class AnnArrayOfEnum(a: Array) annotation class AnnAnn(a: AnnInt) +annotation class AnnClass(a: Class<*>) enum class MyEnum { A diff --git a/compiler/tests/org/jetbrains/jet/resolve/annotation/AnnotationDescriptorResolveTest.java b/compiler/tests/org/jetbrains/jet/resolve/annotation/AnnotationDescriptorResolveTest.java index 6129e4c616d..e689c63f531 100644 --- a/compiler/tests/org/jetbrains/jet/resolve/annotation/AnnotationDescriptorResolveTest.java +++ b/compiler/tests/org/jetbrains/jet/resolve/annotation/AnnotationDescriptorResolveTest.java @@ -119,6 +119,12 @@ public class AnnotationDescriptorResolveTest extends JetLiteFixture { doTest(content, expectedAnnotation); } + public void testJavaClassAnnotation() throws Exception { + String content = getContent("AnnClass(javaClass())"); + String expectedAnnotation = "AnnClass[a = MyClass.class: java.lang.Class]"; + doTest(content, expectedAnnotation); + } + private void doTest(@NotNull String content, @NotNull String expectedAnnotation) { NamespaceDescriptor test = getNamespaceDescriptor(content); ClassDescriptor myClass = getClassDescriptor(test, "MyClass"); From 728e08cc49055ad4fbc7cd20b7d79dc4ced30241 Mon Sep 17 00:00:00 2001 From: "Natalia.Ukhorskaya" Date: Thu, 4 Jul 2013 18:57:01 +0400 Subject: [PATCH 281/291] Rewrite AnnotationCodegen to generate annotation arguments by AnnotationDescriptor --- .../jet/codegen/AnnotationCodegen.java | 219 ++++++++++-------- .../varargInAnnotationParameter.kt | 21 ++ ...lackBoxWithStdlibCodegenTestGenerated.java | 16 +- 3 files changed, 152 insertions(+), 104 deletions(-) create mode 100644 compiler/testData/codegen/boxWithStdlib/annotations/varargInAnnotationParameter.kt diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/AnnotationCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/AnnotationCodegen.java index b8ac58e8cc4..2f230c791fb 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/AnnotationCodegen.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/AnnotationCodegen.java @@ -17,25 +17,26 @@ package org.jetbrains.jet.codegen; import com.intellij.psi.PsiElement; +import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.asm4.AnnotationVisitor; import org.jetbrains.asm4.ClassVisitor; import org.jetbrains.asm4.FieldVisitor; import org.jetbrains.asm4.MethodVisitor; -import org.jetbrains.jet.codegen.intrinsics.IntrinsicMethods; import org.jetbrains.jet.codegen.state.JetTypeMapper; import org.jetbrains.jet.lang.descriptors.*; import org.jetbrains.jet.lang.descriptors.annotations.Annotated; +import org.jetbrains.jet.lang.descriptors.annotations.AnnotationArgumentVisitor; import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor; -import org.jetbrains.jet.lang.psi.*; +import org.jetbrains.jet.lang.psi.JetAnnotationEntry; +import org.jetbrains.jet.lang.psi.JetClass; +import org.jetbrains.jet.lang.psi.JetModifierList; +import org.jetbrains.jet.lang.psi.JetModifierListOwner; import org.jetbrains.jet.lang.resolve.BindingContext; -import org.jetbrains.jet.lang.resolve.calls.model.DefaultValueArgument; import org.jetbrains.jet.lang.resolve.calls.model.ResolvedCall; -import org.jetbrains.jet.lang.resolve.calls.model.ResolvedValueArgument; -import org.jetbrains.jet.lang.resolve.calls.model.VarargValueArgument; -import org.jetbrains.jet.lang.resolve.constants.CompileTimeConstant; -import org.jetbrains.jet.lang.resolve.name.Name; -import org.jetbrains.jet.lang.types.JetType; +import org.jetbrains.jet.lang.resolve.constants.*; +import org.jetbrains.jet.lang.resolve.constants.StringValue; +import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns; import java.lang.annotation.RetentionPolicy; import java.util.List; @@ -84,124 +85,136 @@ public abstract class AnnotationCodegen { AnnotationDescriptor annotationDescriptor = bindingContext.get(BindingContext.ANNOTATION, annotationEntry); if (annotationDescriptor == null) continue; // Skipping annotations if they are not resolved. Needed for JetLightClass generation - JetType type = annotationDescriptor.getType(); - genAnnotation(resolvedCall, type); + genAnnotation(annotationDescriptor); } } - private void genAnnotation( - ResolvedCall resolvedCall, - JetType type - ) { - ClassifierDescriptor classifierDescriptor = type.getConstructor().getDeclarationDescriptor(); + private void genAnnotation(AnnotationDescriptor annotationDescriptor) { + ClassifierDescriptor classifierDescriptor = annotationDescriptor.getType().getConstructor().getDeclarationDescriptor(); RetentionPolicy rp = getRetentionPolicy(classifierDescriptor, typeMapper); if (rp == RetentionPolicy.SOURCE) { return; } - String internalName = typeMapper.mapType(type).getDescriptor(); + String internalName = typeMapper.mapType(annotationDescriptor.getType()).getDescriptor(); AnnotationVisitor annotationVisitor = visitAnnotation(internalName, rp == RetentionPolicy.RUNTIME); - getAnnotation(resolvedCall, annotationVisitor); - + genAnnotationArguments(annotationDescriptor, annotationVisitor); annotationVisitor.visitEnd(); } - private void getAnnotation(ResolvedCall resolvedCall, AnnotationVisitor annotationVisitor) { - for (Map.Entry entry : resolvedCall.getValueArguments().entrySet()) { - ResolvedValueArgument valueArgument = entry.getValue(); - if (valueArgument instanceof DefaultValueArgument) { - continue; - } - - Name keyName = entry.getKey().getName(); - genAnnotationValueArgument(annotationVisitor, valueArgument, keyName.asString()); + private void genAnnotationArguments(AnnotationDescriptor annotationDescriptor, AnnotationVisitor annotationVisitor) { + for (Map.Entry> entry : annotationDescriptor.getAllValueArguments().entrySet()) { + ValueParameterDescriptor descriptor = entry.getKey(); + String name = descriptor.getName().asString(); + genAnnotationArgument(name, entry.getValue(), annotationVisitor); } } - private void genAnnotationValueArgument(AnnotationVisitor annotationVisitor, ResolvedValueArgument valueArgument, String keyName) { - List valueArguments = valueArgument.getArguments(); - if (valueArgument instanceof VarargValueArgument) { - AnnotationVisitor visitor = annotationVisitor.visitArray(keyName); - for (ValueArgument argument : valueArguments) { - genAnnotationExpressionValue(visitor, null, argument.getArgumentExpression()); + private void genAnnotationArgument( + @Nullable final String name, + @NotNull CompileTimeConstant value, + @NotNull final AnnotationVisitor annotationVisitor + ) { + AnnotationArgumentVisitor argumentVisitor = new AnnotationArgumentVisitor() { + @Override + public Void visitLongValue(@NotNull LongValue value, Void data) { + return visitSimpleValue(value); } - visitor.visitEnd(); - } - else { - assert valueArguments.size() == 1 : "Number of arguments on " + keyName + " = " + valueArguments.size(); // todo - JetExpression expression = valueArguments.get(0).getArgumentExpression(); - genAnnotationExpressionValue(annotationVisitor, keyName, expression); - } - } - private void genAnnotationExpressionValue(AnnotationVisitor annotationVisitor, @Nullable String keyName, JetExpression expression) { - CompileTimeConstant compileTimeConstant = - bindingContext.get(BindingContext.COMPILE_TIME_VALUE, expression); + @Override + public Void visitIntValue(IntValue value, Void data) { + return visitSimpleValue(value); + } - if (compileTimeConstant != null) { - Object value = compileTimeConstant.getValue(); - annotationVisitor.visit(keyName, value); - return; - } + @Override + public Void visitShortValue(ShortValue value, Void data) { + return visitSimpleValue(value); + } - if (expression instanceof JetDotQualifiedExpression) { - JetDotQualifiedExpression qualifiedExpression = (JetDotQualifiedExpression) expression; - ResolvedCall call = - bindingContext.get(BindingContext.RESOLVED_CALL, qualifiedExpression.getSelectorExpression()); - if (call != null) { - if (call.getResultingDescriptor() instanceof PropertyDescriptor) { - PropertyDescriptor descriptor = (PropertyDescriptor) call.getResultingDescriptor(); - annotationVisitor.visitEnum(keyName, typeMapper.mapType(descriptor).getDescriptor(), descriptor.getName().asString()); - return; + @Override + public Void visitByteValue(ByteValue value, Void data) { + return visitSimpleValue(value); + } + + @Override + public Void visitDoubleValue(DoubleValue value, Void data) { + return visitSimpleValue(value); + } + + @Override + public Void visitFloatValue(FloatValue value, Void data) { + return visitSimpleValue(value); + } + + @Override + public Void visitBooleanValue(BooleanValue value, Void data) { + return visitSimpleValue(value); + } + + @Override + public Void visitCharValue(CharValue value, Void data) { + return visitSimpleValue(value); + } + + @Override + public Void visitStringValue(StringValue value, Void data) { + return visitSimpleValue(value); + } + + @Override + public Void visitEnumValue(EnumValue value, Void data) { + String propertyName = value.getValue().getName().asString(); + annotationVisitor.visitEnum(name, typeMapper.mapType(value.getType(KotlinBuiltIns.getInstance())).getDescriptor(), propertyName); + return null; + } + + @Override + public Void visitArrayValue(ArrayValue value, Void data) { + AnnotationVisitor visitor = annotationVisitor.visitArray(name); + for (CompileTimeConstant argument : value.getValue()) { + genAnnotationArgument(null, argument, visitor); } + visitor.visitEnd(); + return null; } - } - else { - if (expression instanceof JetCallExpression) { - JetCallExpression callExpression = (JetCallExpression) expression; - ResolvedCall call = - bindingContext.get(BindingContext.RESOLVED_CALL, callExpression.getCalleeExpression()); - if (call != null) { - List annotations = call.getResultingDescriptor().getOriginal().getAnnotations(); - String value = null; - if (annotations != null) { - for (AnnotationDescriptor annotation : annotations) { - //noinspection ConstantConditions - if ("Intrinsic".equals(annotation.getType().getConstructor().getDeclarationDescriptor().getName().asString())) { - value = (String) annotation.getAllValueArguments().values().iterator().next().getValue(); - break; - } - } - } - if (IntrinsicMethods.KOTLIN_JAVA_CLASS_FUNCTION.equals(value)) { - //noinspection ConstantConditions - annotationVisitor.visit(keyName, typeMapper - .mapType(call.getResultingDescriptor().getReturnType().getArguments().get(0).getType())); - return; - } - else if (IntrinsicMethods.KOTLIN_ARRAYS_ARRAY.equals(value)) { - AnnotationVisitor visitor = annotationVisitor.visitArray(keyName); - VarargValueArgument next = (VarargValueArgument) call.getValueArguments().values().iterator().next(); - for (ValueArgument argument : next.getArguments()) { - genAnnotationExpressionValue(visitor, null, argument.getArgumentExpression()); - } - visitor.visitEnd(); - return; - } - else if (call.getResultingDescriptor() instanceof ConstructorDescriptor) { - ConstructorDescriptor descriptor = (ConstructorDescriptor) call.getResultingDescriptor(); - AnnotationVisitor visitor = annotationVisitor.visitAnnotation(keyName, typeMapper - .mapType(descriptor.getContainingDeclaration()).getDescriptor()); - getAnnotation(call, visitor); - visitor.visitEnd(); - return; - } - } - } - } - throw new IllegalStateException("Don't know how to compile annotation value"); + @Override + public Void visitAnnotationValue(AnnotationValue value, Void data) { + String internalAnnName = typeMapper.mapType(value.getValue().getType()).getDescriptor(); + AnnotationVisitor visitor = annotationVisitor.visitAnnotation(name, internalAnnName); + genAnnotationArguments(value.getValue(), visitor); + visitor.visitEnd(); + return null; + } + + @Override + public Void visitJavaClassValue(JavaClassValue value, Void data) { + annotationVisitor.visit(name, typeMapper.mapType(value.getValue())); + return null; + } + + private Void visitSimpleValue(CompileTimeConstant value) { + annotationVisitor.visit(name, value.getValue()); + return null; + } + + @Override + public Void visitErrorValue(ErrorValue value, Void data) { + return visitUnsupportedValue(value); + } + + @Override + public Void visitNullValue(NullValue value, Void data) { + return visitUnsupportedValue(value); + } + + private Void visitUnsupportedValue(CompileTimeConstant value) { + throw new IllegalStateException("Don't know how to compile annotation value " + value); + } + }; + + value.accept(argumentVisitor, null); } private static RetentionPolicy getRetentionPolicy(ClassifierDescriptor descriptor, JetTypeMapper typeMapper) { diff --git a/compiler/testData/codegen/boxWithStdlib/annotations/varargInAnnotationParameter.kt b/compiler/testData/codegen/boxWithStdlib/annotations/varargInAnnotationParameter.kt new file mode 100644 index 00000000000..d845f7ee4d4 --- /dev/null +++ b/compiler/testData/codegen/boxWithStdlib/annotations/varargInAnnotationParameter.kt @@ -0,0 +1,21 @@ +import java.lang.annotation.Retention +import java.lang.annotation.RetentionPolicy + +Retention(RetentionPolicy.RUNTIME) +annotation class Ann(val s: String, vararg val p: Int) + +Ann("str", 1, 2, 3) class MyClass + +fun box(): String { + val ann = javaClass().getAnnotation(javaClass()) + if (ann == null) return "fail: cannot find Ann on MyClass" + if (ann.s != "str") return "fail: annotation parameter s should be \"str\"" + if (ann.p[0] != 1) return "fail: annotation parameter p[0] should be 1" + if (ann.p[1] != 2) return "fail: annotation parameter p[1] should be 2" + if (ann.p[2] != 3) return "fail: annotation parameter p[2] should be 3" + return "OK" +} + +fun main(args: Array) { + println(box()) +} \ No newline at end of file diff --git a/compiler/tests/org/jetbrains/jet/codegen/generated/BlackBoxWithStdlibCodegenTestGenerated.java b/compiler/tests/org/jetbrains/jet/codegen/generated/BlackBoxWithStdlibCodegenTestGenerated.java index 17e6c9b373d..24e69e94441 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.Casts.class, BlackBoxWithStdlibCodegenTestGenerated.DataClasses.class, BlackBoxWithStdlibCodegenTestGenerated.FullJdk.class, BlackBoxWithStdlibCodegenTestGenerated.JdkAnnotations.class, BlackBoxWithStdlibCodegenTestGenerated.Ranges.class, BlackBoxWithStdlibCodegenTestGenerated.Regressions.class, BlackBoxWithStdlibCodegenTestGenerated.Strings.class}) +@InnerTestClasses({BlackBoxWithStdlibCodegenTestGenerated.Annotations.class, 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/annotations") + public static class Annotations extends AbstractBlackBoxCodegenTest { + public void testAllFilesPresentInAnnotations() throws Exception { + JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.GenerateTests", new File("compiler/testData/codegen/boxWithStdlib/annotations"), Pattern.compile("^(.+)\\.kt$"), true); + } + + @TestMetadata("varargInAnnotationParameter.kt") + public void testVarargInAnnotationParameter() throws Exception { + doTestWithStdlib("compiler/testData/codegen/boxWithStdlib/annotations/varargInAnnotationParameter.kt"); + } + + } + @TestMetadata("compiler/testData/codegen/boxWithStdlib/casts") public static class Casts extends AbstractBlackBoxCodegenTest { public void testAllFilesPresentInCasts() throws Exception { @@ -882,6 +895,7 @@ public class BlackBoxWithStdlibCodegenTestGenerated extends AbstractBlackBoxCode public static Test suite() { TestSuite suite = new TestSuite("BlackBoxWithStdlibCodegenTestGenerated"); suite.addTestSuite(BlackBoxWithStdlibCodegenTestGenerated.class); + suite.addTestSuite(Annotations.class); suite.addTestSuite(Casts.class); suite.addTest(DataClasses.innerSuite()); suite.addTestSuite(FullJdk.class); From b76980266dd3f7ac3686c6817481ac1d6770b3c7 Mon Sep 17 00:00:00 2001 From: "Natalia.Ukhorskaya" Date: Fri, 5 Jul 2013 20:23:25 +0400 Subject: [PATCH 282/291] Fix tests on android --- .../tests/org/jetbrains/jet/compiler/android/SpecialFiles.java | 1 + 1 file changed, 1 insertion(+) diff --git a/compiler/android-tests/tests/org/jetbrains/jet/compiler/android/SpecialFiles.java b/compiler/android-tests/tests/org/jetbrains/jet/compiler/android/SpecialFiles.java index 29f2b956b91..d30c83f580b 100644 --- a/compiler/android-tests/tests/org/jetbrains/jet/compiler/android/SpecialFiles.java +++ b/compiler/android-tests/tests/org/jetbrains/jet/compiler/android/SpecialFiles.java @@ -49,6 +49,7 @@ public class SpecialFiles { filesCompiledWithoutStdLib.add("kt773.kt"); // OVERLOAD_RESOLUTION_AMBIGUITY filesCompiledWithoutStdLib.add("kt796_797.kt"); // OVERLOAD_RESOLUTION_AMBIGUITY filesCompiledWithoutStdLib.add("kt950.kt"); // OVERLOAD_RESOLUTION_AMBIGUITY + filesCompiledWithoutStdLib.add("kt3190.kt"); // OVERLOAD_RESOLUTION_AMBIGUITY filesCompiledWithoutStdLib.add("kt2395.kt"); // With MOCK_JDK } From dc9597759a080fdfa04de4c49efe585a8a687dbf Mon Sep 17 00:00:00 2001 From: Leonid Shalupov Date: Sat, 6 Jul 2013 15:27:20 +0400 Subject: [PATCH 283/291] KT-3725 required tags for Maven Central --- libraries/pom.xml | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/libraries/pom.xml b/libraries/pom.xml index 48652d81263..c6a547179bc 100644 --- a/libraries/pom.xml +++ b/libraries/pom.xml @@ -10,6 +10,33 @@ 0.1-SNAPSHOT pom + Kotlin + Kotlin is a statically typed programming language that compiles to JVM byte codes and JavaScrip + http://kotlin.jetbrains.org/ + + + + The Apache Software License, Version 2.0 + http://www.apache.org/licenses/LICENSE-2.0.txt + repo + A business-friendly OSS license + + + + + https://github.com/JetBrains/kotlin + https://github.com/JetBrains/kotlin.git + + + + + JetBrains + JetBrains Team + JetBrains + http://www.jetbrains.com + + + UTF-8 ../../.. From 8162fcd3eb100498903a0413496971f11bc819b3 Mon Sep 17 00:00:00 2001 From: Leonid Shalupov Date: Sat, 6 Jul 2013 16:17:52 +0400 Subject: [PATCH 284/291] KT-3725 better scm references --- libraries/pom.xml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/libraries/pom.xml b/libraries/pom.xml index c6a547179bc..095b2e2ff1e 100644 --- a/libraries/pom.xml +++ b/libraries/pom.xml @@ -25,7 +25,8 @@ https://github.com/JetBrains/kotlin - https://github.com/JetBrains/kotlin.git + scm:git:https://github.com/JetBrains/kotlin.git + scm:git:https://github.com/JetBrains/kotlin.git From fee090239959347069f03b4bd149d8a25078c0bc Mon Sep 17 00:00:00 2001 From: Leonid Shalupov Date: Sat, 6 Jul 2013 17:05:51 +0400 Subject: [PATCH 285/291] KT-3725 set jar packaging for Kotlin compiler artifact --- libraries/tools/kotlin-compiler/pom.xml | 26 ++++++++++++++++++++----- 1 file changed, 21 insertions(+), 5 deletions(-) diff --git a/libraries/tools/kotlin-compiler/pom.xml b/libraries/tools/kotlin-compiler/pom.xml index 63d712a6eb1..28c389d7020 100644 --- a/libraries/tools/kotlin-compiler/pom.xml +++ b/libraries/tools/kotlin-compiler/pom.xml @@ -17,12 +17,13 @@ kotlin-compiler - pom + jar the Kotlin compiler + org.codehaus.mojo build-helper-maven-plugin @@ -36,10 +37,6 @@ - - ${kotlin-sdk}/lib/kotlin-compiler.jar - jar - ${kotlin-dist}/kotlin-compiler-sources.jar jar @@ -56,6 +53,25 @@ + + org.apache.maven.plugins + maven-antrun-plugin + + + copy-jar + package + + + + + + + run + + + + + From d0765d5e4a54d9d86fb018bb70161c3363d1b3b1 Mon Sep 17 00:00:00 2001 From: Leonid Shalupov Date: Mon, 8 Jul 2013 00:56:11 +0400 Subject: [PATCH 286/291] KT-3725 build sources.jar for all maven modules --- libraries/pom.xml | 17 +++++++++++++++++ libraries/stdlib/pom.xml | 16 ---------------- libraries/tools/runtime/pom.xml | 16 ---------------- 3 files changed, 17 insertions(+), 32 deletions(-) diff --git a/libraries/pom.xml b/libraries/pom.xml index 095b2e2ff1e..a70b878593c 100644 --- a/libraries/pom.xml +++ b/libraries/pom.xml @@ -160,6 +160,23 @@ + + + org.apache.maven.plugins + maven-source-plugin + + + + + package + attach-sources + + jar-no-fork + + + + + diff --git a/libraries/stdlib/pom.xml b/libraries/stdlib/pom.xml index dc6bd9ff614..e539dcf82bb 100644 --- a/libraries/stdlib/pom.xml +++ b/libraries/stdlib/pom.xml @@ -43,22 +43,6 @@ - - org.apache.maven.plugins - maven-source-plugin - - - - - package - attach-sources - - jar-no-fork - - - - - org.jetbrains.kotlin kotlin-maven-plugin diff --git a/libraries/tools/runtime/pom.xml b/libraries/tools/runtime/pom.xml index 090bd908eda..5c8219e2209 100644 --- a/libraries/tools/runtime/pom.xml +++ b/libraries/tools/runtime/pom.xml @@ -43,22 +43,6 @@ - - org.apache.maven.plugins - maven-source-plugin - - - - - package - attach-sources - - jar-no-fork - - - - - org.apache.maven.plugins maven-javadoc-plugin From abcf5616f7ad477fc9e0a9aa4b3555ab52090564 Mon Sep 17 00:00:00 2001 From: Leonid Shalupov Date: Mon, 8 Jul 2013 02:25:04 +0400 Subject: [PATCH 287/291] KT-3725 attach empty javadocs to all artifacts except compiler and runtime --- libraries/lib/empty-javadoc.jar | Bin 0 -> 237 bytes libraries/pom.xml | 46 ++++++++++++++++++++++++ libraries/tools/kotlin-compiler/pom.xml | 46 +++++++++++++++--------- libraries/tools/runtime/pom.xml | 19 ++++++++++ 4 files changed, 95 insertions(+), 16 deletions(-) create mode 100644 libraries/lib/empty-javadoc.jar diff --git a/libraries/lib/empty-javadoc.jar b/libraries/lib/empty-javadoc.jar new file mode 100644 index 0000000000000000000000000000000000000000..d845ab23acafb7eb0b387393dcc0ba8def6f5b9c GIT binary patch literal 237 zcmWIWW@Zs#U}E54aOQmB#PKYRyPSc6p%;j`fH=t2(Z$zQucV^H^o$|jAp;(Vi?%`U z9&k_K;h1n^hV>y7}IsC7deXCo%PUg`YwJX-`F-Kjs?7B<79M0WtFWYzD vGr7v3E8;U_fHxzP2m@{h0^P{K$e;kCfB@m#0B=?{kO(6XS^(+!APxfn*7`>0 literal 0 HcmV?d00001 diff --git a/libraries/pom.xml b/libraries/pom.xml index a70b878593c..2ed566aa5a8 100644 --- a/libraries/pom.xml +++ b/libraries/pom.xml @@ -138,6 +138,11 @@ maven-javadoc-plugin 2.9 + + org.codehaus.mojo + build-helper-maven-plugin + 1.7 + @@ -177,6 +182,47 @@ + + org.codehaus.mojo + build-helper-maven-plugin + + + attach-empty-javadoc + prepare-package + + attach-artifact + + + + + ${highest-basedir}/lib/empty-javadoc.jar + jar + javadoc + + + + + + + + + org.commonjava.maven.plugins + directory-maven-plugin + 0.1 + + + directories + + highest-basedir + + initialize + + highest-basedir + + + + + diff --git a/libraries/tools/kotlin-compiler/pom.xml b/libraries/tools/kotlin-compiler/pom.xml index 28c389d7020..8838086c50d 100644 --- a/libraries/tools/kotlin-compiler/pom.xml +++ b/libraries/tools/kotlin-compiler/pom.xml @@ -50,26 +50,40 @@ + + + attach-empty-javadoc + prepare-package + + attach-artifact + + + true + + + - org.apache.maven.plugins - maven-antrun-plugin - - - copy-jar - package - - - - - - - run - - - + org.apache.maven.plugins + maven-antrun-plugin + + + copy-jar + package + + + + + + + run + + + diff --git a/libraries/tools/runtime/pom.xml b/libraries/tools/runtime/pom.xml index 5c8219e2209..ab580b622ce 100644 --- a/libraries/tools/runtime/pom.xml +++ b/libraries/tools/runtime/pom.xml @@ -56,6 +56,25 @@ + + + org.codehaus.mojo + build-helper-maven-plugin + 1.7 + + + attach-empty-javadoc + prepare-package + + attach-artifact + + + true + + + + + From 21fa398380725f5c39c02d39179388f9c3f118ee Mon Sep 17 00:00:00 2001 From: Nikolay Krasko Date: Fri, 5 Jul 2013 20:19:22 +0400 Subject: [PATCH 288/291] KT-3750 When without else #KT-3750 Fixed --- .../jet/lang/resolve/ControlFlowAnalyzer.java | 1 + .../checker/WhenInEnumInExtensionProperty.kt | 15 +++++++++++++++ .../outOfBlock/InGlobalPropertyWithGetter.kt | 9 +++++++++ .../jet/checkers/JetPsiCheckerTestGenerated.java | 5 +++++ .../codeInsight/OutOfBlockModificationTest.java | 4 ++++ 5 files changed, 34 insertions(+) create mode 100644 idea/testData/checker/WhenInEnumInExtensionProperty.kt create mode 100644 idea/testData/codeInsight/outOfBlock/InGlobalPropertyWithGetter.kt diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/ControlFlowAnalyzer.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/ControlFlowAnalyzer.java index b79eb0bb056..3bf6a586695 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/ControlFlowAnalyzer.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/ControlFlowAnalyzer.java @@ -46,6 +46,7 @@ public class ControlFlowAnalyzer { public void process(@NotNull BodiesResolveContext bodiesResolveContext) { for (JetFile file : bodiesResolveContext.getFiles()) { + if (!bodiesResolveContext.completeAnalysisNeeded(file)) continue; checkDeclarationContainer(file); } for (JetClass aClass : bodiesResolveContext.getClasses().keySet()) { diff --git a/idea/testData/checker/WhenInEnumInExtensionProperty.kt b/idea/testData/checker/WhenInEnumInExtensionProperty.kt new file mode 100644 index 00000000000..5217d16fdf7 --- /dev/null +++ b/idea/testData/checker/WhenInEnumInExtensionProperty.kt @@ -0,0 +1,15 @@ +// KT-3750 When without else + +enum class A { + e1 + e2 +} +class B(val a: A) +val B.foo: Int + get() { + // Check absence [NO_ELSE_IN_WHEN] error + return when (a) { + A.e1 -> 1 + A.e2 -> 3 + } + } \ No newline at end of file diff --git a/idea/testData/codeInsight/outOfBlock/InGlobalPropertyWithGetter.kt b/idea/testData/codeInsight/outOfBlock/InGlobalPropertyWithGetter.kt new file mode 100644 index 00000000000..74c94a1805b --- /dev/null +++ b/idea/testData/codeInsight/outOfBlock/InGlobalPropertyWithGetter.kt @@ -0,0 +1,9 @@ +// FALSE +class B(val a: A) +val B.foo: Int + get() { + return when (a) { + A.e1 -> 1 + A.e2 -> 4 + } + } \ No newline at end of file diff --git a/idea/tests/org/jetbrains/jet/checkers/JetPsiCheckerTestGenerated.java b/idea/tests/org/jetbrains/jet/checkers/JetPsiCheckerTestGenerated.java index 306bf099898..38c3a9699eb 100644 --- a/idea/tests/org/jetbrains/jet/checkers/JetPsiCheckerTestGenerated.java +++ b/idea/tests/org/jetbrains/jet/checkers/JetPsiCheckerTestGenerated.java @@ -268,6 +268,11 @@ public class JetPsiCheckerTestGenerated extends AbstractJetPsiCheckerTest { doTest("idea/testData/checker/When.kt"); } + @TestMetadata("WhenInEnumInExtensionProperty.kt") + public void testWhenInEnumInExtensionProperty() throws Exception { + doTest("idea/testData/checker/WhenInEnumInExtensionProperty.kt"); + } + } @TestMetadata("idea/testData/checker/regression") diff --git a/idea/tests/org/jetbrains/jet/plugin/codeInsight/OutOfBlockModificationTest.java b/idea/tests/org/jetbrains/jet/plugin/codeInsight/OutOfBlockModificationTest.java index 3acf3e9fab3..1af69dc5333 100644 --- a/idea/tests/org/jetbrains/jet/plugin/codeInsight/OutOfBlockModificationTest.java +++ b/idea/tests/org/jetbrains/jet/plugin/codeInsight/OutOfBlockModificationTest.java @@ -59,6 +59,10 @@ public class OutOfBlockModificationTest extends LightCodeInsightFixtureTestCase doTest(); } + public void testInGlobalPropertyWithGetter() { + doTest(); + } + public void testInMethod() { doTest(); } From 4a19d4f77b216bd2f351d03371fc008b4a69246d Mon Sep 17 00:00:00 2001 From: Alexey Sedunov Date: Fri, 5 Jul 2013 15:30:03 +0400 Subject: [PATCH 289/291] Fix "Move statement" for the cases when nested closure is used (KT-3735) --- .../jetbrains/jet/lang/psi/JetPsiUtil.java | 10 +-- .../upDownMover/JetExpressionMover.java | 64 ++++++++++++------- .../expressions/closureInDoWhile1.kt | 8 +++ .../expressions/closureInDoWhile1.kt.after | 8 +++ .../expressions/closureInDoWhile2.kt | 8 +++ .../expressions/closureInDoWhile2.kt.after | 8 +++ .../moveUpDown/expressions/closureInFor1.kt | 7 ++ .../expressions/closureInFor1.kt.after | 7 ++ .../moveUpDown/expressions/closureInFor2.kt | 7 ++ .../expressions/closureInFor2.kt.after | 7 ++ .../moveUpDown/expressions/closureInIf1.kt | 7 ++ .../expressions/closureInIf1.kt.after | 7 ++ .../moveUpDown/expressions/closureInIf2.kt | 7 ++ .../expressions/closureInIf2.kt.after | 7 ++ .../moveUpDown/expressions/closureInWhile1.kt | 8 +++ .../expressions/closureInWhile1.kt.after | 8 +++ .../moveUpDown/expressions/closureInWhile2.kt | 8 +++ .../expressions/closureInWhile2.kt.after | 8 +++ .../moveUpDown/CodeMoverTestGenerated.java | 40 ++++++++++++ 19 files changed, 206 insertions(+), 28 deletions(-) create mode 100644 idea/testData/codeInsight/moveUpDown/expressions/closureInDoWhile1.kt create mode 100644 idea/testData/codeInsight/moveUpDown/expressions/closureInDoWhile1.kt.after create mode 100644 idea/testData/codeInsight/moveUpDown/expressions/closureInDoWhile2.kt create mode 100644 idea/testData/codeInsight/moveUpDown/expressions/closureInDoWhile2.kt.after create mode 100644 idea/testData/codeInsight/moveUpDown/expressions/closureInFor1.kt create mode 100644 idea/testData/codeInsight/moveUpDown/expressions/closureInFor1.kt.after create mode 100644 idea/testData/codeInsight/moveUpDown/expressions/closureInFor2.kt create mode 100644 idea/testData/codeInsight/moveUpDown/expressions/closureInFor2.kt.after create mode 100644 idea/testData/codeInsight/moveUpDown/expressions/closureInIf1.kt create mode 100644 idea/testData/codeInsight/moveUpDown/expressions/closureInIf1.kt.after create mode 100644 idea/testData/codeInsight/moveUpDown/expressions/closureInIf2.kt create mode 100644 idea/testData/codeInsight/moveUpDown/expressions/closureInIf2.kt.after create mode 100644 idea/testData/codeInsight/moveUpDown/expressions/closureInWhile1.kt create mode 100644 idea/testData/codeInsight/moveUpDown/expressions/closureInWhile1.kt.after create mode 100644 idea/testData/codeInsight/moveUpDown/expressions/closureInWhile2.kt create mode 100644 idea/testData/codeInsight/moveUpDown/expressions/closureInWhile2.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 1aa0917c074..a5505b3783a 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetPsiUtil.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetPsiUtil.java @@ -779,22 +779,22 @@ public class JetPsiUtil { } @Nullable - public static T getOutermostJetElement( + public static JetElement getOutermostDescendantElement( @Nullable PsiElement root, boolean first, - @NotNull final Class... elementTypes + final @NotNull Predicate predicate ) { if (!(root instanceof JetElement)) return null; - final List results = Lists.newArrayList(); + final List results = Lists.newArrayList(); ((JetElement) root).accept( new JetVisitorVoid() { @Override public void visitJetElement(JetElement element) { - if (PsiTreeUtil.instanceOf(element, elementTypes)) { + if (predicate.apply(element)) { //noinspection unchecked - results.add((T) element); + results.add(element); } else { element.acceptChildren(this); 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 438622f1c8b..1b3a968d083 100644 --- a/idea/src/org/jetbrains/jet/plugin/codeInsight/upDownMover/JetExpressionMover.java +++ b/idea/src/org/jetbrains/jet/plugin/codeInsight/upDownMover/JetExpressionMover.java @@ -1,5 +1,6 @@ package org.jetbrains.jet.plugin.codeInsight.upDownMover; +import com.google.common.base.Predicate; import com.intellij.codeInsight.editorActions.moveUpDown.LineRange; import com.intellij.openapi.editor.Document; import com.intellij.openapi.editor.Editor; @@ -13,10 +14,12 @@ import org.jetbrains.jet.lang.psi.*; import org.jetbrains.jet.lexer.JetTokens; public class JetExpressionMover extends AbstractJetUpDownMover { + public JetExpressionMover() { } - private final 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}; private final static Class[] BLOCKLIKE_ELEMENT_CLASSES = {JetBlockExpression.class, JetWhenExpression.class, JetClassBody.class, JetFile.class}; @@ -24,6 +27,21 @@ public class JetExpressionMover extends AbstractJetUpDownMover { private final static Class[] FUNCTIONLIKE_ELEMENT_CLASSES = {JetFunction.class, JetPropertyAccessor.class, JetClassInitializer.class}; + private static final Predicate CHECK_BLOCK_LIKE_ELEMENT = new Predicate() { + @Override + public boolean apply(@Nullable JetElement input) { + return (input instanceof JetBlockExpression || input instanceof JetClassBody) + && !PsiTreeUtil.instanceOf(input.getParent(), FUNCTIONLIKE_ELEMENT_CLASSES); + } + }; + + private static final Predicate CHECK_BLOCK = new Predicate() { + @Override + public boolean apply(@Nullable JetElement input) { + return input instanceof JetBlockExpression && !PsiTreeUtil.instanceOf(input.getParent(), FUNCTIONLIKE_ELEMENT_CLASSES); + } + }; + @Nullable private static PsiElement getStandaloneClosingBrace(@NotNull PsiFile file, @NotNull Editor editor) { LineRange range = getLineRangeFromSelection(editor); @@ -137,7 +155,7 @@ public class JetExpressionMover extends AbstractJetUpDownMover { PsiElement parent = current.getParent(); if (parent instanceof JetClassBody || parent instanceof JetClassInitializer || - parent instanceof JetFunction || + parent instanceof JetNamedFunction || parent instanceof JetProperty) { return null; } @@ -147,7 +165,7 @@ public class JetExpressionMover extends AbstractJetUpDownMover { PsiElement sibling = down ? current.getNextSibling() : current.getPrevSibling(); if (sibling != null) { //noinspection unchecked - JetBlockExpression block = JetPsiUtil.getOutermostJetElement(sibling, down, JetBlockExpression.class); + JetBlockExpression block = (JetBlockExpression) JetPsiUtil.getOutermostDescendantElement(sibling, down, CHECK_BLOCK); if (block != null) return block; current = sibling; @@ -195,21 +213,13 @@ public class JetExpressionMover extends AbstractJetUpDownMover { else { // moving into code block //noinspection unchecked - JetElement blockLikeElement = JetPsiUtil.getOutermostJetElement(sibling, down, JetBlockExpression.class, JetWhenExpression.class, JetClassBody.class); - if (blockLikeElement != null && - !(PsiTreeUtil.instanceOf(blockLikeElement.getParent(), FUNCTIONLIKE_ELEMENT_CLASSES))) { - if (blockLikeElement instanceof JetWhenExpression) { - //noinspection unchecked - blockLikeElement = JetPsiUtil.getOutermostJetElement(blockLikeElement, down, JetBlockExpression.class); + JetElement blockLikeElement = JetPsiUtil.getOutermostDescendantElement(sibling, down, CHECK_BLOCK_LIKE_ELEMENT); + if (blockLikeElement != null) { + if (down) { + end = JetPsiUtil.findChildByType(blockLikeElement, JetTokens.LBRACE); } - - if (blockLikeElement != null) { - if (down) { - end = JetPsiUtil.findChildByType(blockLikeElement, JetTokens.LBRACE); - } - else { - start = JetPsiUtil.findChildByType(blockLikeElement, JetTokens.RBRACE); - } + else { + start = JetPsiUtil.findChildByType(blockLikeElement, JetTokens.RBRACE); } } } @@ -228,7 +238,12 @@ public class JetExpressionMover extends AbstractJetUpDownMover { } @Nullable - private LineRange getValueParamOrArgTargetRange(@NotNull Editor editor, @NotNull PsiElement elementToCheck, @NotNull PsiElement sibling, boolean down) { + private LineRange getValueParamOrArgTargetRange( + @NotNull Editor editor, + @NotNull PsiElement elementToCheck, + @NotNull PsiElement sibling, + boolean down + ) { PsiElement next = sibling; if (next.getNode().getElementType() == JetTokens.COMMA) { @@ -236,8 +251,8 @@ public class JetExpressionMover extends AbstractJetUpDownMover { } LineRange range = (next instanceof JetParameter || next instanceof JetValueArgument) - ? new LineRange(next, next, editor.getDocument()) - : null; + ? new LineRange(next, next, editor.getDocument()) + : null; if (range != null) { parametersOrArgsToMove = new Pair(elementToCheck, next); @@ -374,8 +389,10 @@ public class JetExpressionMover extends AbstractJetUpDownMover { info.toMove2 = null; return true; } - case MOVABLE: return true; - default: break; + case MOVABLE: + return true; + default: + break; } LineRange oldRange = info.toMove; @@ -394,7 +411,8 @@ public class JetExpressionMover extends AbstractJetUpDownMover { return true; } - if ((firstElement instanceof JetParameter || firstElement instanceof JetValueArgument) && PsiTreeUtil.isAncestor(lastElement, firstElement, false)) { + if ((firstElement instanceof JetParameter || firstElement instanceof JetValueArgument) && + PsiTreeUtil.isAncestor(lastElement, firstElement, false)) { lastElement = firstElement; } diff --git a/idea/testData/codeInsight/moveUpDown/expressions/closureInDoWhile1.kt b/idea/testData/codeInsight/moveUpDown/expressions/closureInDoWhile1.kt new file mode 100644 index 00000000000..6be71feebc9 --- /dev/null +++ b/idea/testData/codeInsight/moveUpDown/expressions/closureInDoWhile1.kt @@ -0,0 +1,8 @@ +// MOVE: down +fun foo(i: Int) { + do { + println(i) + run { + } + } while (i in run { 1..2 }) +} \ No newline at end of file diff --git a/idea/testData/codeInsight/moveUpDown/expressions/closureInDoWhile1.kt.after b/idea/testData/codeInsight/moveUpDown/expressions/closureInDoWhile1.kt.after new file mode 100644 index 00000000000..264ae2ffccc --- /dev/null +++ b/idea/testData/codeInsight/moveUpDown/expressions/closureInDoWhile1.kt.after @@ -0,0 +1,8 @@ +// MOVE: down +fun foo(i: Int) { + do { + println(i) + } while (i in run { 1..2 }) + run { + } +} \ No newline at end of file diff --git a/idea/testData/codeInsight/moveUpDown/expressions/closureInDoWhile2.kt b/idea/testData/codeInsight/moveUpDown/expressions/closureInDoWhile2.kt new file mode 100644 index 00000000000..205672e74e1 --- /dev/null +++ b/idea/testData/codeInsight/moveUpDown/expressions/closureInDoWhile2.kt @@ -0,0 +1,8 @@ +// MOVE: up +fun foo(i: Int) { + do { + println(i) + } while (i in run { 1..2 }) + run { + } +} \ No newline at end of file diff --git a/idea/testData/codeInsight/moveUpDown/expressions/closureInDoWhile2.kt.after b/idea/testData/codeInsight/moveUpDown/expressions/closureInDoWhile2.kt.after new file mode 100644 index 00000000000..93ef156659a --- /dev/null +++ b/idea/testData/codeInsight/moveUpDown/expressions/closureInDoWhile2.kt.after @@ -0,0 +1,8 @@ +// MOVE: up +fun foo(i: Int) { + do { + println(i) + run { + } + } while (i in run { 1..2 }) +} \ No newline at end of file diff --git a/idea/testData/codeInsight/moveUpDown/expressions/closureInFor1.kt b/idea/testData/codeInsight/moveUpDown/expressions/closureInFor1.kt new file mode 100644 index 00000000000..a83aaadfe3b --- /dev/null +++ b/idea/testData/codeInsight/moveUpDown/expressions/closureInFor1.kt @@ -0,0 +1,7 @@ +// MOVE: down +fun foo() { + run { + } + for (i in run { 1..2 }) { + } +} \ No newline at end of file diff --git a/idea/testData/codeInsight/moveUpDown/expressions/closureInFor1.kt.after b/idea/testData/codeInsight/moveUpDown/expressions/closureInFor1.kt.after new file mode 100644 index 00000000000..ee92e89d50b --- /dev/null +++ b/idea/testData/codeInsight/moveUpDown/expressions/closureInFor1.kt.after @@ -0,0 +1,7 @@ +// MOVE: down +fun foo() { + for (i in run { 1..2 }) { + run { + } + } +} \ No newline at end of file diff --git a/idea/testData/codeInsight/moveUpDown/expressions/closureInFor2.kt b/idea/testData/codeInsight/moveUpDown/expressions/closureInFor2.kt new file mode 100644 index 00000000000..a5f140d5191 --- /dev/null +++ b/idea/testData/codeInsight/moveUpDown/expressions/closureInFor2.kt @@ -0,0 +1,7 @@ +// MOVE: up +fun foo() { + for (i in run { 1..2 }) { + run { + } + } +} \ No newline at end of file diff --git a/idea/testData/codeInsight/moveUpDown/expressions/closureInFor2.kt.after b/idea/testData/codeInsight/moveUpDown/expressions/closureInFor2.kt.after new file mode 100644 index 00000000000..523e6803e76 --- /dev/null +++ b/idea/testData/codeInsight/moveUpDown/expressions/closureInFor2.kt.after @@ -0,0 +1,7 @@ +// MOVE: up +fun foo() { + run { + } + for (i in run { 1..2 }) { + } +} \ No newline at end of file diff --git a/idea/testData/codeInsight/moveUpDown/expressions/closureInIf1.kt b/idea/testData/codeInsight/moveUpDown/expressions/closureInIf1.kt new file mode 100644 index 00000000000..e239ea463e1 --- /dev/null +++ b/idea/testData/codeInsight/moveUpDown/expressions/closureInIf1.kt @@ -0,0 +1,7 @@ +// MOVE: down +fun foo(i: Int) { + run { + } + if (i in run { 1..2 }) { + } +} \ No newline at end of file diff --git a/idea/testData/codeInsight/moveUpDown/expressions/closureInIf1.kt.after b/idea/testData/codeInsight/moveUpDown/expressions/closureInIf1.kt.after new file mode 100644 index 00000000000..67cccf2c4b9 --- /dev/null +++ b/idea/testData/codeInsight/moveUpDown/expressions/closureInIf1.kt.after @@ -0,0 +1,7 @@ +// MOVE: down +fun foo(i: Int) { + if (i in run { 1..2 }) { + run { + } + } +} \ No newline at end of file diff --git a/idea/testData/codeInsight/moveUpDown/expressions/closureInIf2.kt b/idea/testData/codeInsight/moveUpDown/expressions/closureInIf2.kt new file mode 100644 index 00000000000..9a4edcd4190 --- /dev/null +++ b/idea/testData/codeInsight/moveUpDown/expressions/closureInIf2.kt @@ -0,0 +1,7 @@ +// MOVE: up +fun foo(i: Int) { + if (i in run { 1..2 }) { + run { + } + } +} \ No newline at end of file diff --git a/idea/testData/codeInsight/moveUpDown/expressions/closureInIf2.kt.after b/idea/testData/codeInsight/moveUpDown/expressions/closureInIf2.kt.after new file mode 100644 index 00000000000..dae5857c1c4 --- /dev/null +++ b/idea/testData/codeInsight/moveUpDown/expressions/closureInIf2.kt.after @@ -0,0 +1,7 @@ +// MOVE: up +fun foo(i: Int) { + run { + } + if (i in run { 1..2 }) { + } +} \ No newline at end of file diff --git a/idea/testData/codeInsight/moveUpDown/expressions/closureInWhile1.kt b/idea/testData/codeInsight/moveUpDown/expressions/closureInWhile1.kt new file mode 100644 index 00000000000..c17d44fb62a --- /dev/null +++ b/idea/testData/codeInsight/moveUpDown/expressions/closureInWhile1.kt @@ -0,0 +1,8 @@ +// MOVE: down +fun foo(i: Int) { + run { + } + while (i in run { 1..2 }) { + println(i) + } +} \ No newline at end of file diff --git a/idea/testData/codeInsight/moveUpDown/expressions/closureInWhile1.kt.after b/idea/testData/codeInsight/moveUpDown/expressions/closureInWhile1.kt.after new file mode 100644 index 00000000000..ff095512df8 --- /dev/null +++ b/idea/testData/codeInsight/moveUpDown/expressions/closureInWhile1.kt.after @@ -0,0 +1,8 @@ +// MOVE: down +fun foo(i: Int) { + while (i in run { 1..2 }) { + run { + } + println(i) + } +} \ No newline at end of file diff --git a/idea/testData/codeInsight/moveUpDown/expressions/closureInWhile2.kt b/idea/testData/codeInsight/moveUpDown/expressions/closureInWhile2.kt new file mode 100644 index 00000000000..1d6c5219f2e --- /dev/null +++ b/idea/testData/codeInsight/moveUpDown/expressions/closureInWhile2.kt @@ -0,0 +1,8 @@ +// MOVE: up +fun foo(i: Int) { + while (i in run { 1..2 }) { + run { + } + println(i) + } +} \ No newline at end of file diff --git a/idea/testData/codeInsight/moveUpDown/expressions/closureInWhile2.kt.after b/idea/testData/codeInsight/moveUpDown/expressions/closureInWhile2.kt.after new file mode 100644 index 00000000000..d284ce877d3 --- /dev/null +++ b/idea/testData/codeInsight/moveUpDown/expressions/closureInWhile2.kt.after @@ -0,0 +1,8 @@ +// MOVE: up +fun foo(i: Int) { + run { + } + while (i in run { 1..2 }) { + println(i) + } +} \ 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 ecd5afbec5c..6979a50b0b2 100644 --- a/idea/tests/org/jetbrains/jet/plugin/codeInsight/moveUpDown/CodeMoverTestGenerated.java +++ b/idea/tests/org/jetbrains/jet/plugin/codeInsight/moveUpDown/CodeMoverTestGenerated.java @@ -777,6 +777,46 @@ public class CodeMoverTestGenerated extends AbstractCodeMoverTest { JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.GenerateTests", new File("idea/testData/codeInsight/moveUpDown/expressions"), Pattern.compile("^(.+)\\.kt$"), true); } + @TestMetadata("closureInDoWhile1.kt") + public void testClosureInDoWhile1() throws Exception { + doTestExpression("idea/testData/codeInsight/moveUpDown/expressions/closureInDoWhile1.kt"); + } + + @TestMetadata("closureInDoWhile2.kt") + public void testClosureInDoWhile2() throws Exception { + doTestExpression("idea/testData/codeInsight/moveUpDown/expressions/closureInDoWhile2.kt"); + } + + @TestMetadata("closureInFor1.kt") + public void testClosureInFor1() throws Exception { + doTestExpression("idea/testData/codeInsight/moveUpDown/expressions/closureInFor1.kt"); + } + + @TestMetadata("closureInFor2.kt") + public void testClosureInFor2() throws Exception { + doTestExpression("idea/testData/codeInsight/moveUpDown/expressions/closureInFor2.kt"); + } + + @TestMetadata("closureInIf1.kt") + public void testClosureInIf1() throws Exception { + doTestExpression("idea/testData/codeInsight/moveUpDown/expressions/closureInIf1.kt"); + } + + @TestMetadata("closureInIf2.kt") + public void testClosureInIf2() throws Exception { + doTestExpression("idea/testData/codeInsight/moveUpDown/expressions/closureInIf2.kt"); + } + + @TestMetadata("closureInWhile1.kt") + public void testClosureInWhile1() throws Exception { + doTestExpression("idea/testData/codeInsight/moveUpDown/expressions/closureInWhile1.kt"); + } + + @TestMetadata("closureInWhile2.kt") + public void testClosureInWhile2() throws Exception { + doTestExpression("idea/testData/codeInsight/moveUpDown/expressions/closureInWhile2.kt"); + } + @TestMetadata("declaration1.kt") public void testDeclaration1() throws Exception { doTestExpression("idea/testData/codeInsight/moveUpDown/expressions/declaration1.kt"); From 3a881672e8261c06756517aec58858e2b946be38 Mon Sep 17 00:00:00 2001 From: Alexey Sedunov Date: Tue, 9 Jul 2013 16:24:18 +0400 Subject: [PATCH 290/291] KT-3732 "Move statement" should respect DSLs --- .../upDownMover/JetExpressionMover.java | 67 ++++++++++++++++--- .../moveUpDown/expressions/intoClosure1.kt | 7 ++ .../expressions/intoClosure1.kt.after | 7 ++ .../moveUpDown/expressions/intoClosure2.kt | 7 ++ .../expressions/intoClosure2.kt.after | 7 ++ .../expressions/intoNestedClosure1.kt | 7 ++ .../expressions/intoNestedClosure1.kt.after | 7 ++ .../expressions/intoNestedClosure2.kt | 7 ++ .../expressions/intoNestedClosure2.kt.after | 7 ++ .../moveUpDown/expressions/outOfClosure1.kt | 7 ++ .../expressions/outOfClosure1.kt.after | 7 ++ .../moveUpDown/expressions/outOfClosure2.kt | 7 ++ .../expressions/outOfClosure2.kt.after | 7 ++ .../expressions/outOfNestedClosure1.kt | 7 ++ .../expressions/outOfNestedClosure1.kt.after | 7 ++ .../expressions/outOfNestedClosure2.kt | 7 ++ .../expressions/outOfNestedClosure2.kt.after | 7 ++ .../moveUpDown/CodeMoverTestGenerated.java | 40 +++++++++++ 18 files changed, 210 insertions(+), 9 deletions(-) create mode 100644 idea/testData/codeInsight/moveUpDown/expressions/intoClosure1.kt create mode 100644 idea/testData/codeInsight/moveUpDown/expressions/intoClosure1.kt.after create mode 100644 idea/testData/codeInsight/moveUpDown/expressions/intoClosure2.kt create mode 100644 idea/testData/codeInsight/moveUpDown/expressions/intoClosure2.kt.after create mode 100644 idea/testData/codeInsight/moveUpDown/expressions/intoNestedClosure1.kt create mode 100644 idea/testData/codeInsight/moveUpDown/expressions/intoNestedClosure1.kt.after create mode 100644 idea/testData/codeInsight/moveUpDown/expressions/intoNestedClosure2.kt create mode 100644 idea/testData/codeInsight/moveUpDown/expressions/intoNestedClosure2.kt.after create mode 100644 idea/testData/codeInsight/moveUpDown/expressions/outOfClosure1.kt create mode 100644 idea/testData/codeInsight/moveUpDown/expressions/outOfClosure1.kt.after create mode 100644 idea/testData/codeInsight/moveUpDown/expressions/outOfClosure2.kt create mode 100644 idea/testData/codeInsight/moveUpDown/expressions/outOfClosure2.kt.after create mode 100644 idea/testData/codeInsight/moveUpDown/expressions/outOfNestedClosure1.kt create mode 100644 idea/testData/codeInsight/moveUpDown/expressions/outOfNestedClosure1.kt.after create mode 100644 idea/testData/codeInsight/moveUpDown/expressions/outOfNestedClosure2.kt create mode 100644 idea/testData/codeInsight/moveUpDown/expressions/outOfNestedClosure2.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 1b3a968d083..450ffc07ace 100644 --- a/idea/src/org/jetbrains/jet/plugin/codeInsight/upDownMover/JetExpressionMover.java +++ b/idea/src/org/jetbrains/jet/plugin/codeInsight/upDownMover/JetExpressionMover.java @@ -13,8 +13,17 @@ import org.jetbrains.annotations.Nullable; import org.jetbrains.jet.lang.psi.*; import org.jetbrains.jet.lexer.JetTokens; +import java.util.List; + public class JetExpressionMover extends AbstractJetUpDownMover { + private static final Predicate IS_CALL_EXPRESSION = new Predicate() { + @Override + public boolean apply(@Nullable JetElement input) { + return input instanceof JetCallExpression; + } + }; + public JetExpressionMover() { } @@ -149,14 +158,14 @@ public class JetExpressionMover extends AbstractJetUpDownMover { } @Nullable - private static JetBlockExpression findClosestBlock(@NotNull PsiElement anchor, boolean down) { - PsiElement current = PsiTreeUtil.getParentOfType(anchor, JetBlockExpression.class); + private static JetBlockExpression findClosestBlock(@NotNull PsiElement anchor, boolean down, boolean strict) { + PsiElement current = PsiTreeUtil.getParentOfType(anchor, JetBlockExpression.class, strict); while (current != null) { PsiElement parent = current.getParent(); if (parent instanceof JetClassBody || parent instanceof JetClassInitializer || parent instanceof JetNamedFunction || - parent instanceof JetProperty) { + (parent instanceof JetProperty && !((JetProperty) parent).isLocal())) { return null; } @@ -178,6 +187,18 @@ public class JetExpressionMover extends AbstractJetUpDownMover { return null; } + @Nullable + private static JetBlockExpression getDSLLambdaBlock(@NotNull PsiElement element, boolean down) { + JetCallExpression callExpression = + (JetCallExpression) JetPsiUtil.getOutermostDescendantElement(element, down, IS_CALL_EXPRESSION); + if (callExpression == null) return null; + + List functionLiterals = callExpression.getFunctionLiteralArguments(); + if (functionLiterals.isEmpty()) return null; + + return ((JetFunctionLiteralExpression) functionLiterals.get(0)).getBodyExpression(); + } + @Nullable private static LineRange getExpressionTargetRange(@NotNull Editor editor, @NotNull PsiElement sibling, boolean down) { PsiElement start = sibling; @@ -188,7 +209,14 @@ public class JetExpressionMover extends AbstractJetUpDownMover { PsiElement parent = sibling.getParent(); if (!(parent instanceof JetBlockExpression || parent instanceof JetFunctionLiteral)) return null; - JetBlockExpression newBlock = findClosestBlock(sibling, down); + JetBlockExpression newBlock; + if (parent instanceof JetFunctionLiteral) { + //noinspection ConstantConditions + newBlock = findClosestBlock(((JetFunctionLiteral) parent).getBodyExpression(), down, false); + } else { + newBlock = findClosestBlock(sibling, down, true); + } + if (newBlock == null) return null; if (PsiTreeUtil.isAncestor(newBlock, parent, true)) { @@ -210,10 +238,19 @@ public class JetExpressionMover extends AbstractJetUpDownMover { } } } + // moving into code block else { - // moving into code block - //noinspection unchecked - JetElement blockLikeElement = JetPsiUtil.getOutermostDescendantElement(sibling, down, CHECK_BLOCK_LIKE_ELEMENT); + PsiElement blockLikeElement; + + JetBlockExpression dslBlock = getDSLLambdaBlock(sibling, down); + if (dslBlock != null) { + // Use JetFunctionLiteral (since it contains braces) + blockLikeElement = dslBlock.getParent(); + } else { + // JetBlockExpression and other block-like elements + blockLikeElement = JetPsiUtil.getOutermostDescendantElement(sibling, down, CHECK_BLOCK_LIKE_ELEMENT); + } + if (blockLikeElement != null) { if (down) { end = JetPsiUtil.findChildByType(blockLikeElement, JetTokens.LBRACE); @@ -331,7 +368,7 @@ public class JetExpressionMover extends AbstractJetUpDownMover { return block.getLBrace() == null && block.getRBrace() == null; } - protected static PsiElement adjustWhiteSpaceSibling( + protected static PsiElement adjustSibling( @NotNull Editor editor, @NotNull LineRange sourceRange, @NotNull MoveInfo info, @@ -371,6 +408,18 @@ public class JetExpressionMover extends AbstractJetUpDownMover { } if (sibling == null) { + JetCallExpression callExpression = PsiTreeUtil.getParentOfType(element, JetCallExpression.class); + if (callExpression != null) { + JetBlockExpression dslBlock = getDSLLambdaBlock(callExpression, down); + if (PsiTreeUtil.isAncestor(dslBlock, element, false)) { + //noinspection ConstantConditions + PsiElement blockParent = dslBlock.getParent(); + return down + ? JetPsiUtil.findChildByType(blockParent, JetTokens.RBRACE) + : JetPsiUtil.findChildByType(blockParent, JetTokens.LBRACE); + } + } + info.toMove2 = null; return null; } @@ -419,7 +468,7 @@ public class JetExpressionMover extends AbstractJetUpDownMover { LineRange sourceRange = getSourceRange(firstElement, lastElement, editor, oldRange); if (sourceRange == null) return false; - PsiElement sibling = adjustWhiteSpaceSibling(editor, sourceRange, info, down); + PsiElement sibling = adjustSibling(editor, sourceRange, info, down); // Either reached last sibling, or jumped over multi-line whitespace if (sibling == null) return true; diff --git a/idea/testData/codeInsight/moveUpDown/expressions/intoClosure1.kt b/idea/testData/codeInsight/moveUpDown/expressions/intoClosure1.kt new file mode 100644 index 00000000000..e5162bdf63b --- /dev/null +++ b/idea/testData/codeInsight/moveUpDown/expressions/intoClosure1.kt @@ -0,0 +1,7 @@ +// MOVE: down +fun foo() { + println("foo") + run(1, 2) { + println("bar") + } +} \ No newline at end of file diff --git a/idea/testData/codeInsight/moveUpDown/expressions/intoClosure1.kt.after b/idea/testData/codeInsight/moveUpDown/expressions/intoClosure1.kt.after new file mode 100644 index 00000000000..02cc59683e8 --- /dev/null +++ b/idea/testData/codeInsight/moveUpDown/expressions/intoClosure1.kt.after @@ -0,0 +1,7 @@ +// MOVE: down +fun foo() { + run(1, 2) { + println("foo") + println("bar") + } +} \ No newline at end of file diff --git a/idea/testData/codeInsight/moveUpDown/expressions/intoClosure2.kt b/idea/testData/codeInsight/moveUpDown/expressions/intoClosure2.kt new file mode 100644 index 00000000000..efc77f761bd --- /dev/null +++ b/idea/testData/codeInsight/moveUpDown/expressions/intoClosure2.kt @@ -0,0 +1,7 @@ +// MOVE: up +fun foo() { + run(1, 2) { + println("bar") + } + println("foo") +} \ No newline at end of file diff --git a/idea/testData/codeInsight/moveUpDown/expressions/intoClosure2.kt.after b/idea/testData/codeInsight/moveUpDown/expressions/intoClosure2.kt.after new file mode 100644 index 00000000000..cbf22757cf7 --- /dev/null +++ b/idea/testData/codeInsight/moveUpDown/expressions/intoClosure2.kt.after @@ -0,0 +1,7 @@ +// MOVE: up +fun foo() { + run(1, 2) { + println("bar") + println("foo") + } +} \ No newline at end of file diff --git a/idea/testData/codeInsight/moveUpDown/expressions/intoNestedClosure1.kt b/idea/testData/codeInsight/moveUpDown/expressions/intoNestedClosure1.kt new file mode 100644 index 00000000000..e09920ecb45 --- /dev/null +++ b/idea/testData/codeInsight/moveUpDown/expressions/intoNestedClosure1.kt @@ -0,0 +1,7 @@ +// MOVE: down +fun foo() { + println("foo") + val x = run(1, 2) { + println("bar") + } +} \ No newline at end of file diff --git a/idea/testData/codeInsight/moveUpDown/expressions/intoNestedClosure1.kt.after b/idea/testData/codeInsight/moveUpDown/expressions/intoNestedClosure1.kt.after new file mode 100644 index 00000000000..aec40a2d8f0 --- /dev/null +++ b/idea/testData/codeInsight/moveUpDown/expressions/intoNestedClosure1.kt.after @@ -0,0 +1,7 @@ +// MOVE: down +fun foo() { + val x = run(1, 2) { + println("foo") + println("bar") + } +} \ No newline at end of file diff --git a/idea/testData/codeInsight/moveUpDown/expressions/intoNestedClosure2.kt b/idea/testData/codeInsight/moveUpDown/expressions/intoNestedClosure2.kt new file mode 100644 index 00000000000..0751420910b --- /dev/null +++ b/idea/testData/codeInsight/moveUpDown/expressions/intoNestedClosure2.kt @@ -0,0 +1,7 @@ +// MOVE: up +fun foo() { + val x = run(1, 2) { + println("bar") + } + println("foo") +} \ No newline at end of file diff --git a/idea/testData/codeInsight/moveUpDown/expressions/intoNestedClosure2.kt.after b/idea/testData/codeInsight/moveUpDown/expressions/intoNestedClosure2.kt.after new file mode 100644 index 00000000000..86257cc7805 --- /dev/null +++ b/idea/testData/codeInsight/moveUpDown/expressions/intoNestedClosure2.kt.after @@ -0,0 +1,7 @@ +// MOVE: up +fun foo() { + val x = run(1, 2) { + println("bar") + println("foo") + } +} \ No newline at end of file diff --git a/idea/testData/codeInsight/moveUpDown/expressions/outOfClosure1.kt b/idea/testData/codeInsight/moveUpDown/expressions/outOfClosure1.kt new file mode 100644 index 00000000000..ef61d689f65 --- /dev/null +++ b/idea/testData/codeInsight/moveUpDown/expressions/outOfClosure1.kt @@ -0,0 +1,7 @@ +// MOVE: up +fun foo() { + run(1, 2) { + println("foo") + println("bar") + } +} \ No newline at end of file diff --git a/idea/testData/codeInsight/moveUpDown/expressions/outOfClosure1.kt.after b/idea/testData/codeInsight/moveUpDown/expressions/outOfClosure1.kt.after new file mode 100644 index 00000000000..86830ae2c63 --- /dev/null +++ b/idea/testData/codeInsight/moveUpDown/expressions/outOfClosure1.kt.after @@ -0,0 +1,7 @@ +// MOVE: up +fun foo() { + println("foo") + run(1, 2) { + println("bar") + } +} \ No newline at end of file diff --git a/idea/testData/codeInsight/moveUpDown/expressions/outOfClosure2.kt b/idea/testData/codeInsight/moveUpDown/expressions/outOfClosure2.kt new file mode 100644 index 00000000000..5f58bc8b907 --- /dev/null +++ b/idea/testData/codeInsight/moveUpDown/expressions/outOfClosure2.kt @@ -0,0 +1,7 @@ +// MOVE: down +fun foo() { + run(1, 2) { + println("bar") + println("foo") + } +} \ No newline at end of file diff --git a/idea/testData/codeInsight/moveUpDown/expressions/outOfClosure2.kt.after b/idea/testData/codeInsight/moveUpDown/expressions/outOfClosure2.kt.after new file mode 100644 index 00000000000..651ec08a4c9 --- /dev/null +++ b/idea/testData/codeInsight/moveUpDown/expressions/outOfClosure2.kt.after @@ -0,0 +1,7 @@ +// MOVE: down +fun foo() { + run(1, 2) { + println("bar") + } + println("foo") +} \ No newline at end of file diff --git a/idea/testData/codeInsight/moveUpDown/expressions/outOfNestedClosure1.kt b/idea/testData/codeInsight/moveUpDown/expressions/outOfNestedClosure1.kt new file mode 100644 index 00000000000..d1f804b1c56 --- /dev/null +++ b/idea/testData/codeInsight/moveUpDown/expressions/outOfNestedClosure1.kt @@ -0,0 +1,7 @@ +// MOVE: up +fun foo() { + val x = run(1, 2) { + println("foo") + println("bar") + } +} \ No newline at end of file diff --git a/idea/testData/codeInsight/moveUpDown/expressions/outOfNestedClosure1.kt.after b/idea/testData/codeInsight/moveUpDown/expressions/outOfNestedClosure1.kt.after new file mode 100644 index 00000000000..c814aaf68e3 --- /dev/null +++ b/idea/testData/codeInsight/moveUpDown/expressions/outOfNestedClosure1.kt.after @@ -0,0 +1,7 @@ +// MOVE: up +fun foo() { + println("foo") + val x = run(1, 2) { + println("bar") + } +} \ No newline at end of file diff --git a/idea/testData/codeInsight/moveUpDown/expressions/outOfNestedClosure2.kt b/idea/testData/codeInsight/moveUpDown/expressions/outOfNestedClosure2.kt new file mode 100644 index 00000000000..8120deeb4e0 --- /dev/null +++ b/idea/testData/codeInsight/moveUpDown/expressions/outOfNestedClosure2.kt @@ -0,0 +1,7 @@ +// MOVE: down +fun foo() { + val x = run(1, 2) { + println("bar") + println("foo") + } +} \ No newline at end of file diff --git a/idea/testData/codeInsight/moveUpDown/expressions/outOfNestedClosure2.kt.after b/idea/testData/codeInsight/moveUpDown/expressions/outOfNestedClosure2.kt.after new file mode 100644 index 00000000000..b032fc4e944 --- /dev/null +++ b/idea/testData/codeInsight/moveUpDown/expressions/outOfNestedClosure2.kt.after @@ -0,0 +1,7 @@ +// MOVE: down +fun foo() { + val x = run(1, 2) { + println("bar") + } + println("foo") +} \ 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 6979a50b0b2..7666e80dbd4 100644 --- a/idea/tests/org/jetbrains/jet/plugin/codeInsight/moveUpDown/CodeMoverTestGenerated.java +++ b/idea/tests/org/jetbrains/jet/plugin/codeInsight/moveUpDown/CodeMoverTestGenerated.java @@ -847,6 +847,26 @@ public class CodeMoverTestGenerated extends AbstractCodeMoverTest { doTestExpression("idea/testData/codeInsight/moveUpDown/expressions/if4.kt"); } + @TestMetadata("intoClosure1.kt") + public void testIntoClosure1() throws Exception { + doTestExpression("idea/testData/codeInsight/moveUpDown/expressions/intoClosure1.kt"); + } + + @TestMetadata("intoClosure2.kt") + public void testIntoClosure2() throws Exception { + doTestExpression("idea/testData/codeInsight/moveUpDown/expressions/intoClosure2.kt"); + } + + @TestMetadata("intoNestedClosure1.kt") + public void testIntoNestedClosure1() throws Exception { + doTestExpression("idea/testData/codeInsight/moveUpDown/expressions/intoNestedClosure1.kt"); + } + + @TestMetadata("intoNestedClosure2.kt") + public void testIntoNestedClosure2() throws Exception { + doTestExpression("idea/testData/codeInsight/moveUpDown/expressions/intoNestedClosure2.kt"); + } + @TestMetadata("lambda1.kt") public void testLambda1() throws Exception { doTestExpression("idea/testData/codeInsight/moveUpDown/expressions/lambda1.kt"); @@ -862,6 +882,26 @@ public class CodeMoverTestGenerated extends AbstractCodeMoverTest { doTestExpression("idea/testData/codeInsight/moveUpDown/expressions/lambda3.kt"); } + @TestMetadata("outOfClosure1.kt") + public void testOutOfClosure1() throws Exception { + doTestExpression("idea/testData/codeInsight/moveUpDown/expressions/outOfClosure1.kt"); + } + + @TestMetadata("outOfClosure2.kt") + public void testOutOfClosure2() throws Exception { + doTestExpression("idea/testData/codeInsight/moveUpDown/expressions/outOfClosure2.kt"); + } + + @TestMetadata("outOfNestedClosure1.kt") + public void testOutOfNestedClosure1() throws Exception { + doTestExpression("idea/testData/codeInsight/moveUpDown/expressions/outOfNestedClosure1.kt"); + } + + @TestMetadata("outOfNestedClosure2.kt") + public void testOutOfNestedClosure2() throws Exception { + doTestExpression("idea/testData/codeInsight/moveUpDown/expressions/outOfNestedClosure2.kt"); + } + @TestMetadata("when1.kt") public void testWhen1() throws Exception { doTestExpression("idea/testData/codeInsight/moveUpDown/expressions/when1.kt"); From b2ccae41f868b80cd06597bdabfc1d56f1a0d9ca Mon Sep 17 00:00:00 2001 From: Erokhin Stanislav Date: Tue, 9 Jul 2013 17:47:46 +0400 Subject: [PATCH 291/291] Update to IDEA 12.1.4 (build 129.713) --- update_dependencies.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/update_dependencies.xml b/update_dependencies.xml index 8af22a17daf..9991fd7bc0e 100644 --- a/update_dependencies.xml +++ b/update_dependencies.xml @@ -1,6 +1,6 @@ - - + +