diff --git a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightUtil.java b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightUtil.java
index 211bcfb67774..7151855d7a4d 100644
--- a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightUtil.java
+++ b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightUtil.java
@@ -1378,7 +1378,7 @@ public class HighlightUtil extends HighlightUtilBase {
if (expr instanceof PsiThisExpression) {
final PsiMethod psiMethod = PsiTreeUtil.getParentOfType(expr, PsiMethod.class);
- if (psiMethod == null || psiMethod.getContainingClass() != aClass) {
+ if (psiMethod == null || psiMethod.getContainingClass() != aClass && !isInsideDefaultMethod(psiMethod, aClass)) {
if (aClass.isInterface()) {
return thisNotFoundInInterfaceInfo(expr);
}
@@ -1393,6 +1393,13 @@ public class HighlightUtil extends HighlightUtilBase {
}
return null;
}
+
+ private static boolean isInsideDefaultMethod(PsiMethod method, PsiClass aClass) {
+ while (method != null && method.getContainingClass() != aClass) {
+ method = PsiTreeUtil.getParentOfType(method, PsiMethod.class, true);
+ }
+ return method != null && method.hasModifierProperty(PsiModifier.DEFAULT);
+ }
private static HighlightInfo thisNotFoundInInterfaceInfo(@NotNull PsiExpression expr) {
return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(expr).descriptionAndTooltip("Cannot find symbol variable this").create();
diff --git a/java/java-psi-api/src/com/intellij/psi/PsiCapturedWildcardType.java b/java/java-psi-api/src/com/intellij/psi/PsiCapturedWildcardType.java
index 560dcbd948dc..85fae4536e8a 100644
--- a/java/java-psi-api/src/com/intellij/psi/PsiCapturedWildcardType.java
+++ b/java/java-psi-api/src/com/intellij/psi/PsiCapturedWildcardType.java
@@ -93,7 +93,15 @@ public class PsiCapturedWildcardType extends PsiType {
}
public PsiType getUpperBound () {
- return myExistential.isExtends() ? myExistential.getBound() : PsiType.getJavaLangObject(myContext.getManager(), getResolveScope());
+ final PsiType bound = myExistential.getBound();
+ if (myExistential.isExtends()) {
+ return bound;
+ }
+ else {
+ return bound instanceof PsiCapturedWildcardType
+ ? ((PsiCapturedWildcardType)bound).getUpperBound()
+ : PsiType.getJavaLangObject(myContext.getManager(), getResolveScope());
+ }
}
public PsiWildcardType getWildcard() {
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting/IDEA105846.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting/IDEA105846.java
new file mode 100644
index 000000000000..8b9c700484c9
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting/IDEA105846.java
@@ -0,0 +1,5 @@
+class MyClass {
+ public static void main(Class extends MyClass> clazz){
+ clazz = (Class extends MyClass>) clazz.getSuperclass();
+ }
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/interfaceMethods/ThisAccessibility.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/interfaceMethods/ThisAccessibility.java
new file mode 100644
index 000000000000..c43ef5200b04
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/interfaceMethods/ThisAccessibility.java
@@ -0,0 +1,24 @@
+interface Bazz {
+ Bazz foo = Bazz.this;
+ static void foo1() {
+ Bazz foo = Bazz.this;
+ }
+
+ Runnable bar = new Runnable() {
+ @Override
+ public void run() {
+ Bazz f = Bazz.this;
+ }
+ };
+
+
+ default void foo() {
+ Bazz foo = Bazz.this;
+ Runnable r = new Runnable() {
+ @Override
+ public void run() {
+ Bazz f = Bazz.this;
+ }
+ };
+ }
+}
\ No newline at end of file
diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/GenericsHighlightingTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/GenericsHighlightingTest.java
index f2a6e3af1fa7..cf73a8cd1910 100644
--- a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/GenericsHighlightingTest.java
+++ b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/GenericsHighlightingTest.java
@@ -205,6 +205,7 @@ public class GenericsHighlightingTest extends LightDaemonAnalyzerTestCase {
public void testIDEA99347() { doTest5(false); }
public void testIDEA86875() { doTest5(false); }
public void testIDEA103760(){ doTest5(false); }
+ public void testIDEA105846(){ doTest5(false); }
public void testWildcardsOnRawTypes() { doTest5(false); }
public void testDisableWithinBoundsCheckForSuperWildcards() {
diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/Interface8MethodsHighlightingTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/Interface8MethodsHighlightingTest.java
index dab1d6306e9b..e77dff317192 100644
--- a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/Interface8MethodsHighlightingTest.java
+++ b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/Interface8MethodsHighlightingTest.java
@@ -29,6 +29,7 @@ public class Interface8MethodsHighlightingTest extends LightDaemonAnalyzerTestCa
public void testInheritDefaultMethodInInterface() { doTest(false, false); }
public void testStaticMethodsInFunctionalInterface() { doTest(false, false); }
public void testCyclicSubstitutor() { doTest(false, false); }
+ public void testThisAccessibility() { doTest(false, false); }
private void doTest() {
doTest(false, false);
diff --git a/platform/lang-impl/src/com/intellij/internal/SelectionBasedPsiElementInternalAction.java b/platform/lang-impl/src/com/intellij/internal/SelectionBasedPsiElementInternalAction.java
new file mode 100644
index 000000000000..4c3e8cb2ab94
--- /dev/null
+++ b/platform/lang-impl/src/com/intellij/internal/SelectionBasedPsiElementInternalAction.java
@@ -0,0 +1,145 @@
+package com.intellij.internal;
+
+import com.intellij.codeInsight.hint.HintManager;
+import com.intellij.openapi.actionSystem.*;
+import com.intellij.openapi.application.ApplicationManager;
+import com.intellij.openapi.application.ex.ApplicationManagerEx;
+import com.intellij.openapi.editor.Editor;
+import com.intellij.openapi.editor.SelectionModel;
+import com.intellij.openapi.util.Pass;
+import com.intellij.openapi.util.TextRange;
+import com.intellij.psi.PsiElement;
+import com.intellij.psi.PsiFile;
+import com.intellij.psi.util.PsiTreeUtil;
+import com.intellij.refactoring.IntroduceTargetChooser;
+import com.intellij.util.Function;
+import com.intellij.util.containers.ContainerUtil;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.List;
+
+/**
+ * @author Nikolay Matveev
+ */
+public abstract class SelectionBasedPsiElementInternalAction extends AnAction {
+ @NotNull
+ protected final Class myClass;
+ @NotNull
+ protected final Class extends PsiFile> myFileClass;
+
+ protected SelectionBasedPsiElementInternalAction(@NotNull Class aClass, @NotNull Class extends PsiFile> fileClass) {
+ myClass = aClass;
+ myFileClass = fileClass;
+ }
+
+ @Override
+ public final void actionPerformed(AnActionEvent e) {
+ final Editor editor = getEditor(e);
+ final PsiFile file = getPsiFile(e);
+ if (editor == null || file == null) return;
+
+ final List expressions = getElement(editor, file);
+ T first = ContainerUtil.getFirstItem(expressions);
+
+ if (expressions.size() > 1) {
+ IntroduceTargetChooser.showChooser(
+ editor, expressions,
+ new Pass() {
+ @Override
+ public void pass(@NotNull T expression) {
+ performOnElement(editor, expression);
+ }
+ },
+ new Function() {
+ public String fun(@NotNull T expression) {
+ return expression.getText();
+ }
+ }
+ );
+ }
+ else if (expressions.size() == 1 && first != null) {
+ performOnElement(editor, first);
+ }
+ else if (expressions.isEmpty()) {
+ showError(editor);
+ }
+ }
+
+ protected void showError(@NotNull final Editor editor) {
+ ApplicationManager.getApplication().invokeLater(new Runnable() {
+ @Override
+ public void run() {
+ final String errorHint = "Cannot find element of class " + myClass.getSimpleName() + " at selection/offset";
+ HintManager.getInstance().showErrorHint(editor, errorHint);
+ }
+ });
+ }
+
+ private void performOnElement(@NotNull final Editor editor, @NotNull T first) {
+ final TextRange textRange = first.getTextRange();
+ editor.getSelectionModel().setSelection(textRange.getStartOffset(), textRange.getEndOffset());
+ final String informationHint = getInformationHint(first);
+ if (informationHint != null) {
+ ApplicationManager.getApplication().invokeLater(new Runnable() {
+ @Override
+ public void run() {
+ HintManager.getInstance().showInformationHint(editor, informationHint);
+ }
+ });
+ }
+ else {
+ ApplicationManager.getApplication().invokeLater(new Runnable() {
+ @Override
+ public void run() {
+ HintManager.getInstance().showErrorHint(editor, getErrorHint());
+ }
+ });
+ }
+ }
+
+ @Nullable
+ protected abstract String getInformationHint(@NotNull T element);
+
+ @NotNull
+ protected abstract String getErrorHint();
+
+ @NotNull
+ protected List getElement(@NotNull Editor editor, @NotNull PsiFile file) {
+ final SelectionModel selectionModel = editor.getSelectionModel();
+ if (selectionModel.hasSelection()) {
+ return ContainerUtil.list(getElementFromSelection(file, selectionModel));
+ }
+ return getElementAtOffset(editor, file);
+ }
+
+ @NotNull
+ protected List getElementAtOffset(@NotNull Editor editor, @NotNull PsiFile file) {
+ return ContainerUtil.list(PsiTreeUtil.findElementOfClassAtOffset(file, editor.getCaretModel().getOffset(), myClass, false));
+ }
+
+ @Nullable
+ protected T getElementFromSelection(@NotNull PsiFile file, @NotNull SelectionModel selectionModel) {
+ final int selectionStart = selectionModel.getSelectionStart();
+ final int selectionEnd = selectionModel.getSelectionEnd();
+ return PsiTreeUtil.findElementOfClassAtRange(file, selectionStart, selectionEnd, myClass);
+ }
+
+ @Override
+ public final void update(AnActionEvent e) {
+ final Presentation presentation = e.getPresentation();
+ boolean enabled = ApplicationManagerEx.getApplicationEx().isInternal() && getEditor(e) != null && myFileClass.isInstance(getPsiFile(e));
+ presentation.setVisible(enabled);
+ presentation.setEnabled(enabled);
+ }
+
+ @Nullable
+ private static Editor getEditor(@NotNull AnActionEvent e) {
+ return PlatformDataKeys.EDITOR.getData(e.getDataContext());
+ }
+
+ @Nullable
+ private static PsiFile getPsiFile(@NotNull AnActionEvent e) {
+ return LangDataKeys.PSI_FILE.getData(e.getDataContext());
+ }
+}
diff --git a/platform/platform-resources/src/META-INF/ExternalSystemExtensions.xml b/platform/platform-resources/src/META-INF/ExternalSystemExtensions.xml
index fab5a6a62530..b726ef82b4ed 100644
--- a/platform/platform-resources/src/META-INF/ExternalSystemExtensions.xml
+++ b/platform/platform-resources/src/META-INF/ExternalSystemExtensions.xml
@@ -12,7 +12,6 @@
serviceImplementation="com.intellij.openapi.externalSystem.service.project.ExternalLibraryPathTypeMapperImpl"/>
-
diff --git a/plugins/IntelliLang/java-support/org/intellij/plugins/intelliLang/inject/java/ConcatenationInjector.java b/plugins/IntelliLang/java-support/org/intellij/plugins/intelliLang/inject/java/ConcatenationInjector.java
index 15c79cbaa3c5..b8dca4df4983 100644
--- a/plugins/IntelliLang/java-support/org/intellij/plugins/intelliLang/inject/java/ConcatenationInjector.java
+++ b/plugins/IntelliLang/java-support/org/intellij/plugins/intelliLang/inject/java/ConcatenationInjector.java
@@ -142,7 +142,7 @@ public class ConcatenationInjector implements ConcatenationAwareInjector {
boolean unparsable) {
InjectorUtils.registerInjection(language, list, containingFile, registrar);
InjectorUtils.registerSupport(mySupport, settingsAvailable, registrar);
- if (unparsable) InjectorUtils.putInjectedFileUserData(registrar, InjectedLanguageUtil.FRANKENSTEIN_INJECTION, Boolean.TRUE);
+ InjectorUtils.putInjectedFileUserData(registrar, InjectedLanguageUtil.FRANKENSTEIN_INJECTION, unparsable ? Boolean.TRUE : null);
}
@Override
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/resolve/noncode/MixinMemberContributor.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/resolve/noncode/MixinMemberContributor.java
index 3cce1d595535..6521f659cb9e 100644
--- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/resolve/noncode/MixinMemberContributor.java
+++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/resolve/noncode/MixinMemberContributor.java
@@ -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.
@@ -17,6 +17,7 @@ package org.jetbrains.plugins.groovy.lang.resolve.noncode;
import com.intellij.codeInsight.completion.originInfo.OriginInfoAwareElement;
import com.intellij.psi.*;
+import com.intellij.psi.impl.compiled.ClsClassImpl;
import com.intellij.psi.impl.light.LightMethod;
import com.intellij.psi.scope.DelegatingScopeProcessor;
import com.intellij.psi.scope.PsiScopeProcessor;
@@ -28,6 +29,7 @@ import org.jetbrains.plugins.groovy.lang.psi.api.auxiliary.modifiers.annotation.
import org.jetbrains.plugins.groovy.lang.psi.api.auxiliary.modifiers.annotation.GrAnnotationMemberValue;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrExpression;
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.GrReferenceExpression;
+import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.GrTypeDefinition;
import org.jetbrains.plugins.groovy.lang.psi.impl.synthetic.GrGdkMethodImpl;
import org.jetbrains.plugins.groovy.lang.psi.util.GdkMethodUtil;
import org.jetbrains.plugins.groovy.lang.psi.util.GroovyCommonClassNames;
@@ -47,8 +49,8 @@ public class MixinMemberContributor extends NonCodeMembersContributor {
@NotNull ResolveState state) {
if (!(qualifierType instanceof PsiClassType)) return;
if (isInAnnotation(place)) return;
- final PsiClassType.ClassResolveResult resolveResult = ((PsiClassType)qualifierType).resolveGenerics();
- final PsiClass aClass = resolveResult.getElement();
+
+ final PsiClass aClass = getClass((PsiClassType)qualifierType);
if (aClass == null) return;
final PsiModifierList modifierList = aClass.getModifierList();
@@ -77,6 +79,21 @@ public class MixinMemberContributor extends NonCodeMembersContributor {
}
}
+ @Nullable
+ private static PsiClass getClass(@NotNull PsiClassType qualifierType) {
+ final PsiClassType.ClassResolveResult resolveResult = qualifierType.resolveGenerics();
+
+ final PsiClass aClass = resolveResult.getElement();
+ if (aClass instanceof ClsClassImpl) {
+ final PsiElement source = aClass.getNavigationElement();
+ if (source instanceof GrTypeDefinition) {
+ return (PsiClass)source;
+ }
+ }
+
+ return aClass;
+ }
+
public static String getOriginInfoForCategory(PsiMethod element) {
PsiClass aClass = element.getContainingClass();
if (aClass != null && aClass.getName() != null) {
@@ -91,7 +108,7 @@ public class MixinMemberContributor extends NonCodeMembersContributor {
private static List getAllMixins(PsiModifierList modifierList) {
final ArrayList result = new ArrayList();
- for (PsiAnnotation annotation : modifierList.getApplicableAnnotations()) {
+ for (PsiAnnotation annotation : modifierList.getAnnotations()) {
if (GroovyCommonClassNames.GROOVY_LANG_MIXIN.equals(annotation.getQualifiedName())) {
result.add(annotation);
}