Refactoring: create DataClassUtils and move all "component" function utils there

This commit is contained in:
Nikolay Krasko
2014-09-11 12:37:54 +04:00
parent 65d358a066
commit c3f44d5030
12 changed files with 75 additions and 38 deletions
@@ -0,0 +1,41 @@
/*
* Copyright 2010-2014 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.dataClassUtils
import org.jetbrains.jet.lang.resolve.name.Name
import java.util.regex.Pattern
private val COMPONENT_FUNCTION_NAME_PREFIX = "component"
public fun isComponentLike(name: Name): Boolean {
if (!name.asString().startsWith(COMPONENT_FUNCTION_NAME_PREFIX)) return false
try {
getComponentIndex(name)
}
catch (e: NumberFormatException) {
return false
}
return true
}
public fun getComponentIndex(componentName: Name): Int =
componentName.asString().substring(COMPONENT_FUNCTION_NAME_PREFIX.length).toInt()
public fun createComponentName(index: Int): Name =
Name.identifier(COMPONENT_FUNCTION_NAME_PREFIX + index)
@@ -34,6 +34,7 @@ import org.jetbrains.jet.lang.psi.*;
import org.jetbrains.jet.lang.resolve.calls.autocasts.DataFlowInfo;
import org.jetbrains.jet.lang.resolve.constants.CompileTimeConstant;
import org.jetbrains.jet.lang.resolve.constants.IntegerValueTypeConstant;
import org.jetbrains.jet.lang.resolve.dataClassUtils.DataClassUtilsPackage;
import org.jetbrains.jet.lang.resolve.name.FqName;
import org.jetbrains.jet.lang.resolve.name.Name;
import org.jetbrains.jet.lang.resolve.scopes.JetScope;
@@ -63,7 +64,6 @@ import static org.jetbrains.jet.lexer.JetTokens.VARARG_KEYWORD;
public class DescriptorResolver {
public static final Name COPY_METHOD_NAME = Name.identifier("copy");
public static final String COMPONENT_FUNCTION_NAME_PREFIX = "component";
private static final Set<JetModifierKeywordToken> MODIFIERS_ILLEGAL_ON_PARAMETERS;
static {
MODIFIERS_ILLEGAL_ON_PARAMETERS = Sets.newHashSet();
@@ -382,13 +382,13 @@ public class DescriptorResolver {
@NotNull ClassDescriptor classDescriptor,
@NotNull BindingTrace trace
) {
String functionName = COMPONENT_FUNCTION_NAME_PREFIX + parameterIndex;
Name functionName = DataClassUtilsPackage.createComponentName(parameterIndex);
JetType returnType = property.getType();
SimpleFunctionDescriptorImpl functionDescriptor = SimpleFunctionDescriptorImpl.create(
classDescriptor,
Annotations.EMPTY,
Name.identifier(functionName),
functionName,
CallableMemberDescriptor.Kind.SYNTHESIZED,
parameter.getSource()
);
@@ -35,6 +35,7 @@ import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor;
import org.jetbrains.jet.lang.descriptors.impl.MutableClassDescriptor;
import org.jetbrains.jet.lang.psi.*;
import org.jetbrains.jet.lang.resolve.calls.CallResolverUtil;
import org.jetbrains.jet.lang.resolve.dataClassUtils.DataClassUtilsPackage;
import org.jetbrains.jet.lang.resolve.name.Name;
import org.jetbrains.jet.lang.resolve.scopes.JetScope;
import org.jetbrains.jet.lang.types.*;
@@ -598,8 +599,7 @@ public class OverrideResolver {
private void checkOverrideForMember(@NotNull final CallableMemberDescriptor declared) {
if (declared.getKind() == CallableMemberDescriptor.Kind.SYNTHESIZED) {
// TODO: this should be replaced soon by a framework of synthesized member generation tools
if (declared.getName().asString().startsWith(DescriptorResolver.COMPONENT_FUNCTION_NAME_PREFIX)) {
if (DataClassUtilsPackage.isComponentLike(declared.getName())) {
checkOverrideForComponentFunction(declared);
}
return;
@@ -26,6 +26,7 @@ import org.jetbrains.jet.lang.descriptors.impl.ConstructorDescriptorImpl;
import org.jetbrains.jet.lang.diagnostics.Errors;
import org.jetbrains.jet.lang.psi.*;
import org.jetbrains.jet.lang.resolve.*;
import org.jetbrains.jet.lang.resolve.dataClassUtils.DataClassUtilsPackage;
import org.jetbrains.jet.lang.resolve.lazy.ResolveSession;
import org.jetbrains.jet.lang.resolve.lazy.data.JetClassLikeInfo;
import org.jetbrains.jet.lang.resolve.lazy.declarations.ClassMemberDeclarationProvider;
@@ -174,10 +175,9 @@ public class LazyClassMemberScope extends AbstractLazyMemberScope<LazyClassDescr
++componentIndex;
if (name.equals(Name.identifier(DescriptorResolver.COMPONENT_FUNCTION_NAME_PREFIX + componentIndex))) {
SimpleFunctionDescriptor functionDescriptor =
DescriptorResolver.createComponentFunctionDescriptor(componentIndex, property,
parameter, thisDescriptor, trace);
if (name.equals(DataClassUtilsPackage.createComponentName(componentIndex))) {
SimpleFunctionDescriptor functionDescriptor = DescriptorResolver.createComponentFunctionDescriptor(
componentIndex, property, parameter, thisDescriptor, trace);
result.add(functionDescriptor);
break;
}
@@ -316,7 +316,7 @@ public class LazyClassMemberScope extends AbstractLazyMemberScope<LazyClassDescr
// Generate componentN functions until there's no such function for some n
int n = 1;
while (true) {
Name componentName = Name.identifier(DescriptorResolver.COMPONENT_FUNCTION_NAME_PREFIX + n);
Name componentName = DataClassUtilsPackage.createComponentName(n);
Set<FunctionDescriptor> functions = getFunctions(componentName);
if (functions.isEmpty()) break;
@@ -43,6 +43,7 @@ import org.jetbrains.jet.lang.resolve.calls.inference.ConstraintsUtil;
import org.jetbrains.jet.lang.resolve.calls.model.ResolvedCall;
import org.jetbrains.jet.lang.resolve.calls.results.OverloadResolutionResults;
import org.jetbrains.jet.lang.resolve.calls.util.CallMaker;
import org.jetbrains.jet.lang.resolve.dataClassUtils.DataClassUtilsPackage;
import org.jetbrains.jet.lang.resolve.name.Name;
import org.jetbrains.jet.lang.resolve.scopes.JetScope;
import org.jetbrains.jet.lang.resolve.scopes.WritableScope;
@@ -336,7 +337,7 @@ public class ExpressionTypingUtils {
) {
int componentIndex = 1;
for (JetMultiDeclarationEntry entry : multiDeclaration.getEntries()) {
Name componentName = Name.identifier(DescriptorResolver.COMPONENT_FUNCTION_NAME_PREFIX + componentIndex);
Name componentName = DataClassUtilsPackage.createComponentName(componentIndex);
componentIndex++;
JetType expectedType = getExpectedTypeForComponent(context, entry);
@@ -1,8 +0,0 @@
package org.jetbrains.jet.lang.resolve.name
import java.util.regex.Pattern
public val COMPONENT_FUNCTION_PATTERN: Pattern = Pattern.compile("^component(\\d+)$")
public fun String.isComponentFunctionName(): Boolean = COMPONENT_FUNCTION_PATTERN.matcher(this).matches()
public fun Name.isComponentFunctionName(): Boolean = asString().isComponentFunctionName()
@@ -29,7 +29,7 @@ import java.util.*
import org.jetbrains.jet.lang.resolve.DescriptorUtils.isEnumEntry
import org.jetbrains.jet.lang.resolve.DescriptorUtils.isSyntheticClassObject
import org.jetbrains.jet.lang.types.error.MissingDependencyErrorClass
import org.jetbrains.jet.lang.resolve.name.isComponentFunctionName
import org.jetbrains.jet.lang.resolve.dataClassUtils.isComponentLike
public fun buildDecompiledText(
classFile: VirtualFile,
@@ -128,7 +128,7 @@ private fun buildDecompiledText(packageFqName: FqName, descriptors: List<Declara
}
if (member is CallableMemberDescriptor
&& member.getKind() != CallableMemberDescriptor.Kind.DECLARATION
&& !member.getName().isComponentFunctionName()) {
&& !isComponentLike(member.getName())) {
continue
}
@@ -31,11 +31,12 @@ import org.jetbrains.jet.lang.descriptors.SimpleFunctionDescriptor;
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.DescriptorResolver;
import org.jetbrains.jet.lang.resolve.DescriptorToSourceUtils;
import org.jetbrains.jet.lang.resolve.calls.callUtil.CallUtilPackage;
import org.jetbrains.jet.lang.resolve.calls.model.ResolvedCall;
import org.jetbrains.jet.lang.resolve.dataClassUtils.DataClassUtilsPackage;
import org.jetbrains.jet.lang.resolve.name.FqName;
import org.jetbrains.jet.lang.resolve.name.Name;
import org.jetbrains.jet.lang.types.ErrorUtils;
import org.jetbrains.jet.lang.types.JetType;
import org.jetbrains.jet.lang.types.checker.JetTypeChecker;
@@ -130,8 +131,8 @@ public class ChangeFunctionReturnTypeFix extends JetIntentionAction<JetFunction>
@NotNull
public static JetMultiDeclarationEntry getMultiDeclarationEntryThatTypeMismatchComponentFunction(Diagnostic diagnostic) {
String componentName = COMPONENT_FUNCTION_RETURN_TYPE_MISMATCH.cast(diagnostic).getA().asString();
int componentIndex = Integer.valueOf(componentName.substring(DescriptorResolver.COMPONENT_FUNCTION_NAME_PREFIX.length()));
Name componentName = COMPONENT_FUNCTION_RETURN_TYPE_MISMATCH.cast(diagnostic).getA();
int componentIndex = DataClassUtilsPackage.getComponentIndex(componentName);
JetMultiDeclaration multiDeclaration = QuickFixUtil.getParentElementOfType(diagnostic, JetMultiDeclaration.class);
assert multiDeclaration != null : "COMPONENT_FUNCTION_RETURN_TYPE_MISMATCH reported on expression that is not within any multi declaration";
return multiDeclaration.getEntries().get(componentIndex - 1);
@@ -70,7 +70,8 @@ import org.jetbrains.jet.plugin.caches.resolve.getAnalysisResults
import org.jetbrains.jet.plugin.caches.resolve.getBindingContext
import org.jetbrains.jet.lang.diagnostics.DiagnosticFactory
import org.jetbrains.jet.lang.resolve.DescriptorToSourceUtils
import org.jetbrains.jet.lang.resolve.name.COMPONENT_FUNCTION_PATTERN
import org.jetbrains.jet.lang.resolve.dataClassUtils.isComponentLike
import org.jetbrains.jet.lang.resolve.dataClassUtils.getComponentIndex
private val TYPE_PARAMETER_LIST_VARIABLE_NAME = "typeParameterList"
private val TEMPLATE_FROM_USAGE_FUNCTION_BODY = "New Kotlin Function Body.kt"
@@ -964,10 +965,9 @@ public class CreateFunctionFromUsageFix internal (
override fun createAction(diagnostic: Diagnostic): IntentionAction? {
val diagnosticWithParameters = Errors.COMPONENT_FUNCTION_MISSING.cast(diagnostic)
val name = diagnosticWithParameters.getA()
val componentNumberMatcher = COMPONENT_FUNCTION_PATTERN.matcher(name.getIdentifier())
if (!componentNumberMatcher.matches()) return null
val componentNumberString = componentNumberMatcher.group(1)!!
val componentNumber = Integer.decode(componentNumberString)!! - 1
if (!isComponentLike(name)) return null
val componentNumber = getComponentIndex(name) - 1
var multiDeclaration = QuickFixUtil.getParentElementOfType(diagnostic, javaClass<JetMultiDeclaration>())
val ownerType = if (multiDeclaration == null) {
@@ -31,12 +31,12 @@ import org.jetbrains.jet.plugin.refactoring.getKotlinFqName
import org.jetbrains.jet.lang.types.expressions.OperatorConventions
import org.jetbrains.jet.lexer.JetToken
import org.jetbrains.jet.plugin.intentions.OperatorToFunctionIntention
import org.jetbrains.jet.lang.psi.psiUtil.getParentByType
import org.jetbrains.jet.plugin.project.AnalyzerFacadeWithCache
import org.jetbrains.jet.lang.resolve.BindingContext
import org.jetbrains.jet.lang.resolve.DescriptorResolver
import com.intellij.util.IncorrectOperationException
import org.jetbrains.jet.lang.psi.psiUtil.getParentByTypeAndBranch
import org.jetbrains.jet.lang.resolve.name.Name
import org.jetbrains.jet.lang.resolve.dataClassUtils.isComponentLike
public class JetSimpleNameReference(
jetSimpleNameExpression: JetSimpleNameExpression
@@ -58,8 +58,11 @@ public class JetSimpleNameReference(
if (newElementName == null) return expression;
// Do not rename if the reference corresponds to synthesized component function
if ((expression.getText() ?: "").startsWith(DescriptorResolver.COMPONENT_FUNCTION_NAME_PREFIX) && resolve() is JetParameter) {
return expression
val expressionText = expression.getText()
if (expressionText != null && Name.isValidIdentifier(expressionText)) {
if (isComponentLike(Name.identifier(expressionText)) && resolve() is JetParameter) {
return expression
}
}
val psiFactory = JetPsiFactory(expression)
@@ -22,7 +22,7 @@ import org.jetbrains.jet.lang.types.expressions.OperatorConventions.*
import com.google.common.collect.ImmutableSet
import org.jetbrains.jet.lexer.JetTokens
import org.jetbrains.jet.lexer.JetSingleValueToken
import java.util.regex.Pattern
import org.jetbrains.jet.lang.resolve.dataClassUtils.isComponentLike
public val ALL_SEARCHABLE_OPERATIONS: ImmutableSet<JetToken> = ImmutableSet
.builder<JetToken>()
@@ -48,8 +48,6 @@ public val INVOKE_OPERATION_NAME: Name = Name.identifier("invoke")
public val ITERATOR_OPERATION_NAME: Name = Name.identifier("iterator")
public val COMPONENT_OPERATION_PATTERN: Pattern = Pattern.compile("component\\d+")
public val IN_OPERATIONS_TO_SEARCH: ImmutableSet<JetToken> = ImmutableSet.of(JetTokens.IN_KEYWORD)
public val COMPARISON_OPERATIONS_TO_SEARCH: ImmutableSet<JetToken> = ImmutableSet.of<JetToken>(JetTokens.LT, JetTokens.GT)
@@ -65,7 +63,7 @@ public fun Name.getOperationSymbolsToSearch(): Set<JetToken> {
in INDEXING_OPERATION_NAMES -> return ImmutableSet.of<JetToken>(JetTokens.LBRACKET)
}
if (COMPONENT_OPERATION_PATTERN.matcher(asString()).matches()) return ImmutableSet.of<JetToken>(JetTokens.LPAR)
if (isComponentLike(this)) return ImmutableSet.of<JetToken>(JetTokens.LPAR)
val unaryOp = UNARY_OPERATION_NAMES.inverse()[this]
if (unaryOp != null) return ImmutableSet.of(unaryOp)
@@ -29,6 +29,7 @@ import org.jetbrains.jet.lang.descriptors.FunctionDescriptor;
import org.jetbrains.jet.lang.descriptors.Visibilities;
import org.jetbrains.jet.lang.psi.JetElement;
import org.jetbrains.jet.lang.resolve.BindingContext;
import org.jetbrains.jet.lang.resolve.dataClassUtils.DataClassUtilsPackage;
import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns;
import org.jetbrains.jet.plugin.KotlinCodeInsightTestCase;
import org.jetbrains.jet.plugin.PluginTestCaseBase;
@@ -87,7 +88,7 @@ public class JetChangeSignatureTest extends KotlinCodeInsightTestCase {
getChangeInfo();
}
catch (CommonRefactoringUtil.RefactoringErrorHintException e) {
assertEquals(JetRefactoringBundle.message("cannot.refactor.synthesized.function", "component1"), e.getMessage());
assertEquals(JetRefactoringBundle.message("cannot.refactor.synthesized.function", DataClassUtilsPackage.createComponentName(1).asString()), e.getMessage());
return;
}
fail();