public static Map<String, SpockVariableDescriptor> getVariableMap(@NotNull GrMethod method) { GrMethod originalMethod; PsiFile containingFile = method.getContainingFile(); if (containingFile != containingFile.getOriginalFile()) { int methodOffset = method.getTextOffset(); PsiElement originalPlace = containingFile.getOriginalFile().findElementAt(methodOffset); originalMethod = PsiTreeUtil.getParentOfType(originalPlace, GrMethod.class); assert originalMethod != null : containingFile .getOriginalFile() .getText() .substring( Math.max(0, methodOffset - 50), Math.min(methodOffset + 50, containingFile.getOriginalFile().getText().length())); } else { originalMethod = method; } Map<String, SpockVariableDescriptor> cachedValue = KEY.getCachedValue(originalMethod); if (cachedValue == null) { cachedValue = createVariableMap(originalMethod); cachedValue = KEY.putCachedValue(originalMethod, cachedValue); } return cachedValue; }
private void createNameAndReturnTypeEditors() { myNameCodeFragment = new GroovyCodeFragment(myProject, ""); myNameField = new EditorTextField( PsiDocumentManager.getInstance(myProject).getDocument(myNameCodeFragment), myProject, myNameCodeFragment.getFileType()); final JavaCodeFragmentFactory factory = JavaCodeFragmentFactory.getInstance(myProject); myReturnTypeCodeFragment = factory.createTypeCodeFragment("", myMethod, true, JavaCodeFragmentFactory.ALLOW_VOID); final Document document = PsiDocumentManager.getInstance(myProject).getDocument(myReturnTypeCodeFragment); myReturnTypeField = new EditorTextField(document, myProject, myReturnTypeCodeFragment.getFileType()); myNameField.setText(myMethod.getName()); final GrTypeElement element = myMethod.getReturnTypeElementGroovy(); if (element != null) { myReturnTypeField.setText(element.getText()); } myReturnTypeLabel = new JLabel(); myReturnTypeLabel.setLabelFor(myReturnTypeField); myNameLabel = new JLabel(); myNameLabel.setLabelFor(myNameField); }
public static GrMethod generateDelegate( PsiMethod prototype, IntroduceParameterData.ExpressionWrapper initializer, Project project) { final GroovyPsiElementFactory factory = GroovyPsiElementFactory.getInstance(project); GrMethod result; if (prototype instanceof GrMethod) { result = (GrMethod) prototype.copy(); } else { StringBuilder builder = new StringBuilder(); builder.append(prototype.getModifierList().getText()).append(' '); if (prototype.getReturnTypeElement() != null) { builder.append(prototype.getReturnTypeElement().getText()); } builder.append(' ').append(prototype.getName()); builder.append(prototype.getParameterList().getText()); builder.append("{}"); result = factory.createMethodFromText(builder.toString()); } StringBuilder call = new StringBuilder(); call.append("def foo(){\n"); final GrParameter[] parameters = result.getParameters(); call.append(prototype.getName()); if (initializer.getExpression() instanceof GrClosableBlock) { if (parameters.length > 0) { call.append('('); for (GrParameter parameter : parameters) { call.append(parameter.getName()).append(", "); } call.replace(call.length() - 2, call.length(), ")"); } call.append(initializer.getText()); } else { call.append('('); for (GrParameter parameter : parameters) { call.append(parameter.getName()).append(", "); } call.append(initializer.getText()); call.append(")"); } call.append("\n}"); final GrOpenBlock block = factory.createMethodFromText(call.toString()).getBlock(); result.getBlock().replace(block); final PsiElement parent = prototype.getParent(); final GrMethod method = (GrMethod) parent.addBefore(result, prototype); GrReferenceAdjuster.shortenReferences(method); return method; }
@Nullable public static PsiType inferReturnType(PsiElement position) { final GrControlFlowOwner flowOwner = ControlFlowUtils.findControlFlowOwner(position); if (flowOwner == null) return null; final PsiElement parent = flowOwner.getContext(); if (flowOwner instanceof GrOpenBlock && parent instanceof GrMethod) { final GrMethod method = (GrMethod) parent; if (method.isConstructor()) return null; return method.getReturnType(); } return null; }
@Override public String generateDocumentationContentStub(PsiComment contextComment) { if (!(contextComment instanceof GrDocComment)) { return null; } final GrDocCommentOwner owner = GrDocCommentUtil.findDocOwner((GrDocComment) contextComment); if (owner == null) return null; Project project = contextComment.getProject(); final CodeDocumentationAwareCommenter commenter = (CodeDocumentationAwareCommenter) LanguageCommenters.INSTANCE.forLanguage(owner.getLanguage()); StringBuilder builder = StringBuilderSpinAllocator.alloc(); try { if (owner instanceof GrMethod) { final GrMethod method = (GrMethod) owner; JavaDocumentationProvider.generateParametersTakingDocFromSuperMethods( project, builder, commenter, method); final PsiType returnType = method.getInferredReturnType(); if ((returnType != null || method.getModifierList().hasModifierProperty(GrModifier.DEF)) && !PsiType.VOID.equals(returnType)) { builder.append( CodeDocumentationUtil.createDocCommentLine(RETURN_TAG, project, commenter)); builder.append(LINE_SEPARATOR); } final PsiClassType[] references = method.getThrowsList().getReferencedTypes(); for (PsiClassType reference : references) { builder.append( CodeDocumentationUtil.createDocCommentLine(THROWS_TAG, project, commenter)); builder.append(reference.getClassName()); builder.append(LINE_SEPARATOR); } } else if (owner instanceof GrTypeDefinition) { final PsiTypeParameterList typeParameterList = ((PsiClass) owner).getTypeParameterList(); if (typeParameterList != null) { JavaDocumentationProvider.createTypeParamsListComment( builder, project, commenter, typeParameterList); } } return builder.length() > 0 ? builder.toString() : null; } finally { StringBuilderSpinAllocator.dispose(builder); } }
protected void init() { super.init(); final PsiClass psiClass = myMethod.getContainingClass(); if (psiClass == null) return; if (psiClass.isInterface()) { myDelegatePanel.setVisible(false); } if (myMethod.hasModifierProperty(GrModifier.PRIVATE)) { myPrivateRadioButton.setSelected(true); } else if (myMethod.hasModifierProperty(GrModifier.PROTECTED)) { myProtectedRadioButton.setSelected(true); } else if (myMethod.hasModifierProperty(GrModifier.PUBLIC)) { myPublicRadioButton.setSelected(true); } }
@Override protected boolean preprocessUsages(Ref<UsageInfo[]> refUsages) { UsageInfo[] usagesIn = refUsages.get(); MultiMap<PsiElement, String> conflicts = new MultiMap<PsiElement, String>(); if (!mySettings.generateDelegate()) { GroovyIntroduceParameterUtil.detectAccessibilityConflicts( mySettings.getExpression(), usagesIn, conflicts, mySettings.replaceFieldsWithGetters() != IntroduceParameterRefactoring.REPLACE_FIELDS_WITH_GETTERS_NONE, myProject); } final GrMethod toReplaceIn = (GrMethod) mySettings.getToReplaceIn(); if (mySettings.getExpression() != null && !toReplaceIn.hasModifierProperty(PsiModifier.PRIVATE)) { final AnySupers anySupers = new AnySupers(); mySettings.getExpression().accept(anySupers); if (anySupers.containsSupers()) { for (UsageInfo usageInfo : usagesIn) { if (!(usageInfo.getElement() instanceof PsiMethod) && !(usageInfo instanceof InternalUsageInfo)) { if (!PsiTreeUtil.isAncestor( toReplaceIn.getContainingClass(), usageInfo.getElement(), false)) { conflicts.putValue( mySettings.getExpression(), RefactoringBundle.message( "parameter.initializer.contains.0.but.not.all.calls.to.method.are.in.its.class", CommonRefactoringUtil.htmlEmphasize(PsiKeyword.SUPER))); break; } } } } } for (IntroduceParameterMethodUsagesProcessor processor : IntroduceParameterMethodUsagesProcessor.EP_NAME.getExtensions()) { processor.findConflicts(this, refUsages.get(), conflicts); } return showConflicts(conflicts, usagesIn); }
@Nullable public static GrConstructorInvocation getChainingConstructorInvocation(GrMethod constructor) { if (constructor instanceof GrReflectedMethod && ((GrReflectedMethod) constructor).getSkippedParameters().length > 0) return null; LOG.assertTrue(constructor.isConstructor()); GrOpenBlock body = constructor.getBlock(); if (body == null) return null; GrStatement[] statements = body.getStatements(); if (statements.length > 0 && statements[0] instanceof GrConstructorInvocation) { return (GrConstructorInvocation) statements[0]; } return null; }
@Override public PsiElement setName(@NonNls @NotNull String name) throws IncorrectOperationException { PsiElement nameElement = getNameIdentifierGroovy(); GroovyPsiElementFactory factory = GroovyPsiElementFactory.getInstance(nameElement.getProject()); PsiElement newNameElement; if (JavaPsiFacade.getInstance(getProject()).getNameHelper().isIdentifier(name)) { try { GrMethod method = factory.createMethod(name, null); newNameElement = method.getNameIdentifierGroovy(); } catch (IncorrectOperationException e) { newNameElement = factory.createLiteralFromValue(name).getFirstChild(); } } else { newNameElement = factory.createLiteralFromValue(name).getFirstChild(); } nameElement.replace(newNameElement); return this; }
private static void processClassUsage(GrTypeDefinition psiClass, JavaChangeInfo changeInfo) { String name = psiClass.getName(); GrMethod constructor = GroovyPsiElementFactory.getInstance(psiClass.getProject()) .createConstructorFromText( name, ArrayUtil.EMPTY_STRING_ARRAY, ArrayUtil.EMPTY_STRING_ARRAY, "{}", null); GrModifierList list = constructor.getModifierList(); if (psiClass.hasModifierProperty(PsiModifier.PRIVATE)) list.setModifierProperty(PsiModifier.PRIVATE, true); if (psiClass.hasModifierProperty(PsiModifier.PROTECTED)) list.setModifierProperty(PsiModifier.PROTECTED, true); if (!list.hasExplicitVisibilityModifiers()) { list.setModifierProperty(GrModifier.DEF, true); } constructor = (GrMethod) psiClass.add(constructor); processConstructor(constructor, changeInfo); }
private static void processConstructor(GrMethod constructor, JavaChangeInfo changeInfo) { final PsiClass containingClass = constructor.getContainingClass(); final PsiClass baseClass = changeInfo.getMethod().getContainingClass(); final PsiSubstitutor substitutor = TypeConversionUtil.getSuperClassSubstitutor( baseClass, containingClass, PsiSubstitutor.EMPTY); GrOpenBlock block = constructor.getBlock(); GrConstructorInvocation invocation = GroovyPsiElementFactory.getInstance(constructor.getProject()) .createConstructorInvocation("super()"); invocation = (GrConstructorInvocation) block.addStatementBefore(invocation, getFirstStatement(block)); processMethodUsage( invocation.getInvokedExpression(), changeInfo, changeInfo.isParameterSetOrOrderChanged() || changeInfo.isParameterNamesChanged(), changeInfo.isExceptionSetChanged(), GrClosureSignatureUtil.ArgInfo.<PsiElement>empty_array(), substitutor); }
public void generateMethodBody(GrMethod method) { final GrOpenBlock block = method.getBlock(); boolean shouldInsertReturnNull; myExitPoints.clear(); PsiType returnType = context.typeProvider.getReturnType(method); if (!method.isConstructor() && returnType != PsiType.VOID) { myExitPoints.addAll(ControlFlowUtils.collectReturns(block)); shouldInsertReturnNull = block != null && !(returnType instanceof PsiPrimitiveType) && MissingReturnInspection.methodMissesSomeReturns( block, MissingReturnInspection.ReturnStatus.getReturnStatus(method)); } else { shouldInsertReturnNull = false; } if (block != null) { generateCodeBlock(block, shouldInsertReturnNull); } }
private void checkExitPoint() { final PsiElement element = PsiTreeUtil.getParentOfType(myExpression, PsiMethod.class, GrClosableBlock.class); if (element instanceof GrMethod) { final GrMethod method = (GrMethod) element; ControlFlowUtils.visitAllExitPoints( method.getBlock(), new ControlFlowUtils.ExitPointVisitor() { @Override public boolean visitExitPoint( Instruction instruction, @Nullable GrExpression returnValue) { if (returnValue == myExpression) { final PsiType returnType = method.getReturnType(); if (returnType != null) { myResult = createSimpleSubTypeResult(returnType); } return false; } return true; } }); } }
public static boolean isMainMethod(GrMethod method) { if (!method.getName().equals(MAIN_METHOD)) return false; else if (!method.hasModifierProperty(PsiModifier.STATIC)) return false; final GrParameter[] parameters = method.getParameters(); if (parameters.length == 0) return false; if (parameters.length == 1 && parameters[0].getTypeElementGroovy() == null) return true; int args_count = 0; int optional_count = 0; for (GrParameter p : parameters) { final GrTypeElement declaredType = p.getTypeElementGroovy(); if ((declaredType == null || declaredType.getType().equalsToText(CommonClassNames.JAVA_LANG_STRING + "[]")) && p.getInitializerGroovy() == null) { args_count++; } if (p.getInitializerGroovy() != null) optional_count++; } return optional_count == parameters.length - 1 && args_count == 1; }
public void generateCodeBlock(GrCodeBlock block, boolean shouldInsertReturnNull) { builder.append("{"); GrParameter[] parameters; if (block.getParent() instanceof GrMethod) { GrMethod method = (GrMethod) block.getParent(); parameters = method.getParameters(); } else if (block instanceof GrClosableBlock) { parameters = ((GrClosableBlock) block).getAllParameters(); } else { parameters = GrParameter.EMPTY_ARRAY; } for (GrParameter parameter : parameters) { if (context.analyzedVars.toWrap(parameter)) { StringBuilder typeText = new StringBuilder().append(GroovyCommonClassNames.GROOVY_LANG_REFERENCE); writeTypeParameters( typeText, new PsiType[] {context.typeProvider.getParameterType(parameter)}, parameter, new GeneratorClassNameProvider()); builder .append("final ") .append(typeText) .append(' ') .append(context.analyzedVars.toVarName(parameter)) .append(" = new ") .append(typeText) .append('(') .append(parameter.getName()) .append(");\n"); } } visitStatementOwner(block, shouldInsertReturnNull); builder.append("}\n"); }
private static void generateParametersForDelegateCall( GrChangeInfoImpl grInfo, GrMethod method, StringBuilder buffer) { buffer.append("("); final GrParameter[] oldParameters = method.getParameterList().getParameters(); final JavaParameterInfo[] parameters = grInfo.getNewParameters(); String[] params = new String[parameters.length]; for (int i = 0; i < parameters.length; i++) { JavaParameterInfo parameter = parameters[i]; final int oldIndex = parameter.getOldIndex(); if (oldIndex >= 0) { params[i] = oldParameters[oldIndex].getName(); } else { params[i] = parameter.getDefaultValue(); } } buffer.append(StringUtil.join(params, ",")); buffer.append(");"); }
private static boolean generateDelegate(GrChangeInfoImpl grInfo) { final GrMethod method = grInfo.getMethod(); final PsiClass psiClass = method.getContainingClass(); GrMethod newMethod = (GrMethod) method.copy(); newMethod = (GrMethod) psiClass.addAfter(newMethod, method); StringBuilder buffer = new StringBuilder(); buffer.append("\n"); if (method.isConstructor()) { buffer.append("this"); } else { if (!PsiType.VOID.equals(method.getReturnType())) { buffer.append("return "); } buffer.append( GrChangeSignatureUtil.getNameWithQuotesIfNeeded( grInfo.getNewName(), method.getProject())); } generateParametersForDelegateCall(grInfo, method, buffer); final GrCodeBlock codeBlock = GroovyPsiElementFactory.getInstance(method.getProject()) .createMethodBodyFromText(buffer.toString()); newMethod.setBlock(codeBlock); newMethod.getModifierList().setModifierProperty(PsiModifier.ABSTRACT, false); CodeStyleManager.getInstance(method.getProject()).reformat(newMethod); return processPrimaryMethodInner(grInfo, method, null); }
public static GrMethod[] getMethodOrReflectedMethods(GrMethod method) { final GrReflectedMethod[] reflectedMethods = method.getReflectedMethods(); return reflectedMethods.length > 0 ? reflectedMethods : new GrMethod[] {method}; }
public String generateDocumentationContentStub(PsiComment contextComment) { if (!(contextComment instanceof GrDocComment)) { return null; } final GrDocCommentOwner owner = GrDocCommentUtil.findDocOwner((GrDocComment) contextComment); if (owner == null) return null; Project project = contextComment.getProject(); final CodeDocumentationAwareCommenter commenter = (CodeDocumentationAwareCommenter) LanguageCommenters.INSTANCE.forLanguage(owner.getLanguage()); StringBuilder builder = StringBuilderSpinAllocator.alloc(); try { if (owner instanceof GrMethod) { final GrMethod method = (GrMethod) owner; final GrParameter[] parameters = method.getParameters(); final Map<String, String> param2Description = new HashMap<String, String>(); final PsiMethod[] superMethods = method.findSuperMethods(); for (PsiMethod superMethod : superMethods) { final PsiDocComment comment = superMethod.getDocComment(); if (comment != null) { final PsiDocTag[] params = comment.findTagsByName("param"); for (PsiDocTag param : params) { final PsiElement[] dataElements = param.getDataElements(); if (dataElements != null) { String paramName = null; for (PsiElement dataElement : dataElements) { if (dataElement instanceof PsiDocParamRef) { paramName = dataElement.getReference().getCanonicalText(); break; } } if (paramName != null) { param2Description.put(paramName, param.getText()); } } } } } for (PsiParameter parameter : parameters) { String description = param2Description.get(parameter.getName()); if (description != null) { builder.append(CodeDocumentationUtil.createDocCommentLine("", project, commenter)); if (description.indexOf('\n') > -1) description = description.substring(0, description.lastIndexOf('\n')); builder.append(description); } else { builder.append( CodeDocumentationUtil.createDocCommentLine(PARAM_TAG, project, commenter)); builder.append(parameter.getName()); } builder.append(LINE_SEPARATOR); } final PsiType returnType = method.getInferredReturnType(); if ((returnType != null || method.getModifierList().hasModifierProperty(GrModifier.DEF)) && returnType != PsiType.VOID) { builder.append( CodeDocumentationUtil.createDocCommentLine(RETURN_TAG, project, commenter)); builder.append(LINE_SEPARATOR); } final PsiClassType[] references = method.getThrowsList().getReferencedTypes(); for (PsiClassType reference : references) { builder.append( CodeDocumentationUtil.createDocCommentLine(THROWS_TAG, project, commenter)); builder.append(reference.getClassName()); builder.append(LINE_SEPARATOR); } } else if (owner instanceof GrTypeDefinition) { final PsiTypeParameterList typeParameterList = ((PsiClass) owner).getTypeParameterList(); if (typeParameterList != null) { createTypeParamsListComment(builder, project, commenter, typeParameterList); } } return builder.length() > 0 ? builder.toString() : null; } finally { StringBuilderSpinAllocator.dispose(builder); } }
private void doMoveMethod(PsiSubstitutor substitutor, GrMemberInfo info) { GroovyPsiElementFactory elementFactory = GroovyPsiElementFactory.getInstance(myProject); GrMethod method = (GrMethod) info.getMember(); PsiMethod sibling = method; PsiMethod anchor = null; while (sibling != null) { sibling = PsiTreeUtil.getNextSiblingOfType(sibling, PsiMethod.class); if (sibling != null) { anchor = MethodSignatureUtil.findMethodInSuperClassBySignatureInDerived( method.getContainingClass(), myTargetSuperClass, sibling.getSignature(PsiSubstitutor.EMPTY), false); if (anchor != null) { break; } } } GrMethod methodCopy = (GrMethod) method.copy(); if (method.findSuperMethods(myTargetSuperClass).length == 0) { deleteOverrideAnnotationIfFound(methodCopy); } final boolean isOriginalMethodAbstract = method.hasModifierProperty(PsiModifier.ABSTRACT) || method.hasModifierProperty(PsiModifier.DEFAULT); if (myTargetSuperClass.isInterface() || info.isToAbstract()) { GroovyChangeContextUtil.clearContextInfo(method); RefactoringUtil.makeMethodAbstract(myTargetSuperClass, methodCopy); if (myTargetSuperClass.isInterface()) { PsiUtil.setModifierProperty(methodCopy, PsiModifier.ABSTRACT, false); } replaceMovedMemberTypeParameters( methodCopy, PsiUtil.typeParametersIterable(mySourceClass), substitutor, elementFactory); final GrMethod movedElement = anchor != null ? (GrMethod) myTargetSuperClass.addBefore(methodCopy, anchor) : (GrMethod) myTargetSuperClass.add(methodCopy); CodeStyleSettings styleSettings = CodeStyleSettingsManager.getSettings(method.getProject()); if (styleSettings.INSERT_OVERRIDE_ANNOTATION) { if (PsiUtil.isLanguageLevel5OrHigher(mySourceClass) && !myTargetSuperClass.isInterface() || PsiUtil.isLanguageLevel6OrHigher(mySourceClass)) { new AddAnnotationFix(CommonClassNames.JAVA_LANG_OVERRIDE, method) .invoke(method.getProject(), null, mySourceClass.getContainingFile()); } } GrDocComment oldDoc = method.getDocComment(); if (oldDoc != null) { GrDocCommentUtil.setDocComment(movedElement, oldDoc); } myDocCommentPolicy.processCopiedJavaDoc( methodCopy.getDocComment(), oldDoc, isOriginalMethodAbstract); myMembersAfterMove.add(movedElement); if (isOriginalMethodAbstract) { deleteMemberWithDocComment(method); } } else { if (isOriginalMethodAbstract) { PsiUtil.setModifierProperty(myTargetSuperClass, PsiModifier.ABSTRACT, true); } // fixReferencesToStatic(methodCopy, movedMembers); replaceMovedMemberTypeParameters( methodCopy, PsiUtil.typeParametersIterable(mySourceClass), substitutor, elementFactory); final PsiMethod superClassMethod = myTargetSuperClass.findMethodBySignature(methodCopy, false); final GrMethod movedElement; if (superClassMethod != null && superClassMethod.hasModifierProperty(PsiModifier.ABSTRACT)) { movedElement = (GrMethod) superClassMethod.replace(methodCopy); } else { movedElement = anchor != null ? (GrMethod) myTargetSuperClass.addBefore(methodCopy, anchor) : (GrMethod) myTargetSuperClass.add(methodCopy); myMembersAfterMove.add(movedElement); } GrDocCommentUtil.setDocComment(movedElement, method.getDocComment()); deleteMemberWithDocComment(method); } }
public static MultiMap<PsiElement, String> checkConflicts( final MemberInfoBase<? extends GrMember>[] infos, @NotNull final PsiClass subclass, @Nullable PsiClass superClass, @NotNull final PsiPackage targetPackage, @NotNull PsiDirectory targetDirectory, final InterfaceContainmentVerifier interfaceContainmentVerifier, boolean movedMembers2Super) { final PsiElement targetRepresentativeElement; final boolean isInterfaceTarget; if (superClass != null) { isInterfaceTarget = superClass.isInterface(); targetRepresentativeElement = superClass; } else { isInterfaceTarget = false; targetRepresentativeElement = targetDirectory; } final Set<GrMember> movedMembers = ContainerUtil.newHashSet(); final Set<GrMethod> abstractMethods = ContainerUtil.newHashSet(); for (MemberInfoBase<? extends GrMember> info : infos) { GrMember member = info.getMember(); if (member instanceof GrMethod) { if (!info.isToAbstract() && !isInterfaceTarget) { movedMembers.add(member); } else { abstractMethods.add((GrMethod) member); } } else { movedMembers.add(member); } } final Set<PsiMethod> allAbstractMethods = new HashSet<PsiMethod>(abstractMethods); if (superClass != null) { for (PsiMethod method : subclass.getMethods()) { if (!movedMembers.contains(method) && !method.hasModifierProperty(PsiModifier.PRIVATE)) { if (method.findSuperMethods(superClass).length > 0) { allAbstractMethods.add(method); } } } } final MultiMap<PsiElement, String> conflicts = new MultiMap<PsiElement, String>(); GrRefactoringConflictsUtil.analyzeAccessibilityConflicts( movedMembers, superClass, conflicts, VisibilityUtil.ESCALATE_VISIBILITY, targetRepresentativeElement, allAbstractMethods); if (superClass != null) { if (movedMembers2Super) { checkSuperclassMembers(superClass, infos, conflicts); if (isInterfaceTarget) { checkInterfaceTarget(infos, conflicts); } } else { final String qualifiedName = superClass.getQualifiedName(); assert qualifiedName != null; if (superClass.hasModifierProperty(PsiModifier.PACKAGE_LOCAL)) { if (!Comparing.strEqual( StringUtil.getPackageName(qualifiedName), targetPackage.getQualifiedName())) { conflicts.putValue( superClass, RefactoringUIUtil.getDescription(superClass, true) + " won't be accessible from " + RefactoringUIUtil.getDescription(targetPackage, true)); } } } } // check if moved methods use other members in the classes between Subclass and Superclass List<PsiElement> checkModuleConflictsList = new ArrayList<PsiElement>(); for (PsiMember member : movedMembers) { if (member instanceof PsiMethod || member instanceof PsiClass && !(member instanceof PsiCompiledElement)) { GrClassMemberReferenceVisitor visitor = movedMembers2Super ? new ConflictingUsagesOfSubClassMembers( member, movedMembers, abstractMethods, subclass, superClass, superClass != null ? null : targetPackage, conflicts, interfaceContainmentVerifier) : new ConflictingUsagesOfSuperClassMembers( member, subclass, targetPackage, movedMembers, conflicts); ((GroovyPsiElement) member).accept(visitor); } checkModuleConflictsList.add(member); } for (final PsiMethod method : abstractMethods) { ContainerUtil.addIfNotNull(checkModuleConflictsList, method.getParameterList()); ContainerUtil.addIfNotNull(checkModuleConflictsList, method.getReturnTypeElement()); ContainerUtil.addIfNotNull(checkModuleConflictsList, method.getTypeParameterList()); } GrRefactoringConflictsUtil.analyzeModuleConflicts( subclass.getProject(), checkModuleConflictsList, new UsageInfo[0], targetRepresentativeElement, conflicts); final String fqName = subclass.getQualifiedName(); final String packageName; if (fqName != null) { packageName = StringUtil.getPackageName(fqName); } else { final PsiFile psiFile = PsiTreeUtil.getParentOfType(subclass, PsiFile.class); if (psiFile instanceof PsiClassOwner) { packageName = ((PsiClassOwner) psiFile).getPackageName(); } else { packageName = null; } } final boolean toDifferentPackage = !Comparing.strEqual(targetPackage.getQualifiedName(), packageName); for (final GrMethod abstractMethod : abstractMethods) { abstractMethod.accept( new GrClassMemberReferenceVisitor(subclass) { @Override protected void visitClassMemberReferenceElement( GrMember classMember, GrReferenceElement classMemberReference) { if (classMember != null && willBeMoved(classMember, movedMembers)) { boolean isAccessible = false; if (classMember.hasModifierProperty(PsiModifier.PRIVATE)) { isAccessible = true; } else if (classMember.hasModifierProperty(PsiModifier.PACKAGE_LOCAL) && toDifferentPackage) { isAccessible = true; } if (isAccessible) { String message = RefactoringUIUtil.getDescription(abstractMethod, false) + " uses " + RefactoringUIUtil.getDescription(classMember, true) + " which won't be accessible from the subclass."; message = CommonRefactoringUtil.capitalize(message); conflicts.putValue(classMember, message); } } } }); if (abstractMethod.hasModifierProperty(PsiModifier.PACKAGE_LOCAL) && toDifferentPackage) { if (!isInterfaceTarget) { String message = "Can't make " + RefactoringUIUtil.getDescription(abstractMethod, false) + " abstract as it won't be accessible from the subclass."; message = CommonRefactoringUtil.capitalize(message); conflicts.putValue(abstractMethod, message); } } } return conflicts; }
@Override protected void performRefactoring(UsageInfo[] usages) { GroovyPsiElementFactory factory = GroovyPsiElementFactory.getInstance(myProject); PsiType initializerType = mySettings.getSelectedType(); // Changing external occurrences (the tricky part) IntroduceParameterUtil.processUsages(usages, this); final GrMethod toReplaceIn = (GrMethod) mySettings.getToReplaceIn(); final PsiMethod toSearchFor = (PsiMethod) mySettings.getToSearchFor(); final boolean methodsToProcessAreDifferent = toReplaceIn != toSearchFor; if (mySettings.generateDelegate()) { GroovyIntroduceParameterUtil.generateDelegate(toReplaceIn, myParameterInitializer, myProject); if (methodsToProcessAreDifferent) { final GrMethod method = GroovyIntroduceParameterUtil.generateDelegate( toSearchFor, myParameterInitializer, myProject); final PsiClass containingClass = method.getContainingClass(); if (containingClass != null && containingClass.isInterface()) { final GrOpenBlock block = method.getBlock(); if (block != null) { block.delete(); } } } } // Changing signature of initial method // (signature of myMethodToReplaceIn will be either changed now or have already been changed) LOG.assertTrue(initializerType == null || initializerType.isValid()); final FieldConflictsResolver fieldConflictsResolver = new FieldConflictsResolver(mySettings.getName(), toReplaceIn.getBlock()); IntroduceParameterUtil.changeMethodSignatureAndResolveFieldConflicts( new UsageInfo(toReplaceIn), usages, this); if (methodsToProcessAreDifferent) { IntroduceParameterUtil.changeMethodSignatureAndResolveFieldConflicts( new UsageInfo(toSearchFor), usages, this); } // Replacing expression occurrences for (UsageInfo usage : usages) { if (usage instanceof ChangedMethodCallInfo) { PsiElement element = usage.getElement(); GroovyIntroduceParameterUtil.processChangedMethodCall(element, mySettings, myProject); } else if (usage instanceof InternalUsageInfo) { PsiElement element = usage.getElement(); if (element == null) continue; GrExpression newExpr = factory.createExpressionFromText(mySettings.getName()); if (element instanceof GrExpression) { ((GrExpression) element).replaceWithExpression(newExpr, true); } else { element.replace(newExpr); } } } final StringPartInfo stringPartInfo = mySettings.getStringPartInfo(); if (stringPartInfo != null) { final GrExpression expr = GrIntroduceHandlerBase.processLiteral( mySettings.getName(), mySettings.getStringPartInfo(), mySettings.getProject()); final Editor editor = PsiUtilBase.findEditor(expr); if (editor != null) { editor.getSelectionModel().removeSelection(); editor.getCaretModel().moveToOffset(expr.getTextRange().getEndOffset()); } } final GrVariable var = mySettings.getVar(); if (var != null && mySettings.removeLocalVariable()) { var.delete(); } fieldConflictsResolver.fix(); }
private boolean validateInputData() { if (!isGroovyMethodName(getNewName())) { showErrorHint(message("name.is.wrong", getNewName())); return false; } if (!checkType(myReturnTypeCodeFragment, true)) { showErrorHint(message("return.type.is.wrong")); return false; } List<GrTableParameterInfo> parameterInfos = myParameterModel.getParameterInfos(); for (int i = 0; i < parameterInfos.size(); i++) { GrTableParameterInfo info = parameterInfos.get(i); if (!StringUtil.isJavaIdentifier(info.getName())) { showErrorHint(message("name.is.wrong", info.getName())); return false; } if (!checkType(info.getTypeFragment(), i == parameterInfos.size() - 1)) { showErrorHint(message("type.for.parameter.is.incorrect", info.getName())); return false; } String defaultValue = info.getDefaultValue(); final String initializer = info.getDefaultInitializerFragment().getText(); if (info.getOldIndex() < 0 && defaultValue.trim().length() == 0 && initializer.trim().length() == 0) { showErrorHint(message("specify.default.value", info.getName())); return false; } } ThrownExceptionInfo[] exceptionInfos = myExceptionTableModel.getThrownExceptions(); PsiTypeCodeFragment[] typeCodeFragments = myExceptionTableModel.getTypeCodeFragments(); for (int i = 0; i < exceptionInfos.length; i++) { ThrownExceptionInfo exceptionInfo = exceptionInfos[i]; PsiTypeCodeFragment typeCodeFragment = typeCodeFragments[i]; try { PsiType type = typeCodeFragment.getType(); if (!(type instanceof PsiClassType)) { showErrorHint( GroovyRefactoringBundle.message( "changeSignature.wrong.type.for.exception", typeCodeFragment.getText())); return false; } PsiClassType throwable = JavaPsiFacade.getInstance(myMethod.getProject()) .getElementFactory() .createTypeByFQClassName("java.lang.Throwable", myMethod.getResolveScope()); if (!throwable.isAssignableFrom(type)) { showErrorHint( GroovyRefactoringBundle.message( "changeSignature.not.throwable.type", typeCodeFragment.getText())); return false; } exceptionInfo.setType((PsiClassType) type); } catch (PsiTypeCodeFragment.TypeSyntaxException e) { showErrorHint( GroovyRefactoringBundle.message( "changeSignature.wrong.type.for.exception", typeCodeFragment.getText())); return false; } catch (PsiTypeCodeFragment.NoTypeException e) { showErrorHint(GroovyRefactoringBundle.message("changeSignature.no.type.for.exception")); return false; } } return true; }
private static boolean processPrimaryMethodInner( JavaChangeInfo changeInfo, GrMethod method, @Nullable PsiMethod baseMethod) { if (changeInfo.isNameChanged()) { String newName = baseMethod == null ? changeInfo.getNewName() : RefactoringUtil.suggestNewOverriderName( method.getName(), baseMethod.getName(), changeInfo.getNewName()); if (newName != null && !newName.equals(method.getName())) { method.setName(changeInfo.getNewName()); } } final GrModifierList modifierList = method.getModifierList(); if (changeInfo.isVisibilityChanged()) { modifierList.setModifierProperty(changeInfo.getNewVisibility(), true); } PsiSubstitutor substitutor = baseMethod != null ? calculateSubstitutor(method, baseMethod) : PsiSubstitutor.EMPTY; final PsiMethod context = changeInfo.getMethod(); GrTypeElement oldReturnTypeElement = method.getReturnTypeElementGroovy(); if (changeInfo.isReturnTypeChanged()) { CanonicalTypes.Type newReturnType = changeInfo.getNewReturnType(); if (newReturnType == null) { if (oldReturnTypeElement != null) { oldReturnTypeElement.delete(); if (modifierList.getModifiers().length == 0) { modifierList.setModifierProperty(GrModifier.DEF, true); } } } else { PsiType type = newReturnType.getType(context, method.getManager()); GrReferenceAdjuster.shortenAllReferencesIn( method.setReturnType(substitutor.substitute(type))); if (oldReturnTypeElement == null) { modifierList.setModifierProperty(GrModifier.DEF, false); } } } JavaParameterInfo[] newParameters = changeInfo.getNewParameters(); final GrParameterList parameterList = method.getParameterList(); GrParameter[] oldParameters = parameterList.getParameters(); final PsiParameter[] oldBaseParams = baseMethod != null ? baseMethod.getParameterList().getParameters() : null; Set<GrParameter> toRemove = new HashSet<GrParameter>(oldParameters.length); ContainerUtil.addAll(toRemove, oldParameters); GrParameter anchor = null; final GrDocComment docComment = method.getDocComment(); final GrDocTag[] tags = docComment == null ? null : docComment.getTags(); for (JavaParameterInfo newParameter : newParameters) { // if old parameter name differs from base method parameter name we don't change it final String newName; final int oldIndex = newParameter.getOldIndex(); if (oldIndex >= 0 && oldBaseParams != null) { final String oldName = oldParameters[oldIndex].getName(); if (oldName.equals(oldBaseParams[oldIndex].getName())) { newName = newParameter.getName(); } else { newName = oldName; } } else { newName = newParameter.getName(); } final GrParameter oldParameter = oldIndex >= 0 ? oldParameters[oldIndex] : null; if (docComment != null && oldParameter != null) { final String oldName = oldParameter.getName(); for (GrDocTag tag : tags) { if ("@param".equals(tag.getName())) { final GrDocParameterReference parameterReference = tag.getDocParameterReference(); if (parameterReference != null && oldName.equals(parameterReference.getText())) { parameterReference.handleElementRename(newName); } } } } GrParameter grParameter = createNewParameter(substitutor, context, parameterList, newParameter, newName); if (oldParameter != null) { grParameter.getModifierList().replace(oldParameter.getModifierList()); } if ("def".equals(newParameter.getTypeText())) { grParameter.getModifierList().setModifierProperty(GrModifier.DEF, true); } else if (StringUtil.isEmpty(newParameter.getTypeText())) { grParameter.getModifierList().setModifierProperty(GrModifier.DEF, false); } anchor = (GrParameter) parameterList.addAfter(grParameter, anchor); } for (GrParameter oldParameter : toRemove) { oldParameter.delete(); } JavaCodeStyleManager.getInstance(parameterList.getProject()) .shortenClassReferences(parameterList); CodeStyleManager.getInstance(parameterList.getProject()).reformat(parameterList); if (changeInfo.isExceptionSetOrOrderChanged()) { final ThrownExceptionInfo[] infos = changeInfo.getNewExceptions(); PsiClassType[] exceptionTypes = new PsiClassType[infos.length]; for (int i = 0; i < infos.length; i++) { ThrownExceptionInfo info = infos[i]; exceptionTypes[i] = (PsiClassType) info.createType(method, method.getManager()); } PsiReferenceList thrownList = GroovyPsiElementFactory.getInstance(method.getProject()).createThrownList(exceptionTypes); thrownList = (PsiReferenceList) method.getThrowsList().replace(thrownList); JavaCodeStyleManager.getInstance(thrownList.getProject()).shortenClassReferences(thrownList); CodeStyleManager.getInstance(method.getProject()).reformat(method.getThrowsList()); } return true; }
// See org.spockframework.compiler.WhereBlockRewriter public static Map<String, SpockVariableDescriptor> createVariableMap(GrMethod method) { GrOpenBlock block = method.getBlock(); if (block == null) return Collections.emptyMap(); PsiElement elementUnderLabel = null; PsiElement elementAfterLabel = null; main: for (PsiElement e = block.getFirstChild(); e != null; e = e.getNextSibling()) { if (e instanceof GrLabeledStatement) { GrLabeledStatement l = (GrLabeledStatement) e; elementAfterLabel = l.getNextSibling(); while (true) { GrStatement statement = l.getStatement(); if ("where".equals(l.getName())) { elementUnderLabel = statement; break main; } if (statement instanceof GrLabeledStatement) { l = (GrLabeledStatement) statement; continue; } break; } } } if (elementUnderLabel == null) return Collections.emptyMap(); Map<String, SpockVariableDescriptor> res = new HashMap<>(); PsiElement e = elementUnderLabel; while (e != null) { if (e instanceof GrBinaryExpression && ((GrBinaryExpression) e).getOperationTokenType() == GroovyElementTypes.COMPOSITE_LSHIFT_SIGN) { GrBinaryExpression shift = (GrBinaryExpression) e; GrExpression leftOperand = shift.getLeftOperand(); GrExpression rightOperand = shift.getRightOperand(); if (leftOperand instanceof GrReferenceExpression) { String name = getNameByReference(leftOperand); if (name != null) { SpockVariableDescriptor descriptor = new SpockVariableDescriptor(leftOperand, name); descriptor.addExpressionOfCollection(rightOperand); res.put(name, descriptor); } } else if (leftOperand instanceof GrListOrMap) { GrExpression[] variableDefinitions = ((GrListOrMap) leftOperand).getInitializers(); SpockVariableDescriptor[] variables = createVariables(res, Arrays.asList(variableDefinitions)); if (rightOperand instanceof GrListOrMap) { for (GrExpression expression : ((GrListOrMap) rightOperand).getInitializers()) { if (expression instanceof GrListOrMap) { add(variables, Arrays.asList(((GrListOrMap) expression).getInitializers())); } else { for (SpockVariableDescriptor variable : variables) { if (variable != null) { variable.addExpressionOfCollection(expression); } } } } } } } else if (e instanceof GrAssignmentExpression) { GrAssignmentExpression assExpr = (GrAssignmentExpression) e; GrExpression lValue = assExpr.getLValue(); String name = getNameByReference(lValue); if (name != null) { res.put( name, new SpockVariableDescriptor(lValue, name).addExpression(assExpr.getRValue())); } } else if (isOrStatement(e)) { // See org.spockframework.compiler.WhereBlockRewriter#rewriteTableLikeParameterization() List<GrExpression> variableDefinitions = new ArrayList<>(); splitOr(variableDefinitions, (GrExpression) e); SpockVariableDescriptor[] variables = createVariables(res, variableDefinitions); List<GrExpression> row = new ArrayList<>(); PsiElement rowElement = getNext(e, elementUnderLabel, elementAfterLabel); while (isOrStatement(rowElement)) { row.clear(); splitOr(row, (GrExpression) rowElement); add(variables, row); rowElement = getNext(rowElement, elementUnderLabel, elementAfterLabel); } e = rowElement; continue; } e = getNext(e, elementUnderLabel, elementAfterLabel); } return res; }