diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/compiled/ClsJavaCodeReferenceElementImpl.java b/java/java-psi-impl/src/com/intellij/psi/impl/compiled/ClsJavaCodeReferenceElementImpl.java index 3096f2485d6b..534b4c77a811 100644 --- a/java/java-psi-impl/src/com/intellij/psi/impl/compiled/ClsJavaCodeReferenceElementImpl.java +++ b/java/java-psi-impl/src/com/intellij/psi/impl/compiled/ClsJavaCodeReferenceElementImpl.java @@ -17,6 +17,7 @@ package com.intellij.psi.impl.compiled; import com.intellij.openapi.util.Comparing; import com.intellij.openapi.util.TextRange; +import com.intellij.openapi.util.text.StringUtil; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.psi.*; import com.intellij.psi.impl.PsiSubstitutorImpl; @@ -128,6 +129,7 @@ public class ClsJavaCodeReferenceElementImpl extends ClsElementImpl implements P } index++; } + collectOuterClassTypeArgs(((PsiClass)resolve), myCanonicalText, substitutionMap); return new CandidateInfo(resolve, PsiSubstitutorImpl.createSubstitutor(substitutionMap)); } else { @@ -135,6 +137,24 @@ public class ClsJavaCodeReferenceElementImpl extends ClsElementImpl implements P } } + private void collectOuterClassTypeArgs(final PsiClass psiClass, + final String canonicalText, + final Map substitutionMap) { + final PsiClass containingClass = psiClass.getContainingClass(); + if (containingClass != null && !containingClass.hasModifierProperty(PsiModifier.STATIC)) { + final String outerClassRef = StringUtil.getPackageName(canonicalText); + final String[] classParameters = PsiNameHelper.getClassParametersText(outerClassRef); + final PsiType[] args = classParameters.length == 0 ? null : new ClsReferenceParameterListImpl(this, classParameters).getTypeArguments(); + final PsiTypeParameter[] typeParameters = containingClass.getTypeParameters(); + for (int i = 0; i < typeParameters.length; i++) { + if (args != null && i < args.length) { + substitutionMap.put(typeParameters[i], args[i]); + } + } + collectOuterClassTypeArgs(containingClass, outerClassRef, substitutionMap); + } + } + @Override @NotNull public JavaResolveResult advancedResolve(boolean incompleteCode) { diff --git a/java/java-tests/testData/codeInsight/clsHighlighting/IDEA118733.java b/java/java-tests/testData/codeInsight/clsHighlighting/IDEA118733.java new file mode 100644 index 000000000000..9b2a124cfa6a --- /dev/null +++ b/java/java-tests/testData/codeInsight/clsHighlighting/IDEA118733.java @@ -0,0 +1,5 @@ +public class MyChild { + public void evaluate(Child child) { + Parent.InnerBase i = child.foo(); + } +} \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/clsHighlighting/IDEA97887.java b/java/java-tests/testData/codeInsight/clsHighlighting/IDEA97887.java new file mode 100644 index 000000000000..36c97bdcbfcb --- /dev/null +++ b/java/java-tests/testData/codeInsight/clsHighlighting/IDEA97887.java @@ -0,0 +1,6 @@ +public class MyChild extends Child { + @Override + public void evaluate(InnerImpl impl) { + String s = impl.t; + } +} \ No newline at end of file diff --git a/java/java-tests/testData/codeInsight/clsHighlighting/libs/IDEA118733.jar b/java/java-tests/testData/codeInsight/clsHighlighting/libs/IDEA118733.jar new file mode 100644 index 000000000000..bd96af38f4a8 Binary files /dev/null and b/java/java-tests/testData/codeInsight/clsHighlighting/libs/IDEA118733.jar differ diff --git a/java/java-tests/testData/codeInsight/clsHighlighting/libs/IDEA97887.jar b/java/java-tests/testData/codeInsight/clsHighlighting/libs/IDEA97887.jar new file mode 100644 index 000000000000..cbc7bf1830ad Binary files /dev/null and b/java/java-tests/testData/codeInsight/clsHighlighting/libs/IDEA97887.jar differ diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/ClsGenericsHighlightingTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/ClsGenericsHighlightingTest.java new file mode 100644 index 000000000000..d9897f516ec5 --- /dev/null +++ b/java/java-tests/testSrc/com/intellij/codeInsight/ClsGenericsHighlightingTest.java @@ -0,0 +1,128 @@ +/* + * Copyright 2000-2014 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. + */ + +/* + * User: anna + * Date: 27-Jun-2007 + */ +package com.intellij.codeInsight; + +import com.intellij.codeInsight.intention.AddAnnotationPsiFix; +import com.intellij.codeInsight.intention.IntentionAction; +import com.intellij.codeInsight.intention.impl.DeannotateIntentionAction; +import com.intellij.openapi.application.ApplicationManager; +import com.intellij.openapi.application.Result; +import com.intellij.openapi.application.ex.PathManagerEx; +import com.intellij.openapi.command.WriteCommandAction; +import com.intellij.openapi.editor.CaretModel; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.fileEditor.FileDocumentManager; +import com.intellij.openapi.module.Module; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.roots.AnnotationOrderRootType; +import com.intellij.openapi.roots.ModifiableRootModel; +import com.intellij.openapi.roots.ModuleRootManager; +import com.intellij.openapi.roots.OrderRootType; +import com.intellij.openapi.roots.libraries.Library; +import com.intellij.openapi.roots.libraries.LibraryTable; +import com.intellij.openapi.util.Trinity; +import com.intellij.openapi.util.io.FileUtil; +import com.intellij.openapi.util.io.StreamUtil; +import com.intellij.openapi.vfs.*; +import com.intellij.psi.*; +import com.intellij.psi.util.PsiTreeUtil; +import com.intellij.testFramework.IdeaTestCase; +import com.intellij.testFramework.PsiTestUtil; +import com.intellij.testFramework.UsefulTestCase; +import com.intellij.testFramework.builders.JavaModuleFixtureBuilder; +import com.intellij.testFramework.fixtures.*; +import com.intellij.util.messages.MessageBusConnection; +import org.jetbrains.annotations.NonNls; +import org.jetbrains.annotations.NotNull; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +public class ClsGenericsHighlightingTest extends UsefulTestCase { + private CodeInsightTestFixture myFixture; + private Module myModule; + + public ClsGenericsHighlightingTest() { + IdeaTestCase.initPlatformPrefix(); + } + + @Override + public void setUp() throws Exception { + super.setUp(); + final TestFixtureBuilder projectBuilder = IdeaTestFixtureFactory.getFixtureFactory().createFixtureBuilder(getName()); + + myFixture = JavaTestFixtureFactory.getFixtureFactory().createCodeInsightFixture(projectBuilder.getFixture()); + final String dataPath = PathManagerEx.getTestDataPath() + "/codeInsight/clsHighlighting"; + myFixture.setTestDataPath(dataPath); + final JavaModuleFixtureBuilder builder = projectBuilder.addModule(JavaModuleFixtureBuilder.class); + builder.setMockJdkLevel(JavaModuleFixtureBuilder.MockJdkLevel.jdk15); + + myFixture.setUp(); + myModule = builder.getFixture().getModule(); + } + + @Override + protected void tearDown() throws Exception { + super.tearDown(); + myFixture.tearDown(); + myFixture = null; + myModule = null; + } + + private void addLibrary(@NotNull final String... libraryPath) { + ApplicationManager.getApplication().runWriteAction(new Runnable() { + @Override + public void run() { + final ModifiableRootModel model = ModuleRootManager.getInstance(myModule).getModifiableModel(); + final LibraryTable libraryTable = model.getModuleLibraryTable(); + final Library library = libraryTable.createLibrary("test"); + + final Library.ModifiableModel libraryModel = library.getModifiableModel(); + for (String annotationsDir : libraryPath) { + final VirtualFile libJarLocal = LocalFileSystem.getInstance().findFileByPath(myFixture.getTestDataPath() + "/libs/" + annotationsDir); + assertNotNull(libJarLocal); + final VirtualFile jarRoot = JarFileSystem.getInstance().getJarRootForLocalFile(libJarLocal); + assertNotNull(jarRoot); + libraryModel.addRoot(jarRoot , OrderRootType.CLASSES); + } + libraryModel.commit(); + final String contentUrl = VfsUtilCore.pathToUrl(myFixture.getTempDirPath()); + model.addContentEntry(contentUrl).addSourceFolder(contentUrl, false); + model.commit(); + } + }); + } + + public void testIDEA97887() throws Throwable { + doTest(); + } + + public void testIDEA118733() throws Exception { + doTest(); + } + + private void doTest() { + addLibrary(getTestName(false) + ".jar"); + myFixture.configureByFile(getTestName(false) + ".java"); + myFixture.checkHighlighting(); + } +}