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:
+2
-3
@@ -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) {
|
||||
|
||||
+39
-25
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+9
-5
@@ -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(";")) {
|
||||
|
||||
+28
-21
@@ -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);
|
||||
}
|
||||
};
|
||||
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
// "Replace with lambda" "true"
|
||||
class Test {
|
||||
{
|
||||
String o = "";
|
||||
Comparable<String> c = o1 -> 0;
|
||||
}
|
||||
}
|
||||
+12
@@ -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;
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -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;
|
||||
}
|
||||
|
||||
+6
-21
@@ -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;
|
||||
}
|
||||
|
||||
+15
@@ -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
-1
@@ -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
|
||||
|
||||
+1
@@ -13,6 +13,7 @@ public enum DeploymentStatus {
|
||||
myPresentableText = presentableText;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public String getPresentableText() {
|
||||
return myPresentableText;
|
||||
}
|
||||
|
||||
+1
-1
@@ -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;
|
||||
}
|
||||
|
||||
+2
@@ -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
|
||||
|
||||
+2
-1
@@ -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);
|
||||
|
||||
|
||||
+6
@@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
+7
-27
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
+5
-7
@@ -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();
|
||||
}
|
||||
|
||||
+2
-1
@@ -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
|
||||
|
||||
+74
-15
@@ -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());
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+92
@@ -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>
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user