Frontend: fixed resolve annotation parameters on properties, accessors, accessor parameters, function parameters when not need complete analysis.

This commit is contained in:
Zalim Bashorov
2014-01-27 14:44:49 +04:00
parent f5499a93ed
commit d032b5589c
8 changed files with 98 additions and 29 deletions
@@ -117,6 +117,7 @@ public enum AnalyzerFacadeForJVM implements AnalyzerFacade {
return new ResolveSession(project, storageManager, module, declarationProviderFactory, trace); return new ResolveSession(project, storageManager, module, declarationProviderFactory, trace);
} }
@NotNull
public static AnalyzeExhaust analyzeOneFileWithJavaIntegrationAndCheckForErrors( public static AnalyzeExhaust analyzeOneFileWithJavaIntegrationAndCheckForErrors(
JetFile file, List<AnalyzerScriptParameter> scriptParameters) { JetFile file, List<AnalyzerScriptParameter> scriptParameters) {
AnalyzingUtils.checkForSyntacticErrors(file); AnalyzingUtils.checkForSyntacticErrors(file);
@@ -128,12 +129,14 @@ public enum AnalyzerFacadeForJVM implements AnalyzerFacade {
return analyzeExhaust; return analyzeExhaust;
} }
@NotNull
public static AnalyzeExhaust analyzeOneFileWithJavaIntegration( public static AnalyzeExhaust analyzeOneFileWithJavaIntegration(
JetFile file, List<AnalyzerScriptParameter> scriptParameters) { JetFile file, List<AnalyzerScriptParameter> scriptParameters) {
return analyzeFilesWithJavaIntegration(file.getProject(), Collections.singleton(file), scriptParameters, return analyzeFilesWithJavaIntegration(file.getProject(), Collections.singleton(file), scriptParameters,
Predicates.<PsiFile>alwaysTrue()); Predicates.<PsiFile>alwaysTrue());
} }
@NotNull
public static AnalyzeExhaust analyzeFilesWithJavaIntegrationAndCheckForErrors( public static AnalyzeExhaust analyzeFilesWithJavaIntegrationAndCheckForErrors(
Project project, Project project,
Collection<JetFile> files, Collection<JetFile> files,
@@ -152,6 +155,7 @@ public enum AnalyzerFacadeForJVM implements AnalyzerFacade {
return analyzeExhaust; return analyzeExhaust;
} }
@NotNull
public static AnalyzeExhaust analyzeFilesWithJavaIntegration( public static AnalyzeExhaust analyzeFilesWithJavaIntegration(
Project project, Project project,
Collection<JetFile> files, Collection<JetFile> files,
@@ -162,6 +166,7 @@ public enum AnalyzerFacadeForJVM implements AnalyzerFacade {
project, files, scriptParameters, filesToAnalyzeCompletely, false); project, files, scriptParameters, filesToAnalyzeCompletely, false);
} }
@NotNull
public static AnalyzeExhaust analyzeFilesWithJavaIntegration( public static AnalyzeExhaust analyzeFilesWithJavaIntegration(
Project project, Collection<JetFile> files, List<AnalyzerScriptParameter> scriptParameters, Predicate<PsiFile> filesToAnalyzeCompletely, Project project, Collection<JetFile> files, List<AnalyzerScriptParameter> scriptParameters, Predicate<PsiFile> filesToAnalyzeCompletely,
boolean storeContextForBodiesResolve) { boolean storeContextForBodiesResolve) {
@@ -171,6 +176,7 @@ public enum AnalyzerFacadeForJVM implements AnalyzerFacade {
storeContextForBodiesResolve); storeContextForBodiesResolve);
} }
@NotNull
public static AnalyzeExhaust analyzeFilesWithJavaIntegration( public static AnalyzeExhaust analyzeFilesWithJavaIntegration(
Project project, Project project,
Collection<JetFile> files, Collection<JetFile> files,
@@ -183,6 +189,7 @@ public enum AnalyzerFacadeForJVM implements AnalyzerFacade {
storeContextForBodiesResolve, createJavaModule("<module>")); storeContextForBodiesResolve, createJavaModule("<module>"));
} }
@NotNull
public static AnalyzeExhaust analyzeFilesWithJavaIntegration( public static AnalyzeExhaust analyzeFilesWithJavaIntegration(
Project project, Project project,
Collection<JetFile> files, Collection<JetFile> files,
@@ -30,6 +30,7 @@ public class AnalyzeExhaust {
return new AnalyzeExhaust(bindingContext, module, null, null); return new AnalyzeExhaust(bindingContext, module, null, null);
} }
@NotNull
public static AnalyzeExhaust success(@NotNull BindingContext bindingContext, public static AnalyzeExhaust success(@NotNull BindingContext bindingContext,
@Nullable BodiesResolveContext bodiesResolveContext, @Nullable BodiesResolveContext bodiesResolveContext,
@NotNull ModuleDescriptor module @NotNull ModuleDescriptor module
@@ -37,6 +38,7 @@ public class AnalyzeExhaust {
return new AnalyzeExhaust(bindingContext, module, bodiesResolveContext, null); return new AnalyzeExhaust(bindingContext, module, bodiesResolveContext, null);
} }
@NotNull
public static AnalyzeExhaust error(@NotNull BindingContext bindingContext, @NotNull Throwable error) { public static AnalyzeExhaust error(@NotNull BindingContext bindingContext, @NotNull Throwable error) {
return new AnalyzeExhaust(bindingContext, ErrorUtils.getErrorModule(), null, error); return new AnalyzeExhaust(bindingContext, ErrorUtils.getErrorModule(), null, error);
} }
@@ -428,7 +428,6 @@ public class BodyResolver {
for (Map.Entry<JetClassOrObject, MutableClassDescriptor> entry : context.getClasses().entrySet()) { for (Map.Entry<JetClassOrObject, MutableClassDescriptor> entry : context.getClasses().entrySet()) {
if (!(entry.getKey() instanceof JetClass)) continue; if (!(entry.getKey() instanceof JetClass)) continue;
JetClass jetClass = (JetClass) entry.getKey(); JetClass jetClass = (JetClass) entry.getKey();
if (!context.completeAnalysisNeeded(jetClass)) continue;
MutableClassDescriptor classDescriptor = entry.getValue(); MutableClassDescriptor classDescriptor = entry.getValue();
for (JetProperty property : jetClass.getProperties()) { for (JetProperty property : jetClass.getProperties()) {
@@ -462,7 +461,6 @@ public class BodyResolver {
// Top-level properties & properties of objects // Top-level properties & properties of objects
for (Map.Entry<JetProperty, PropertyDescriptor> entry : this.context.getProperties().entrySet()) { for (Map.Entry<JetProperty, PropertyDescriptor> entry : this.context.getProperties().entrySet()) {
JetProperty property = entry.getKey(); JetProperty property = entry.getKey();
if (!context.completeAnalysisNeeded(property)) continue;
if (processed.contains(property)) continue; if (processed.contains(property)) continue;
PropertyDescriptor propertyDescriptor = entry.getValue(); PropertyDescriptor propertyDescriptor = entry.getValue();
@@ -611,20 +609,22 @@ public class BodyResolver {
@NotNull BindingTrace trace, @NotNull BindingTrace trace,
@NotNull JetDeclarationWithBody function, @NotNull JetDeclarationWithBody function,
@NotNull FunctionDescriptor functionDescriptor, @NotNull FunctionDescriptor functionDescriptor,
@NotNull JetScope declaringScope) { @NotNull JetScope declaringScope
if (!context.completeAnalysisNeeded(function)) return; ) {
JetExpression bodyExpression = function.getBodyExpression();
JetScope functionInnerScope = FunctionDescriptorUtil.getFunctionInnerScope(declaringScope, functionDescriptor, trace); JetScope functionInnerScope = FunctionDescriptorUtil.getFunctionInnerScope(declaringScope, functionDescriptor, trace);
if (bodyExpression != null) {
expressionTypingServices.checkFunctionReturnType(functionInnerScope, function, functionDescriptor, context.getOuterDataFlowInfo(), null, trace);
}
List<JetParameter> valueParameters = function.getValueParameters(); List<JetParameter> valueParameters = function.getValueParameters();
List<ValueParameterDescriptor> valueParameterDescriptors = functionDescriptor.getValueParameters(); List<ValueParameterDescriptor> valueParameterDescriptors = functionDescriptor.getValueParameters();
expressionTypingServices.resolveValueParameters(valueParameters, valueParameterDescriptors, functionInnerScope, context.getOuterDataFlowInfo(), trace); expressionTypingServices.resolveValueParameters(valueParameters, valueParameterDescriptors, functionInnerScope, context.getOuterDataFlowInfo(), trace);
if (!context.completeAnalysisNeeded(function)) return;
JetExpression bodyExpression = function.getBodyExpression();
if (bodyExpression != null) {
expressionTypingServices.checkFunctionReturnType(functionInnerScope, function, functionDescriptor, context.getOuterDataFlowInfo(), null, trace);
}
assert functionDescriptor.getReturnType() != null; assert functionDescriptor.getReturnType() != null;
} }
@@ -8,7 +8,7 @@ ANNOTATION class MyClass [ANNOTATION]([ANNOTATION] param: Int, [ANNOTATION] val
ANNOTATION var prop: Int = 1 ANNOTATION var prop: Int = 1
[ANNOTATION] get [ANNOTATION] get
[ANNOTATION] set [ANNOTATION] set([ANNOTATION] param) = $prop = param
ANNOTATION fun foo([ANNOTATION] param: Int) { ANNOTATION fun foo([ANNOTATION] param: Int) {
[ANNOTATION] class LocalClass { } [ANNOTATION] class LocalClass { }
@@ -29,7 +29,7 @@ ANNOTATION object MyObject {
ANNOTATION var topProp: Int = 1 ANNOTATION var topProp: Int = 1
[ANNOTATION] get [ANNOTATION] get
[ANNOTATION] set [ANNOTATION] set([ANNOTATION] param) = $topProp = param
ANNOTATION fun topFoo([ANNOTATION] param: Int) { ANNOTATION fun topFoo([ANNOTATION] param: Int) {
} }
@@ -16,6 +16,7 @@
package org.jetbrains.jet; package org.jetbrains.jet;
import com.google.common.base.Predicates;
import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Lists; import com.google.common.collect.Lists;
import com.google.common.collect.Maps; import com.google.common.collect.Maps;
@@ -28,6 +29,7 @@ import com.intellij.openapi.util.ShutDownTracker;
import com.intellij.openapi.util.io.FileUtil; import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.util.text.StringUtil; import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vfs.CharsetToolkit; import com.intellij.openapi.vfs.CharsetToolkit;
import com.intellij.psi.PsiFile;
import com.intellij.psi.PsiFileFactory; import com.intellij.psi.PsiFileFactory;
import com.intellij.psi.impl.PsiFileFactoryImpl; import com.intellij.psi.impl.PsiFileFactoryImpl;
import com.intellij.rt.execution.junit.FileComparisonFailure; import com.intellij.rt.execution.junit.FileComparisonFailure;
@@ -221,10 +223,19 @@ public class JetTestUtils {
private JetTestUtils() { private JetTestUtils() {
} }
@NotNull
public static AnalyzeExhaust analyzeFile(@NotNull JetFile file) { public static AnalyzeExhaust analyzeFile(@NotNull JetFile file) {
return AnalyzerFacadeForJVM.analyzeOneFileWithJavaIntegration(file, Collections.<AnalyzerScriptParameter>emptyList()); return AnalyzerFacadeForJVM.analyzeOneFileWithJavaIntegration(file, Collections.<AnalyzerScriptParameter>emptyList());
} }
@NotNull
public static AnalyzeExhaust analyzeFileWithoutBody(@NotNull JetFile file) {
return AnalyzerFacadeForJVM.analyzeFilesWithJavaIntegration(file.getProject(),
Collections.singleton(file),
Collections.<AnalyzerScriptParameter>emptyList(),
Predicates.<PsiFile>alwaysFalse());
}
@NotNull @NotNull
public static JetCoreEnvironment createEnvironmentWithFullJdk(Disposable disposable) { public static JetCoreEnvironment createEnvironmentWithFullJdk(Disposable disposable) {
return createEnvironmentWithJdkAndNullabilityAnnotationsFromIdea(disposable, return createEnvironmentWithJdkAndNullabilityAnnotationsFromIdea(disposable,
@@ -60,6 +60,11 @@ public abstract class AbstractAnnotationDescriptorResolveTest extends JetLiteFix
} }
protected void doTest(@NotNull String content, @NotNull String expectedAnnotation) { protected void doTest(@NotNull String content, @NotNull String expectedAnnotation) {
checkAnnotationOnAllExceptLocalDeclarations(content, expectedAnnotation);
checkAnnotationOnLocalDeclarations(expectedAnnotation);
}
protected void checkAnnotationOnAllExceptLocalDeclarations(String content, String expectedAnnotation) {
PackageViewDescriptor test = getPackage(content); PackageViewDescriptor test = getPackage(content);
ClassDescriptor myClass = getClassDescriptor(test, "MyClass"); ClassDescriptor myClass = getClassDescriptor(test, "MyClass");
checkDescriptor(expectedAnnotation, myClass); checkDescriptor(expectedAnnotation, myClass);
@@ -67,13 +72,7 @@ public abstract class AbstractAnnotationDescriptorResolveTest extends JetLiteFix
checkDescriptor(expectedAnnotation, getInnerClassDescriptor(myClass, "InnerClass")); checkDescriptor(expectedAnnotation, getInnerClassDescriptor(myClass, "InnerClass"));
FunctionDescriptor foo = getFunctionDescriptor(myClass, "foo"); FunctionDescriptor foo = getFunctionDescriptor(myClass, "foo");
checkDescriptor(expectedAnnotation, foo); checkAnnotationsOnFunction(expectedAnnotation, foo);
checkDescriptor(expectedAnnotation, getFunctionParameterDescriptor(foo, "param"));
checkDescriptor(expectedAnnotation, getLocalClassDescriptor("LocalClass"));
checkDescriptor(expectedAnnotation, getLocalObjectDescriptor("LocalObject"));
checkDescriptor(expectedAnnotation, getLocalFunDescriptor("localFun"));
checkDescriptor(expectedAnnotation, getLocalVarDescriptor("localVar"));
SimpleFunctionDescriptor anonymousFun = getAnonymousFunDescriptor(); SimpleFunctionDescriptor anonymousFun = getAnonymousFunDescriptor();
if (anonymousFun instanceof AnonymousFunctionDescriptor) { if (anonymousFun instanceof AnonymousFunctionDescriptor) {
@@ -83,18 +82,13 @@ public abstract class AbstractAnnotationDescriptorResolveTest extends JetLiteFix
} }
PropertyDescriptor prop = getPropertyDescriptor(myClass, "prop"); PropertyDescriptor prop = getPropertyDescriptor(myClass, "prop");
checkDescriptor(expectedAnnotation, prop); checkAnnotationsOnProperty(expectedAnnotation, prop);
checkDescriptor(expectedAnnotation, prop.getGetter());
checkDescriptor(expectedAnnotation, prop.getSetter());
FunctionDescriptor topFoo = getFunctionDescriptor(test, "topFoo"); FunctionDescriptor topFoo = getFunctionDescriptor(test, "topFoo");
checkDescriptor(expectedAnnotation, topFoo); checkAnnotationsOnFunction(expectedAnnotation, topFoo);
checkDescriptor(expectedAnnotation, getFunctionParameterDescriptor(topFoo, "param"));
PropertyDescriptor topProp = getPropertyDescriptor(test, "topProp"); PropertyDescriptor topProp = getPropertyDescriptor(test, "topProp");
checkDescriptor(expectedAnnotation, topProp); checkAnnotationsOnProperty(expectedAnnotation, topProp);
checkDescriptor(expectedAnnotation, topProp.getGetter());
checkDescriptor(expectedAnnotation, topProp.getSetter());
checkDescriptor(expectedAnnotation, getClassDescriptor(test, "MyObject")); checkDescriptor(expectedAnnotation, getClassDescriptor(test, "MyObject"));
@@ -102,6 +96,26 @@ public abstract class AbstractAnnotationDescriptorResolveTest extends JetLiteFix
checkDescriptor(expectedAnnotation, getConstructorParameterDescriptor(myClass, "param")); checkDescriptor(expectedAnnotation, getConstructorParameterDescriptor(myClass, "param"));
} }
private void checkAnnotationOnLocalDeclarations(String expectedAnnotation) {
checkDescriptor(expectedAnnotation, getLocalClassDescriptor("LocalClass"));
checkDescriptor(expectedAnnotation, getLocalObjectDescriptor("LocalObject"));
checkDescriptor(expectedAnnotation, getLocalFunDescriptor("localFun"));
checkDescriptor(expectedAnnotation, getLocalVarDescriptor("localVar"));
}
private static void checkAnnotationsOnProperty(String expectedAnnotation, PropertyDescriptor prop) {
checkDescriptor(expectedAnnotation, prop);
checkDescriptor(expectedAnnotation, prop.getGetter());
PropertySetterDescriptor propSetter = prop.getSetter();
assertNotNull(propSetter);
checkAnnotationsOnFunction(expectedAnnotation, propSetter);
}
private static void checkAnnotationsOnFunction(String expectedAnnotation, FunctionDescriptor foo) {
checkDescriptor(expectedAnnotation, foo);
checkDescriptor(expectedAnnotation, getFunctionParameterDescriptor(foo, "param"));
}
@NotNull @NotNull
protected static FunctionDescriptor getFunctionDescriptor(@NotNull PackageViewDescriptor packageView, @NotNull String name) { protected static FunctionDescriptor getFunctionDescriptor(@NotNull PackageViewDescriptor packageView, @NotNull String name) {
Name functionName = Name.identifier(name); Name functionName = Name.identifier(name);
@@ -265,7 +279,7 @@ public abstract class AbstractAnnotationDescriptorResolveTest extends JetLiteFix
@NotNull @NotNull
protected PackageViewDescriptor getPackage(@NotNull String content) { protected PackageViewDescriptor getPackage(@NotNull String content) {
JetFile ktFile = JetTestUtils.createFile("dummy.kt", content, getProject()); JetFile ktFile = JetTestUtils.createFile("dummy.kt", content, getProject());
AnalyzeExhaust analyzeExhaust = JetTestUtils.analyzeFile(ktFile); AnalyzeExhaust analyzeExhaust = analyzeFile(ktFile);
context = analyzeExhaust.getBindingContext(); context = analyzeExhaust.getBindingContext();
PackageViewDescriptor packageView = analyzeExhaust.getModuleDescriptor().getPackage(PACKAGE); PackageViewDescriptor packageView = analyzeExhaust.getModuleDescriptor().getPackage(PACKAGE);
@@ -273,6 +287,11 @@ public abstract class AbstractAnnotationDescriptorResolveTest extends JetLiteFix
return packageView; return packageView;
} }
@NotNull
protected AnalyzeExhaust analyzeFile(@NotNull JetFile ktFile) {
return JetTestUtils.analyzeFile(ktFile);
}
protected static String getContent(@NotNull String annotationText) throws IOException { protected static String getContent(@NotNull String annotationText) throws IOException {
File file = new File(PATH); File file = new File(PATH);
return JetTestUtils.doLoadFile(file).replaceAll("ANNOTATION", annotationText); return JetTestUtils.doLoadFile(file).replaceAll("ANNOTATION", annotationText);
@@ -0,0 +1,30 @@
/*
* Copyright 2010-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.
*/
package org.jetbrains.jet.resolve.annotation
import org.jetbrains.jet.analyzer.AnalyzeExhaust
import org.jetbrains.jet.lang.psi.JetFile
import org.jetbrains.jet.JetTestUtils
class AnnotationDescriptorResolveWithoutAnalyzeBodyTest : AnnotationDescriptorResolveTest() {
override fun doTest(content: String, expectedAnnotation: String) {
checkAnnotationOnAllExceptLocalDeclarations(content, expectedAnnotation)
}
override fun analyzeFile(ktFile: JetFile): AnalyzeExhaust = JetTestUtils.analyzeFileWithoutBody(ktFile)
}
@@ -1,7 +1,7 @@
//package a { //package a {
val afoo = <error descr="[TYPECHECKER_HAS_RUN_INTO_RECURSIVE_PROBLEM] Type checking has run into a recursive problem. Easiest workaround: specify types of your declarations explicitly">abar()</error> val afoo = abar()
fun abar() = <error>afoo</error> fun abar() = <error descr="[TYPECHECKER_HAS_RUN_INTO_RECURSIVE_PROBLEM] Type checking has run into a recursive problem. Easiest workaround: specify types of your declarations explicitly">afoo</error>
//} //}
//package b { //package b {