mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
Merge remote-tracking branch 'origin/master'
This commit is contained in:
Generated
-1
@@ -3,7 +3,6 @@
|
||||
<CLASSES>
|
||||
<root url="jar://$PROJECT_DIR$/lib/jna-utils.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/lib/jna.jar!/" />
|
||||
<root url="jar://$PROJECT_DIR$/lib/jna-platform.jar!/" />
|
||||
</CLASSES>
|
||||
<JAVADOC />
|
||||
<SOURCES>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2013 JetBrains s.r.o.
|
||||
* Copyright 2000-2009 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.
|
||||
@@ -130,13 +130,8 @@ class ReloadClassesWorker {
|
||||
continue;
|
||||
}
|
||||
redefineProcessor.processClass(qualifiedName, content);
|
||||
if (myProgress.isCancelled()) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!myProgress.isCancelled()) {
|
||||
redefineProcessor.processPending();
|
||||
}
|
||||
redefineProcessor.processPending();
|
||||
myProgress.setFraction(1);
|
||||
|
||||
final int partiallyRedefinedClassesCount = redefineProcessor.getPartiallyRedefinedClassesCount();
|
||||
|
||||
+41
-1
@@ -288,9 +288,48 @@ public class HighlightUtil extends HighlightUtilBase {
|
||||
}
|
||||
|
||||
|
||||
@Nullable
|
||||
static HighlightInfo checkIntersectionInTypeCast(@NotNull PsiTypeCastExpression expression) {
|
||||
final PsiTypeElement castTypeElement = expression.getCastType();
|
||||
if (castTypeElement == null) return null;
|
||||
PsiType castType = castTypeElement.getType();
|
||||
if (isIntersection(castTypeElement, castType)) {
|
||||
if (PsiUtil.isLanguageLevel8OrHigher(expression)) {
|
||||
final PsiTypeElement[] conjuncts = PsiTreeUtil.getChildrenOfType(castTypeElement, PsiTypeElement.class);
|
||||
if (conjuncts != null) {
|
||||
final List<PsiTypeElement> conjList = new ArrayList<PsiTypeElement>(Arrays.asList(conjuncts));
|
||||
for (int i = 1; i < conjuncts.length; i++) {
|
||||
final PsiTypeElement conjunct = conjuncts[i];
|
||||
final PsiType conjType = conjunct.getType();
|
||||
if (conjType instanceof PsiClassType) {
|
||||
final PsiClass aClass = ((PsiClassType)conjType).resolve();
|
||||
if (aClass != null && !aClass.isInterface()) {
|
||||
final HighlightInfo errorResult = HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR)
|
||||
.range(conjunct)
|
||||
.descriptionAndTooltip(JavaErrorMessages.message("interface.expected")).create();
|
||||
QuickFixAction.registerQuickFixAction(errorResult, new FlipIntersectionSidesFix(aClass.getName(), conjList, conjunct, castTypeElement), null);
|
||||
return errorResult;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR)
|
||||
.range(expression)
|
||||
.descriptionAndTooltip("Intersection types in cast are not supported at this language level").create();
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
static boolean isIntersection(PsiTypeElement castTypeElement, PsiType castType) {
|
||||
if (castType instanceof PsiIntersectionType) return true;
|
||||
return PsiTreeUtil.getChildrenOfType(castTypeElement, PsiTypeElement.class) != null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
static HighlightInfo checkInconvertibleTypeCast(@NotNull PsiTypeCastExpression expression) {
|
||||
PsiTypeElement castTypeElement = expression.getCastType();
|
||||
final PsiTypeElement castTypeElement = expression.getCastType();
|
||||
if (castTypeElement == null) return null;
|
||||
PsiType castType = castTypeElement.getType();
|
||||
|
||||
@@ -306,6 +345,7 @@ public class HighlightUtil extends HighlightUtilBase {
|
||||
return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(expression).descriptionAndTooltip(message).create();
|
||||
}
|
||||
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
+1
@@ -1336,6 +1336,7 @@ public class HighlightVisitorImpl extends JavaElementVisitor implements Highligh
|
||||
public void visitTypeCastExpression(PsiTypeCastExpression typeCast) {
|
||||
super.visitTypeCastExpression(typeCast);
|
||||
try {
|
||||
if (!myHolder.hasErrorResults()) myHolder.add(HighlightUtil.checkIntersectionInTypeCast(typeCast));
|
||||
if (!myHolder.hasErrorResults()) myHolder.add(HighlightUtil.checkInconvertibleTypeCast(typeCast));
|
||||
}
|
||||
catch (IndexNotReadyException ignore) {
|
||||
|
||||
+100
@@ -0,0 +1,100 @@
|
||||
/*
|
||||
* Copyright 2000-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 com.intellij.codeInsight.daemon.impl.quickfix;
|
||||
|
||||
import com.intellij.codeInsight.FileModificationService;
|
||||
import com.intellij.codeInsight.intention.IntentionAction;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.editor.Editor;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.Comparing;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.codeStyle.CodeStyleManager;
|
||||
import com.intellij.util.Function;
|
||||
import com.intellij.util.IncorrectOperationException;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* User: anna
|
||||
* Date: 10/31/13
|
||||
*/
|
||||
public class FlipIntersectionSidesFix implements IntentionAction {
|
||||
private static final Logger LOG = Logger.getInstance("#" + FlipIntersectionSidesFix.class.getName());
|
||||
private final String myClassName;
|
||||
private final List<PsiTypeElement> myConjuncts;
|
||||
private final PsiTypeElement myConjunct;
|
||||
private final PsiTypeElement myCastTypeElement;
|
||||
|
||||
public FlipIntersectionSidesFix(String className,
|
||||
@NotNull List<PsiTypeElement> conjList,
|
||||
PsiTypeElement conjunct,
|
||||
PsiTypeElement castTypeElement) {
|
||||
myClassName = className;
|
||||
myConjuncts = conjList;
|
||||
LOG.assertTrue(!conjList.isEmpty());
|
||||
myConjunct = conjunct;
|
||||
myCastTypeElement = castTypeElement;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public String getText() {
|
||||
return "Move '" + myClassName + "' to the beginning";
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public String getFamilyName() {
|
||||
return "Move to front";
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAvailable(@NotNull Project project, Editor editor, PsiFile file) {
|
||||
for (PsiTypeElement typeElement : myConjuncts) {
|
||||
if (!typeElement.isValid()) return false;
|
||||
}
|
||||
return !Comparing.strEqual(myConjunct.getText(), myConjuncts.get(0).getText());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void invoke(@NotNull Project project, Editor editor, PsiFile file) throws IncorrectOperationException {
|
||||
if (!FileModificationService.getInstance().prepareFileForWrite(file)) return;
|
||||
myConjuncts.remove(myConjunct);
|
||||
myConjuncts.add(0, myConjunct);
|
||||
|
||||
final String intersectionTypeText = StringUtil.join(myConjuncts, new Function<PsiTypeElement, String>() {
|
||||
@Override
|
||||
public String fun(PsiTypeElement element) {
|
||||
return element.getText();
|
||||
}
|
||||
}, " & ");
|
||||
final PsiElementFactory elementFactory = JavaPsiFacade.getElementFactory(project);
|
||||
final PsiTypeCastExpression fixedCast =
|
||||
(PsiTypeCastExpression)elementFactory.createExpressionFromText("(" + intersectionTypeText + ") a", myCastTypeElement);
|
||||
final PsiTypeElement fixedCastCastType = fixedCast.getCastType();
|
||||
LOG.assertTrue(fixedCastCastType != null);
|
||||
final PsiElement flippedTypeElement = myCastTypeElement.replace(fixedCastCastType);
|
||||
CodeStyleManager.getInstance(project).reformat(flippedTypeElement);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean startInWriteAction() {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
+4
-2
@@ -13,8 +13,9 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.intellij.codeInsight.daemon.impl.analysis;
|
||||
package com.intellij.codeInsight.daemon.impl.quickfix;
|
||||
|
||||
import com.intellij.codeInsight.FileModificationService;
|
||||
import com.intellij.codeInsight.intention.IntentionAction;
|
||||
import com.intellij.openapi.editor.Editor;
|
||||
import com.intellij.openapi.project.Project;
|
||||
@@ -26,7 +27,7 @@ import org.jetbrains.annotations.NotNull;
|
||||
/**
|
||||
* User: anna
|
||||
*/
|
||||
class QualifyWithThisFix implements IntentionAction {
|
||||
public class QualifyWithThisFix implements IntentionAction {
|
||||
private final PsiClass myContainingClass;
|
||||
private final PsiElement myExpression;
|
||||
|
||||
@@ -54,6 +55,7 @@ class QualifyWithThisFix implements IntentionAction {
|
||||
|
||||
@Override
|
||||
public void invoke(@NotNull Project project, Editor editor, PsiFile file) throws IncorrectOperationException {
|
||||
if (!FileModificationService.getInstance().prepareFileForWrite(file)) return;
|
||||
final PsiThisExpression thisExpression =
|
||||
RefactoringChangeUtil.createThisExpression(PsiManager.getInstance(project), myContainingClass);
|
||||
((PsiReferenceExpression)myExpression).setQualifierExpression(thisExpression);
|
||||
@@ -179,7 +179,15 @@ public class TypeConversionUtil {
|
||||
}
|
||||
return false;
|
||||
}
|
||||
else if (toType instanceof PsiIntersectionType) return false;
|
||||
else if (toType instanceof PsiIntersectionType) {
|
||||
if (fromType instanceof PsiClassType && ((PsiClassType)fromType).getLanguageLevel().isAtLeast(LanguageLevel.JDK_1_8)) {
|
||||
for (PsiType conjunct : ((PsiIntersectionType)toType).getConjuncts()) {
|
||||
if (!isNarrowingReferenceConversionAllowed(fromType, conjunct)) return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
if (fromType instanceof PsiDisjunctionType) {
|
||||
return isNarrowingReferenceConversionAllowed(((PsiDisjunctionType)fromType).getLeastUpperBound(), toType);
|
||||
|
||||
+26
-8
@@ -445,14 +445,18 @@ public class InferenceSession {
|
||||
}
|
||||
else if (acceptObject || upperBounds.size() > 1 || !upperBounds.get(0).equalsToText(CommonClassNames.JAVA_LANG_OBJECT)) {
|
||||
PsiType glb = null;
|
||||
for (PsiType upperBound : upperBounds) {
|
||||
upperBound = acceptBoundsWithRecursiveDependencies(typeParameter, upperBound, substitutor);
|
||||
if (isProperType(upperBound, false)) {
|
||||
if (glb == null) {
|
||||
glb = upperBound;
|
||||
}
|
||||
else {
|
||||
glb = GenericsUtil.getGreatestLowerBound(glb, upperBound);
|
||||
if (isThrowable(upperBounds)) {
|
||||
glb = PsiType.getJavaLangRuntimeException(myManager, GlobalSearchScope.allScope(myManager.getProject()));
|
||||
} else {
|
||||
for (PsiType upperBound : upperBounds) {
|
||||
upperBound = acceptBoundsWithRecursiveDependencies(typeParameter, upperBound, substitutor);
|
||||
if (isProperType(upperBound, false)) {
|
||||
if (glb == null) {
|
||||
glb = upperBound;
|
||||
}
|
||||
else {
|
||||
glb = GenericsUtil.getGreatestLowerBound(glb, upperBound);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -473,6 +477,20 @@ public class InferenceSession {
|
||||
return substitutor;
|
||||
}
|
||||
|
||||
private static boolean isThrowable(List<PsiType> upperBounds) {
|
||||
boolean commonThrowable = false;
|
||||
for (PsiType upperBound : upperBounds) {
|
||||
if (upperBound.equalsToText(CommonClassNames.JAVA_LANG_OBJECT)) continue;
|
||||
if (upperBound.equalsToText(CommonClassNames.JAVA_LANG_EXCEPTION) ||
|
||||
upperBound.equalsToText(CommonClassNames.JAVA_LANG_THROWABLE)) {
|
||||
commonThrowable = true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return commonThrowable;
|
||||
}
|
||||
|
||||
private PsiType acceptBoundsWithRecursiveDependencies(PsiTypeParameter typeParameter, PsiType bound, PsiSubstitutor substitutor) {
|
||||
if (!isProperType(bound)) {
|
||||
final PsiSubstitutor subst = PsiUtil.resolveClassInType(bound) != typeParameter ? substitutor.put(typeParameter, null) : substitutor;
|
||||
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
import java.io.Serializable;
|
||||
|
||||
public class FooBar1 {
|
||||
{
|
||||
Object x = null;
|
||||
Object y = (CharSequence & Serializable) x;
|
||||
Object y2 = (CharSequence & Integer) x;
|
||||
Object y3 = (Integer & CharSequence) x;
|
||||
<error descr="Incompatible types. Found: 'java.lang.CharSequence & java.io.Serializable', required: 'int'">int y1 = (CharSequence & Serializable) x;</error>
|
||||
}
|
||||
}
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
// "Move 'Number' to the beginning" "true"
|
||||
class C {
|
||||
{
|
||||
Object x = null;
|
||||
Object y2 = (Number & CharSequence) x;
|
||||
}
|
||||
}
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
// "Move 'Number' to the beginning" "true"
|
||||
class C {
|
||||
{
|
||||
Object x = null;
|
||||
Object y2 = (CharSequence & Num<caret>ber) x;
|
||||
}
|
||||
}
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
// "Move 'Number' to the beginning" "false"
|
||||
class C {
|
||||
{
|
||||
Object x = null;
|
||||
Object y2 = (Number & Num<caret>ber) x;
|
||||
}
|
||||
}
|
||||
+8
-16
@@ -13,24 +13,16 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package org.jetbrains.plugins.groovy.refactoring.introduce.constant;
|
||||
package com.intellij.codeInsight.daemon.quickFix;
|
||||
|
||||
import com.intellij.ui.components.JBCheckBox;
|
||||
|
||||
import javax.swing.*;
|
||||
|
||||
/**
|
||||
* Created by Max Medvedev on 8/29/13
|
||||
*/
|
||||
public class GrInplaceIntroduceConstantPanel {
|
||||
private JBCheckBox myMoveToAnotherClassJBCheckBox;
|
||||
private JPanel myRootPane;
|
||||
|
||||
public boolean isMoveToAnotherClass() {
|
||||
return myMoveToAnotherClassJBCheckBox.isSelected();
|
||||
public class FlipIntersectionTypesTest extends LightQuickFixTestCase {
|
||||
public void test() throws Exception {
|
||||
doAllTests();
|
||||
}
|
||||
|
||||
public JComponent getRootPane() {
|
||||
return myRootPane;
|
||||
@Override
|
||||
protected String getBasePath() {
|
||||
return "/codeInsight/daemonCodeAnalyzer/quickFix/flipIntersection";
|
||||
}
|
||||
}
|
||||
|
||||
Binary file not shown.
@@ -21,7 +21,6 @@ jgoodies-forms.jar
|
||||
jgoodies-looks-2.4.2.jar
|
||||
jh.jar
|
||||
jna-utils.jar
|
||||
jna-platform.jar
|
||||
jna.jar
|
||||
jsch-0.1.50.jar
|
||||
jsr166e.jar
|
||||
|
||||
+28
-29
@@ -163,40 +163,39 @@ public class FileReference implements PsiFileReference, FileReferenceOwner, PsiP
|
||||
}
|
||||
else {
|
||||
final String decoded = decode(text);
|
||||
if (decoded != null) {
|
||||
|
||||
if (context instanceof PackagePrefixFileSystemItem) {
|
||||
context = ((PackagePrefixFileSystemItem)context).getDirectory();
|
||||
if (context instanceof PackagePrefixFileSystemItem) {
|
||||
context = ((PackagePrefixFileSystemItem)context).getDirectory();
|
||||
}
|
||||
|
||||
if (context instanceof PsiDirectory && caseSensitivityApplies((PsiDirectory)context, caseSensitive)) {
|
||||
// optimization: do not load all children into VFS
|
||||
PsiDirectory directory = (PsiDirectory)context;
|
||||
PsiFileSystemItem child = directory.findFile(decoded);
|
||||
if (child == null) child = directory.findSubdirectory(decoded);
|
||||
if (child != null) {
|
||||
result.add(new PsiElementResolveResult(getOriginalFile(child)));
|
||||
}
|
||||
|
||||
if (context instanceof PsiDirectory && caseSensitivityApplies((PsiDirectory)context, caseSensitive)) {
|
||||
// optimization: do not load all children into VFS
|
||||
PsiDirectory directory = (PsiDirectory)context;
|
||||
PsiFileSystemItem child = directory.findFile(decoded);
|
||||
if (child == null) child = directory.findSubdirectory(decoded);
|
||||
if (child != null) {
|
||||
result.add(new PsiElementResolveResult(getOriginalFile(child)));
|
||||
}
|
||||
else {
|
||||
processVariants(context, new PsiFileSystemItemProcessor() {
|
||||
@Override
|
||||
public boolean acceptItem(String name, boolean isDirectory) {
|
||||
return caseSensitive ? decoded.equals(name) : decoded.compareToIgnoreCase(name) == 0;
|
||||
}
|
||||
}
|
||||
else {
|
||||
processVariants(context, new PsiFileSystemItemProcessor() {
|
||||
@Override
|
||||
public boolean acceptItem(String name, boolean isDirectory) {
|
||||
return caseSensitive ? decoded.equals(name) : decoded.compareToIgnoreCase(name) == 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean execute(@NotNull PsiFileSystemItem element) {
|
||||
result.add(new PsiElementResolveResult(getOriginalFile(element)));
|
||||
return true;
|
||||
}
|
||||
});
|
||||
}
|
||||
@Override
|
||||
public boolean execute(@NotNull PsiFileSystemItem element) {
|
||||
result.add(new PsiElementResolveResult(getOriginalFile(element)));
|
||||
return true;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public String getFileNameToCreate() {
|
||||
return decode(getCanonicalText());
|
||||
}
|
||||
@@ -218,8 +217,8 @@ public class FileReference implements PsiFileReference, FileReferenceOwner, PsiP
|
||||
!myFileReferenceSet.isEndingSlashNotAllowed() && myIndex > 0);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public String decode(final String text) {
|
||||
@NotNull
|
||||
public String decode(@NotNull final String text) {
|
||||
// strip http get parameters
|
||||
String _text = text;
|
||||
if (text.indexOf('?') >= 0) {
|
||||
@@ -228,7 +227,7 @@ public class FileReference implements PsiFileReference, FileReferenceOwner, PsiP
|
||||
|
||||
if (myFileReferenceSet.isUrlEncoded()) {
|
||||
try {
|
||||
return new URI(_text).getPath();
|
||||
return StringUtil.notNullize(new URI(_text).getPath(), text);
|
||||
}
|
||||
catch (Exception e) {
|
||||
return text;
|
||||
@@ -504,7 +503,7 @@ public class FileReference implements PsiFileReference, FileReferenceOwner, PsiP
|
||||
public String getUnresolvedMessagePattern() {
|
||||
return LangBundle.message("error.cannot.resolve")
|
||||
+ " " + (isLast() ? LangBundle.message("terms.file") : LangBundle.message("terms.directory"))
|
||||
+ " '" + StringUtil.escapePattern(StringUtil.notNullize(decode(getCanonicalText()))) + "'";
|
||||
+ " '" + StringUtil.escapePattern(decode(getCanonicalText())) + "'";
|
||||
}
|
||||
|
||||
public final boolean isLast() {
|
||||
|
||||
+2
-2
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2010 JetBrains s.r.o.
|
||||
* Copyright 2000-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.
|
||||
@@ -44,7 +44,7 @@ import java.util.List;
|
||||
// This prevents languages with polyadic expressions or sequences
|
||||
// from reusing it, use simpleChooser instead.
|
||||
public abstract class OccurrencesChooser<T> {
|
||||
public static enum ReplaceChoice {
|
||||
public enum ReplaceChoice {
|
||||
NO("Replace this occurrence only"), NO_WRITE("Replace all occurrences but write"), ALL("Replace all {0} occurrences");
|
||||
|
||||
private final String myDescription;
|
||||
|
||||
+3
-2
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2012 JetBrains s.r.o.
|
||||
* Copyright 2000-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.
|
||||
@@ -30,6 +30,7 @@ import com.intellij.lang.refactoring.NamesValidator;
|
||||
import com.intellij.openapi.Disposable;
|
||||
import com.intellij.openapi.actionSystem.Shortcut;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.application.Result;
|
||||
import com.intellij.openapi.command.CommandProcessor;
|
||||
import com.intellij.openapi.command.WriteCommandAction;
|
||||
import com.intellij.openapi.command.impl.FinishMarkAction;
|
||||
@@ -327,7 +328,7 @@ public abstract class InplaceRefactoring {
|
||||
|
||||
new WriteCommandAction(myProject, getCommandName()) {
|
||||
@Override
|
||||
protected void run(com.intellij.openapi.application.Result result) throws Throwable {
|
||||
protected void run(Result result) throws Throwable {
|
||||
startTemplate(builder);
|
||||
}
|
||||
}.execute();
|
||||
|
||||
@@ -416,9 +416,7 @@ public class PathManager {
|
||||
// helpers
|
||||
|
||||
private static String getAbsolutePath(String path) {
|
||||
if (path.startsWith("~/") || path.startsWith("~\\")) {
|
||||
path = getUserHome() + path.substring(1);
|
||||
}
|
||||
path = FileUtil.expandUserHome(path);
|
||||
return new File(path).getAbsolutePath();
|
||||
}
|
||||
|
||||
|
||||
@@ -1213,6 +1213,13 @@ public class FileUtil extends FileUtilRt {
|
||||
return path;
|
||||
}
|
||||
|
||||
public static String expandUserHome(String path) {
|
||||
if (path.startsWith("~/") || path.startsWith("~\\")) {
|
||||
path = SystemProperties.getUserHome() + path.substring(1);
|
||||
}
|
||||
return path;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static File[] notNullize(@Nullable File[] files) {
|
||||
return notNullize(files, ArrayUtil.EMPTY_FILE_ARRAY);
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
/*
|
||||
* Copyright 2000-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 com.intellij.vcs.log;
|
||||
|
||||
import com.intellij.openapi.vcs.changes.ContentRevision;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
* <p>This factory is used to create a particular {@link ContentRevision} instance which corresponds to the file and the commit hash.</p>
|
||||
* <p>Different VCS plugins may use different {@link ContentRevision} implementation, therefore we need to be able
|
||||
* to retrieve a correct instance for a commit.</p>
|
||||
*/
|
||||
public abstract class ContentRevisionFactory {
|
||||
|
||||
@NotNull
|
||||
public abstract ContentRevision createRevision(@NotNull VirtualFile file, @NotNull Hash hash);
|
||||
|
||||
@NotNull
|
||||
public abstract ContentRevision createRevision(@NotNull VirtualFile root, @NotNull String path, @NotNull Hash hash);
|
||||
|
||||
}
|
||||
@@ -11,8 +11,8 @@ import java.util.List;
|
||||
* <p>Full details of a commit: all metadata (commit message, author, committer, etc.) and the changes.</p>
|
||||
* <p>These details will be shown in dedicated panels displayed near the log.</p>
|
||||
* <p>An instance of this object can be obtained via
|
||||
* {@link VcsLogObjectsFactory#createFullDetails(
|
||||
* Hash, List, long, VirtualFile, String, String, String, String, String, String, long, List) VcsLogObjectsFactory#createFullDetails}</p>
|
||||
* {@link VcsLogObjectsFactory#createFullDetails(Hash, List, long, VirtualFile, String, String, String, String, String, String, long,
|
||||
* List, ContentRevisionFactory) VcsLogObjectsFactory#createFullDetails}</p>
|
||||
*
|
||||
* @author Kirill Likhodedov
|
||||
*/
|
||||
|
||||
@@ -31,7 +31,8 @@ public interface VcsLogObjectsFactory {
|
||||
@NotNull String subject,
|
||||
@NotNull String authorName, @NotNull String authorEmail, @NotNull String message,
|
||||
@NotNull String committerName,
|
||||
@NotNull String committerEmail, long commitTime, @NotNull List<Change> changes);
|
||||
@NotNull String committerEmail, long commitTime, @NotNull List<Change> changes,
|
||||
@NotNull ContentRevisionFactory contentRevisionFactory);
|
||||
|
||||
@NotNull
|
||||
VcsUser createUser(@NotNull String name);
|
||||
|
||||
@@ -1,11 +1,16 @@
|
||||
package com.intellij.vcs.log.data;
|
||||
|
||||
import com.intellij.openapi.vcs.FilePathImpl;
|
||||
import com.intellij.openapi.vcs.changes.Change;
|
||||
import com.intellij.openapi.vcs.changes.ContentRevision;
|
||||
import com.intellij.openapi.vcs.changes.SimpleContentRevision;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.vcs.log.ContentRevisionFactory;
|
||||
import com.intellij.vcs.log.Hash;
|
||||
import com.intellij.vcs.log.impl.VcsFullCommitDetailsImpl;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.Collections;
|
||||
|
||||
/**
|
||||
@@ -19,7 +24,20 @@ public class LoadingDetails extends VcsFullCommitDetailsImpl {
|
||||
private final long myLoadingTaskIndex;
|
||||
|
||||
public LoadingDetails(@NotNull Hash hash, long loadingTaskIndex, @NotNull VirtualFile root) {
|
||||
super(hash, Collections.<Hash>emptyList(), -1, root, "Loading...", "", "", "", "", "", -1, Collections.<Change>emptyList());
|
||||
super(hash, Collections.<Hash>emptyList(), -1, root, "Loading...", "", "", "", "", "", -1, Collections.<Change>emptyList(),
|
||||
new ContentRevisionFactory() {
|
||||
@NotNull
|
||||
@Override
|
||||
public ContentRevision createRevision(@NotNull VirtualFile file, @NotNull Hash hash) {
|
||||
return new SimpleContentRevision("", new FilePathImpl(file), hash.asString());
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public ContentRevision createRevision(@NotNull VirtualFile root, @NotNull String path, @NotNull Hash hash) {
|
||||
return new SimpleContentRevision("", new FilePathImpl(new File(path), false), hash.asString());
|
||||
}
|
||||
});
|
||||
myLoadingTaskIndex = loadingTaskIndex;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,7 +1,12 @@
|
||||
package com.intellij.vcs.log.impl;
|
||||
|
||||
import com.intellij.openapi.vcs.FilePath;
|
||||
import com.intellij.openapi.vcs.changes.Change;
|
||||
import com.intellij.openapi.vcs.changes.ContentRevision;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.util.Function;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import com.intellij.vcs.log.ContentRevisionFactory;
|
||||
import com.intellij.vcs.log.Hash;
|
||||
import com.intellij.vcs.log.VcsFullCommitDetails;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
@@ -21,19 +26,24 @@ public class VcsFullCommitDetailsImpl extends VcsShortCommitDetailsImpl implemen
|
||||
@NotNull private final String myCommitterEmail;
|
||||
private final long myCommitTime;
|
||||
|
||||
@NotNull private final Collection<Change> myChanges;
|
||||
@NotNull private final Collection<LightChange> myChanges;
|
||||
|
||||
public VcsFullCommitDetailsImpl(@NotNull Hash hash, @NotNull List<Hash> parents, long authorTime, @NotNull VirtualFile root,
|
||||
@NotNull String subject, @NotNull String authorName, @NotNull String authorEmail, @NotNull String message,
|
||||
@NotNull String committerName, @NotNull String committerEmail, long commitTime,
|
||||
@NotNull List<Change> changes) {
|
||||
@NotNull List<Change> changes, @NotNull final ContentRevisionFactory contentRevisionFactory) {
|
||||
super(hash, parents, authorTime, root, subject, authorName);
|
||||
myAuthorEmail = authorEmail;
|
||||
myCommitterName = committerName;
|
||||
myCommitterEmail = committerEmail;
|
||||
myCommitTime = commitTime;
|
||||
myFullMessage = message;
|
||||
myChanges = changes;
|
||||
myChanges = ContainerUtil.map(changes, new Function<Change, LightChange>() {
|
||||
@Override
|
||||
public LightChange fun(Change change) {
|
||||
return LightChange.create(contentRevisionFactory, VcsFullCommitDetailsImpl.this, change);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -45,7 +55,12 @@ public class VcsFullCommitDetailsImpl extends VcsShortCommitDetailsImpl implemen
|
||||
@Override
|
||||
@NotNull
|
||||
public final Collection<Change> getChanges() {
|
||||
return myChanges;
|
||||
return ContainerUtil.map(myChanges, new Function<LightChange, Change>() {
|
||||
@Override
|
||||
public Change fun(LightChange change) {
|
||||
return change.toChange();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -70,4 +85,79 @@ public class VcsFullCommitDetailsImpl extends VcsShortCommitDetailsImpl implemen
|
||||
public long getCommitTime() {
|
||||
return myCommitTime;
|
||||
}
|
||||
|
||||
private static class LightChange {
|
||||
|
||||
private ContentRevisionFactory myContentRevisionFactory;
|
||||
private VcsFullCommitDetails myDetails;
|
||||
private boolean myModification;
|
||||
private VirtualFile myBeforeFile;
|
||||
private VirtualFile myAfterFile;
|
||||
private String myBeforePath;
|
||||
private String myAfterPath;
|
||||
|
||||
private static LightChange create(ContentRevisionFactory contentRevisionFactory, VcsFullCommitDetails details, Change change) {
|
||||
LightChange lc = new LightChange();
|
||||
Change.Type type = change.getType();
|
||||
lc.myModification = type == Change.Type.MODIFICATION;
|
||||
lc.myContentRevisionFactory = contentRevisionFactory;
|
||||
|
||||
ContentRevision before = change.getBeforeRevision();
|
||||
if (before != null && !lc.myModification) { // don't store the same path twice (for modification store only after path)
|
||||
FilePath filePath = before.getFile();
|
||||
if (filePath.getVirtualFile() == null) {
|
||||
lc.myBeforePath = filePath.getIOFile().getPath();
|
||||
}
|
||||
else {
|
||||
lc.myBeforeFile = filePath.getVirtualFile();
|
||||
}
|
||||
}
|
||||
|
||||
ContentRevision after = change.getAfterRevision();
|
||||
if (after != null) {
|
||||
FilePath filePath = after.getFile();
|
||||
if (filePath.getVirtualFile() == null) {
|
||||
lc.myAfterPath = filePath.getIOFile().getPath();
|
||||
}
|
||||
else {
|
||||
lc.myAfterFile = filePath.getVirtualFile();
|
||||
}
|
||||
}
|
||||
|
||||
lc.myDetails = details;
|
||||
return lc;
|
||||
}
|
||||
|
||||
Change toChange() {
|
||||
List<Hash> parents = myDetails.getParents();
|
||||
Hash parentHash = parents.isEmpty() ? null : parents.get(0); // no parents for the initial commit
|
||||
|
||||
ContentRevision before = null;
|
||||
if (parentHash != null) {
|
||||
if (myBeforeFile != null) {
|
||||
before = myContentRevisionFactory.createRevision(myBeforeFile, parentHash);
|
||||
}
|
||||
else if (myBeforePath != null) {
|
||||
before = myContentRevisionFactory.createRevision(myDetails.getRoot(), myBeforePath, parentHash);
|
||||
}
|
||||
}
|
||||
|
||||
ContentRevision after = null;
|
||||
if (myAfterFile != null) {
|
||||
after = myContentRevisionFactory.createRevision(myAfterFile, myDetails.getHash());
|
||||
if (myModification && parentHash != null) { // we didn't store myBeforeFile/Path to avoid duplicate path
|
||||
before = myContentRevisionFactory.createRevision(myAfterFile, parentHash);
|
||||
}
|
||||
}
|
||||
else if (myAfterPath != null) {
|
||||
after = myContentRevisionFactory.createRevision(myDetails.getRoot(), myAfterPath, myDetails.getHash());
|
||||
if (myModification && parentHash != null) {
|
||||
before = myContentRevisionFactory.createRevision(myDetails.getRoot(), myAfterPath, parentHash);
|
||||
}
|
||||
}
|
||||
|
||||
return new Change(before, after);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -42,9 +42,10 @@ public class VcsLogObjectsFactoryImpl implements VcsLogObjectsFactory {
|
||||
public VcsFullCommitDetails createFullDetails(@NotNull Hash hash, @NotNull List<Hash> parents, long authorTime, @NotNull VirtualFile root,
|
||||
@NotNull String subject, @NotNull String authorName, @NotNull String authorEmail,
|
||||
@NotNull String message, @NotNull String committerName,
|
||||
@NotNull String committerEmail, long commitTime, @NotNull List<Change> changes) {
|
||||
@NotNull String committerEmail, long commitTime, @NotNull List<Change> changes,
|
||||
@NotNull ContentRevisionFactory contentRevisionFactory) {
|
||||
return new VcsFullCommitDetailsImpl(hash, parents, authorTime, root, subject, authorName, authorEmail, message, committerName,
|
||||
committerEmail, commitTime, changes);
|
||||
committerEmail, commitTime, changes, contentRevisionFactory);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
|
||||
+5
@@ -518,6 +518,11 @@ public class ParenthesesUtils {
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (parentExpression instanceof PsiConditionalExpression && expression instanceof PsiConditionalExpression) {
|
||||
final PsiConditionalExpression conditionalExpression = (PsiConditionalExpression)parentExpression;
|
||||
final PsiExpression condition = conditionalExpression.getCondition();
|
||||
return PsiTreeUtil.isAncestor(condition, expression, true);
|
||||
}
|
||||
return parentPrecedence < childPrecedence;
|
||||
}
|
||||
}
|
||||
|
||||
+13
@@ -11,4 +11,17 @@ class UnnecessaryParentheses {
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
class ConditionalCondition {
|
||||
|
||||
String s;
|
||||
String t;
|
||||
|
||||
public boolean equals(Object other) {
|
||||
if (!(other instanceof ConditionalCondition)) return false;
|
||||
final ConditionalCondition condition = (ConditionalCondition)other;
|
||||
|
||||
|
||||
return (s != null ? !s.equals(condition.s) : condition.s != null) ? false : t.equals(condition.t);
|
||||
}
|
||||
}
|
||||
+15
-19
@@ -18,7 +18,6 @@ package com.siyeh.ipp.trivialif;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.impl.PsiDiamondTypeUtil;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import com.intellij.util.IncorrectOperationException;
|
||||
import com.siyeh.ig.psiutils.EquivalenceChecker;
|
||||
import com.siyeh.ig.psiutils.ParenthesesUtils;
|
||||
import com.siyeh.ipp.base.Intention;
|
||||
@@ -36,8 +35,7 @@ public class ReplaceIfWithConditionalIntention extends Intention {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void processIntention(@NotNull PsiElement element)
|
||||
throws IncorrectOperationException {
|
||||
public void processIntention(@NotNull PsiElement element) {
|
||||
final PsiIfStatement ifStatement = (PsiIfStatement)element.getParent();
|
||||
if (ifStatement == null) {
|
||||
return;
|
||||
@@ -183,9 +181,8 @@ public class ReplaceIfWithConditionalIntention extends Intention {
|
||||
return null;
|
||||
}
|
||||
@NonNls final StringBuilder conditional = new StringBuilder();
|
||||
final String conditionText = getExpressionText(condition);
|
||||
conditional.append(conditionText);
|
||||
conditional.append('?');
|
||||
final String conditionText = getExpressionText(condition, true);
|
||||
conditional.append(conditionText).append('?');
|
||||
final PsiType thenType = thenValue.getType();
|
||||
final PsiType elseType = elseValue.getType();
|
||||
if (thenType instanceof PsiPrimitiveType &&
|
||||
@@ -195,28 +192,24 @@ public class ReplaceIfWithConditionalIntention extends Intention {
|
||||
// prevent unboxing of boxed value to preserve semantics (IDEADEV-36008)
|
||||
final PsiPrimitiveType primitiveType = (PsiPrimitiveType)thenType;
|
||||
conditional.append(primitiveType.getBoxedTypeName());
|
||||
conditional.append(".valueOf(");
|
||||
conditional.append(thenValue.getText());
|
||||
conditional.append("):");
|
||||
conditional.append(getExpressionText(elseValue));
|
||||
conditional.append(".valueOf(").append(thenValue.getText()).append("):");
|
||||
conditional.append(getExpressionText(elseValue, false));
|
||||
}
|
||||
else if (elseType instanceof PsiPrimitiveType &&
|
||||
!PsiType.NULL.equals(elseType) &&
|
||||
!(thenType instanceof PsiPrimitiveType) &&
|
||||
!(requiredType instanceof PsiPrimitiveType)) {
|
||||
// prevent unboxing of boxed value to preserve semantics (IDEADEV-36008)
|
||||
conditional.append(getExpressionText(thenValue));
|
||||
conditional.append(getExpressionText(thenValue, false));
|
||||
conditional.append(':');
|
||||
final PsiPrimitiveType primitiveType = (PsiPrimitiveType)elseType;
|
||||
conditional.append(primitiveType.getBoxedTypeName());
|
||||
conditional.append(".valueOf(");
|
||||
conditional.append(elseValue.getText());
|
||||
conditional.append(')');
|
||||
conditional.append(".valueOf(").append(elseValue.getText()).append(')');
|
||||
}
|
||||
else {
|
||||
conditional.append(getExpressionText(thenValue));
|
||||
conditional.append(getExpressionText(thenValue, false));
|
||||
conditional.append(':');
|
||||
conditional.append(getExpressionText(elseValue));
|
||||
conditional.append(getExpressionText(elseValue, false));
|
||||
}
|
||||
return conditional.toString();
|
||||
}
|
||||
@@ -230,9 +223,12 @@ public class ReplaceIfWithConditionalIntention extends Intention {
|
||||
return thenValue;
|
||||
}
|
||||
|
||||
private static String getExpressionText(PsiExpression expression) {
|
||||
if (ParenthesesUtils.getPrecedence(expression) <=
|
||||
ParenthesesUtils.CONDITIONAL_PRECEDENCE) {
|
||||
private static String getExpressionText(PsiExpression expression, boolean isCondition) {
|
||||
final int precedence = ParenthesesUtils.getPrecedence(expression);
|
||||
if (precedence <= ParenthesesUtils.CONDITIONAL_PRECEDENCE) {
|
||||
if (isCondition && precedence == ParenthesesUtils.CONDITIONAL_PRECEDENCE) {
|
||||
return '(' + expression.getText() + ')';
|
||||
}
|
||||
return expression.getText();
|
||||
}
|
||||
else {
|
||||
|
||||
+16
@@ -0,0 +1,16 @@
|
||||
package com.siyeh.ipp.trivialif.replaceIfWithConditional;
|
||||
|
||||
class ConditionalCondition {
|
||||
|
||||
String s;
|
||||
String t;
|
||||
|
||||
public boolean equals(Object other) {
|
||||
if (!(other instanceof ConditionalCondition)) return false;
|
||||
final ConditionalCondition condition = (ConditionalCondition)other;
|
||||
|
||||
|
||||
if<caret> (s != null ? !s.equals(condition.s) : condition.s != null) return false;
|
||||
return t.equals(condition.t);
|
||||
}
|
||||
}
|
||||
+15
@@ -0,0 +1,15 @@
|
||||
package com.siyeh.ipp.trivialif.replaceIfWithConditional;
|
||||
|
||||
class ConditionalCondition {
|
||||
|
||||
String s;
|
||||
String t;
|
||||
|
||||
public boolean equals(Object other) {
|
||||
if (!(other instanceof ConditionalCondition)) return false;
|
||||
final ConditionalCondition condition = (ConditionalCondition)other;
|
||||
|
||||
|
||||
return (s != null ? !s.equals(condition.s) : condition.s != null) ? false : t.equals(condition.t);
|
||||
}
|
||||
}
|
||||
+8
-12
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2011 JetBrains s.r.o.
|
||||
* Copyright 2000-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.
|
||||
@@ -18,19 +18,15 @@ package com.siyeh.ipp.trivialif;
|
||||
import com.siyeh.IntentionPowerPackBundle;
|
||||
import com.siyeh.ipp.IPPTestCase;
|
||||
|
||||
/**
|
||||
* @see com.siyeh.ipp.trivialif.ReplaceIfWithConditionalIntention
|
||||
*/
|
||||
public class ReplaceIfWithConditionalIntentionTest extends IPPTestCase {
|
||||
|
||||
public void testReturnValueWithDiamonds() {
|
||||
doTest();
|
||||
}
|
||||
|
||||
public void testReplaceableAssignmentsWithDiamonds() {
|
||||
doTest();
|
||||
}
|
||||
|
||||
public void testReplaceableAssignmentsWithDiamondsLeave() {
|
||||
doTest();
|
||||
}
|
||||
public void testReturnValueWithDiamonds() { doTest(); }
|
||||
public void testReplaceableAssignmentsWithDiamonds() { doTest(); }
|
||||
public void testReplaceableAssignmentsWithDiamondsLeave() { doTest(); }
|
||||
public void testConditionalCondition() { doTest(); }
|
||||
|
||||
@Override
|
||||
protected String getIntentionName() {
|
||||
|
||||
@@ -148,6 +148,8 @@
|
||||
<projectService serviceInterface="git4idea.branch.GitBrancher"
|
||||
serviceImplementation="git4idea.branch.GitBrancherImpl"/>
|
||||
|
||||
<projectService serviceImplementation="git4idea.log.GitContentRevisionFactory" />
|
||||
|
||||
<applicationService serviceImplementation="git4idea.history.wholeTree.GitCommitsSequentialIndex"
|
||||
serviceInterface="git4idea.history.wholeTree.GitCommitsSequentially"/>
|
||||
<applicationService serviceInterface="git4idea.config.GitVcsApplicationSettings"
|
||||
|
||||
@@ -15,10 +15,12 @@
|
||||
*/
|
||||
package git4idea;
|
||||
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.vcs.changes.Change;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.vcs.log.Hash;
|
||||
import com.intellij.vcs.log.impl.VcsFullCommitDetailsImpl;
|
||||
import git4idea.log.GitContentRevisionFactory;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.List;
|
||||
@@ -30,10 +32,13 @@ import java.util.List;
|
||||
*/
|
||||
public final class GitCommit extends VcsFullCommitDetailsImpl {
|
||||
|
||||
public GitCommit(@NotNull Hash hash, @NotNull List<Hash> parents, long authorTime, @NotNull VirtualFile root, @NotNull String subject,
|
||||
public GitCommit(final Project project, @NotNull Hash hash, @NotNull List<Hash> parents, long authorTime, @NotNull VirtualFile root,
|
||||
@NotNull String subject,
|
||||
@NotNull String authorName,
|
||||
@NotNull String authorEmail, @NotNull String message, @NotNull String committerName, @NotNull String committerEmail,
|
||||
long commitTime, @NotNull List<Change> changes) {
|
||||
super(hash, parents, authorTime, root, subject, authorName, authorEmail, message, committerName, committerEmail, commitTime, changes);
|
||||
super(hash, parents, authorTime, root, subject, authorName, authorEmail, message, committerName, committerEmail, commitTime, changes,
|
||||
GitContentRevisionFactory.getInstance(project));
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -199,12 +199,12 @@ public class GitContentRevision implements ContentRevision {
|
||||
}
|
||||
|
||||
public static ContentRevision createRevision(@NotNull final VirtualFile file, @Nullable final VcsRevisionNumber revisionNumber,
|
||||
@NotNull final Project project) throws VcsException {
|
||||
@NotNull final Project project) {
|
||||
return createRevision(file, revisionNumber, project, null);
|
||||
}
|
||||
|
||||
public static ContentRevision createRevision(@NotNull final VirtualFile file, @Nullable final VcsRevisionNumber revisionNumber,
|
||||
@NotNull final Project project, @Nullable final Charset charset) throws VcsException {
|
||||
@NotNull final Project project, @Nullable final Charset charset) {
|
||||
final FilePathImpl filePath = new FilePathImpl(file);
|
||||
return createRevision(filePath, revisionNumber, project, charset);
|
||||
}
|
||||
|
||||
@@ -39,6 +39,7 @@ import git4idea.config.GitVcsSettings;
|
||||
import git4idea.history.browser.GitHeavyCommit;
|
||||
import git4idea.history.wholeTree.AbstractHash;
|
||||
import git4idea.history.wholeTree.GitCommitDetailsProvider;
|
||||
import git4idea.log.GitContentRevisionFactory;
|
||||
import git4idea.repo.GitRepository;
|
||||
import icons.Git4ideaIcons;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
@@ -166,14 +167,14 @@ public class GitCherryPickAction extends DumbAwareAction {
|
||||
// TODO remove after removing the old Vcs Log implementation
|
||||
@Nullable
|
||||
private List<? extends VcsFullCommitDetails> getSelectedCommits(AnActionEvent e) {
|
||||
List<GitHeavyCommit> commits = e.getData(GitVcs.SELECTED_COMMITS);
|
||||
if (commits != null) {
|
||||
return convertHeavyCommitToFullDetails(commits);
|
||||
}
|
||||
final Project project = e.getProject();
|
||||
if (project == null) {
|
||||
return null;
|
||||
}
|
||||
List<GitHeavyCommit> commits = e.getData(GitVcs.SELECTED_COMMITS);
|
||||
if (commits != null) {
|
||||
return convertHeavyCommitToFullDetails(commits, project);
|
||||
}
|
||||
final VcsLog log = getVcsLog(project);
|
||||
if (log == null) {
|
||||
return null;
|
||||
@@ -197,7 +198,7 @@ public class GitCherryPickAction extends DumbAwareAction {
|
||||
return selectedDetails;
|
||||
}
|
||||
|
||||
private static List<? extends VcsFullCommitDetails> convertHeavyCommitToFullDetails(List<GitHeavyCommit> commits) {
|
||||
private static List<? extends VcsFullCommitDetails> convertHeavyCommitToFullDetails(List<GitHeavyCommit> commits, final Project project) {
|
||||
return ContainerUtil.map(commits, new Function<GitHeavyCommit, VcsFullCommitDetails>() {
|
||||
@Override
|
||||
public VcsFullCommitDetails fun(GitHeavyCommit commit) {
|
||||
@@ -211,7 +212,7 @@ public class GitCherryPickAction extends DumbAwareAction {
|
||||
return factory.createFullDetails(
|
||||
factory.createHash(commit.getHash().getValue()), parents, commit.getAuthorTime(), commit.getRoot(), commit.getSubject(),
|
||||
commit.getAuthor(), commit.getAuthorEmail(), commit.getDescription(), commit.getCommitter(), commit.getCommitterEmail(),
|
||||
commit.getDate().getTime(), commit.getChanges()
|
||||
commit.getDate().getTime(), commit.getChanges(), GitContentRevisionFactory.getInstance(project)
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -458,6 +458,7 @@ public abstract class GitHandler {
|
||||
startHandlingStreams();
|
||||
}
|
||||
catch (Throwable t) {
|
||||
LOG.error(t);
|
||||
cleanupEnv();
|
||||
myListeners.getMulticaster().startFailed(t);
|
||||
}
|
||||
|
||||
@@ -711,7 +711,7 @@ public class GitHistoryUtils {
|
||||
return HashImpl.build(hash);
|
||||
}
|
||||
});
|
||||
return new GitCommit(HashImpl.build(record.getHash()), parents, record.getAuthorTimeStamp(), root, record.getSubject(),
|
||||
return new GitCommit(project, HashImpl.build(record.getHash()), parents, record.getAuthorTimeStamp(), root, record.getSubject(),
|
||||
record.getAuthorName(), record.getAuthorEmail(), record.getFullMessage(), record.getCommitterName(),
|
||||
record.getCommitterEmail(), record.getLongTimeStamp(),
|
||||
record.parseChanges(project, root));
|
||||
|
||||
@@ -0,0 +1,57 @@
|
||||
/*
|
||||
* Copyright 2000-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 git4idea.log;
|
||||
|
||||
import com.intellij.openapi.components.ServiceManager;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.vcs.FilePathImpl;
|
||||
import com.intellij.openapi.vcs.changes.ContentRevision;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.vcs.log.ContentRevisionFactory;
|
||||
import com.intellij.vcs.log.Hash;
|
||||
import git4idea.GitContentRevision;
|
||||
import git4idea.GitRevisionNumber;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
public class GitContentRevisionFactory extends ContentRevisionFactory {
|
||||
|
||||
@NotNull private final Project myProject;
|
||||
|
||||
@SuppressWarnings("UnusedDeclaration")
|
||||
private GitContentRevisionFactory(@NotNull Project project) {
|
||||
myProject = project;
|
||||
}
|
||||
|
||||
public static ContentRevisionFactory getInstance(Project project) {
|
||||
return ServiceManager.getService(project, GitContentRevisionFactory.class);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public ContentRevision createRevision(@NotNull VirtualFile file, @NotNull Hash hash) {
|
||||
return GitContentRevision.createRevision(file, new GitRevisionNumber(hash.asString()), myProject);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public ContentRevision createRevision(@NotNull VirtualFile root, @NotNull String path, @NotNull Hash hash) {
|
||||
return GitContentRevision.createRevision(new FilePathImpl(new File(path), false),
|
||||
new GitRevisionNumber(hash.asString()), myProject, null);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -39,6 +39,7 @@ import cucumber.annotation.en.Then;
|
||||
import cucumber.annotation.en.When;
|
||||
import git4idea.cherrypick.GitCherryPicker;
|
||||
import git4idea.config.GitVersionSpecialty;
|
||||
import git4idea.log.GitContentRevisionFactory;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
@@ -263,7 +264,7 @@ public class GitCherryPickStepdefs {
|
||||
changes.add(new Change(null, new MockContentRevision(new FilePathImpl(new MockVirtualFile("name")), VcsRevisionNumber.NULL)));
|
||||
return ServiceManager.getService(VcsLogObjectsFactory.class).createFullDetails(
|
||||
HashImpl.build(hash), Collections.<Hash>emptyList(), 0, NullVirtualFile.INSTANCE, message, "John Smith", "john@mail.com", message,
|
||||
"John Smith", "john@mail.com", 0, changes);
|
||||
"John Smith", "john@mail.com", 0, changes, GitContentRevisionFactory.getInstance(myProject));
|
||||
}
|
||||
|
||||
}
|
||||
+2
-2
@@ -204,7 +204,7 @@ public class ImportMavenRepositoriesTask implements Runnable {
|
||||
if (uri.getScheme() != null && StringUtil.startsWith(uri.getScheme(), "http")) return uri;
|
||||
}
|
||||
}
|
||||
catch (URISyntaxException e) {
|
||||
catch (URISyntaxException ignored) {
|
||||
// ignore it
|
||||
}
|
||||
|
||||
@@ -219,7 +219,7 @@ public class ImportMavenRepositoriesTask implements Runnable {
|
||||
if (uri.getScheme() != null && StringUtil.startsWith("http", uri.getScheme())) return uri;
|
||||
}
|
||||
}
|
||||
catch (URISyntaxException e) {
|
||||
catch (URISyntaxException ignored) {
|
||||
// ignore it
|
||||
}
|
||||
|
||||
|
||||
-8
@@ -19,11 +19,9 @@ import com.intellij.codeInsight.CodeInsightActionHandler;
|
||||
import com.intellij.codeInsight.CodeInsightUtilBase;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.command.WriteCommandAction;
|
||||
import com.intellij.openapi.editor.Document;
|
||||
import com.intellij.openapi.editor.Editor;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.Condition;
|
||||
import com.intellij.psi.PsiDocumentManager;
|
||||
import com.intellij.psi.PsiFile;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import com.intellij.util.ArrayUtil;
|
||||
@@ -91,12 +89,6 @@ class AddGradleDslDependencyActionHandler implements CodeInsightActionHandler {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
PsiDocumentManager documentManager = PsiDocumentManager.getInstance(project);
|
||||
Document document = documentManager.getDocument(file);
|
||||
if (document != null) {
|
||||
documentManager.commitDocument(document);
|
||||
}
|
||||
}
|
||||
}.execute();
|
||||
}
|
||||
|
||||
+277
@@ -0,0 +1,277 @@
|
||||
/*
|
||||
* Copyright 2000-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.plugins.groovy.refactoring.introduce;
|
||||
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.editor.Editor;
|
||||
import com.intellij.openapi.editor.RangeMarker;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.Comparing;
|
||||
import com.intellij.openapi.util.Computable;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import com.intellij.psi.util.PsiUtilCore;
|
||||
import com.intellij.refactoring.introduce.inplace.AbstractInplaceIntroducer;
|
||||
import com.intellij.refactoring.introduce.inplace.OccurrencesChooser;
|
||||
import com.intellij.util.Function;
|
||||
import com.intellij.util.IncorrectOperationException;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.plugins.groovy.GroovyFileType;
|
||||
import org.jetbrains.plugins.groovy.lang.lexer.GroovyTokenTypes;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElementFactory;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrVariable;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrExpression;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrMethodCall;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrNewExpression;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrReferenceExpression;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.path.GrMethodCallExpression;
|
||||
import org.jetbrains.plugins.groovy.refactoring.GroovyRefactoringUtil;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
|
||||
/**
|
||||
* Created by Max Medvedev on 10/28/13
|
||||
*/
|
||||
public abstract class GrAbstractInplaceIntroducer<Settings extends GrIntroduceSettings> extends AbstractInplaceIntroducer<GrVariable, PsiElement> {
|
||||
|
||||
private SmartTypePointer myTypePointer;
|
||||
private OccurrencesChooser.ReplaceChoice myReplaceChoice;
|
||||
|
||||
private RangeMarker myVarMarker;
|
||||
private final PsiFile myFile;
|
||||
|
||||
private final GrIntroduceContext myContext;
|
||||
|
||||
public GrAbstractInplaceIntroducer(String title,
|
||||
OccurrencesChooser.ReplaceChoice replaceChoice,
|
||||
GrIntroduceContext context) {
|
||||
super(context.getProject(), context.getEditor(), context.getExpression(), context.getVar(), context.getOccurrences(), title, GroovyFileType.GROOVY_FILE_TYPE);
|
||||
myReplaceChoice = replaceChoice;
|
||||
myContext = context;
|
||||
myFile = context.getPlace().getContainingFile();
|
||||
}
|
||||
|
||||
public GrIntroduceContext getContext() {
|
||||
return myContext;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setReplaceAllOccurrences(boolean allOccurrences) {
|
||||
throw new IncorrectOperationException("don't invoke this method");
|
||||
}
|
||||
|
||||
@Override
|
||||
public GrExpression restoreExpression(PsiFile containingFile, GrVariable variable, RangeMarker marker, String exprText) {
|
||||
if (exprText == null) return null;
|
||||
if (variable == null || !variable.isValid()) return null;
|
||||
final PsiElement refVariableElement = containingFile.findElementAt(marker.getStartOffset());
|
||||
final PsiElement refVariableElementParent = refVariableElement != null ? refVariableElement.getParent() : null;
|
||||
GrExpression expression =
|
||||
refVariableElementParent instanceof GrNewExpression && refVariableElement.getNode().getElementType() == GroovyTokenTypes.kNEW
|
||||
? (GrNewExpression)refVariableElementParent
|
||||
: PsiTreeUtil.getParentOfType(refVariableElement, GrReferenceExpression.class);
|
||||
if (expression instanceof GrReferenceExpression && !(expression.getParent() instanceof GrMethodCall)) {
|
||||
final String referenceName = ((GrReferenceExpression)expression).getReferenceName();
|
||||
if (((GrReferenceExpression)expression).resolve() == variable ||
|
||||
Comparing.strEqual(variable.getName(), referenceName) ||
|
||||
Comparing.strEqual(exprText, referenceName)) {
|
||||
return (GrExpression)expression
|
||||
.replace(GroovyPsiElementFactory.getInstance(myProject).createExpressionFromText(exprText, variable));
|
||||
}
|
||||
}
|
||||
if (expression == null) {
|
||||
expression = PsiTreeUtil.getParentOfType(refVariableElement, GrExpression.class);
|
||||
}
|
||||
while (expression instanceof GrReferenceExpression) {
|
||||
final PsiElement parent = expression.getParent();
|
||||
if (parent instanceof GrMethodCallExpression) {
|
||||
if (parent.getText().equals(exprText)) return (GrExpression)parent;
|
||||
}
|
||||
if (parent instanceof GrExpression) {
|
||||
expression = (GrExpression)parent;
|
||||
if (expression.getText().equals(exprText)) {
|
||||
return expression;
|
||||
}
|
||||
}
|
||||
else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
if (expression != null && expression.isValid() && expression.getText().equals(exprText)) {
|
||||
return expression;
|
||||
}
|
||||
|
||||
if (refVariableElementParent instanceof GrExpression && refVariableElementParent.getText().equals(exprText)) {
|
||||
return (GrExpression)refVariableElementParent;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void updateTitle(@Nullable GrVariable variable, String value) {
|
||||
if (variable == null) {
|
||||
super.updateTitle(variable, value);
|
||||
}
|
||||
else {
|
||||
final String variableText = variable.getParent().getText();
|
||||
final PsiElement identifier = variable.getNameIdentifierGroovy();
|
||||
final int startOffsetInParent = identifier.getStartOffsetInParent() + variable.getStartOffsetInParent();
|
||||
setPreviewText(
|
||||
variableText.substring(0, startOffsetInParent) + value + variableText.substring(startOffsetInParent + identifier.getTextLength()));
|
||||
revalidate();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void updateTitle(@Nullable GrVariable variable) {
|
||||
if (variable == null) return;
|
||||
setPreviewText(variable.getParent().getText());
|
||||
revalidate();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
protected PsiElement getNameIdentifier() {
|
||||
return ((GrVariable)myElementToRename).getNameIdentifierGroovy();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected GrVariable getVariable() {
|
||||
if (myVarMarker == null) return null;
|
||||
|
||||
int offset = myVarMarker.getStartOffset();
|
||||
PsiElement at = myFile.findElementAt(offset);
|
||||
GrVariable var = PsiTreeUtil.getParentOfType(at, GrVariable.class);
|
||||
return var;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void performIntroduce() {
|
||||
final List<RangeMarker> markers = getOccurrenceMarkers();
|
||||
GrIntroduceContext context = new GrIntroduceContext() {
|
||||
@NotNull
|
||||
@Override
|
||||
public Project getProject() {
|
||||
return myProject;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Editor getEditor() {
|
||||
return myEditor;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public GrExpression getExpression() {
|
||||
return (GrExpression)getExpr();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public GrVariable getVar() {
|
||||
return getLocalVariable();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public StringPartInfo getStringPart() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public PsiElement[] getOccurrences() {
|
||||
List<PsiElement> result = ContainerUtil.map(markers, new Function<RangeMarker, PsiElement>() {
|
||||
@Override
|
||||
public PsiElement fun(RangeMarker marker) {
|
||||
return GroovyRefactoringUtil.findElementInRange(myFile, marker.getStartOffset(), marker.getEndOffset(), GrExpression.class);
|
||||
}
|
||||
});
|
||||
return PsiUtilCore.toPsiElementArray(result);
|
||||
}
|
||||
|
||||
@Override
|
||||
public PsiElement getScope() {
|
||||
return myScope;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public PsiElement getPlace() {
|
||||
GrExpression expression = getExpression();
|
||||
return expression != null ? expression : getLocalVariable();
|
||||
}
|
||||
};
|
||||
runRefactoring(context, getSettings(), true);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
protected GrVariable createFieldToStartTemplateOn(boolean replaceAll, String[] names) {
|
||||
|
||||
final Settings settings = getInitialSettingsForInplace(myContext, myReplaceChoice, names);
|
||||
if (settings == null) return null;
|
||||
|
||||
SmartPsiElementPointer<GrVariable> pointer = ApplicationManager.getApplication().runWriteAction(new Computable<SmartPsiElementPointer<GrVariable>>() {
|
||||
@Override
|
||||
public SmartPsiElementPointer<GrVariable> compute() {
|
||||
GrVariable var = runRefactoring(myContext, settings, false);
|
||||
return var != null ? SmartPointerManager.getInstance(myProject).createSmartPsiElementPointer(var) : null;
|
||||
}
|
||||
});
|
||||
|
||||
if (pointer != null) {
|
||||
GrVariable var = pointer.getElement();
|
||||
if (var != null) {
|
||||
myVarMarker = myContext.getEditor().getDocument().createRangeMarker(var.getTextRange());
|
||||
}
|
||||
return var;
|
||||
}
|
||||
else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
protected abstract GrVariable runRefactoring(GrIntroduceContext context, Settings settings, boolean processUsages);
|
||||
|
||||
@Nullable
|
||||
protected abstract Settings getInitialSettingsForInplace(@NotNull GrIntroduceContext context,
|
||||
@NotNull OccurrencesChooser.ReplaceChoice choice,
|
||||
String[] names);
|
||||
|
||||
@Override
|
||||
public boolean isReplaceAllOccurrences() {
|
||||
return myReplaceChoice != OccurrencesChooser.ReplaceChoice.NO || myContext.getOccurrences().length == 1;
|
||||
}
|
||||
|
||||
protected abstract Settings getSettings();
|
||||
|
||||
@Override
|
||||
protected void restoreState(GrVariable psiField) {
|
||||
PsiType declaredType = psiField.getDeclaredType();
|
||||
myTypePointer = declaredType != null ? SmartTypePointerManager.getInstance(myProject).createSmartTypePointer(declaredType) : null;
|
||||
super.restoreState(psiField);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
protected PsiType getSelectedType() {
|
||||
return myTypePointer != null ? myTypePointer.getType() : null;
|
||||
}
|
||||
}
|
||||
+25
-64
@@ -21,7 +21,6 @@ import com.intellij.lang.LanguageRefactoringSupport;
|
||||
import com.intellij.lang.refactoring.RefactoringSupportProvider;
|
||||
import com.intellij.openapi.actionSystem.DataContext;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.command.CommandProcessor;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.editor.Document;
|
||||
import com.intellij.openapi.editor.Editor;
|
||||
@@ -32,7 +31,6 @@ import com.intellij.openapi.editor.colors.EditorColorsManager;
|
||||
import com.intellij.openapi.editor.markup.RangeHighlighter;
|
||||
import com.intellij.openapi.editor.markup.TextAttributes;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.Computable;
|
||||
import com.intellij.openapi.util.Pass;
|
||||
import com.intellij.openapi.util.TextRange;
|
||||
import com.intellij.openapi.wm.WindowManager;
|
||||
@@ -77,7 +75,7 @@ import java.util.*;
|
||||
import static org.jetbrains.plugins.groovy.lang.psi.util.PsiUtil.skipParentheses;
|
||||
|
||||
/**
|
||||
* @author Maxim.Medvedev
|
||||
* Created by Max Medvedev on 10/29/13
|
||||
*/
|
||||
public abstract class GrIntroduceHandlerBase<Settings extends GrIntroduceSettings, Scope extends PsiElement> implements RefactoringActionHandler {
|
||||
private static final Logger LOG = Logger.getInstance(GrIntroduceHandlerBase.class);
|
||||
@@ -144,15 +142,8 @@ public abstract class GrIntroduceHandlerBase<Settings extends GrIntroduceSetting
|
||||
@Nullable
|
||||
public abstract GrVariable runRefactoring(@NotNull GrIntroduceContext context, @NotNull Settings settings);
|
||||
|
||||
protected abstract GrInplaceIntroducer getIntroducer(@NotNull GrVariable var,
|
||||
@NotNull GrIntroduceContext context,
|
||||
@NotNull Settings settings,
|
||||
@NotNull List<RangeMarker> occurrenceMarkers,
|
||||
RangeMarker varRangeMarker,
|
||||
@Nullable RangeMarker expressionRangeMarker,
|
||||
@Nullable RangeMarker stringPartRangeMarker);
|
||||
|
||||
protected abstract Settings getSettingsForInplace(GrIntroduceContext context, OccurrencesChooser.ReplaceChoice choice);
|
||||
protected abstract GrAbstractInplaceIntroducer<Settings> getIntroducer(@NotNull GrIntroduceContext context,
|
||||
OccurrencesChooser.ReplaceChoice choice);
|
||||
|
||||
public static Map<OccurrencesChooser.ReplaceChoice, List<Object>> fillChoice(GrIntroduceContext context) {
|
||||
HashMap<OccurrencesChooser.ReplaceChoice, List<Object>> map = ContainerUtil.newLinkedHashMap();
|
||||
@@ -296,7 +287,8 @@ public abstract class GrIntroduceHandlerBase<Settings extends GrIntroduceSetting
|
||||
};
|
||||
|
||||
if (scopes.length == 0) {
|
||||
CommonRefactoringUtil.showErrorHint(project, editor, RefactoringBundle.getCannotRefactorMessage( getRefactoringName() + "is not available in current scope"),
|
||||
CommonRefactoringUtil.showErrorHint(project, editor, RefactoringBundle
|
||||
.getCannotRefactorMessage(getRefactoringName() + "is not available in current scope"),
|
||||
getRefactoringName(), getHelpID());
|
||||
}
|
||||
else if (scopes.length == 1) {
|
||||
@@ -310,11 +302,11 @@ public abstract class GrIntroduceHandlerBase<Settings extends GrIntroduceSetting
|
||||
protected abstract void showScopeChooser(Scope[] scopes, Pass<Scope> callback, Editor editor);
|
||||
|
||||
public GrIntroduceContext getContext(@NotNull Project project,
|
||||
@NotNull Editor editor,
|
||||
@Nullable GrExpression expression,
|
||||
@Nullable GrVariable variable,
|
||||
@Nullable StringPartInfo stringPart,
|
||||
@NotNull PsiElement scope) {
|
||||
@NotNull Editor editor,
|
||||
@Nullable GrExpression expression,
|
||||
@Nullable GrVariable variable,
|
||||
@Nullable StringPartInfo stringPart,
|
||||
@NotNull PsiElement scope) {
|
||||
if (variable != null) {
|
||||
final List<PsiElement> list = Collections.synchronizedList(new ArrayList<PsiElement>());
|
||||
ReferencesSearch.search(variable, new LocalSearchScope(scope)).forEach(new Processor<PsiReference>() {
|
||||
@@ -348,48 +340,6 @@ public abstract class GrIntroduceHandlerBase<Settings extends GrIntroduceSetting
|
||||
checkOccurrences(context.getOccurrences());
|
||||
|
||||
|
||||
final boolean isInplace = isInplace(context.getEditor(), context.getPlace());
|
||||
Pass<OccurrencesChooser.ReplaceChoice> callback = new Pass<OccurrencesChooser.ReplaceChoice>() {
|
||||
@Override
|
||||
public void pass(final OccurrencesChooser.ReplaceChoice choice) {
|
||||
|
||||
final Settings settings = isInplace ? getSettingsForInplace(context, choice) : showDialog(context);
|
||||
if (settings == null) return;
|
||||
|
||||
CommandProcessor.getInstance().executeCommand(project, new Runnable() {
|
||||
public void run() {
|
||||
List<RangeMarker> occurrences = ContainerUtil.newArrayList();
|
||||
Document document = editor.getDocument();
|
||||
for (PsiElement element : context.getOccurrences()) {
|
||||
occurrences.add(createRange(document, element));
|
||||
}
|
||||
RangeMarker expressionRangeMarker = createRange(document, context.getExpression());
|
||||
RangeMarker stringPartRangeMarker = createRange(document, context.getStringPart());
|
||||
RangeMarker varRangeMarker = createRange(document, context.getVar());
|
||||
|
||||
SmartPsiElementPointer<GrVariable> pointer =
|
||||
ApplicationManager.getApplication().runWriteAction(new Computable<SmartPsiElementPointer<GrVariable>>() {
|
||||
@Override
|
||||
public SmartPsiElementPointer<GrVariable> compute() {
|
||||
GrVariable var = runRefactoring(context, settings);
|
||||
return var != null
|
||||
? SmartPointerManager.getInstance(context.getProject()).createSmartPsiElementPointer(var)
|
||||
: null;
|
||||
}
|
||||
});
|
||||
GrVariable var = pointer != null ? pointer.getElement() : null;
|
||||
|
||||
if (isInplace && var != null) {
|
||||
GrInplaceIntroducer introducer = getIntroducer(var, context, settings, occurrences, varRangeMarker, expressionRangeMarker, stringPartRangeMarker);
|
||||
LinkedHashSet<String> suggestions = introducer.suggestNames(context);
|
||||
PsiDocumentManager.getInstance(project).doPostponedOperationsAndUnblockDocument(editor.getDocument());
|
||||
introducer.performInplaceRefactoring(suggestions);
|
||||
}
|
||||
}
|
||||
}, getRefactoringName(), getRefactoringName());
|
||||
}
|
||||
};
|
||||
|
||||
if (isInplace(context.getEditor(), context.getPlace())) {
|
||||
Map<OccurrencesChooser.ReplaceChoice, List<Object>> occurrencesMap = fillChoice(context);
|
||||
new OccurrencesChooser<Object>(editor) {
|
||||
@@ -405,17 +355,28 @@ public abstract class GrIntroduceHandlerBase<Settings extends GrIntroduceSetting
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}.showChooser(callback, occurrencesMap);
|
||||
}.showChooser(new Pass<OccurrencesChooser.ReplaceChoice>() {
|
||||
@Override
|
||||
public void pass(final OccurrencesChooser.ReplaceChoice choice) {
|
||||
getIntroducer(context, choice).startInplaceIntroduceTemplate();
|
||||
}
|
||||
}, occurrencesMap);
|
||||
}
|
||||
else {
|
||||
callback.pass(null);
|
||||
final Settings settings = showDialog(context);
|
||||
if (settings == null) return false;
|
||||
ApplicationManager.getApplication().runWriteAction(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
runRefactoring(context, settings);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
catch (GrRefactoringError e) {
|
||||
CommonRefactoringUtil
|
||||
.showErrorHint(project, editor, RefactoringBundle.getCannotRefactorMessage(e.getMessage()), getRefactoringName(), getHelpID());
|
||||
CommonRefactoringUtil.showErrorHint(project, editor, RefactoringBundle.getCannotRefactorMessage(e.getMessage()), getRefactoringName(), getHelpID());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
+100
-96
@@ -15,127 +15,118 @@
|
||||
*/
|
||||
package org.jetbrains.plugins.groovy.refactoring.introduce.constant;
|
||||
|
||||
import com.intellij.openapi.editor.RangeMarker;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import com.intellij.psi.util.PsiUtilCore;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import com.intellij.refactoring.introduce.inplace.OccurrencesChooser;
|
||||
import com.intellij.refactoring.introduceField.IntroduceConstantHandler;
|
||||
import com.intellij.ui.components.JBCheckBox;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.GroovyFileBase;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrVariable;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrVariableDeclaration;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrBinaryExpression;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrExpression;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrReferenceExpression;
|
||||
import org.jetbrains.plugins.groovy.refactoring.GroovyNameSuggestionUtil;
|
||||
import org.jetbrains.plugins.groovy.refactoring.introduce.GrInplaceIntroducer;
|
||||
import org.jetbrains.plugins.groovy.refactoring.introduce.GrAbstractInplaceIntroducer;
|
||||
import org.jetbrains.plugins.groovy.refactoring.introduce.GrIntroduceContext;
|
||||
import org.jetbrains.plugins.groovy.refactoring.introduce.GrIntroduceContextImpl;
|
||||
import org.jetbrains.plugins.groovy.refactoring.introduce.StringPartInfo;
|
||||
import org.jetbrains.plugins.groovy.refactoring.introduce.field.GroovyInplaceFieldValidator;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Created by Max Medvedev on 8/29/13
|
||||
*/
|
||||
public class GrInplaceConstantIntroducer extends GrInplaceIntroducer {
|
||||
public class GrInplaceConstantIntroducer extends GrAbstractInplaceIntroducer<GrIntroduceConstantSettings> {
|
||||
private final GrInplaceIntroduceConstantPanel myPanel;
|
||||
private final GrIntroduceContext myContext;
|
||||
private final RangeMarker myExpressionRangeMarker;
|
||||
private final RangeMarker myStringPartRangeMarker;
|
||||
private final boolean myReplaceAll;
|
||||
private String[] mySuggestedNames;
|
||||
|
||||
public GrInplaceConstantIntroducer(GrVariable var,
|
||||
GrIntroduceContext context,
|
||||
List<RangeMarker> occurrences,
|
||||
boolean replaceAllOccurrences,
|
||||
RangeMarker expressionRangeMarker,
|
||||
RangeMarker stringPartRangeMarker) {
|
||||
super(var, context.getEditor(), context.getProject(), GrIntroduceConstantHandler.REFACTORING_NAME, occurrences, context.getPlace());
|
||||
public GrInplaceConstantIntroducer(GrIntroduceContext context, OccurrencesChooser.ReplaceChoice choice) {
|
||||
super(IntroduceConstantHandler.REFACTORING_NAME, choice, context);
|
||||
|
||||
myContext = context;
|
||||
myReplaceAll = replaceAllOccurrences;
|
||||
myExpressionRangeMarker = expressionRangeMarker;
|
||||
myStringPartRangeMarker = stringPartRangeMarker;
|
||||
|
||||
myPanel = new GrInplaceIntroduceConstantPanel();
|
||||
|
||||
mySuggestedNames = GroovyNameSuggestionUtil.suggestVariableNames(context.getExpression(), new GroovyInplaceFieldValidator(context),
|
||||
true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public LinkedHashSet<String> suggestNames(GrIntroduceContext context) {
|
||||
return ContainerUtil.newLinkedHashSet(GroovyNameSuggestionUtil.suggestVariableNames(
|
||||
context.getExpression(),
|
||||
new GroovyInplaceFieldValidator(context),
|
||||
getVariable().hasModifierProperty(PsiModifier.STATIC))
|
||||
);
|
||||
protected String getActionName() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void moveOffsetAfter(boolean success) {
|
||||
if (success) {
|
||||
final GrVariable field = getVariable();
|
||||
assert field != null;
|
||||
GrIntroduceConstantProcessor processor = new GrIntroduceConstantProcessor(generateContext(), generateSettings()) {
|
||||
@Override
|
||||
protected GrVariableDeclaration addDeclaration(PsiClass targetClass, GrVariableDeclaration declaration) {
|
||||
return (GrVariableDeclaration)field.getParent();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean checkErrors(@NotNull PsiClass targetClass) {
|
||||
return false;
|
||||
}
|
||||
};
|
||||
processor.run();
|
||||
}
|
||||
super.moveOffsetAfter(success);
|
||||
}
|
||||
|
||||
private GrIntroduceContext generateContext() {
|
||||
final List<RangeMarker> occurrenceMarkers = getOccurrenceMarkers();
|
||||
|
||||
List<PsiElement> occurrences = ContainerUtil.newArrayList();
|
||||
for (RangeMarker marker : occurrenceMarkers) {
|
||||
ContainerUtil.addIfNotNull(occurrences, findExpression(marker));
|
||||
}
|
||||
|
||||
GrExpression expr = null;
|
||||
if (myExpressionRangeMarker != null) expr = findExpression(myExpressionRangeMarker);
|
||||
if (myStringPartRangeMarker != null) {
|
||||
expr = findExpressionFromStringPartMarker(myStringPartRangeMarker);
|
||||
occurrences.add(expr);
|
||||
}
|
||||
|
||||
return new GrIntroduceContextImpl(myContext.getProject(), myContext.getEditor(), expr, null, null, PsiUtilCore.toPsiElementArray(
|
||||
occurrences), myContext.getScope());
|
||||
protected String[] suggestNames(boolean replaceAll, @Nullable GrVariable variable) {
|
||||
return mySuggestedNames;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private GrExpression findExpressionFromStringPartMarker(RangeMarker marker) {
|
||||
PsiFile file = PsiDocumentManager.getInstance(myContext.getProject()).getPsiFile(marker.getDocument());
|
||||
if (file == null) return null;
|
||||
PsiElement leaf = file.findElementAt(marker.getStartOffset());
|
||||
GrBinaryExpression binary = PsiTreeUtil.getParentOfType(leaf, GrBinaryExpression.class);
|
||||
if (binary != null) {
|
||||
return binary.getRightOperand();
|
||||
@Override
|
||||
protected JComponent getComponent() {
|
||||
return myPanel.getRootPane();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void saveSettings(@NotNull GrVariable variable) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
protected GrVariable runRefactoring(GrIntroduceContext context, GrIntroduceConstantSettings settings, boolean processUsages) {
|
||||
if (processUsages) {
|
||||
return new GrIntroduceConstantProcessor(context, settings).run();
|
||||
}
|
||||
else {
|
||||
PsiElement scope = context.getScope();
|
||||
return new GrIntroduceConstantProcessor(context, settings).addDeclaration(scope instanceof GroovyFileBase ? ((GroovyFileBase)scope).getScriptClass() : (PsiClass)scope).getVariables()[0];
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private GrExpression findExpression(@NotNull RangeMarker marker) {
|
||||
PsiFile file = PsiDocumentManager.getInstance(myContext.getProject()).getPsiFile(marker.getDocument());
|
||||
if (file == null) return null;
|
||||
PsiElement leaf = file.findElementAt(marker.getStartOffset());
|
||||
if (leaf != null && leaf.getParent() instanceof GrReferenceExpression) {
|
||||
return (GrExpression)leaf.getParent();
|
||||
}
|
||||
return null;
|
||||
@Override
|
||||
protected GrIntroduceConstantSettings getInitialSettingsForInplace(@NotNull final GrIntroduceContext context,
|
||||
@NotNull final OccurrencesChooser.ReplaceChoice choice,
|
||||
final String[] names) {
|
||||
return new GrIntroduceConstantSettings() {
|
||||
@Override
|
||||
public String getVisibilityModifier() {
|
||||
return PsiModifier.PUBLIC;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public PsiClass getTargetClass() {
|
||||
return (PsiClass)context.getScope();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public String getName() {
|
||||
return names[0];
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean replaceAllOccurrences() {
|
||||
return isReplaceAllOccurrences();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public PsiType getSelectedType() {
|
||||
GrExpression expression = context.getExpression();
|
||||
GrVariable var = context.getVar();
|
||||
StringPartInfo stringPart = context.getStringPart();
|
||||
return var != null ? var.getDeclaredType() :
|
||||
expression != null ? expression.getType() :
|
||||
stringPart != null ? stringPart.getLiteral().getType() :
|
||||
null;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
private GrIntroduceConstantSettings generateSettings() {
|
||||
@Override
|
||||
protected GrIntroduceConstantSettings getSettings() {
|
||||
return new GrIntroduceConstantSettings() {
|
||||
@Override
|
||||
public String getVisibilityModifier() {
|
||||
@@ -145,18 +136,18 @@ public class GrInplaceConstantIntroducer extends GrInplaceIntroducer {
|
||||
@Nullable
|
||||
@Override
|
||||
public String getName() {
|
||||
return getVariable().getName();
|
||||
return getInputName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean replaceAllOccurrences() {
|
||||
return myReplaceAll;
|
||||
return isReplaceAllOccurrences();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public PsiType getSelectedType() {
|
||||
return getVariable().getDeclaredType();
|
||||
return GrInplaceConstantIntroducer.this.getSelectedType();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@@ -167,17 +158,30 @@ public class GrInplaceConstantIntroducer extends GrInplaceIntroducer {
|
||||
};
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
protected JComponent getComponent() {
|
||||
//return myPanel.getRootPane();
|
||||
return null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
protected PsiElement checkLocalScope() {
|
||||
return getVariable().getContainingFile();
|
||||
return ((PsiField)getVariable()).getContainingClass();
|
||||
}
|
||||
|
||||
/**
|
||||
* Created by Max Medvedev on 8/29/13
|
||||
*/
|
||||
public class GrInplaceIntroduceConstantPanel {
|
||||
private JBCheckBox myMoveToAnotherClassJBCheckBox;
|
||||
private JPanel myRootPane;
|
||||
private JComponent myPreview;
|
||||
|
||||
public boolean isMoveToAnotherClass() {
|
||||
return myMoveToAnotherClassJBCheckBox.isSelected();
|
||||
}
|
||||
|
||||
public JComponent getRootPane() {
|
||||
return myRootPane;
|
||||
}
|
||||
|
||||
private void createUIComponents() {
|
||||
myPreview = getPreviewComponent();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+11
-4
@@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<form xmlns="http://www.intellij.com/uidesigner/form/" version="1" bind-to-class="org.jetbrains.plugins.groovy.refactoring.introduce.constant.GrInplaceIntroduceConstantPanel">
|
||||
<grid id="27dc6" binding="myRootPane" layout-manager="GridLayoutManager" row-count="2" column-count="1" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
|
||||
<form xmlns="http://www.intellij.com/uidesigner/form/" version="1" bind-to-class="org.jetbrains.plugins.groovy.refactoring.introduce.constant.GrInplaceConstantIntroducer.GrInplaceIntroduceConstantPanel">
|
||||
<grid id="27dc6" binding="myRootPane" layout-manager="GridLayoutManager" row-count="3" column-count="1" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
|
||||
<margin top="0" left="0" bottom="0" right="0"/>
|
||||
<constraints>
|
||||
<xy x="20" y="20" width="500" height="400"/>
|
||||
@@ -10,17 +10,24 @@
|
||||
<children>
|
||||
<vspacer id="3c553">
|
||||
<constraints>
|
||||
<grid row="1" column="0" row-span="1" col-span="1" vsize-policy="6" hsize-policy="1" anchor="0" fill="2" indent="0" use-parent-layout="false"/>
|
||||
<grid row="2" column="0" row-span="1" col-span="1" vsize-policy="6" hsize-policy="1" anchor="0" fill="2" indent="0" use-parent-layout="false"/>
|
||||
</constraints>
|
||||
</vspacer>
|
||||
<component id="1ff44" class="com.intellij.ui.components.JBCheckBox" binding="myMoveToAnotherClassJBCheckBox" default-binding="true">
|
||||
<constraints>
|
||||
<grid row="0" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
|
||||
<grid row="1" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
|
||||
</constraints>
|
||||
<properties>
|
||||
<focusable value="false"/>
|
||||
<requestFocusEnabled value="true"/>
|
||||
<text value="&Move to another class"/>
|
||||
</properties>
|
||||
</component>
|
||||
<component id="3e5fd" class="javax.swing.JComponent" binding="myPreview" custom-create="true">
|
||||
<constraints>
|
||||
<grid row="0" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
|
||||
</constraints>
|
||||
</component>
|
||||
</children>
|
||||
</grid>
|
||||
</form>
|
||||
|
||||
+3
-65
@@ -15,7 +15,6 @@
|
||||
*/
|
||||
package org.jetbrains.plugins.groovy.refactoring.introduce.constant;
|
||||
|
||||
import com.intellij.openapi.editor.RangeMarker;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import com.intellij.refactoring.HelpID;
|
||||
@@ -27,16 +26,11 @@ import org.jetbrains.plugins.groovy.lang.psi.GroovyRecursiveElementVisitor;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrField;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrVariable;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.blocks.GrClosableBlock;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrBinaryExpression;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrExpression;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrReferenceExpression;
|
||||
import org.jetbrains.plugins.groovy.refactoring.GrRefactoringError;
|
||||
import org.jetbrains.plugins.groovy.refactoring.GroovyRefactoringBundle;
|
||||
import org.jetbrains.plugins.groovy.refactoring.introduce.*;
|
||||
import org.jetbrains.plugins.groovy.refactoring.introduce.field.GrFieldNameSuggester;
|
||||
import org.jetbrains.plugins.groovy.refactoring.introduce.field.GroovyInplaceFieldValidator;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author Maxim.Medvedev
|
||||
@@ -99,65 +93,9 @@ public class GrIntroduceConstantHandler extends GrIntroduceFieldHandlerBase<GrIn
|
||||
}
|
||||
|
||||
@Override
|
||||
protected GrInplaceIntroducer getIntroducer(@NotNull final GrVariable var,
|
||||
@NotNull GrIntroduceContext context,
|
||||
@NotNull GrIntroduceConstantSettings settings,
|
||||
@NotNull List<RangeMarker> occurrenceMarkers,
|
||||
RangeMarker varRangeMarker, RangeMarker expressionRangeMarker,
|
||||
RangeMarker stringPartRangeMarker) {
|
||||
if (varRangeMarker != null) {
|
||||
context.getEditor().getCaretModel().moveToOffset(var.getNameIdentifierGroovy().getTextRange().getStartOffset());
|
||||
}
|
||||
else if (expressionRangeMarker != null) {
|
||||
context.getEditor().getCaretModel().moveToOffset(expressionRangeMarker.getStartOffset());
|
||||
}
|
||||
else if (stringPartRangeMarker != null) {
|
||||
int offset = stringPartRangeMarker.getStartOffset();
|
||||
PsiElement at = var.getContainingFile().findElementAt(offset);
|
||||
GrExpression ref = PsiTreeUtil.getParentOfType(at, GrBinaryExpression.class).getRightOperand();
|
||||
context.getEditor().getCaretModel().moveToOffset(ref.getTextRange().getStartOffset());
|
||||
}
|
||||
|
||||
return new GrInplaceConstantIntroducer(var, context, occurrenceMarkers, settings.replaceAllOccurrences(), expressionRangeMarker, stringPartRangeMarker);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected GrIntroduceConstantSettings getSettingsForInplace(final GrIntroduceContext context, final OccurrencesChooser.ReplaceChoice choice) {
|
||||
return new GrIntroduceConstantSettings() {
|
||||
@Override
|
||||
public String getVisibilityModifier() {
|
||||
return PsiModifier.PUBLIC;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public PsiClass getTargetClass() {
|
||||
return (PsiClass)context.getScope();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public String getName() {
|
||||
return new GrFieldNameSuggester(context, new GroovyInplaceFieldValidator(context), false).suggestNames().iterator().next();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean replaceAllOccurrences() {
|
||||
return choice == OccurrencesChooser.ReplaceChoice.ALL;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public PsiType getSelectedType() {
|
||||
GrExpression expression = context.getExpression();
|
||||
GrVariable var = context.getVar();
|
||||
StringPartInfo stringPart = context.getStringPart();
|
||||
return var != null ? var.getDeclaredType() :
|
||||
expression != null ? expression.getType() :
|
||||
stringPart != null ? stringPart.getLiteral().getType() :
|
||||
null;
|
||||
}
|
||||
};
|
||||
protected GrAbstractInplaceIntroducer<GrIntroduceConstantSettings> getIntroducer(@NotNull GrIntroduceContext context,
|
||||
OccurrencesChooser.ReplaceChoice choice) {
|
||||
return new GrInplaceConstantIntroducer(context, choice);
|
||||
}
|
||||
|
||||
private static class ConstantChecker extends GroovyRecursiveElementVisitor {
|
||||
|
||||
+3
-3
@@ -69,8 +69,7 @@ public class GrIntroduceConstantProcessor {
|
||||
return null;
|
||||
}
|
||||
|
||||
final GrVariableDeclaration rawDeclaration = createField(targetClass);
|
||||
final GrVariableDeclaration declaration = addDeclaration(targetClass, rawDeclaration);
|
||||
final GrVariableDeclaration declaration = addDeclaration(targetClass);
|
||||
final GrField field = (GrField)declaration.getVariables()[0];
|
||||
|
||||
if (context.getVar() != null) {
|
||||
@@ -102,7 +101,8 @@ public class GrIntroduceConstantProcessor {
|
||||
context.getEditor().getSelectionModel().removeSelection();
|
||||
}
|
||||
|
||||
protected GrVariableDeclaration addDeclaration(PsiClass targetClass, GrVariableDeclaration declaration) {
|
||||
protected GrVariableDeclaration addDeclaration(PsiClass targetClass) {
|
||||
GrVariableDeclaration declaration = createField(targetClass);
|
||||
final GrVariableDeclaration added;
|
||||
if (targetClass instanceof GrEnumTypeDefinition) {
|
||||
final GrEnumConstantList enumConstants = ((GrEnumTypeDefinition)targetClass).getEnumConstantList();
|
||||
|
||||
+121
-106
@@ -17,140 +17,133 @@ package org.jetbrains.plugins.groovy.refactoring.introduce.field;
|
||||
|
||||
import com.intellij.openapi.application.Result;
|
||||
import com.intellij.openapi.command.WriteCommandAction;
|
||||
import com.intellij.openapi.editor.RangeMarker;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import com.intellij.psi.util.PsiUtilCore;
|
||||
import com.intellij.refactoring.introduce.inplace.KeyboardComboSwitcher;
|
||||
import com.intellij.refactoring.introduce.inplace.OccurrencesChooser;
|
||||
import com.intellij.refactoring.introduceField.IntroduceFieldHandler;
|
||||
import com.intellij.ui.NonFocusableCheckBox;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrVariable;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrVariableDeclaration;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrBinaryExpression;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrExpression;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrReferenceExpression;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.util.PsiUtil;
|
||||
import org.jetbrains.plugins.groovy.refactoring.GroovyNameSuggestionUtil;
|
||||
import org.jetbrains.plugins.groovy.refactoring.introduce.GrAbstractInplaceIntroducer;
|
||||
import org.jetbrains.plugins.groovy.refactoring.introduce.GrFinalListener;
|
||||
import org.jetbrains.plugins.groovy.refactoring.introduce.GrInplaceIntroducer;
|
||||
import org.jetbrains.plugins.groovy.refactoring.introduce.GrIntroduceContext;
|
||||
import org.jetbrains.plugins.groovy.refactoring.introduce.GrIntroduceContextImpl;
|
||||
import org.jetbrains.plugins.groovy.refactoring.introduce.StringPartInfo;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
import java.util.EnumSet;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author Max Medvedev
|
||||
*/
|
||||
public class GrInplaceFieldIntroducer extends GrInplaceIntroducer {
|
||||
private final GrInplaceIntroduceFieldPanel myPanel;
|
||||
private final GrIntroduceContext myContext;
|
||||
private final RangeMarker myExpressionRangeMarker;
|
||||
private final RangeMarker myStringPartRangeMarker;
|
||||
private final GrExpression myInitializer;
|
||||
public class GrInplaceFieldIntroducer extends GrAbstractInplaceIntroducer<GrIntroduceFieldSettings> {
|
||||
private GrInplaceIntroduceFieldPanel myPanel;
|
||||
private final GrFinalListener finalListener;
|
||||
private final boolean myReplaceAll;
|
||||
private String[] mySuggestedNames;
|
||||
private boolean myIsStatic;
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
protected PsiElement checkLocalScope() {
|
||||
return getVariable().getContainingFile();
|
||||
return ((PsiField)getVariable()).getContainingClass();
|
||||
}
|
||||
|
||||
public GrInplaceFieldIntroducer(GrVariable var,
|
||||
GrIntroduceContext context,
|
||||
List<RangeMarker> occurrences,
|
||||
boolean replaceAll,
|
||||
@Nullable RangeMarker expressionRangeMarker,
|
||||
@Nullable RangeMarker stringPartRangeMarker,
|
||||
GrExpression initializer) {
|
||||
super(var, context.getEditor(), context.getProject(), IntroduceFieldHandler.REFACTORING_NAME, occurrences, context.getPlace());
|
||||
|
||||
myContext = context;
|
||||
myReplaceAll = replaceAll;
|
||||
myExpressionRangeMarker = expressionRangeMarker;
|
||||
myStringPartRangeMarker = stringPartRangeMarker;
|
||||
myInitializer = initializer;
|
||||
|
||||
myPanel = new GrInplaceIntroduceFieldPanel(context.getProject(),
|
||||
GrIntroduceFieldHandler.getApplicableInitPlaces(context, replaceAll));
|
||||
public GrInplaceFieldIntroducer(GrIntroduceContext context, OccurrencesChooser.ReplaceChoice choice) {
|
||||
super(IntroduceFieldHandler.REFACTORING_NAME, choice, context);
|
||||
|
||||
finalListener = new GrFinalListener(myEditor);
|
||||
|
||||
mySuggestedNames = GroovyNameSuggestionUtil.suggestVariableNames(context.getExpression(), new GroovyInplaceFieldValidator(getContext()), false);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void moveOffsetAfter(boolean success) {
|
||||
if (success) {
|
||||
final GrVariable field = getVariable();
|
||||
assert field != null;
|
||||
GrIntroduceFieldProcessor processor = new GrIntroduceFieldProcessor(generateContext(), generateSettings(), false) {
|
||||
@NotNull
|
||||
@Override
|
||||
protected GrExpression getInitializer() {
|
||||
return myInitializer;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
protected GrVariableDeclaration insertField(@NotNull PsiClass targetClass, @NotNull GrVariableDeclaration declaration) {
|
||||
return (GrVariableDeclaration)field.getParent();
|
||||
}
|
||||
};
|
||||
processor.run();
|
||||
}
|
||||
super.moveOffsetAfter(success);
|
||||
}
|
||||
|
||||
private GrIntroduceContext generateContext() {
|
||||
final List<RangeMarker> occurrenceMarkers = getOccurrenceMarkers();
|
||||
|
||||
List<PsiElement> occurrences = ContainerUtil.newArrayList();
|
||||
for (RangeMarker marker : occurrenceMarkers) {
|
||||
ContainerUtil.addIfNotNull(occurrences, findExpression(marker));
|
||||
}
|
||||
|
||||
GrExpression expr = null;
|
||||
if (myExpressionRangeMarker != null) expr = findExpression(myExpressionRangeMarker);
|
||||
if (myStringPartRangeMarker != null) {
|
||||
expr = findExpressionFromStringPartMarker(myStringPartRangeMarker);
|
||||
occurrences.add(expr);
|
||||
}
|
||||
|
||||
return new GrIntroduceContextImpl(myContext.getProject(), myContext.getEditor(), expr, null, null, PsiUtilCore.toPsiElementArray(
|
||||
occurrences), myContext.getScope());
|
||||
protected GrVariable runRefactoring(GrIntroduceContext context, GrIntroduceFieldSettings settings, boolean processUsages) {
|
||||
GrIntroduceFieldProcessor processor = new GrIntroduceFieldProcessor(context, settings);
|
||||
return processUsages ? processor.run()
|
||||
: processor.insertField((PsiClass)context.getScope()).getVariables()[0];
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private GrExpression findExpressionFromStringPartMarker(RangeMarker marker) {
|
||||
PsiFile file = PsiDocumentManager.getInstance(myContext.getProject()).getPsiFile(marker.getDocument());
|
||||
if (file == null) return null;
|
||||
PsiElement leaf = file.findElementAt(marker.getStartOffset());
|
||||
GrBinaryExpression binary = PsiTreeUtil.getParentOfType(leaf, GrBinaryExpression.class);
|
||||
if (binary != null) {
|
||||
return binary.getRightOperand();
|
||||
}
|
||||
return null;
|
||||
@Override
|
||||
protected GrIntroduceFieldSettings getInitialSettingsForInplace(@NotNull final GrIntroduceContext context,
|
||||
@NotNull final OccurrencesChooser.ReplaceChoice choice,
|
||||
final String[] names) {
|
||||
return new GrIntroduceFieldSettings() {
|
||||
@Override
|
||||
public boolean declareFinal() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Init initializeIn() {
|
||||
return Init.FIELD_DECLARATION;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getVisibilityModifier() {
|
||||
return PsiModifier.PRIVATE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isStatic() {
|
||||
boolean hasInstanceInScope = true;
|
||||
PsiClass clazz = (PsiClass)context.getScope();
|
||||
if (replaceAllOccurrences()) {
|
||||
for (PsiElement occurrence : context.getOccurrences()) {
|
||||
if (!PsiUtil.hasEnclosingInstanceInScope(clazz, occurrence, false)) {
|
||||
hasInstanceInScope = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (context.getExpression() != null) {
|
||||
hasInstanceInScope = PsiUtil.hasEnclosingInstanceInScope(clazz, context.getExpression(), false);
|
||||
}
|
||||
else if (context.getStringPart() != null) {
|
||||
hasInstanceInScope = PsiUtil.hasEnclosingInstanceInScope(clazz, context.getStringPart().getLiteral(), false);
|
||||
}
|
||||
|
||||
return !hasInstanceInScope;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean removeLocalVar() {
|
||||
return context.getVar() != null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public String getName() {
|
||||
return names[0];
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean replaceAllOccurrences() {
|
||||
return context.getVar() != null || choice == OccurrencesChooser.ReplaceChoice.ALL;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public PsiType getSelectedType() {
|
||||
GrExpression expression = context.getExpression();
|
||||
GrVariable var = context.getVar();
|
||||
StringPartInfo stringPart = context.getStringPart();
|
||||
return var != null ? var.getDeclaredType() :
|
||||
expression != null ? expression.getType() :
|
||||
stringPart != null ? stringPart.getLiteral().getType() :
|
||||
null;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private GrExpression findExpression(@NotNull RangeMarker marker) {
|
||||
PsiFile file = PsiDocumentManager.getInstance(myContext.getProject()).getPsiFile(marker.getDocument());
|
||||
if (file == null) return null;
|
||||
PsiElement leaf = file.findElementAt(marker.getStartOffset());
|
||||
if (leaf != null && leaf.getParent() instanceof GrReferenceExpression) {
|
||||
return (GrExpression)leaf.getParent();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private GrIntroduceFieldSettings generateSettings() {
|
||||
@Override
|
||||
protected GrIntroduceFieldSettings getSettings() {
|
||||
return new GrIntroduceFieldSettings() {
|
||||
@Override
|
||||
public boolean declareFinal() {
|
||||
@@ -169,7 +162,7 @@ public class GrInplaceFieldIntroducer extends GrInplaceIntroducer {
|
||||
|
||||
@Override
|
||||
public boolean isStatic() {
|
||||
return getVariable().hasModifierProperty(PsiModifier.STATIC);
|
||||
return myIsStatic;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -180,39 +173,57 @@ public class GrInplaceFieldIntroducer extends GrInplaceIntroducer {
|
||||
@Nullable
|
||||
@Override
|
||||
public String getName() {
|
||||
return getVariable().getName();
|
||||
return getInputName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean replaceAllOccurrences() {
|
||||
return myReplaceAll;
|
||||
return isReplaceAllOccurrences();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public PsiType getSelectedType() {
|
||||
return getVariable().getDeclaredType();
|
||||
return GrInplaceFieldIntroducer.this.getSelectedType();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getActionName() {
|
||||
return IntroduceFieldHandler.REFACTORING_NAME;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String[] suggestNames(boolean replaceAll, @Nullable GrVariable variable) {
|
||||
return mySuggestedNames;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void saveSettings(@NotNull GrVariable variable) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void restoreState(GrVariable psiField) {
|
||||
myIsStatic = psiField.hasModifierProperty(PsiModifier.STATIC);
|
||||
|
||||
super.restoreState(psiField);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
protected JComponent getComponent() {
|
||||
myPanel = new GrInplaceIntroduceFieldPanel(myProject, GrIntroduceFieldHandler.getApplicableInitPlaces(getContext(), isReplaceAllOccurrences()));
|
||||
return myPanel.getRootPane();
|
||||
}
|
||||
|
||||
@Override
|
||||
public LinkedHashSet<String> suggestNames(GrIntroduceContext context) {
|
||||
return ContainerUtil.newLinkedHashSet(
|
||||
GroovyNameSuggestionUtil.suggestVariableNames(myInitializer, new GroovyInplaceFieldValidator(context), false));
|
||||
}
|
||||
|
||||
public class GrInplaceIntroduceFieldPanel {
|
||||
private final Project myProject;
|
||||
private JPanel myRootPane;
|
||||
private JComboBox myInitCB;
|
||||
private NonFocusableCheckBox myDeclareFinalCB;
|
||||
private JComponent myPreview;
|
||||
|
||||
public GrInplaceIntroduceFieldPanel(Project project, EnumSet<GrIntroduceFieldSettings.Init> initPlaces) {
|
||||
myProject = project;
|
||||
@@ -251,5 +262,9 @@ public class GrInplaceFieldIntroducer extends GrInplaceIntroducer {
|
||||
public boolean isFinal() {
|
||||
return myDeclareFinalCB.isSelected();
|
||||
}
|
||||
|
||||
private void createUIComponents() {
|
||||
myPreview = getPreviewComponent();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+9
-4
@@ -1,9 +1,9 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<form xmlns="http://www.intellij.com/uidesigner/form/" version="1" bind-to-class="org.jetbrains.plugins.groovy.refactoring.introduce.field.GrInplaceFieldIntroducer.GrInplaceIntroduceFieldPanel">
|
||||
<grid id="27dc6" binding="myRootPane" layout-manager="GridLayoutManager" row-count="2" column-count="2" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
|
||||
<grid id="27dc6" binding="myRootPane" layout-manager="GridLayoutManager" row-count="3" column-count="2" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
|
||||
<margin top="0" left="0" bottom="0" right="0"/>
|
||||
<constraints>
|
||||
<xy x="20" y="20" width="540" height="63"/>
|
||||
<xy x="20" y="20" width="540" height="88"/>
|
||||
</constraints>
|
||||
<properties/>
|
||||
<border type="none"/>
|
||||
@@ -11,7 +11,7 @@
|
||||
<grid id="3dec1" layout-manager="GridLayoutManager" row-count="1" column-count="2" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
|
||||
<margin top="0" left="0" bottom="0" right="0"/>
|
||||
<constraints>
|
||||
<grid row="0" column="0" row-span="1" col-span="2" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
|
||||
<grid row="1" column="0" row-span="1" col-span="2" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
|
||||
</constraints>
|
||||
<properties/>
|
||||
<border type="none"/>
|
||||
@@ -35,13 +35,18 @@
|
||||
</grid>
|
||||
<component id="23db" class="com.intellij.ui.NonFocusableCheckBox" binding="myDeclareFinalCB">
|
||||
<constraints>
|
||||
<grid row="1" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
|
||||
<grid row="2" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
|
||||
</constraints>
|
||||
<properties>
|
||||
<horizontalAlignment value="10"/>
|
||||
<text value="Declare &final"/>
|
||||
</properties>
|
||||
</component>
|
||||
<component id="d8bd5" class="javax.swing.JComponent" binding="myPreview" custom-create="true">
|
||||
<constraints>
|
||||
<grid row="0" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
|
||||
</constraints>
|
||||
</component>
|
||||
</children>
|
||||
</grid>
|
||||
</form>
|
||||
|
||||
+14
-112
@@ -16,25 +16,21 @@
|
||||
package org.jetbrains.plugins.groovy.refactoring.introduce.field;
|
||||
|
||||
import com.intellij.codeInsight.TestFrameworks;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.editor.RangeMarker;
|
||||
import com.intellij.psi.PsiClass;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.PsiModifier;
|
||||
import com.intellij.psi.PsiType;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import com.intellij.refactoring.HelpID;
|
||||
import com.intellij.refactoring.introduce.inplace.OccurrencesChooser;
|
||||
import com.intellij.refactoring.introduceField.IntroduceFieldHandler;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElementFactory;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.GroovyFileBase;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrVariable;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrBinaryExpression;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrExpression;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.GrTypeDefinition;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrMember;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.impl.synthetic.GroovyScriptClass;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.util.PsiUtil;
|
||||
import org.jetbrains.plugins.groovy.refactoring.GrRefactoringError;
|
||||
import org.jetbrains.plugins.groovy.refactoring.GroovyRefactoringBundle;
|
||||
@@ -100,133 +96,39 @@ public class GrIntroduceFieldHandler extends GrIntroduceFieldHandlerBase<GrIntro
|
||||
|
||||
@Override
|
||||
public GrVariable runRefactoring(@NotNull GrIntroduceContext context, @NotNull GrIntroduceFieldSettings settings) {
|
||||
return new GrIntroduceFieldProcessor(context, settings, isInplace(context.getEditor(), context.getPlace())).run();
|
||||
return new GrIntroduceFieldProcessor(context, settings).run();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected GrInplaceFieldIntroducer getIntroducer(@NotNull final GrVariable var,
|
||||
@NotNull GrIntroduceContext context,
|
||||
@NotNull GrIntroduceFieldSettings settings,
|
||||
@NotNull List<RangeMarker> occurrenceMarkers,
|
||||
@Nullable RangeMarker varRangeMarker,
|
||||
@Nullable RangeMarker expressionRangeMarker,
|
||||
@Nullable RangeMarker stringPartRangeMarker) {
|
||||
if (varRangeMarker != null) {
|
||||
context.getEditor().getCaretModel().moveToOffset(var.getNameIdentifierGroovy().getTextRange().getStartOffset());
|
||||
}
|
||||
else if (expressionRangeMarker != null) {
|
||||
context.getEditor().getCaretModel().moveToOffset(expressionRangeMarker.getStartOffset());
|
||||
}
|
||||
else if (stringPartRangeMarker != null) {
|
||||
int offset = stringPartRangeMarker.getStartOffset();
|
||||
PsiElement at = var.getContainingFile().findElementAt(offset);
|
||||
GrExpression ref = PsiTreeUtil.getParentOfType(at, GrBinaryExpression.class).getRightOperand();
|
||||
context.getEditor().getCaretModel().moveToOffset(ref.getTextRange().getStartOffset());
|
||||
}
|
||||
GrExpression initializer =
|
||||
GroovyPsiElementFactory.getInstance(context.getProject()).createExpressionFromText(var.getInitializerGroovy().getText());
|
||||
ApplicationManager.getApplication().runWriteAction(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
var.setInitializerGroovy(null);
|
||||
}
|
||||
});
|
||||
|
||||
return new GrInplaceFieldIntroducer(var, context, occurrenceMarkers, settings.replaceAllOccurrences(), expressionRangeMarker,
|
||||
stringPartRangeMarker, initializer);
|
||||
@Override
|
||||
protected GrAbstractInplaceIntroducer<GrIntroduceFieldSettings> getIntroducer(@NotNull GrIntroduceContext context,
|
||||
OccurrencesChooser.ReplaceChoice choice) {
|
||||
return new GrInplaceFieldIntroducer(context, choice);
|
||||
}
|
||||
|
||||
static EnumSet<GrIntroduceFieldSettings.Init> getApplicableInitPlaces(GrIntroduceContext context, boolean replaceAll) {
|
||||
EnumSet<GrIntroduceFieldSettings.Init> result = EnumSet.of(GrIntroduceFieldSettings.Init.FIELD_DECLARATION,
|
||||
GrIntroduceFieldSettings.Init.CONSTRUCTOR);
|
||||
EnumSet<GrIntroduceFieldSettings.Init> result = EnumSet.of(GrIntroduceFieldSettings.Init.FIELD_DECLARATION);
|
||||
|
||||
if (!(context.getScope() instanceof GroovyScriptClass || context.getScope() instanceof GroovyFileBase)) {
|
||||
result.add(GrIntroduceFieldSettings.Init.CONSTRUCTOR);
|
||||
}
|
||||
|
||||
GrTypeDefinition clazz = (GrTypeDefinition)context.getScope();
|
||||
PsiElement scope = context.getScope();
|
||||
|
||||
if (replaceAll) {
|
||||
PsiElement anchor = GrIntroduceHandlerBase.findAnchor(context.getOccurrences(), clazz);
|
||||
PsiElement anchor = GrIntroduceHandlerBase.findAnchor(context.getOccurrences(), scope);
|
||||
if (anchor != null) {
|
||||
result.add(GrIntroduceFieldSettings.Init.CUR_METHOD);
|
||||
}
|
||||
}
|
||||
|
||||
if (TestFrameworks.getInstance().isTestClass(clazz)) {
|
||||
if (scope instanceof GrTypeDefinition && TestFrameworks.getInstance().isTestClass((PsiClass)scope)) {
|
||||
result.add(GrIntroduceFieldSettings.Init.SETUP_METHOD);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected GrIntroduceFieldSettings getSettingsForInplace(final GrIntroduceContext context, final OccurrencesChooser.ReplaceChoice choice) {
|
||||
return new GrIntroduceFieldSettings() {
|
||||
@Override
|
||||
public boolean declareFinal() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Init initializeIn() {
|
||||
return Init.FIELD_DECLARATION;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getVisibilityModifier() {
|
||||
return PsiModifier.PRIVATE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isStatic() {
|
||||
boolean hasInstanceInScope = true;
|
||||
PsiClass clazz = (PsiClass)context.getScope();
|
||||
if (replaceAllOccurrences()) {
|
||||
for (PsiElement occurrence : context.getOccurrences()) {
|
||||
if (!PsiUtil.hasEnclosingInstanceInScope(clazz, occurrence, false)) {
|
||||
hasInstanceInScope = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (context.getExpression() != null) {
|
||||
hasInstanceInScope = PsiUtil.hasEnclosingInstanceInScope(clazz, context.getExpression(), false);
|
||||
}
|
||||
else if (context.getStringPart() != null) {
|
||||
hasInstanceInScope = PsiUtil.hasEnclosingInstanceInScope(clazz, context.getStringPart().getLiteral(), false);
|
||||
}
|
||||
|
||||
return !hasInstanceInScope;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean removeLocalVar() {
|
||||
return context.getVar() != null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public String getName() {
|
||||
return new GrFieldNameSuggester(context, new GroovyInplaceFieldValidator(context), false).suggestNames().iterator().next();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean replaceAllOccurrences() {
|
||||
return context.getVar() != null || choice == OccurrencesChooser.ReplaceChoice.ALL;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public PsiType getSelectedType() {
|
||||
GrExpression expression = context.getExpression();
|
||||
GrVariable var = context.getVar();
|
||||
StringPartInfo stringPart = context.getStringPart();
|
||||
return var != null ? var.getDeclaredType() :
|
||||
expression != null ? expression.getType() :
|
||||
stringPart != null ? stringPart.getLiteral().getType() :
|
||||
null;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
protected PsiElement[] findOccurrences(@NotNull GrExpression expression, @NotNull PsiElement scope) {
|
||||
|
||||
+14
-11
@@ -25,8 +25,10 @@ import com.intellij.util.ArrayUtil;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.plugins.groovy.codeStyle.GrReferenceAdjuster;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.GrQualifiedReference;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.GroovyFile;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.GroovyFileBase;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.GroovyPsiElementFactory;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.auxiliary.modifiers.GrModifier;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.*;
|
||||
@@ -62,19 +64,19 @@ public class GrIntroduceFieldProcessor {
|
||||
|
||||
private final GrIntroduceContext context;
|
||||
private final GrIntroduceFieldSettings settings;
|
||||
private boolean myForInplacePrepare;
|
||||
|
||||
public GrIntroduceFieldProcessor(@NotNull GrIntroduceContext context, @NotNull GrIntroduceFieldSettings settings, boolean forInplacePrepare) {
|
||||
public GrIntroduceFieldProcessor(@NotNull GrIntroduceContext context,
|
||||
@NotNull GrIntroduceFieldSettings settings) {
|
||||
this.context = context;
|
||||
this.settings = settings;
|
||||
myForInplacePrepare = forInplacePrepare;
|
||||
}
|
||||
|
||||
public GrVariable run() {
|
||||
final PsiClass targetClass = (PsiClass)context.getScope();
|
||||
PsiElement scope = context.getScope();
|
||||
final PsiClass targetClass = scope instanceof GroovyFileBase ? ((GroovyFileBase)scope).getScriptClass() : (PsiClass)scope;
|
||||
if (targetClass == null) return null;
|
||||
|
||||
final GrVariableDeclaration declaration = insertField(targetClass, createField());
|
||||
final GrVariableDeclaration declaration = insertField(targetClass);
|
||||
final GrVariable field = declaration.getVariables()[0];
|
||||
|
||||
switch (settings.initializeIn()) {
|
||||
@@ -119,7 +121,7 @@ public class GrIntroduceFieldProcessor {
|
||||
else {
|
||||
final GrExpression expression = context.getExpression();
|
||||
assert expression != null;
|
||||
if (!myForInplacePrepare && PsiUtil.isExpressionStatement(expression)) {
|
||||
if (PsiUtil.isExpressionStatement(expression)) {
|
||||
expression.delete();
|
||||
}
|
||||
else {
|
||||
@@ -135,7 +137,8 @@ public class GrIntroduceFieldProcessor {
|
||||
}
|
||||
|
||||
@NotNull
|
||||
protected GrVariableDeclaration insertField(@NotNull PsiClass targetClass, @NotNull GrVariableDeclaration declaration) {
|
||||
protected GrVariableDeclaration insertField(@NotNull PsiClass targetClass) {
|
||||
GrVariableDeclaration declaration = createField(targetClass);
|
||||
if (targetClass instanceof GrEnumTypeDefinition) {
|
||||
final GrEnumConstantList enumConstants = ((GrEnumTypeDefinition)targetClass).getEnumConstantList();
|
||||
return (GrVariableDeclaration)targetClass.addAfter(declaration, enumConstants);
|
||||
@@ -304,7 +307,7 @@ public class GrIntroduceFieldProcessor {
|
||||
}
|
||||
|
||||
if (replaced instanceof GrQualifiedReference<?>) {
|
||||
org.jetbrains.plugins.groovy.codeStyle.GrReferenceAdjuster.shortenReference((GrQualifiedReference<?>)replaced);
|
||||
GrReferenceAdjuster.shortenReference((GrQualifiedReference<?>)replaced);
|
||||
}
|
||||
if (isOriginal) {
|
||||
updateCaretPosition(replaced);
|
||||
@@ -326,13 +329,13 @@ public class GrIntroduceFieldProcessor {
|
||||
return GroovyPsiElementFactory.getInstance(place.getProject()).createReferenceExpressionFromText(refText, place);
|
||||
}
|
||||
|
||||
private GrVariableDeclaration createField() {
|
||||
private GrVariableDeclaration createField(PsiClass targetClass) {
|
||||
final String name = settings.getName();
|
||||
final PsiType type = settings.getSelectedType();
|
||||
final String modifier = settings.getVisibilityModifier();
|
||||
|
||||
List<String> modifiers = new ArrayList<String>();
|
||||
if (context.getScope() instanceof GroovyScriptClass) {
|
||||
if (targetClass instanceof GroovyScriptClass) {
|
||||
modifiers.add("@" + GroovyCommonClassNames.GROOVY_TRANSFORM_FIELD);
|
||||
}
|
||||
if (settings.isStatic()) modifiers.add(PsiModifier.STATIC);
|
||||
@@ -341,7 +344,7 @@ public class GrIntroduceFieldProcessor {
|
||||
|
||||
final String[] arr_modifiers = ArrayUtil.toStringArray(modifiers);
|
||||
final GroovyPsiElementFactory factory = GroovyPsiElementFactory.getInstance(context.getProject());
|
||||
if (context.getScope() instanceof GroovyScriptClass) {
|
||||
if (targetClass instanceof GroovyScriptClass) {
|
||||
return factory.createVariableDeclaration(arr_modifiers, ((GrExpression)null), type, name);
|
||||
}
|
||||
else {
|
||||
|
||||
+118
-30
@@ -16,25 +16,31 @@
|
||||
package org.jetbrains.plugins.groovy.refactoring.introduce.variable;
|
||||
|
||||
import com.intellij.codeInsight.template.TemplateBuilderImpl;
|
||||
import com.intellij.openapi.actionSystem.Shortcut;
|
||||
import com.intellij.openapi.application.Result;
|
||||
import com.intellij.openapi.command.WriteCommandAction;
|
||||
import com.intellij.openapi.editor.Editor;
|
||||
import com.intellij.openapi.editor.RangeMarker;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.keymap.Keymap;
|
||||
import com.intellij.openapi.keymap.KeymapManager;
|
||||
import com.intellij.openapi.keymap.KeymapUtil;
|
||||
import com.intellij.psi.PsiDocumentManager;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.PsiType;
|
||||
import com.intellij.refactoring.introduce.inplace.OccurrencesChooser;
|
||||
import com.intellij.refactoring.util.CanonicalTypes;
|
||||
import com.intellij.ui.NonFocusableCheckBox;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.auxiliary.modifiers.GrModifier;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.GrVariable;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrExpression;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.expectedTypes.SupertypeConstraint;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.expectedTypes.TypeConstraint;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.util.PsiUtil;
|
||||
import org.jetbrains.plugins.groovy.refactoring.GroovyNameSuggestionUtil;
|
||||
import org.jetbrains.plugins.groovy.refactoring.introduce.GrAbstractInplaceIntroducer;
|
||||
import org.jetbrains.plugins.groovy.refactoring.introduce.GrFinalListener;
|
||||
import org.jetbrains.plugins.groovy.refactoring.introduce.GrInplaceIntroducer;
|
||||
import org.jetbrains.plugins.groovy.refactoring.introduce.GrIntroduceContext;
|
||||
import org.jetbrains.plugins.groovy.refactoring.introduce.StringPartInfo;
|
||||
import org.jetbrains.plugins.groovy.settings.GroovyApplicationSettings;
|
||||
import org.jetbrains.plugins.groovy.template.expressions.ChooseTypeExpression;
|
||||
|
||||
@@ -42,30 +48,40 @@ import javax.swing.*;
|
||||
import java.awt.*;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author Max Medvedev
|
||||
* Created by Max Medvedev on 10/29/13
|
||||
*/
|
||||
public class GrInplaceVariableIntroducer extends GrInplaceIntroducer {
|
||||
public abstract class GrInplaceVariableIntroducer extends GrAbstractInplaceIntroducer<GroovyIntroduceVariableSettings> {
|
||||
private JCheckBox myCanBeFinalCb;
|
||||
|
||||
public GrInplaceVariableIntroducer(GrVariable elementToRename,
|
||||
Editor editor,
|
||||
Project project,
|
||||
String title,
|
||||
List<RangeMarker> occurrences,
|
||||
@Nullable PsiElement elementToIntroduce) {
|
||||
super(elementToRename, editor, project, title, occurrences, elementToIntroduce);
|
||||
}
|
||||
|
||||
@Override
|
||||
public LinkedHashSet<String> suggestNames(GrIntroduceContext context) {
|
||||
return ContainerUtil.newLinkedHashSet(GroovyNameSuggestionUtil.suggestVariableNames(getVariable().getInitializerGroovy(), new GroovyVariableValidator(context)));
|
||||
public GrInplaceVariableIntroducer(String title,
|
||||
OccurrencesChooser.ReplaceChoice replaceChoice,
|
||||
GrIntroduceContext context) {
|
||||
super(title, replaceChoice, context);
|
||||
setAdvertisementText(getAdvertisementText());
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static String getAdvertisementText() {
|
||||
final Keymap keymap = KeymapManager.getInstance().getActiveKeymap();
|
||||
final Shortcut[] shortcuts = keymap.getShortcuts("PreviousTemplateVariable");
|
||||
if (shortcuts.length > 0) {
|
||||
return "Press " + KeymapUtil.getShortcutText(shortcuts[0]) + " to change type";
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getActionName() {
|
||||
return GrIntroduceVariableHandler.REFACTORING_NAME;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String[] suggestNames(boolean replaceAll, @Nullable GrVariable variable) {
|
||||
return GroovyNameSuggestionUtil.suggestVariableNames(getContext().getExpression(), new GroovyVariableValidator(getContext()));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected JComponent getComponent() {
|
||||
myCanBeFinalCb = new NonFocusableCheckBox("Declare final");
|
||||
@@ -91,22 +107,58 @@ public class GrInplaceVariableIntroducer extends GrInplaceIntroducer {
|
||||
panel.setBorder(null);
|
||||
|
||||
if (myCanBeFinalCb != null) {
|
||||
panel.add(myCanBeFinalCb, new GridBagConstraints(0, 1, 1, 1, 1, 0, GridBagConstraints.NORTHWEST, GridBagConstraints.HORIZONTAL, new Insets(5, 5, 5, 5), 0, 0));
|
||||
panel.add(myCanBeFinalCb, new GridBagConstraints(0, 1, 1, 1, 1, 0, GridBagConstraints.NORTHWEST, GridBagConstraints.HORIZONTAL,
|
||||
new Insets(5, 5, 5, 5), 0, 0));
|
||||
}
|
||||
|
||||
panel.add(Box.createVerticalBox(), new GridBagConstraints(0, 2, 1, 1, 1, 1, GridBagConstraints.NORTHWEST, GridBagConstraints.BOTH, new Insets(0,0,0,0), 0,0));
|
||||
panel.add(Box.createVerticalBox(),
|
||||
new GridBagConstraints(0, 2, 1, 1, 1, 1, GridBagConstraints.NORTHWEST, GridBagConstraints.BOTH, new Insets(0, 0, 0, 0), 0, 0));
|
||||
|
||||
return panel;
|
||||
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public void finish(boolean success) {
|
||||
super.finish(success);
|
||||
protected GroovyIntroduceVariableSettings getInitialSettingsForInplace(@NotNull final GrIntroduceContext context,
|
||||
@NotNull final OccurrencesChooser.ReplaceChoice choice,
|
||||
final String[] names) {
|
||||
return new GroovyIntroduceVariableSettings() {
|
||||
private final CanonicalTypes.Type myType;
|
||||
|
||||
if (success) {
|
||||
GroovyApplicationSettings.getInstance().INTRODUCE_LOCAL_SELECT_DEF = getVariable().getDeclaredType() == null;
|
||||
}
|
||||
{
|
||||
GrExpression expression = context.getExpression();
|
||||
StringPartInfo stringPart = context.getStringPart();
|
||||
GrVariable var = context.getVar();
|
||||
PsiType type = expression != null ? expression.getType() :
|
||||
var != null ? var.getType() :
|
||||
stringPart != null ? stringPart.getLiteral().getType() :
|
||||
null;
|
||||
myType = type != null ? CanonicalTypes.createTypeWrapper(type) : null;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public boolean isDeclareFinal() {
|
||||
return myCanBeFinalCb != null ? myCanBeFinalCb.isSelected() : false;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public String getName() {
|
||||
return names[0];
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean replaceAllOccurrences() {
|
||||
return choice == OccurrencesChooser.ReplaceChoice.ALL;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public PsiType getSelectedType() {
|
||||
return myType != null ? myType.getType(context.getPlace(), context.getPlace().getManager()) : null;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -119,4 +171,40 @@ public class GrInplaceVariableIntroducer extends GrInplaceIntroducer {
|
||||
: PsiUtil.findModifierInList(variable.getModifierList(), GrModifier.DEF);
|
||||
builder.replaceElement(element, "Variable_type", typeExpression, true, true);
|
||||
}
|
||||
}
|
||||
|
||||
protected GroovyIntroduceVariableSettings getSettings() {
|
||||
return new GroovyIntroduceVariableSettings() {
|
||||
@Override
|
||||
public boolean isDeclareFinal() {
|
||||
return myCanBeFinalCb.isSelected();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public String getName() {
|
||||
return GrInplaceVariableIntroducer.this.getInputName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean replaceAllOccurrences() {
|
||||
return isReplaceAllOccurrences();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public PsiType getSelectedType() {
|
||||
return GrInplaceVariableIntroducer.this.getSelectedType();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void saveSettings(@NotNull GrVariable variable) {
|
||||
GroovyApplicationSettings.getInstance().INTRODUCE_LOCAL_SELECT_DEF = variable.getDeclaredType() == null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected int getCaretOffset() {
|
||||
return getVariable().getNameIdentifierGroovy().getTextRange().getEndOffset();
|
||||
}
|
||||
}
|
||||
+6
-8
@@ -46,26 +46,26 @@ import java.util.List;
|
||||
/**
|
||||
* @author Max Medvedev
|
||||
*/
|
||||
public class GrIntroduceLocalVariableProcessor {
|
||||
public abstract class GrIntroduceLocalVariableProcessor {
|
||||
private static final Logger LOG = Logger.getInstance(GrIntroduceLocalVariableProcessor.class);
|
||||
|
||||
private final GrIntroduceContext myContext;
|
||||
private final GroovyIntroduceVariableSettings mySettings;
|
||||
private final boolean myProcessUsages;
|
||||
private final PsiElement[] myOccurrences;
|
||||
private GrExpression myExpression;
|
||||
private final GrIntroduceVariableHandler myHandler;
|
||||
|
||||
public GrIntroduceLocalVariableProcessor(@NotNull GrIntroduceContext context,
|
||||
@NotNull GroovyIntroduceVariableSettings settings,
|
||||
@NotNull PsiElement[] occurrences,
|
||||
@NotNull GrExpression expression,
|
||||
@NotNull GrIntroduceVariableHandler handler) {
|
||||
boolean processUsages) {
|
||||
|
||||
myContext = context;
|
||||
mySettings = settings;
|
||||
myProcessUsages = processUsages;
|
||||
myOccurrences = settings.replaceAllOccurrences() ? occurrences : new PsiElement[]{expression};
|
||||
myExpression = expression;
|
||||
myHandler = handler;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@@ -75,7 +75,7 @@ public class GrIntroduceLocalVariableProcessor {
|
||||
preprocessOccurrences();
|
||||
|
||||
int expressionIndex = ArrayUtilRt.find(myOccurrences, myExpression);
|
||||
final PsiElement[] replaced = processOccurrences();
|
||||
final PsiElement[] replaced = myProcessUsages ? processOccurrences() : myOccurrences;
|
||||
PsiElement replacedExpression = replaced[expressionIndex];
|
||||
GrStatement anchor = getAnchor(replaced);
|
||||
|
||||
@@ -84,9 +84,7 @@ public class GrIntroduceLocalVariableProcessor {
|
||||
return insertVariableDefinition(declaration, anchor, replacedExpression);
|
||||
}
|
||||
|
||||
private void refreshPositionMarker(PsiElement e) {
|
||||
myHandler.refreshPositionMarker(myContext.getEditor().getDocument().createRangeMarker(e.getTextRange()));
|
||||
}
|
||||
protected abstract void refreshPositionMarker(PsiElement e);
|
||||
|
||||
private static boolean isControlStatementBranch(GrStatement statement) {
|
||||
return statement.getParent() instanceof GrLoopStatement && statement == ((GrLoopStatement)statement.getParent()).getBody() ||
|
||||
|
||||
+19
-84
@@ -13,24 +13,16 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.plugins.groovy.refactoring.introduce.variable;
|
||||
|
||||
import com.intellij.openapi.actionSystem.Shortcut;
|
||||
import com.intellij.openapi.editor.Editor;
|
||||
import com.intellij.openapi.editor.RangeMarker;
|
||||
import com.intellij.openapi.keymap.Keymap;
|
||||
import com.intellij.openapi.keymap.KeymapManager;
|
||||
import com.intellij.openapi.keymap.KeymapUtil;
|
||||
import com.intellij.openapi.util.Pass;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.PsiModifier;
|
||||
import com.intellij.psi.PsiType;
|
||||
import com.intellij.refactoring.HelpID;
|
||||
import com.intellij.refactoring.introduce.inplace.OccurrencesChooser;
|
||||
import com.intellij.refactoring.util.CanonicalTypes;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.plugins.groovy.codeInspection.utils.ControlFlowUtils;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.GrControlFlowOwner;
|
||||
import org.jetbrains.plugins.groovy.lang.psi.GroovyFileBase;
|
||||
@@ -48,10 +40,8 @@ import org.jetbrains.plugins.groovy.refactoring.introduce.GrIntroduceContext;
|
||||
import org.jetbrains.plugins.groovy.refactoring.introduce.GrIntroduceHandlerBase;
|
||||
import org.jetbrains.plugins.groovy.refactoring.introduce.StringPartInfo;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author ilyas
|
||||
* Created by Max Medvedev on 10/29/13
|
||||
*/
|
||||
public class GrIntroduceVariableHandler extends GrIntroduceHandlerBase<GroovyIntroduceVariableSettings, GrControlFlowOwner> {
|
||||
public static final String DUMMY_NAME = "________________xxx_________________";
|
||||
@@ -129,8 +119,7 @@ public class GrIntroduceVariableHandler extends GrIntroduceHandlerBase<GroovyInt
|
||||
public GrVariable runRefactoring(@NotNull final GrIntroduceContext context, @NotNull final GroovyIntroduceVariableSettings settings) {
|
||||
// Generating variable declaration
|
||||
|
||||
final GrVariableDeclaration varDecl = generateDeclaration(context, settings);
|
||||
GrVariable insertedVar = processExpression(context, settings, varDecl);
|
||||
GrVariable insertedVar = processExpression(context, settings, true);
|
||||
|
||||
if (context.getEditor() != null && getPositionMarker() != null) {
|
||||
context.getEditor().getCaretModel().moveToOffset(getPositionMarker().getEndOffset());
|
||||
@@ -140,72 +129,11 @@ public class GrIntroduceVariableHandler extends GrIntroduceHandlerBase<GroovyInt
|
||||
}
|
||||
|
||||
@Override
|
||||
protected GrInplaceVariableIntroducer getIntroducer(@NotNull GrVariable var,
|
||||
@NotNull GrIntroduceContext context,
|
||||
@NotNull GroovyIntroduceVariableSettings settings,
|
||||
@NotNull List<RangeMarker> occurrenceMarkers,
|
||||
RangeMarker varRangeMarker, RangeMarker expressionRangeMarker,
|
||||
RangeMarker stringPartRangeMarker) {
|
||||
context.getEditor().getCaretModel().moveToOffset(var.getTextOffset());
|
||||
GrInplaceVariableIntroducer introducer = new GrInplaceVariableIntroducer(var, context.getEditor(), context.getProject(), REFACTORING_NAME, occurrenceMarkers, var);
|
||||
introducer.setAdvertisementText(getAdvertisementText(var.getDeclaredType() != null));
|
||||
|
||||
return introducer;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static String getAdvertisementText(final boolean hasTypeSuggestion) {
|
||||
final Keymap keymap = KeymapManager.getInstance().getActiveKeymap();
|
||||
if (hasTypeSuggestion) {
|
||||
final Shortcut[] shortcuts = keymap.getShortcuts("PreviousTemplateVariable");
|
||||
if (shortcuts.length > 0) {
|
||||
return "Press " + KeymapUtil.getShortcutText(shortcuts[0]) + " to change type";
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected GroovyIntroduceVariableSettings getSettingsForInplace(final GrIntroduceContext context, final OccurrencesChooser.ReplaceChoice choice) {
|
||||
return new GroovyIntroduceVariableSettings() {
|
||||
private final CanonicalTypes.Type myType;
|
||||
private final String myName;
|
||||
|
||||
|
||||
{
|
||||
GrExpression expression = context.getExpression();
|
||||
StringPartInfo stringPart = context.getStringPart();
|
||||
GrVariable var = context.getVar();
|
||||
PsiType type = expression != null ? expression.getType() :
|
||||
var != null ? var.getType() :
|
||||
stringPart != null ? stringPart.getLiteral().getType() :
|
||||
null;
|
||||
myType = type != null ?CanonicalTypes.createTypeWrapper(type) : null;
|
||||
|
||||
myName = new GrVariableNameSuggester(context, new GroovyVariableValidator(context)).suggestNames().iterator().next();
|
||||
}
|
||||
|
||||
|
||||
protected GrInplaceVariableIntroducer getIntroducer(@NotNull GrIntroduceContext context, OccurrencesChooser.ReplaceChoice choice) {
|
||||
return new GrInplaceVariableIntroducer(getRefactoringName(), choice, context) {
|
||||
@Override
|
||||
public boolean isDeclareFinal() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public String getName() {
|
||||
return myName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean replaceAllOccurrences() {
|
||||
return choice == OccurrencesChooser.ReplaceChoice.ALL;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public PsiType getSelectedType() {
|
||||
return myType != null ? myType.getType(context.getPlace(), context.getPlace().getManager()) : null;
|
||||
protected GrVariable runRefactoring(GrIntroduceContext context, GroovyIntroduceVariableSettings settings, boolean processUsages) {
|
||||
return processExpression(context, settings, processUsages);
|
||||
}
|
||||
};
|
||||
}
|
||||
@@ -231,24 +159,31 @@ public class GrIntroduceVariableHandler extends GrIntroduceHandlerBase<GroovyInt
|
||||
@NotNull
|
||||
private GrVariable processExpression(@NotNull GrIntroduceContext context,
|
||||
@NotNull GroovyIntroduceVariableSettings settings,
|
||||
@NotNull GrVariableDeclaration varDecl) {
|
||||
boolean processUsages) {
|
||||
GrVariableDeclaration varDecl = generateDeclaration(context, settings);
|
||||
|
||||
if (context.getStringPart() != null) {
|
||||
final GrExpression ref = processLiteral(DUMMY_NAME, context.getStringPart(), context.getProject());
|
||||
return doProcessExpression(context, settings, varDecl, new PsiElement[]{ref}, ref);
|
||||
return doProcessExpression(context, settings, varDecl, new PsiElement[]{ref}, ref, processUsages);
|
||||
}
|
||||
else {
|
||||
final GrExpression expression = context.getExpression();
|
||||
assert expression != null;
|
||||
return doProcessExpression(context, settings, varDecl, context.getOccurrences(), expression);
|
||||
return doProcessExpression(context, settings, varDecl, context.getOccurrences(), expression, processUsages);
|
||||
}
|
||||
}
|
||||
|
||||
private GrVariable doProcessExpression(@NotNull GrIntroduceContext context,
|
||||
private GrVariable doProcessExpression(@NotNull final GrIntroduceContext context,
|
||||
@NotNull GroovyIntroduceVariableSettings settings,
|
||||
@NotNull GrVariableDeclaration varDecl,
|
||||
@NotNull PsiElement[] elements,
|
||||
@NotNull GrExpression expression) {
|
||||
return new GrIntroduceLocalVariableProcessor(context, settings, elements, expression, this).processExpression(varDecl);
|
||||
@NotNull GrExpression expression, boolean processUsages) {
|
||||
return new GrIntroduceLocalVariableProcessor(context, settings, elements, expression, processUsages) {
|
||||
@Override
|
||||
protected void refreshPositionMarker(PsiElement e) {
|
||||
GrIntroduceVariableHandler.this.refreshPositionMarker(context.getEditor().getDocument().createRangeMarker(e.getTextRange()));
|
||||
}
|
||||
}.processExpression(varDecl);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
|
||||
@@ -22,6 +22,8 @@
|
||||
serviceImplementation="org.zmlx.hg4idea.HgRootsHandler" />
|
||||
<projectService serviceInterface="org.zmlx.hg4idea.HgRememberedInputs"
|
||||
serviceImplementation="org.zmlx.hg4idea.HgRememberedInputs"/>
|
||||
|
||||
<projectService serviceImplementation="org.zmlx.hg4idea.log.HgContentRevisionFactory"/>
|
||||
</extensions>
|
||||
|
||||
<project-components>
|
||||
|
||||
@@ -0,0 +1,58 @@
|
||||
/*
|
||||
* Copyright 2000-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.zmlx.hg4idea.log;
|
||||
|
||||
import com.intellij.openapi.components.ServiceManager;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.vcs.changes.ContentRevision;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.vcs.log.ContentRevisionFactory;
|
||||
import com.intellij.vcs.log.Hash;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.zmlx.hg4idea.HgContentRevision;
|
||||
import org.zmlx.hg4idea.HgFile;
|
||||
import org.zmlx.hg4idea.HgRevisionNumber;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public class HgContentRevisionFactory extends ContentRevisionFactory {
|
||||
|
||||
@NotNull private final Project myProject;
|
||||
|
||||
@SuppressWarnings("UnusedDeclaration")
|
||||
private HgContentRevisionFactory(@NotNull Project project) {
|
||||
myProject = project;
|
||||
}
|
||||
|
||||
public static HgContentRevisionFactory getInstance(Project project) {
|
||||
return ServiceManager.getService(project, HgContentRevisionFactory.class);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public ContentRevision createRevision(@NotNull VirtualFile file, @NotNull Hash hash) {
|
||||
return new HgContentRevision(myProject, new HgFile(myProject, file), HgRevisionNumber.getInstance("", hash.asString()));
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public ContentRevision createRevision(@NotNull VirtualFile root, @NotNull String path, @NotNull Hash hash) {
|
||||
return new HgContentRevision(myProject, new HgFile(root, new File(path)), HgRevisionNumber.getInstance("", hash.asString()));
|
||||
}
|
||||
}
|
||||
@@ -33,6 +33,7 @@ import org.zmlx.hg4idea.*;
|
||||
import org.zmlx.hg4idea.action.HgCommandResultNotifier;
|
||||
import org.zmlx.hg4idea.command.HgLogCommand;
|
||||
import org.zmlx.hg4idea.execution.HgCommandException;
|
||||
import org.zmlx.hg4idea.log.HgContentRevisionFactory;
|
||||
import org.zmlx.hg4idea.provider.HgCommittedChangeList;
|
||||
|
||||
import java.io.File;
|
||||
@@ -61,7 +62,7 @@ public class HgHistoryUtil {
|
||||
return ContainerUtil.mapNotNull(result, new Function<HgCommittedChangeList, VcsFullCommitDetails>() {
|
||||
@Override
|
||||
public VcsFullCommitDetails fun(HgCommittedChangeList record) {
|
||||
return createCommit(root, record);
|
||||
return createCommit(project, root, record);
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -169,7 +170,7 @@ public class HgHistoryUtil {
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static VcsFullCommitDetails createCommit(@NotNull VirtualFile root,
|
||||
private static VcsFullCommitDetails createCommit(@NotNull Project project, @NotNull VirtualFile root,
|
||||
@NotNull HgCommittedChangeList record) {
|
||||
|
||||
final VcsLogObjectsFactory factory = ServiceManager.getService(VcsLogObjectsFactory.class);
|
||||
@@ -185,7 +186,7 @@ public class HgHistoryUtil {
|
||||
revNumber.getSubject(),
|
||||
revNumber.getAuthor(), "", revNumber.getCommitMessage(), record.getCommitterName(),
|
||||
"", record.getCommitDate().getTime(),
|
||||
ContainerUtil.newArrayList(record.getChanges()));
|
||||
ContainerUtil.newArrayList(record.getChanges()), HgContentRevisionFactory.getInstance(project));
|
||||
}
|
||||
|
||||
@Nullable
|
||||
|
||||
@@ -224,10 +224,10 @@ SIMPLE_VALUE_RE = re.compile(
|
||||
|
||||
########################### parsing ###########################################################
|
||||
if version[0] < 3:
|
||||
from pyparsing import *
|
||||
from pycharm_generator_utils.pyparsing import *
|
||||
else:
|
||||
#noinspection PyUnresolvedReferences
|
||||
from pyparsing_py3 import *
|
||||
from pycharm_generator_utils.pyparsing_py3 import *
|
||||
|
||||
# grammar to parse parameter lists
|
||||
|
||||
|
||||
@@ -169,10 +169,12 @@ public class PyNames {
|
||||
"__all__",
|
||||
"__author__",
|
||||
"__bases__",
|
||||
"__defaults__",
|
||||
"__dict__",
|
||||
"__doc__",
|
||||
"__docformat__",
|
||||
"__file__",
|
||||
"__kwdefaults__",
|
||||
"__members__",
|
||||
"__metaclass__",
|
||||
"__mod__",
|
||||
@@ -304,6 +306,7 @@ public class PyNames {
|
||||
.put("__rdivmod__", _self_other_descr)
|
||||
.put("__reduce__", _only_self_descr)
|
||||
.put("__repr__", _only_self_descr)
|
||||
.put("__reversed__", _only_self_descr)
|
||||
.put("__rfloordiv__", _self_other_descr)
|
||||
.put("__rlshift__", _self_other_descr)
|
||||
.put("__rmod__", _self_other_descr)
|
||||
@@ -338,6 +341,9 @@ public class PyNames {
|
||||
public static ImmutableMap<String, BuiltinDescription> PY3_BUILTIN_METHODS = ImmutableMap.<String, BuiltinDescription>builder()
|
||||
.putAll(BuiltinMethods)
|
||||
.put("__bool__", _only_self_descr)
|
||||
.put("__bytes__", _only_self_descr)
|
||||
.put("__format__", new BuiltinDescription("(self, format_spec)"))
|
||||
.put("__round__", new BuiltinDescription("(self, n=None)"))
|
||||
.build();
|
||||
|
||||
public static ImmutableMap<String, BuiltinDescription> getBuiltinMethods(LanguageLevel level) {
|
||||
|
||||
@@ -17,15 +17,21 @@ package com.jetbrains.python.projectView;
|
||||
|
||||
import com.intellij.ide.projectView.SelectableTreeStructureProvider;
|
||||
import com.intellij.ide.projectView.ViewSettings;
|
||||
import com.intellij.ide.projectView.impl.nodes.NamedLibraryElementNode;
|
||||
import com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode;
|
||||
import com.intellij.ide.projectView.impl.nodes.PsiFileNode;
|
||||
import com.intellij.ide.util.treeView.AbstractTreeNode;
|
||||
import com.intellij.openapi.project.DumbAware;
|
||||
import com.intellij.openapi.roots.JdkOrderEntry;
|
||||
import com.intellij.openapi.roots.LibraryOrSdkOrderEntry;
|
||||
import com.intellij.psi.PsiDirectory;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.PsiFile;
|
||||
import com.intellij.psi.util.PsiTreeUtil;
|
||||
import com.jetbrains.python.psi.PyDocStringOwner;
|
||||
import com.jetbrains.python.psi.PyFile;
|
||||
import com.jetbrains.python.psi.PyFunction;
|
||||
import com.jetbrains.python.sdk.PythonSdkType;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
@@ -37,6 +43,9 @@ import java.util.List;
|
||||
public class PyTreeStructureProvider implements SelectableTreeStructureProvider, DumbAware {
|
||||
@Override
|
||||
public Collection<AbstractTreeNode> modify(AbstractTreeNode parent, Collection<AbstractTreeNode> children, ViewSettings settings) {
|
||||
if (parent instanceof NamedLibraryElementNode) {
|
||||
return hideSkeletons((NamedLibraryElementNode)parent, children);
|
||||
}
|
||||
if (settings.isShowMembers()) {
|
||||
List<AbstractTreeNode> newChildren = new ArrayList<AbstractTreeNode>();
|
||||
for (AbstractTreeNode child : children) {
|
||||
@@ -52,6 +61,25 @@ public class PyTreeStructureProvider implements SelectableTreeStructureProvider,
|
||||
return children;
|
||||
}
|
||||
|
||||
protected Collection<AbstractTreeNode> hideSkeletons(NamedLibraryElementNode parent, Collection<AbstractTreeNode> children) {
|
||||
LibraryOrSdkOrderEntry orderEntry = parent.getValue().getOrderEntry();
|
||||
if (orderEntry instanceof JdkOrderEntry) {
|
||||
List<AbstractTreeNode> newChildren = new ArrayList<AbstractTreeNode>();
|
||||
for (AbstractTreeNode child : children) {
|
||||
if (child instanceof PsiDirectoryNode) {
|
||||
PsiDirectory directory = ((PsiDirectoryNode)child).getValue();
|
||||
PsiDirectory dirParent = directory.getParent();
|
||||
if (dirParent != null && dirParent.getName().equals(PythonSdkType.SKELETON_DIR_NAME)) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
newChildren.add(child);
|
||||
}
|
||||
return newChildren;
|
||||
}
|
||||
return children;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getData(Collection<AbstractTreeNode> selected, String dataName) {
|
||||
return null;
|
||||
|
||||
@@ -17,9 +17,9 @@ package com.jetbrains.python.sdk.flavors;
|
||||
|
||||
import com.intellij.ide.DataManager;
|
||||
import com.intellij.openapi.actionSystem.CommonDataKeys;
|
||||
import com.intellij.openapi.actionSystem.PlatformDataKeys;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.SystemInfo;
|
||||
import com.intellij.openapi.util.io.FileUtil;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.openapi.vfs.LocalFileSystem;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
@@ -67,7 +67,7 @@ public class VirtualEnvSdkFlavor extends CPythonSdkFlavor {
|
||||
public static VirtualFile getDefaultLocation() {
|
||||
final String path = System.getenv().get("WORKON_HOME");
|
||||
if (!StringUtil.isEmpty(path)) {
|
||||
return LocalFileSystem.getInstance().findFileByPath(path.replace('\\','/'));
|
||||
return LocalFileSystem.getInstance().findFileByPath(FileUtil.expandUserHome(path).replace('\\','/'));
|
||||
}
|
||||
|
||||
final VirtualFile userHome = LocalFileSystem.getInstance().findFileByPath(SystemProperties.getUserHome().replace('\\','/'));
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
print(dict.fromkeys(<warning descr="Parameter 'seq' unfilled">)</warning>)
|
||||
print(dict.fromkeys(['foo', 'bar']))
|
||||
@@ -0,0 +1,5 @@
|
||||
print(unicode())
|
||||
print(unicode(''))
|
||||
print(unicode('', 'utf-8'))
|
||||
print(unicode('', 'utf-8', 'ignore'))
|
||||
print(unicode('', 'utf-8', 'ignore', <warning descr="Unexpected argument">foo</warning>))
|
||||
@@ -158,4 +158,14 @@ public class PyArgumentListInspectionTest extends PyTestCase {
|
||||
public void testPropertyReturnsCallable() {
|
||||
doTest();
|
||||
}
|
||||
|
||||
// PY-11162
|
||||
public void testUnicodeConstructor() {
|
||||
doTest();
|
||||
}
|
||||
|
||||
// PY-11169
|
||||
public void testDictFromKeys() {
|
||||
doTest();
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user