Merge remote-tracking branch 'origin/master'

This commit is contained in:
Dmitry Trofimov
2013-09-09 16:31:38 +02:00
45 changed files with 705 additions and 186 deletions
@@ -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.
@@ -26,7 +26,6 @@ import com.intellij.openapi.roots.ui.configuration.libraries.AddCustomLibraryDia
import com.intellij.openapi.roots.ui.configuration.libraries.CustomLibraryDescription;
import com.intellij.openapi.roots.ui.configuration.libraries.LibraryPresentationManager;
import com.intellij.openapi.util.Ref;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.util.Processor;
import javax.swing.*;
@@ -67,7 +66,7 @@ public class FrameworkLibraryValidatorImpl extends FrameworkLibraryValidator {
});
if (found.get()) return ValidationResult.OK;
return new ValidationResult(StringUtil.capitalize(myLibraryCategoryName) + " library not found in the module dependencies list", new LibrariesQuickFix(myLibraryDescription));
return new ValidationResult(IdeBundle.message("label.missed.libraries.text", myLibraryCategoryName), new LibrariesQuickFix(myLibraryDescription));
}
private class LibrariesQuickFix extends FacetConfigurationQuickFix {
@@ -27,6 +27,7 @@ import com.intellij.openapi.vcs.VcsKey;
import com.intellij.openapi.vfs.LocalFileSystem;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.projectImport.ProjectImportProvider;
import org.jetbrains.annotations.Nullable;
import java.io.File;
import java.util.Collections;
@@ -48,7 +49,7 @@ public class NewProjectCheckoutListener implements VcsAwareCheckoutListener {
final Project[] projects = pm.getOpenProjects();
final Set<VirtualFile> files = projectsLocationSet(projects);
VirtualFile file = LocalFileSystem.getInstance().findFileByIoFile(directory);
AddModuleWizard wizard = ImportModuleAction.createImportWizard(null, null, file, ProjectImportProvider.PROJECT_IMPORT_PROVIDER.getExtensions());
AddModuleWizard wizard = createImportWizard(file);
if (wizard == null) return false;
if (wizard.showAndGet()) {
ImportModuleAction.createFromWizard(null, wizard);
@@ -67,6 +68,11 @@ public class NewProjectCheckoutListener implements VcsAwareCheckoutListener {
return false;
}
@Nullable
protected AddModuleWizard createImportWizard(VirtualFile file) {
return ImportModuleAction.createImportWizard(null, null, file, ProjectImportProvider.PROJECT_IMPORT_PROVIDER.getExtensions());
}
private static Set<VirtualFile> projectsLocationSet(Project[] projects) {
final Set<VirtualFile> files = new HashSet<VirtualFile>();
for (Project project1 : projects) {
@@ -23,6 +23,7 @@ import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.pom.java.LanguageLevel;
import com.intellij.psi.*;
import com.intellij.psi.codeStyle.JavaCodeStyleManager;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.psi.util.PsiUtil;
import com.intellij.util.Function;
@@ -151,13 +152,14 @@ public class AnonymousCanBeLambdaInspection extends BaseJavaBatchLocalInspection
final PsiAnonymousClass anonymousClass = PsiTreeUtil.getParentOfType(element, PsiAnonymousClass.class);
LOG.assertTrue(anonymousClass != null);
ChangeContextUtil.encodeContextInfo(anonymousClass, true);
boolean validContext = LambdaUtil.isValidLambdaContext(anonymousClass.getParent().getParent());
final PsiElement lambdaContext = anonymousClass.getParent().getParent();
boolean validContext = LambdaUtil.isValidLambdaContext(lambdaContext);
final String canonicalText = anonymousClass.getBaseClassType().getCanonicalText();
final PsiMethod method = anonymousClass.getMethods()[0];
LOG.assertTrue(method != null);
final String lambdaWithTypesDeclared = composeLambdaText(method, true);
final String withoutTypesDeclared = composeLambdaText(method, false);
final String lambdaWithTypesDeclared = composeLambdaText(method, lambdaContext, true);
final String withoutTypesDeclared = composeLambdaText(method, lambdaContext, false);
final PsiElementFactory elementFactory = JavaPsiFacade.getElementFactory(project);
PsiLambdaExpression lambdaExpression =
(PsiLambdaExpression)elementFactory.createExpressionFromText(withoutTypesDeclared, anonymousClass);
@@ -229,32 +231,44 @@ public class AnonymousCanBeLambdaInspection extends BaseJavaBatchLocalInspection
interfaceType) != null;
}
private static String composeLambdaText(PsiMethod method, final boolean appendType) {
private static String composeLambdaText(PsiMethod method, final PsiElement lambdaContext, final boolean appendType) {
final StringBuilder buf = new StringBuilder();
if (appendType) {
buf.append(method.getParameterList().getText());
} else {
final PsiParameter[] parameters = method.getParameterList().getParameters();
if (parameters.length != 1) {
buf.append("(");
}
buf.append(StringUtil.join(parameters,
new Function<PsiParameter, String>() {
@Override
public String fun(PsiParameter parameter) {
String parameterName = parameter.getName();
if (parameterName == null) {
parameterName = "";
}
return parameterName;
}
}, ","));
if (parameters.length != 1) {
buf.append(")");
}
final PsiParameter[] parameters = method.getParameterList().getParameters();
if (parameters.length != 1 || appendType) {
buf.append("(");
}
final JavaCodeStyleManager codeStyleManager = JavaCodeStyleManager.getInstance(lambdaContext.getProject());
buf.append(StringUtil.join(parameters,
new Function<PsiParameter, String>() {
@Override
public String fun(PsiParameter parameter) {
return composeParameter(parameter, appendType, codeStyleManager, lambdaContext);
}
}, ","));
if (parameters.length != 1 || appendType) {
buf.append(")");
}
buf.append("-> {}");
return buf.toString();
}
private static String composeParameter(PsiParameter parameter,
boolean appendType,
JavaCodeStyleManager codeStyleManager,
PsiElement lambdaContext) {
final String parameterType;
if (appendType) {
final PsiTypeElement typeElement = parameter.getTypeElement();
parameterType = typeElement != null ? (typeElement.getText() + " ") : "";
}
else {
parameterType = "";
}
String parameterName = parameter.getName();
if (parameterName == null) {
parameterName = "";
}
return parameterType + codeStyleManager.suggestUniqueVariableName(parameterName, lambdaContext, true);
}
}
}
@@ -52,6 +52,7 @@ class ControlFlowAnalyzer extends JavaElementVisitor {
throw new UnsupportedOperationException("Not implemented");
}
};
public static final String ORG_JETBRAINS_ANNOTATIONS_CONTRACT = "org.jetbrains.annotations.Contract";
private boolean myIgnoreAssertions;
private static class CannotAnalyzeException extends RuntimeException { }
@@ -1421,18 +1422,17 @@ class ControlFlowAnalyzer extends JavaElementVisitor {
private static List<MethodContract> getCallContracts(PsiMethodCallExpression expression) {
PsiMethod resolved = expression.resolveMethod();
if (resolved != null) {
final PsiAnnotation contractAnno = AnnotationUtil.findAnnotation(resolved, "org.jetbrains.annotations.Contract");
final PsiAnnotation contractAnno = findContractAnnotation(resolved);
if (contractAnno != null) {
final Project project = expression.getProject();
return CachedValuesManager.getManager(project).getCachedValue(contractAnno, new CachedValueProvider<List<MethodContract>>() {
@Nullable
@Override
public Result<List<MethodContract>> compute() {
PsiAnnotationMemberValue value = contractAnno.findAttributeValue(null);
Object text = JavaPsiFacade.getInstance(project).getConstantEvaluationHelper().computeConstantExpression(value);
if (text instanceof String) {
String text = AnnotationUtil.getStringAttributeValue(contractAnno, null);
if (text != null) {
try {
return Result.create(parseContract((String)text), contractAnno);
return Result.create(parseContract(text), contractAnno);
}
catch (Exception ignored) {
}
@@ -1507,6 +1507,10 @@ class ControlFlowAnalyzer extends JavaElementVisitor {
return Collections.emptyList();
}
public static PsiAnnotation findContractAnnotation(PsiMethod method) {
return AnnotationUtil.findAnnotation(method, ORG_JETBRAINS_ANNOTATIONS_CONTRACT);
}
public static List<MethodContract> parseContract(String text) throws ParseException {
List<MethodContract> result = ContainerUtil.newArrayList();
for (String clause : StringUtil.replace(text, " ", "").split(";")) {
@@ -49,7 +49,6 @@ import com.intellij.util.IncorrectOperationException;
import com.intellij.util.SmartList;
import com.intellij.util.containers.MultiMap;
import org.jdom.Element;
import org.jetbrains.annotations.Contract;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -103,35 +102,43 @@ public class DataFlowInspectionBase extends BaseJavaBatchLocalInspectionTool {
@Override
public void visitAnnotation(PsiAnnotation annotation) {
if (!Contract.class.getName().equals(annotation.getQualifiedName())) return;
if (!ControlFlowAnalyzer.ORG_JETBRAINS_ANNOTATIONS_CONTRACT.equals(annotation.getQualifiedName())) return;
PsiMethod method = PsiTreeUtil.getParentOfType(annotation, PsiMethod.class);
if (method == null) return;
PsiAnnotationMemberValue value = annotation.findAttributeValue(null);
Object text = JavaPsiFacade.getInstance(annotation.getProject()).getConstantEvaluationHelper().computeConstantExpression(value);
if (!(text instanceof String)) return;
List<MethodContract> contracts;
try {
contracts = ControlFlowAnalyzer.parseContract((String)text);
}
catch (ControlFlowAnalyzer.ParseException e) {
holder.registerProblem(value, e.getMessage());
return;
}
int paramCount = method.getParameterList().getParametersCount();
for (int i = 0; i < contracts.size(); i++) {
MethodContract contract = contracts.get(i);
if (contract.arguments.length != paramCount) {
holder.registerProblem(value, "Method takes " + paramCount + " parameters, while contract clause " + i + " expects " + contract.arguments.length);
return;
}
String text = AnnotationUtil.getStringAttributeValue(annotation, null);
if (text == null) return;
String error = checkContract(method, text);
if (error != null) {
PsiAnnotationMemberValue value = annotation.findAttributeValue(null);
assert value != null;
holder.registerProblem(value, error);
}
}
};
}
@Nullable
public static String checkContract(PsiMethod method, String text) {
List<MethodContract> contracts;
try {
contracts = ControlFlowAnalyzer.parseContract(text);
}
catch (ControlFlowAnalyzer.ParseException e) {
return e.getMessage();
}
int paramCount = method.getParameterList().getParametersCount();
for (int i = 0; i < contracts.size(); i++) {
MethodContract contract = contracts.get(i);
if (contract.arguments.length != paramCount) {
return "Method takes " + paramCount + " parameters, while contract clause " + i + " expects " + contract.arguments.length;
}
}
return null;
}
private void analyzeCodeBlock(@Nullable final PsiElement scope, ProblemsHolder holder) {
if (scope == null) return;
@@ -0,0 +1,123 @@
/*
* 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.codeInspection.dataFlow;
import com.intellij.codeInsight.AnnotationUtil;
import com.intellij.codeInsight.ExternalAnnotationsManager;
import com.intellij.codeInsight.intention.AddAnnotationPsiFix;
import com.intellij.codeInsight.intention.impl.BaseIntentionAction;
import com.intellij.openapi.application.AccessToken;
import com.intellij.openapi.application.WriteAction;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.InputValidatorEx;
import com.intellij.openapi.ui.Messages;
import com.intellij.psi.*;
import com.intellij.psi.codeStyle.CodeStyleSettingsManager;
import com.intellij.psi.util.PsiUtil;
import com.intellij.util.IncorrectOperationException;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.generate.tostring.util.StringUtil;
/**
* @author peter
*/
public class EditContractIntention extends BaseIntentionAction {
@NotNull
@Override
public String getFamilyName() {
return "Edit method contract";
}
@Nullable
private static PsiMethod getTargetMethod(@NotNull Project project, Editor editor, PsiFile file) {
PsiElement element = file.findElementAt(editor.getCaretModel().getOffset());
if (element == null) return null;
if (!PsiUtil.isLanguageLevel5OrHigher(element)) return null;
if (!element.getManager().isInProject(element) || CodeStyleSettingsManager.getSettings(project).USE_EXTERNAL_ANNOTATIONS) {
final PsiModifierListOwner owner = AddAnnotationPsiFix.getContainer(element);
if (owner instanceof PsiMethod) {
return (PsiMethod)owner;
}
}
return null;
}
@Override
public boolean isAvailable(@NotNull Project project, Editor editor, PsiFile file) {
final PsiMethod method = getTargetMethod(project, editor, file);
if (method != null) {
boolean hasContract = ControlFlowAnalyzer.findContractAnnotation(method) != null;
setText(hasContract ? "Edit method contract" : "Add method contract");
return true;
}
return false;
}
@Override
public void invoke(@NotNull Project project, Editor editor, PsiFile file) throws IncorrectOperationException {
final PsiMethod method = getTargetMethod(project, editor, file);
assert method != null;
PsiAnnotation existingAnno = ControlFlowAnalyzer.findContractAnnotation(method);
String oldContract = existingAnno != null ? AnnotationUtil.getStringAttributeValue(existingAnno, null) : null;
String prompt =
"<html>Please specify the contract text<p>" +
"Example: <code>_, null -> false</code><br>" +
"<small>See intention action description for more details</small></html>";
String newContract = Messages.showInputDialog(project, prompt, "Edit Method Contract", null, oldContract, new InputValidatorEx() {
@Nullable
@Override
public String getErrorText(String inputString) {
if (StringUtil.isEmpty(inputString)) return null;
return DataFlowInspectionBase.checkContract(method, inputString);
}
@Override
public boolean checkInput(String inputString) {
return getErrorText(inputString) == null;
}
@Override
public boolean canClose(String inputString) {
return checkInput(inputString);
}
});
if (newContract == null) return;
AccessToken token = WriteAction.start();
try {
ExternalAnnotationsManager manager = ExternalAnnotationsManager.getInstance(project);
manager.deannotate(method, ControlFlowAnalyzer.ORG_JETBRAINS_ANNOTATIONS_CONTRACT);
if (StringUtil.isNotEmpty(newContract)) {
PsiAnnotation mockAnno = JavaPsiFacade.getElementFactory(project).createAnnotationFromText("@Foo(\"" + newContract + "\")", null);
manager.annotateExternally(method, ControlFlowAnalyzer.ORG_JETBRAINS_ANNOTATIONS_CONTRACT, file,
mockAnno.getParameterList().getAttributes());
}
}
finally {
token.finish();
}
}
@Override
public boolean startInWriteAction() {
return false;
}
}
@@ -236,7 +236,7 @@ public class PullUpHelper extends BaseRefactoringProcessor{
if (myIsTargetInterface || info.isToAbstract()) {
ChangeContextUtil.clearContextInfo(method);
if (!info.isToAbstract() && !method.hasModifierProperty(PsiModifier.ABSTRACT)) {
if (!info.isToAbstract() && !method.hasModifierProperty(PsiModifier.ABSTRACT) && PsiUtil.isLanguageLevel8OrHigher(myTargetSuperClass)) {
//pull as default
RefactoringUtil.makeMethodDefault(methodCopy);
isOriginalMethodAbstract = true;
@@ -432,4 +432,11 @@ public class AnnotationUtil {
public static boolean isInsideAnnotation(PsiElement element) {
return PsiTreeUtil.getParentOfType(element, PsiNameValuePair.class, PsiArrayInitializerMemberValue.class) != null;
}
@Nullable
public static String getStringAttributeValue(PsiAnnotation anno, @Nullable final String attributeName) {
PsiAnnotationMemberValue attrValue = anno.findAttributeValue(attributeName);
Object constValue = JavaPsiFacade.getInstance(anno.getProject()).getConstantEvaluationHelper().computeConstantExpression(attrValue);
return constValue instanceof String ? (String)constValue : null;
}
}
@@ -31,7 +31,7 @@ public class PsiMethodUtil {
@Override
public boolean value(final PsiClass psiClass) {
if (psiClass instanceof PsiAnonymousClass) return false;
if (psiClass.isInterface()) return false;
if (psiClass.isInterface() && !PsiUtil.isLanguageLevel8OrHigher(psiClass)) return false;
return psiClass.getContainingClass() == null || psiClass.hasModifierProperty(PsiModifier.STATIC);
}
};
@@ -0,0 +1,7 @@
// "Replace with lambda" "true"
class Test {
{
String o = "";
Comparable<String> c = o1 -> 0;
}
}
@@ -0,0 +1,12 @@
// "Replace with lambda" "true"
class Test {
{
String o = "";
Comparable<String> c = new Compa<caret>rable<String>() {
@Override
public int compareTo(String o) {
return 0;
}
};
}
}
@@ -34,7 +34,7 @@ public class JavaDebuggerLauncherImpl extends JavaDebuggerLauncher {
private static final Logger LOG = Logger.getInstance(JavaDebuggerLauncherImpl.class);
@Override
public void startDebugSession(@NotNull JavaDebugConnectionData info, @NotNull ExecutionEnvironment executionEnvironment, RemoteServer<?> server)
public void startDebugSession(@NotNull JavaDebugConnectionData info, @NotNull ExecutionEnvironment executionEnvironment, @NotNull RemoteServer<?> server)
throws ExecutionException {
final Project project = executionEnvironment.getProject();
Executor executor = DefaultDebugExecutor.getDebugExecutorInstance();
@@ -55,6 +55,7 @@ import com.intellij.openapi.fileTypes.FileTypes;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.*;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.util.text.StringUtilRt;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.PsiFile;
import com.intellij.psi.PsiManager;
@@ -85,6 +86,7 @@ import java.util.concurrent.atomic.AtomicBoolean;
/**
* @author Gregory.Shrago
* In case of REPL consider to use {@link com.intellij.execution.runners.LanguageConsoleBuilder}
*/
public class LanguageConsoleImpl implements Disposable, TypeSafeDataProvider {
private static final Logger LOG = Logger.getInstance("#" + LanguageConsoleImpl.class.getName());
@@ -380,10 +382,6 @@ public class LanguageConsoleImpl implements Disposable, TypeSafeDataProvider {
this.myTitle = title;
}
public void addToHistory(final String text, final TextAttributes attributes) {
printToHistory(text, attributes);
}
public void printToHistory(@NotNull final List<Pair<String, TextAttributes>> attributedText) {
ApplicationManager.getApplication().assertIsDispatchThread();
if (LOG.isDebugEnabled()) {
@@ -400,7 +398,7 @@ public class LanguageConsoleImpl implements Disposable, TypeSafeDataProvider {
}
final DocumentEx history = myHistoryViewer.getDocument();
final int oldHistoryLength = history.getTextLength();
appendToHistoryDocument(history, sb.toString());
appendToHistoryDocument(history, sb);
assert oldHistoryLength + offsets[i] >= history.getTextLength()
: "unexpected history length " + oldHistoryLength + " " + offsets[i] + " " + history.getTextLength();
@@ -435,9 +433,9 @@ public class LanguageConsoleImpl implements Disposable, TypeSafeDataProvider {
LOG.debug("printToHistory(): completed");
}
public void printToHistory(String text, final TextAttributes attributes) {
public void printToHistory(@NotNull CharSequence text, @NotNull TextAttributes attributes) {
ApplicationManager.getApplication().assertIsDispatchThread();
text = StringUtil.convertLineSeparators(text);
text = StringUtilRt.unifyLineSeparators(text);
final boolean scrollToEnd = shouldScrollHistoryToEnd();
addTextToHistory(text, attributes);
if (scrollToEnd) {
@@ -446,8 +444,11 @@ public class LanguageConsoleImpl implements Disposable, TypeSafeDataProvider {
queueUiUpdate(scrollToEnd);
}
protected void addTextToHistory(@Nullable String text, @Nullable TextAttributes attributes) {
if (text == null || text.length() == 0) return;
protected void addTextToHistory(@Nullable CharSequence text, @Nullable TextAttributes attributes) {
if (StringUtil.isEmpty(text)) {
return;
}
Document history = myHistoryViewer.getDocument();
MarkupModel markupModel = DocumentMarkupModel.forDocument(history, myProject, true);
int offset = history.getTextLength();
@@ -557,7 +558,7 @@ public class LanguageConsoleImpl implements Disposable, TypeSafeDataProvider {
addTextToHistory(myPrompt, ConsoleViewContentType.USER_INPUT.getAttributes());
}
protected void appendToHistoryDocument(@NotNull Document history, @NotNull String text) {
protected void appendToHistoryDocument(@NotNull Document history, @NotNull CharSequence text) {
ApplicationManager.getApplication().assertIsDispatchThread();
history.insertString(history.getTextLength(), text);
}
@@ -619,7 +620,6 @@ public class LanguageConsoleImpl implements Disposable, TypeSafeDataProvider {
public void calcData(DataKey key, DataSink sink) {
if (OpenFileDescriptor.NAVIGATE_IN_EDITOR == key) {
sink.put(OpenFileDescriptor.NAVIGATE_IN_EDITOR, myConsoleEditor);
return;
}
else if (getProject().isInitialized()) {
FileEditorManager editorManager = FileEditorManager.getInstance(getProject());
@@ -729,8 +729,23 @@ public class LanguageConsoleImpl implements Disposable, TypeSafeDataProvider {
}
}
public void printToHistoryOnEdt(@NotNull final CharSequence text, @NotNull final TextAttributes attributes) {
Application application = ApplicationManager.getApplication();
if (application.isDispatchThread()) {
printToHistory(text, attributes);
}
else {
application.invokeLater(new Runnable() {
@Override
public void run() {
printToHistory(text, attributes);
}
}, ModalityState.stateForComponent(getComponent()));
}
}
public static void printToConsole(@NotNull final LanguageConsoleImpl console,
@NotNull final String string,
@NotNull final CharSequence string,
@NotNull final ConsoleViewContentType mainType,
@Nullable ConsoleViewContentType additionalType) {
final TextAttributes mainAttributes = mainType.getAttributes();
@@ -743,18 +758,7 @@ public class LanguageConsoleImpl implements Disposable, TypeSafeDataProvider {
attributes.setBackgroundColor(mainAttributes.getBackgroundColor());
}
Application application = ApplicationManager.getApplication();
if (application.isDispatchThread()) {
console.printToHistory(string, attributes);
}
else {
application.invokeLater(new Runnable() {
@Override
public void run() {
console.printToHistory(string, attributes);
}
}, ModalityState.stateForComponent(console.getComponent()));
}
console.printToHistoryOnEdt(string, attributes);
}
private class MyLayout extends AbstractLayoutManager {
@@ -16,6 +16,7 @@
package com.intellij.execution.console;
import com.intellij.execution.ui.ConsoleView;
import com.intellij.openapi.project.Project;
import org.jetbrains.annotations.NotNull;
/**
@@ -24,4 +25,7 @@ import org.jetbrains.annotations.NotNull;
public interface LanguageConsoleView extends ConsoleView {
@NotNull
LanguageConsoleImpl getConsole();
@NotNull
Project getProject();
}
@@ -20,6 +20,7 @@ import com.intellij.lang.Language;
import com.intellij.openapi.editor.ex.EditorEx;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Disposer;
import com.intellij.psi.search.GlobalSearchScope;
import org.jetbrains.annotations.NotNull;
import javax.swing.*;
@@ -36,7 +37,12 @@ public class LanguageConsoleViewImpl extends ConsoleViewImpl implements Language
}
public LanguageConsoleViewImpl(@NotNull LanguageConsoleImpl console) {
super(console.getProject(), true);
this(console, true);
}
public LanguageConsoleViewImpl(@NotNull LanguageConsoleImpl console, boolean usePredefinedMessageFilter) {
super(console.getProject(), GlobalSearchScope.allScope(console.getProject()), true, null, usePredefinedMessageFilter);
myConsole = console;
Disposer.register(this, myConsole);
}
@@ -1885,6 +1885,7 @@ public class ConsoleViewImpl extends JPanel implements ConsoleView, ObservableCo
}
}
@NotNull
public Project getProject() {
return myProject;
}
@@ -47,7 +47,7 @@ import java.util.List;
* This class provides basic functionality for running consoles.
* It launches external process and handles line input with history
*/
public abstract class AbstractConsoleRunnerWithHistory<T extends LanguageConsoleView> extends ConsoleRunnerWithHistory<T> {
public abstract class AbstractConsoleRunnerWithHistory<T extends LanguageConsoleView> {
private final String myConsoleTitle;
private ProcessHandler myProcessHandler;
@@ -55,11 +55,12 @@ public abstract class AbstractConsoleRunnerWithHistory<T extends LanguageConsole
private T myConsoleView;
private final Project myProject;
private ConsoleExecuteActionHandler myConsoleExecuteActionHandler;
public AbstractConsoleRunnerWithHistory(@NotNull Project project, @NotNull String consoleTitle, @Nullable String workingDir) {
super(project);
myProject = project;
myConsoleTitle = consoleTitle;
myWorkingDir = workingDir;
}
@@ -245,30 +246,14 @@ public abstract class AbstractConsoleRunnerWithHistory<T extends LanguageConsole
public static AnAction createConsoleExecAction(final LanguageConsoleImpl languageConsole,
final ProcessHandler processHandler,
final ConsoleExecuteActionHandler consoleExecuteActionHandler) {
return new ProcessBackedConsoleExecuteAction(languageConsole, processHandler, consoleExecuteActionHandler);
return new ConsoleExecuteAction(languageConsole, consoleExecuteActionHandler, ConsoleExecuteAction.CONSOLE_EXECUTE_ACTION_ID,
new LanguageConsoleBuilder.ProcessBackedExecutionEnabledCondition(processHandler));
}
@NotNull
protected abstract ConsoleExecuteActionHandler createConsoleExecuteActionHandler();
private static class ProcessBackedConsoleExecuteAction extends ConsoleExecuteAction {
private final ProcessHandler myProcessHandler;
public ProcessBackedConsoleExecuteAction(LanguageConsoleImpl languageConsole,
ProcessHandler processHandler,
ConsoleExecuteActionHandler consoleExecuteActionHandler) {
super(languageConsole, consoleExecuteActionHandler);
myProcessHandler = processHandler;
}
@Override
protected boolean isEnabled() {
return !myProcessHandler.isProcessTerminated();
}
}
public T getConsoleView() {
return myConsoleView;
}
@@ -1,3 +1,18 @@
/*
* 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.execution.runners;
import com.intellij.execution.console.LanguageConsoleImpl;
@@ -1,3 +1,18 @@
/*
* 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.execution.runners;
import com.intellij.codeInsight.lookup.Lookup;
@@ -8,24 +23,28 @@ import com.intellij.openapi.actionSystem.AnActionEvent;
import com.intellij.openapi.actionSystem.EmptyAction;
import com.intellij.openapi.editor.ex.EditorEx;
import com.intellij.openapi.project.DumbAwareAction;
import com.intellij.openapi.util.Condition;
import com.intellij.openapi.util.Conditions;
import org.jetbrains.annotations.NotNull;
public class ConsoleExecuteAction extends DumbAwareAction {
public static final String CONSOLE_EXECUTE_ACTION_ID = "Console.Execute";
static final String CONSOLE_EXECUTE_ACTION_ID = "Console.Execute";
private final LanguageConsoleImpl myConsole;
private final BaseConsoleExecuteActionHandler myExecuteActionHandler;
private final Condition<LanguageConsoleImpl> myEnabledCondition;
public ConsoleExecuteAction(@NotNull LanguageConsoleImpl console, @NotNull BaseConsoleExecuteActionHandler executeActionHandler) {
this(console, executeActionHandler, CONSOLE_EXECUTE_ACTION_ID);
this(console, executeActionHandler, CONSOLE_EXECUTE_ACTION_ID, Conditions.<LanguageConsoleImpl>alwaysTrue());
}
public ConsoleExecuteAction(@NotNull LanguageConsoleImpl console, @NotNull BaseConsoleExecuteActionHandler executeActionHandler,
@NotNull String emptyExecuteActionId) {
@NotNull String emptyExecuteActionId, @NotNull Condition<LanguageConsoleImpl> enabledCondition) {
super(null, null, AllIcons.Actions.Execute);
myConsole = console;
myExecuteActionHandler = executeActionHandler;
myEnabledCondition = enabledCondition;
EmptyAction.setupAction(this, emptyExecuteActionId, null);
}
@@ -35,7 +54,7 @@ public class ConsoleExecuteAction extends DumbAwareAction {
EditorEx editor = myConsole.getConsoleEditor();
Lookup lookup = LookupManager.getActiveLookup(editor);
e.getPresentation().setEnabled(!editor.isRendererMode() && isEnabled() &&
(lookup == null || !(lookup.isCompletion() && lookup.isFocused())));
(lookup == null || !lookup.isCompletion()));
}
@Override
@@ -44,6 +63,6 @@ public class ConsoleExecuteAction extends DumbAwareAction {
}
protected boolean isEnabled() {
return true;
return myEnabledCondition.value(myConsole);
}
}
@@ -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.
@@ -1,13 +0,0 @@
package com.intellij.execution.runners;
import com.intellij.execution.console.LanguageConsoleView;
import com.intellij.openapi.project.Project;
import org.jetbrains.annotations.NotNull;
public abstract class ConsoleRunnerWithHistory<T extends LanguageConsoleView> {
protected final Project myProject;
public ConsoleRunnerWithHistory(@NotNull Project project) {
myProject = project;
}
}
@@ -0,0 +1,50 @@
package com.intellij.execution.runners;
import com.intellij.execution.console.ConsoleHistoryController;
import com.intellij.execution.console.LanguageConsoleImpl;
import com.intellij.execution.console.LanguageConsoleView;
import com.intellij.execution.process.ProcessHandler;
import com.intellij.openapi.util.Condition;
import com.intellij.openapi.util.Conditions;
import org.jetbrains.annotations.NotNull;
public class LanguageConsoleBuilder {
private LanguageConsoleImpl myConsole;
private Condition<LanguageConsoleImpl> myExecutionEnabled = Conditions.alwaysTrue();
public LanguageConsoleBuilder console(@NotNull LanguageConsoleView console) {
myConsole = console.getConsole();
return this;
}
public LanguageConsoleBuilder processHandler(@NotNull ProcessHandler processHandler) {
myExecutionEnabled = new ProcessBackedExecutionEnabledCondition(processHandler);
return this;
}
public LanguageConsoleBuilder executionEnabled(@NotNull Condition<LanguageConsoleImpl> condition) {
myExecutionEnabled = condition;
return this;
}
public LanguageConsoleBuilder initActions(@NotNull BaseConsoleExecuteActionHandler executeActionHandler, @NotNull String historyType) {
ConsoleExecuteAction action = new ConsoleExecuteAction(myConsole, executeActionHandler, ConsoleExecuteAction.CONSOLE_EXECUTE_ACTION_ID, myExecutionEnabled);
action.registerCustomShortcutSet(action.getShortcutSet(), myConsole.getConsoleEditor().getComponent());
new ConsoleHistoryController(historyType, "", myConsole, executeActionHandler.getConsoleHistoryModel()).install();
return this;
}
static class ProcessBackedExecutionEnabledCondition implements Condition<LanguageConsoleImpl> {
private ProcessHandler myProcessHandler;
public ProcessBackedExecutionEnabledCondition(ProcessHandler myProcessHandler) {
this.myProcessHandler = myProcessHandler;
}
@Override
public boolean value(LanguageConsoleImpl console) {
return !myProcessHandler.isProcessTerminated();
}
}
}
@@ -295,7 +295,7 @@ license.panel.buildit.evaluation.expires.in.one=1 day left
license.panel.buildit.evaluation.expires.in.many={0} days left
license.panel.discover.license.server.error.message=Unable to discover license server url
license.panel.ping.license.server.error.message=No response from autodetected license server {0}
license.panel.ping.license.server.error.title=No response from server
license.panel.ping.license.server.error.title=No response from server
license.panel.default.server.discover=Discover
editbox.license.user.name=User name:
editbox.license.license.key=License key:
@@ -982,7 +982,7 @@ error.file.download.failed=Downloading failed: {0}
maven.repository.presentable.name=Maven repository
label.missed.libraries.prefix=The following libraries are missing:
label.missed.libraries.text={0}.<br>Class ''{1}'' not found
label.missed.libraries.text=''{0}'' library not found in the module dependencies list
missing.libraries.fix.button=Fix...
setup.library.dialog.title=Setup Library
label.library.will.be.created.description.text={0} level library <b>{1}</b> with {2} {2, choice, 1#file|2#files} will be created
@@ -13,6 +13,7 @@ public enum DeploymentStatus {
myPresentableText = presentableText;
}
@NotNull
public String getPresentableText() {
return myPresentableText;
}
@@ -9,5 +9,5 @@ import org.jetbrains.annotations.NotNull;
* @author nik
*/
public interface DebuggerLauncher<D extends DebugConnectionData> {
void startDebugSession(@NotNull D info, @NotNull ExecutionEnvironment executionEnvironment, RemoteServer<?> server) throws ExecutionException;
void startDebugSession(@NotNull D info, @NotNull ExecutionEnvironment executionEnvironment, @NotNull RemoteServer<?> server) throws ExecutionException;
}
@@ -1,11 +1,13 @@
package com.intellij.remoteServer.runtime.deployment.debug;
import com.intellij.openapi.components.ServiceManager;
import org.jetbrains.annotations.NotNull;
/**
* @author nik
*/
public abstract class JavaDebuggerLauncher implements DebuggerLauncher<JavaDebugConnectionData> {
@NotNull
public static JavaDebuggerLauncher getInstance() {
return ServiceManager.getService(JavaDebuggerLauncher.class);
}
@@ -101,6 +101,19 @@ public class StringUtilRt {
@NotNull String newSeparator,
@Nullable int[] offsetsToKeep,
boolean keepCarriageReturn) {
return unifyLineSeparators(text, newSeparator, offsetsToKeep, keepCarriageReturn).toString();
}
@NotNull
public static CharSequence unifyLineSeparators(@NotNull CharSequence text) {
return unifyLineSeparators(text, "\n", null, false);
}
@NotNull
public static CharSequence unifyLineSeparators(@NotNull CharSequence text,
@NotNull String newSeparator,
@Nullable int[] offsetsToKeep,
boolean keepCarriageReturn) {
StringBuilder buffer = null;
int intactLength = 0;
final boolean newSeparatorIsSlashN = "\n".equals(newSeparator);
@@ -156,7 +169,7 @@ public class StringUtilRt {
}
}
}
return buffer == null ? text : buffer.toString();
return buffer == null ? text : buffer;
}
private static void shiftOffsets(int[] offsets, int changeOffset, int oldLength, int newLength) {
@@ -19,12 +19,13 @@ package com.intellij.xdebugger;
import com.intellij.execution.filters.TextConsoleBuilderFactory;
import com.intellij.execution.process.ProcessHandler;
import com.intellij.execution.ui.ExecutionConsole;
import com.intellij.execution.ui.RunnerLayoutUi;
import com.intellij.openapi.actionSystem.DefaultActionGroup;
import com.intellij.xdebugger.breakpoints.XBreakpointHandler;
import com.intellij.xdebugger.evaluation.XDebuggerEditorsProvider;
import com.intellij.xdebugger.frame.XValueMarkerProvider;
import com.intellij.xdebugger.stepping.XSmartStepIntoHandler;
import com.intellij.xdebugger.ui.XDebugLayouter;
import com.intellij.xdebugger.ui.XDebugTabLayouter;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -171,6 +172,13 @@ public abstract class XDebugProcess {
return null;
}
/**
* @deprecated override {@link #createTabLayouter()} and {@link com.intellij.xdebugger.ui.XDebugTabLayouter#registerAdditionalContent} instead
*/
@Deprecated
public void registerAdditionalContent(@NotNull RunnerLayoutUi ui) {
}
/**
* Override this method to provide additional actions in 'Debug' tool window
*/
@@ -189,9 +197,17 @@ public abstract class XDebugProcess {
return null;
}
/**
* Override this method to customize content of tab in 'Debug' tool window
*/
@NotNull
public XDebugLayouter createLayouter() {
return new XDebugLayouter();
public XDebugTabLayouter createTabLayouter() {
return new XDebugTabLayouter() {
@Override
public void registerAdditionalContent(@NotNull RunnerLayoutUi ui) {
XDebugProcess.this.registerAdditionalContent(ui);
}
};
}
/**
@@ -201,4 +217,5 @@ public abstract class XDebugProcess {
public boolean isValuesCustomSorted() {
return false;
}
}
}
@@ -60,6 +60,16 @@ public abstract class XValue extends XValueContainer {
navigatable.setSourcePosition(null);
}
/**
* Return {@code true} from this method and override {@link #computeSourcePosition(XNavigatable)} if navigation to the source
* is supported for the value
* @return {@code true} if navigation to the value's source is supported
*/
public boolean canNavigateToSource() {
// should be false, but cannot be due to compatibility reasons
return true;
}
/**
* Return {@code true} from this method and override {@link #computeTypeSourcePosition(XNavigatable)} if navigation to the value's type
* is supported for the value
@@ -13,8 +13,9 @@ import org.jetbrains.annotations.NotNull;
* Allows to customize xdebug layout for 'Debug' tool window.
*
* @author Sergey Simonchik
* @see com.intellij.xdebugger.XDebugProcess#createTabLayouter()
*/
public class XDebugLayouter {
public class XDebugTabLayouter {
/**
* Registers tab for the given {@code console}.
@@ -46,7 +46,7 @@ import com.intellij.xdebugger.impl.frame.XFramesView;
import com.intellij.xdebugger.impl.frame.XVariablesView;
import com.intellij.xdebugger.impl.frame.XWatchesView;
import com.intellij.xdebugger.impl.ui.tree.actions.SortValuesToggleAction;
import com.intellij.xdebugger.ui.XDebugLayouter;
import com.intellij.xdebugger.ui.XDebugTabLayouter;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -127,7 +127,7 @@ public class XDebugSessionTab extends DebuggerSessionTabBase {
myUi.addContent(createFramesContent(session), 0, PlaceInGrid.left, false);
myUi.addContent(createVariablesContent(session), 0, PlaceInGrid.center, false);
myUi.addContent(createWatchesContent(session, sessionData), 0, PlaceInGrid.right, false);
XDebugLayouter layouter = debugProcess.createLayouter();
XDebugTabLayouter layouter = debugProcess.createTabLayouter();
Content consoleContent = layouter.registerConsoleContent(myUi, myConsole);
attachNotificationTo(consoleContent);
@@ -17,6 +17,7 @@ package com.intellij.xdebugger.impl.ui.tree.actions;
import com.intellij.xdebugger.frame.XNavigatable;
import com.intellij.xdebugger.frame.XValue;
import com.intellij.xdebugger.impl.ui.tree.nodes.XValueNodeImpl;
/**
* @author nik
@@ -26,4 +27,9 @@ public class XJumpToSourceAction extends XJumpToSourceActionBase {
protected void startComputingSourcePosition(XValue value, XNavigatable navigatable) {
value.computeSourcePosition(navigatable);
}
@Override
protected boolean isEnabled(XValueNodeImpl node) {
return super.isEnabled(node) && node.getValueContainer().canNavigateToSource();
}
}
@@ -16,6 +16,7 @@
package com.siyeh.ipp.braces;
import com.intellij.psi.*;
import com.intellij.psi.util.TypeConversionUtil;
import com.intellij.util.IncorrectOperationException;
import com.siyeh.IntentionPowerPackBundle;
import com.siyeh.ipp.base.MutablyNamedIntention;
@@ -35,39 +36,18 @@ public class AddArrayCreationExpressionIntention extends MutablyNamedIntention {
protected String getTextForElement(PsiElement element) {
final PsiArrayInitializerExpression arrayInitializerExpression = (PsiArrayInitializerExpression)element;
final PsiType type = arrayInitializerExpression.getType();
final StringBuilder typeText = buildTypeText(type, new StringBuilder());
return IntentionPowerPackBundle.message("add.array.creation.expression.intention.name", typeText.toString());
return IntentionPowerPackBundle.message("add.array.creation.expression.intention.name",
TypeConversionUtil.erasure(type).getCanonicalText());
}
@Override
protected void processIntention(@NotNull PsiElement element)
throws IncorrectOperationException {
final PsiArrayInitializerExpression arrayInitializerExpression =
(PsiArrayInitializerExpression)element;
protected void processIntention(@NotNull PsiElement element) throws IncorrectOperationException {
final PsiArrayInitializerExpression arrayInitializerExpression = (PsiArrayInitializerExpression)element;
final PsiType type = arrayInitializerExpression.getType();
if (type == null) {
return;
}
@NonNls final StringBuilder text = new StringBuilder();
text.append("new ");
buildTypeText(type, text);
text.append(arrayInitializerExpression.getText());
replaceExpression(text.toString(), arrayInitializerExpression);
}
private static StringBuilder buildTypeText(PsiType type, StringBuilder typeText) {
if (type instanceof PsiArrayType) {
final PsiArrayType arrayType = (PsiArrayType)type;
buildTypeText(arrayType.getComponentType(), typeText);
typeText.append("[]");
}
else if (type instanceof PsiClassType) {
final PsiClassType classType = (PsiClassType)type;
typeText.append(classType.getClassName()); // no parameters -> no generic array creation
}
else {
typeText.append(type.getCanonicalText());
}
return typeText;
replaceExpression("new " + TypeConversionUtil.erasure(type).getCanonicalText() + arrayInitializerExpression.getText(),
arrayInitializerExpression);
}
}
@@ -1,5 +1,5 @@
/*
* Copyright 2011 Bas Leijdekkers
* Copyright 2011-2013 Bas Leijdekkers
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -15,9 +15,7 @@
*/
package com.siyeh.ipp.braces;
import com.intellij.psi.PsiArrayInitializerExpression;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiNewExpression;
import com.intellij.psi.*;
import com.siyeh.ipp.base.PsiElementPredicate;
import org.jetbrains.annotations.NotNull;
@@ -27,9 +25,9 @@ class ArrayCreationExpressionPredicate implements PsiElementPredicate {
if (!(element instanceof PsiArrayInitializerExpression)) {
return false;
}
final PsiArrayInitializerExpression arrayInitializerExpression =
(PsiArrayInitializerExpression)element;
if (arrayInitializerExpression.getType() == null) {
final PsiArrayInitializerExpression arrayInitializerExpression = (PsiArrayInitializerExpression)element;
final PsiType type = arrayInitializerExpression.getType();
if (type == null || !(type instanceof PsiArrayType)) {
return false;
}
final PsiElement parent = element.getParent();
@@ -0,0 +1,7 @@
package com.siyeh.ipp.braces.array_creation;
import java.util.Map;
class NotAnArray {{
Map<String, String> m = <caret>{};
}}
@@ -15,9 +15,14 @@
*/
package com.siyeh.ipp;
import com.intellij.codeInsight.intention.IntentionAction;
import com.intellij.codeInsight.intention.impl.config.IntentionActionWrapper;
import com.intellij.openapi.application.PluginPathManager;
import com.intellij.testFramework.fixtures.CodeInsightTestUtil;
import com.intellij.testFramework.fixtures.LightCodeInsightFixtureTestCase;
import com.intellij.util.SmartList;
import java.util.List;
public abstract class IPPTestCase extends LightCodeInsightFixtureTestCase {
@Override
@@ -47,5 +52,22 @@ public abstract class IPPTestCase extends LightCodeInsightFixtureTestCase {
myFixture.filterAvailableIntentions(intentionName));
}
protected void assertIntentionNotAvailable(Class<? extends IntentionAction> intentionClass) {
myFixture.configureByFile(getTestName(false) + ".java");
final List<IntentionAction> result = new SmartList<IntentionAction>();
for (final IntentionAction intention : myFixture.getAvailableIntentions()) {
if (intentionClass.isInstance(intention)) {
result.add(intention);
}
else if (intention instanceof IntentionActionWrapper) {
final IntentionActionWrapper wrapper = (IntentionActionWrapper)intention;
if (intentionClass.isInstance(wrapper.getDelegate())) {
result.add(intention);
}
}
}
assertEmpty("Intention of class \'" + intentionClass + "\' is available but should not", result);
}
protected abstract String getIntentionName();
}
@@ -23,10 +23,11 @@ import com.siyeh.ipp.IPPTestCase;
*/
public class AddArrayCreationExpressionIntentionTest extends IPPTestCase {
public void testGeneric() { doTest(); }
public void testNotAnArray() { assertIntentionNotAvailable(AddArrayCreationExpressionIntention.class); }
@Override
protected String getIntentionName() {
return IntentionPowerPackBundle.message("add.array.creation.expression.intention.name", "Map[][]");
return IntentionPowerPackBundle.message("add.array.creation.expression.intention.name", "java.util.Map[][]");
}
@Override
@@ -6,15 +6,23 @@ import com.intellij.codeInsight.lookup.LookupElement;
import com.intellij.codeInsight.lookup.LookupElementBuilder;
import com.intellij.icons.AllIcons;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Ref;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFile;
import com.intellij.psi.impl.PsiImplUtil;
import com.intellij.psi.xml.XmlFile;
import com.intellij.psi.xml.XmlTag;
import com.intellij.psi.xml.XmlText;
import com.intellij.psi.xml.XmlTokenType;
import com.intellij.util.Processor;
import com.intellij.util.xml.DomElement;
import com.intellij.util.xml.DomFileElement;
import com.intellij.util.xml.DomManager;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.idea.maven.dom.MavenDomProjectProcessorUtils;
import org.jetbrains.idea.maven.dom.model.MavenDomDependency;
import org.jetbrains.idea.maven.dom.model.MavenDomProjectModel;
import org.jetbrains.idea.maven.indices.MavenProjectIndicesManager;
/**
@@ -59,6 +67,29 @@ public class MavenDependenciesCompletionProvider extends CompletionContributor {
}
}
private static MavenDomDependency findManagedDependency(MavenDomProjectModel domModel, Project project,
@NotNull final String groupId, @NotNull final String artifactId) {
final Ref<MavenDomDependency> ref = new Ref<MavenDomDependency>();
MavenDomProjectProcessorUtils.processDependenciesInDependencyManagement(domModel,
new Processor<MavenDomDependency>() {
@Override
public boolean process(MavenDomDependency dependency) {
if (groupId.equals(dependency.getGroupId().getStringValue())
&&
artifactId.equals(
dependency.getArtifactId().getStringValue())) {
ref.set(dependency);
return false;
}
return true;
}
}, project);
return ref.get();
}
private static class MavenDependencyInsertHandler implements InsertHandler<LookupElement> {
public static final InsertHandler<LookupElement> INSTANCE = new MavenDependencyInsertHandler();
@@ -71,21 +102,47 @@ public class MavenDependenciesCompletionProvider extends CompletionContributor {
String groupId = s.substring(0, idx);
String artifactId = s.substring(idx + 1);
String value = "<groupId>" + groupId + "</groupId>\n" +
"<artifactId>" + artifactId + "</artifactId>\n" +
"<version></version>";
int startOffset = context.getStartOffset();
context.getDocument().replaceString(startOffset, context.getSelectionEndOffset(), value);
PsiFile psiFile = context.getFile();
context.getEditor().getCaretModel().moveToOffset(startOffset + value.length() - 10);
DomFileElement<MavenDomProjectModel> domModel = DomManager.getDomManager(context.getProject()).getFileElement((XmlFile)psiFile, MavenDomProjectModel.class);
if (domModel == null) return;
boolean shouldInvokeCompletion = false;
MavenDomDependency managedDependency = findManagedDependency(domModel.getRootElement(), context.getProject(), groupId, artifactId);
if (managedDependency == null) {
String value = "<groupId>" + groupId + "</groupId>\n" +
"<artifactId>" + artifactId + "</artifactId>\n" +
"<version></version>";
context.getDocument().replaceString(startOffset, context.getSelectionEndOffset(), value);
context.getEditor().getCaretModel().moveToOffset(startOffset + value.length() - 10);
shouldInvokeCompletion = true;
}
else {
StringBuilder sb = new StringBuilder();
sb.append("<groupId>").append(groupId).append("</groupId>\n")
.append("<artifactId>").append(artifactId).append("</artifactId>\n");
String type = managedDependency.getType().getStringValue();
if (type != null && !type.equals("jar")) {
sb.append("<type>").append(type).append("</type>\n");
}
String classifier = managedDependency.getClassifier().getStringValue();
if (StringUtil.isNotEmpty(classifier)) {
sb.append("<classifier>").append(classifier).append("</classifier>\n");
}
context.getDocument().replaceString(startOffset, context.getSelectionEndOffset(), sb);
}
context.commitDocument();
PsiFile psiFile = context.getFile();
PsiElement e = psiFile.findElementAt(startOffset);
while (e != null && (!(e instanceof XmlTag) || !"dependency".equals(((XmlTag)e).getName()))) {
e = e.getParent();
@@ -95,12 +152,14 @@ public class MavenDependenciesCompletionProvider extends CompletionContributor {
new ReformatCodeProcessor(psiFile.getProject(), psiFile, e.getTextRange(), true).run();
}
context.setLaterRunnable(new Runnable() {
@Override
public void run() {
new CodeCompletionHandlerBase(CompletionType.BASIC).invokeCompletion(context.getProject(), context.getEditor());
}
});
if (shouldInvokeCompletion) {
context.setLaterRunnable(new Runnable() {
@Override
public void run() {
new CodeCompletionHandlerBase(CompletionType.BASIC).invokeCompletion(context.getProject(), context.getEditor());
}
});
}
}
}
}
@@ -49,4 +49,96 @@ public class MavenDependencySmartCompletionTest extends MavenDomWithIndicesTestC
"</dependencies>\n"));
}
public void testInsertManagedDependency() throws IOException {
createProjectPom("<groupId>test</groupId>\n" +
"<artifactId>project</artifactId>\n" +
"<version>1</version>\n" +
"<dependencyManagement>\n" +
" <dependencies>\n" +
" <dependency>\n" +
" <groupId>junit</groupId>\n" +
" <artifactId>junit</artifactId>\n" +
" <version>4.0</version>\n" +
" </dependency>\n" +
" </dependencies>\n" +
"</dependencyManagement>\n" +
"<dependencies>\n" +
" <dependency>ju<caret></dependency>\n" +
"</dependencies>\n");
configTest(myProjectPom);
myFixture.complete(CompletionType.SMART);
myFixture.checkResult(createPomXml("<groupId>test</groupId>\n" +
"<artifactId>project</artifactId>\n" +
"<version>1</version>\n" +
"<dependencyManagement>\n" +
" <dependencies>\n" +
" <dependency>\n" +
" <groupId>junit</groupId>\n" +
" <artifactId>junit</artifactId>\n" +
" <version>4.0</version>\n" +
" </dependency>\n" +
" </dependencies>\n" +
"</dependencyManagement>\n" +
"<dependencies>\n" +
" <dependency>\n" +
" <groupId>junit</groupId>\n" +
" <artifactId>junit</artifactId>\n" +
" </dependency>\n" +
"</dependencies>\n"));
}
public void testInsertManagedDependencyWithTypeAndClassifier() throws IOException {
createProjectPom("<groupId>test</groupId>\n" +
"<artifactId>project</artifactId>\n" +
"<version>1</version>\n" +
"<dependencyManagement>\n" +
" <dependencies>\n" +
" <dependency>\n" +
" <groupId>junit</groupId>\n" +
" <artifactId>junit</artifactId>\n" +
" <version>4.0</version>\n" +
" <type>test-jar</type>\n" +
" <classifier>sources</classifier>\n" +
" </dependency>\n" +
" </dependencies>\n" +
"</dependencyManagement>\n" +
"<dependencies>\n" +
" <dependency>ju<caret></dependency>\n" +
"</dependencies>\n");
configTest(myProjectPom);
myFixture.complete(CompletionType.SMART);
myFixture.checkResult(createPomXml("<groupId>test</groupId>\n" +
"<artifactId>project</artifactId>\n" +
"<version>1</version>\n" +
"<dependencyManagement>\n" +
" <dependencies>\n" +
" <dependency>\n" +
" <groupId>junit</groupId>\n" +
" <artifactId>junit</artifactId>\n" +
" <version>4.0</version>\n" +
" <type>test-jar</type>\n" +
" <classifier>sources</classifier>\n" +
" </dependency>\n" +
" </dependencies>\n" +
"</dependencyManagement>\n" +
"<dependencies>\n" +
" <dependency>\n" +
" <groupId>junit</groupId>\n" +
" <artifactId>junit</artifactId>\n" +
" <type>test-jar</type>\n" +
" <classifier>sources</classifier>\n" +
" </dependency>\n" +
"</dependencies>\n"));
}
}
@@ -0,0 +1,10 @@
import org.jetbrains.annotations.Contract;
class A {
<spot>@Contract("any->null")</spot>
Object getObject() {
//do smth
return null;
}
}
@@ -0,0 +1,7 @@
class A {
Object getObject() {
//do smth
return null;
}
}
@@ -0,0 +1,27 @@
<html><body>
This intention changes a library method contract.
Method contract has the following syntax:<br/>
contract ::= (clause ';')* clause<br/>
clause ::= args '->' effect<br/>
args ::= ((arg ',')* arg )?<br/>
arg ::= value-constraint<br/>
value-constraint ::= 'any' | 'null' | '!null' | 'false' | 'true'<br/>
effect ::= value-constraint | 'fail' | 'exit'<p/>
The constraints denote the following:<br/>
<ul>
<li> _ - any value
<li> null - null value
<li> !null - a value statically proved to be not-null
<li> true - true boolean value
<li> false - false boolean value
<li> fail - the method throws exception, if the arguments satisfy argument constraints
<li> exit - the method terminates the current process, if the arguments satisfy argument constraints
</ul>
Examples:<p/>
<code>@Contract("_, null -> null")</code> - method returns null if its second argument is null<br/>
<code>@Contract("_, null -> null; _, !null -> !null")</code> - method returns null if its second argument is null and not-null otherwise<br/>
<code>@Contract("true -> fail")</code> - a typical assertFalse method which throws an exception if <code>true</code> is passed to it<br/>
</body></html>
+5
View File
@@ -693,6 +693,11 @@
<category>Control Flow</category>
<descriptionDirectoryName>AddAnnotationFix</descriptionDirectoryName>
</intentionAction>
<intentionAction>
<className>com.intellij.codeInspection.dataFlow.EditContractIntention</className>
<category>Control Flow</category>
<descriptionDirectoryName>EditContractIntention</descriptionDirectoryName>
</intentionAction>
<intentionAction>
<className>com.intellij.codeInsight.daemon.impl.quickfix.IterateOverIterableIntention</className>
<category>Control Flow</category>
@@ -154,6 +154,13 @@ abstract class BaseHtmlLexer extends DelegateLexer {
}
}
}
@Nullable
protected Language getScriptLanguage() {
Collection<Language> instancesByMimeType = Language.findInstancesByMimeType(scriptType != null ? scriptType.trim() : null);
return instancesByMimeType.isEmpty() ? null : instancesByMimeType.iterator().next();
}
@Nullable
protected IElementType getCurrentScriptElementType() {
HtmlScriptContentProvider scriptContentProvider = findScriptContentProvider(scriptType);
@@ -333,7 +340,7 @@ abstract class BaseHtmlLexer extends DelegateLexer {
protected boolean isValidAttributeValueTokenType(final IElementType tokenType) {
return tokenType == XmlTokenType.XML_ATTRIBUTE_VALUE_TOKEN ||
tokenType == XmlTokenType.XML_ENTITY_REF_TOKEN ||
tokenType == XmlTokenType.XML_CHAR_ENTITY_REF;
tokenType == XmlTokenType.XML_CHAR_ENTITY_REF;
}
public void advance() {
@@ -16,7 +16,9 @@
package com.intellij.lexer;
import com.intellij.lang.HtmlInlineScriptTokenTypesProvider;
import com.intellij.lang.Language;
import com.intellij.lang.LanguageHtmlInlineScriptTokenTypesProvider;
import com.intellij.lang.LanguageUtil;
import com.intellij.openapi.extensions.Extensions;
import com.intellij.psi.TokenType;
import com.intellij.psi.tree.IElementType;
@@ -74,7 +76,9 @@ public class HtmlLexer extends BaseHtmlLexer {
tokenType = ourInlineStyleElementType;
}
} else if (hasSeenScript()) {
if (hasSeenTag() && isStartOfEmbeddmentTagContent(tokenType)) {
Language scriptLanguage = getScriptLanguage();
boolean canInject = scriptLanguage == null || LanguageUtil.isInjectableLanguage(scriptLanguage);
if (hasSeenTag() && isStartOfEmbeddmentTagContent(tokenType) && canInject) {
myTokenEnd = skipToTheEndOfTheEmbeddment();
IElementType currentScriptElementType = getCurrentScriptElementType();
tokenType = currentScriptElementType == null ? XmlTokenType.XML_DATA_CHARACTERS : currentScriptElementType;