Refactoring: create DataClassUtils and move all "component" function utils there
This commit is contained in:
@@ -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;
|
||||
|
||||
+5
-5
@@ -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;
|
||||
|
||||
|
||||
+2
-1
@@ -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)
|
||||
|
||||
+2
-1
@@ -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();
|
||||
|
||||
Reference in New Issue
Block a user