Added platform static checker with provider implementation

This commit is contained in:
Michael Bogdanov
2014-09-15 14:38:29 +04:00
parent 9b065a89b9
commit b763aa9995
36 changed files with 443 additions and 52 deletions
@@ -22,6 +22,7 @@ import org.jetbrains.jet.storage.StorageManager;
import org.jetbrains.jet.lang.resolve.BindingTrace;
import org.jetbrains.jet.lang.descriptors.ModuleDescriptor;
import org.jetbrains.jet.lang.PlatformToKotlinClassMap;
import org.jetbrains.jet.lang.resolve.AdditionalCheckerProvider;
import org.jetbrains.jet.lang.resolve.BodyResolver;
import org.jetbrains.jet.lang.resolve.AnnotationResolver;
import org.jetbrains.jet.lang.resolve.calls.CallResolver;
@@ -57,6 +58,7 @@ public class InjectorForBodyResolve {
private final BindingTrace bindingTrace;
private final ModuleDescriptor moduleDescriptor;
private final PlatformToKotlinClassMap platformToKotlinClassMap;
private final AdditionalCheckerProvider additionalCheckerProvider;
private final BodyResolver bodyResolver;
private final AnnotationResolver annotationResolver;
private final CallResolver callResolver;
@@ -84,7 +86,8 @@ public class InjectorForBodyResolve {
@NotNull Project project,
@NotNull GlobalContext globalContext,
@NotNull BindingTrace bindingTrace,
@NotNull ModuleDescriptor moduleDescriptor
@NotNull ModuleDescriptor moduleDescriptor,
@NotNull AdditionalCheckerProvider additionalCheckerProvider
) {
this.project = project;
this.globalContext = globalContext;
@@ -92,6 +95,7 @@ public class InjectorForBodyResolve {
this.bindingTrace = bindingTrace;
this.moduleDescriptor = moduleDescriptor;
this.platformToKotlinClassMap = moduleDescriptor.getPlatformToKotlinClassMap();
this.additionalCheckerProvider = additionalCheckerProvider;
this.bodyResolver = new BodyResolver();
this.annotationResolver = new AnnotationResolver();
this.callResolver = new CallResolver();
@@ -146,6 +150,7 @@ public class InjectorForBodyResolve {
expressionTypingServices.setProject(project);
expressionTypingServices.setTypeResolver(typeResolver);
expressionTypingComponents.setAdditionalCheckerProvider(additionalCheckerProvider);
expressionTypingComponents.setCallResolver(callResolver);
expressionTypingComponents.setControlStructureTypingUtils(controlStructureTypingUtils);
expressionTypingComponents.setExpressionTypingServices(expressionTypingServices);
@@ -178,6 +183,7 @@ public class InjectorForBodyResolve {
controlFlowAnalyzer.setTrace(bindingTrace);
declarationsChecker.setAdditionalCheckerProvider(additionalCheckerProvider);
declarationsChecker.setDescriptorResolver(descriptorResolver);
declarationsChecker.setTrace(bindingTrace);
@@ -23,6 +23,7 @@ import org.jetbrains.jet.lang.descriptors.impl.ModuleDescriptorImpl;
import org.jetbrains.jet.lang.PlatformToKotlinClassMap;
import org.jetbrains.jet.lang.resolve.lazy.declarations.DeclarationProviderFactory;
import org.jetbrains.jet.lang.resolve.BindingTrace;
import org.jetbrains.jet.lang.resolve.AdditionalCheckerProvider;
import org.jetbrains.jet.lang.resolve.lazy.ResolveSession;
import org.jetbrains.jet.lang.resolve.AnnotationResolver;
import org.jetbrains.jet.lang.resolve.calls.CallResolver;
@@ -58,6 +59,7 @@ public class InjectorForLazyResolve {
private final PlatformToKotlinClassMap platformToKotlinClassMap;
private final DeclarationProviderFactory declarationProviderFactory;
private final BindingTrace bindingTrace;
private final AdditionalCheckerProvider additionalCheckerProvider;
private final ResolveSession resolveSession;
private final AnnotationResolver annotationResolver;
private final CallResolver callResolver;
@@ -85,7 +87,8 @@ public class InjectorForLazyResolve {
@NotNull GlobalContext globalContext,
@NotNull ModuleDescriptorImpl moduleDescriptor,
@NotNull DeclarationProviderFactory declarationProviderFactory,
@NotNull BindingTrace bindingTrace
@NotNull BindingTrace bindingTrace,
@NotNull AdditionalCheckerProvider additionalCheckerProvider
) {
this.project = project;
this.globalContext = globalContext;
@@ -94,6 +97,7 @@ public class InjectorForLazyResolve {
this.platformToKotlinClassMap = moduleDescriptor.getPlatformToKotlinClassMap();
this.declarationProviderFactory = declarationProviderFactory;
this.bindingTrace = bindingTrace;
this.additionalCheckerProvider = additionalCheckerProvider;
this.resolveSession = new ResolveSession(project, globalContext, moduleDescriptor, declarationProviderFactory, bindingTrace);
this.annotationResolver = new AnnotationResolver();
this.callResolver = new CallResolver();
@@ -145,6 +149,7 @@ public class InjectorForLazyResolve {
expressionTypingServices.setProject(project);
expressionTypingServices.setTypeResolver(typeResolver);
expressionTypingComponents.setAdditionalCheckerProvider(additionalCheckerProvider);
expressionTypingComponents.setCallResolver(callResolver);
expressionTypingComponents.setControlStructureTypingUtils(controlStructureTypingUtils);
expressionTypingComponents.setExpressionTypingServices(expressionTypingServices);
@@ -24,6 +24,7 @@ import org.jetbrains.jet.lang.types.expressions.ExpressionTypingComponents;
import org.jetbrains.jet.lang.resolve.calls.CallResolver;
import org.jetbrains.jet.context.GlobalContext;
import org.jetbrains.jet.storage.StorageManager;
import org.jetbrains.jet.lang.resolve.AdditionalCheckerProvider;
import org.jetbrains.jet.lang.resolve.AnnotationResolver;
import org.jetbrains.jet.lang.resolve.TypeResolver;
import org.jetbrains.jet.lang.resolve.QualifiedExpressionResolver;
@@ -53,6 +54,7 @@ public class InjectorForMacros {
private final CallResolver callResolver;
private final GlobalContext globalContext;
private final StorageManager storageManager;
private final AdditionalCheckerProvider additionalCheckerProvider;
private final AnnotationResolver annotationResolver;
private final TypeResolver typeResolver;
private final QualifiedExpressionResolver qualifiedExpressionResolver;
@@ -80,6 +82,7 @@ public class InjectorForMacros {
this.callResolver = new CallResolver();
this.globalContext = org.jetbrains.jet.context.ContextPackage.GlobalContext();
this.storageManager = globalContext.getStorageManager();
this.additionalCheckerProvider = org.jetbrains.jet.lang.resolve.AdditionalCheckerProvider.Empty.INSTANCE$;
this.annotationResolver = new AnnotationResolver();
this.typeResolver = new TypeResolver();
this.qualifiedExpressionResolver = new QualifiedExpressionResolver();
@@ -103,6 +106,7 @@ public class InjectorForMacros {
this.expressionTypingServices.setProject(project);
this.expressionTypingServices.setTypeResolver(typeResolver);
this.expressionTypingComponents.setAdditionalCheckerProvider(additionalCheckerProvider);
this.expressionTypingComponents.setCallResolver(callResolver);
this.expressionTypingComponents.setControlStructureTypingUtils(controlStructureTypingUtils);
this.expressionTypingComponents.setExpressionTypingServices(expressionTypingServices);
@@ -25,6 +25,7 @@ import org.jetbrains.jet.lang.PlatformToKotlinClassMap;
import org.jetbrains.jet.lang.resolve.TopDownAnalyzer;
import org.jetbrains.jet.lang.resolve.LazyTopDownAnalyzer;
import org.jetbrains.jet.lang.resolve.MutablePackageFragmentProvider;
import org.jetbrains.jet.lang.resolve.AdditionalCheckerProvider;
import org.jetbrains.jet.lang.resolve.BodyResolver;
import org.jetbrains.jet.lang.resolve.AnnotationResolver;
import org.jetbrains.jet.lang.resolve.calls.CallResolver;
@@ -70,6 +71,7 @@ public class InjectorForTopDownAnalyzerBasic {
private final TopDownAnalyzer topDownAnalyzer;
private final LazyTopDownAnalyzer lazyTopDownAnalyzer;
private final MutablePackageFragmentProvider mutablePackageFragmentProvider;
private final AdditionalCheckerProvider additionalCheckerProvider;
private final BodyResolver bodyResolver;
private final AnnotationResolver annotationResolver;
private final CallResolver callResolver;
@@ -104,7 +106,8 @@ public class InjectorForTopDownAnalyzerBasic {
@NotNull Project project,
@NotNull GlobalContext globalContext,
@NotNull BindingTrace bindingTrace,
@NotNull ModuleDescriptor moduleDescriptor
@NotNull ModuleDescriptor moduleDescriptor,
@NotNull AdditionalCheckerProvider additionalCheckerProvider
) {
this.project = project;
this.globalContext = globalContext;
@@ -115,6 +118,7 @@ public class InjectorForTopDownAnalyzerBasic {
this.topDownAnalyzer = new TopDownAnalyzer();
this.lazyTopDownAnalyzer = new LazyTopDownAnalyzer();
this.mutablePackageFragmentProvider = new MutablePackageFragmentProvider(getModuleDescriptor());
this.additionalCheckerProvider = additionalCheckerProvider;
this.bodyResolver = new BodyResolver();
this.annotationResolver = new AnnotationResolver();
this.callResolver = new CallResolver();
@@ -145,6 +149,7 @@ public class InjectorForTopDownAnalyzerBasic {
this.typeHierarchyResolver = new TypeHierarchyResolver();
this.scriptHeaderResolver = new ScriptHeaderResolver();
this.topDownAnalyzer.setAdditionalCheckerProvider(additionalCheckerProvider);
this.topDownAnalyzer.setBodyResolver(bodyResolver);
this.topDownAnalyzer.setDeclarationResolver(declarationResolver);
this.topDownAnalyzer.setLazyTopDownAnalyzer(lazyTopDownAnalyzer);
@@ -194,6 +199,7 @@ public class InjectorForTopDownAnalyzerBasic {
expressionTypingServices.setProject(project);
expressionTypingServices.setTypeResolver(typeResolver);
expressionTypingComponents.setAdditionalCheckerProvider(additionalCheckerProvider);
expressionTypingComponents.setCallResolver(callResolver);
expressionTypingComponents.setControlStructureTypingUtils(controlStructureTypingUtils);
expressionTypingComponents.setExpressionTypingServices(expressionTypingServices);
@@ -226,6 +232,7 @@ public class InjectorForTopDownAnalyzerBasic {
controlFlowAnalyzer.setTrace(bindingTrace);
declarationsChecker.setAdditionalCheckerProvider(additionalCheckerProvider);
declarationsChecker.setDescriptorResolver(descriptorResolver);
declarationsChecker.setTrace(bindingTrace);
@@ -0,0 +1,31 @@
/*
* 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.lang.resolve
import org.jetbrains.annotations.ReadOnly
import java.util.Collections
public trait AdditionalCheckerProvider {
public val annotationCheckers: List<AnnotationChecker>
public object Empty : AdditionalCheckerProvider {
override val annotationCheckers: List<AnnotationChecker> = listOf()
}
}
@@ -0,0 +1,29 @@
/*
* 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.lang.resolve
import org.jetbrains.jet.lang.psi.JetDeclaration
import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor
import org.jetbrains.jet.lang.descriptors.MemberDescriptor
import org.jetbrains.jet.lang.psi.JetDeclarationModifierList
import org.jetbrains.jet.lang.diagnostics.DiagnosticHolder
public trait AnnotationChecker {
public fun check(declaration: JetDeclaration, descriptor: MemberDescriptor, diagnosticHolder: DiagnosticHolder);
}
@@ -0,0 +1,33 @@
/*
* 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.lang.resolve.annotations
import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor
import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor
import org.jetbrains.jet.lang.resolve.name.FqName
import org.jetbrains.jet.lang.descriptors.CallableDescriptor
import org.jetbrains.jet.lang.resolve.DescriptorUtils
public fun DeclarationDescriptor.hasPlatformStaticAnnotation(): Boolean {
return getAnnotations().findAnnotation(FqName("kotlin.platform.platformStatic")) != null
}
public fun CallableDescriptor.isPlatformStaticInObject(): Boolean =
DescriptorUtils.isObject(getContainingDeclaration()) && hasPlatformStaticAnnotation()
public fun CallableDescriptor.isPlatformStaticInClassObject(): Boolean =
DescriptorUtils.isClassObject(getContainingDeclaration()) && hasPlatformStaticAnnotation()
@@ -44,6 +44,9 @@ public class DeclarationsChecker {
@NotNull
private DescriptorResolver descriptorResolver;
@NotNull
private AdditionalCheckerProvider additionalCheckerProvider;
@Inject
public void setTrace(@NotNull BindingTrace trace) {
this.trace = trace;
@@ -55,6 +58,11 @@ public class DeclarationsChecker {
this.descriptorResolver = descriptorResolver;
}
@Inject
public void setAdditionalCheckerProvider(@NotNull AdditionalCheckerProvider additionalCheckerProvider) {
this.additionalCheckerProvider = additionalCheckerProvider;
}
public void process(@NotNull BodiesResolveContext bodiesResolveContext) {
for (JetFile file : bodiesResolveContext.getFiles()) {
checkModifiersAndAnnotationsInPackageDirective(file);
@@ -80,6 +88,7 @@ public class DeclarationsChecker {
}
modifiersChecker.checkModifiersForDeclaration(classOrObject, classDescriptor);
runAnnotationCheckers(classOrObject, classDescriptor);
}
Map<JetNamedFunction, SimpleFunctionDescriptor> functions = bodiesResolveContext.getFunctions();
@@ -90,6 +99,7 @@ public class DeclarationsChecker {
if (!bodiesResolveContext.completeAnalysisNeeded(function)) continue;
checkFunction(function, functionDescriptor);
modifiersChecker.checkModifiersForDeclaration(function, functionDescriptor);
runAnnotationCheckers(function, functionDescriptor);
}
Map<JetProperty, PropertyDescriptor> properties = bodiesResolveContext.getProperties();
@@ -100,6 +110,7 @@ public class DeclarationsChecker {
if (!bodiesResolveContext.completeAnalysisNeeded(property)) continue;
checkProperty(property, propertyDescriptor);
modifiersChecker.checkModifiersForDeclaration(property, propertyDescriptor);
runAnnotationCheckers(property, propertyDescriptor);
}
}
@@ -559,4 +570,10 @@ public class DeclarationsChecker {
}
}
}
private void runAnnotationCheckers(@NotNull JetDeclaration declaration, @NotNull MemberDescriptor descriptor) {
for (AnnotationChecker checker : additionalCheckerProvider.getAnnotationCheckers()) {
checker.check(declaration, descriptor, trace);
}
}
}
@@ -62,6 +62,8 @@ public class TopDownAnalyzer {
@NotNull
private BodyResolver bodyResolver;
@NotNull
private AdditionalCheckerProvider additionalCheckerProvider;
@NotNull
private Project project;
@NotNull
@@ -117,6 +119,11 @@ public class TopDownAnalyzer {
this.lazyTopDownAnalyzer = lazyTopDownAnalyzer;
}
@Inject
public void setAdditionalCheckerProvider(@NotNull AdditionalCheckerProvider additionalCheckerProvider) {
this.additionalCheckerProvider = additionalCheckerProvider;
}
public void doProcess(
@NotNull TopDownAnalysisContext c,
@NotNull JetScope outerScope,
@@ -132,7 +139,8 @@ public class TopDownAnalyzer {
new GlobalContextImpl((LockBasedStorageManager) c.getStorageManager(), c.getExceptionTracker()), // TODO
(ModuleDescriptorImpl) moduleDescriptor, // TODO
new FileBasedDeclarationProviderFactory(c.getStorageManager(), getFiles(declarations)),
trace
trace,
additionalCheckerProvider
).getResolveSession();
lazyTopDownAnalyzer.analyzeDeclarations(
@@ -193,7 +201,8 @@ public class TopDownAnalyzer {
@Nullable final WritableScope scope,
@NotNull ExpressionTypingContext context,
@NotNull final DeclarationDescriptor containingDeclaration,
@NotNull JetClassOrObject object
@NotNull JetClassOrObject object,
@NotNull AdditionalCheckerProvider additionalCheckerProvider
) {
TopDownAnalysisParameters topDownAnalysisParameters =
TopDownAnalysisParameters.createForLocalDeclarations(
@@ -203,7 +212,11 @@ public class TopDownAnalyzer {
);
InjectorForTopDownAnalyzerBasic injector = new InjectorForTopDownAnalyzerBasic(
object.getProject(), topDownAnalysisParameters, context.trace, DescriptorUtils.getContainingModule(containingDeclaration)
object.getProject(),
topDownAnalysisParameters,
context.trace,
DescriptorUtils.getContainingModule(containingDeclaration),
additionalCheckerProvider
);
TopDownAnalysisContext c = new TopDownAnalysisContext(topDownAnalysisParameters);
@@ -89,7 +89,7 @@ public class ClosureExpressionsTypingVisitor extends ExpressionTypingVisitor {
null, // don't need to add classifier of object literal to any scope
context.replaceBindingTrace(traceAdapter).replaceContextDependency(INDEPENDENT),
context.scope.getContainingDeclaration(),
expression.getObjectDeclaration());
expression.getObjectDeclaration(), components.additionalCheckerProvider);
DelegatingBindingTrace cloneDelta = new DelegatingBindingTrace(
new BindingTraceContext().getBindingContext(), "cached delta trace for object literal expression resolve", expression);
@@ -20,6 +20,7 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.context.GlobalContext;
import org.jetbrains.jet.lang.PlatformToKotlinClassMap;
import org.jetbrains.jet.lang.reflect.ReflectionTypes;
import org.jetbrains.jet.lang.resolve.AdditionalCheckerProvider;
import org.jetbrains.jet.lang.resolve.calls.CallResolver;
import javax.inject.Inject;
@@ -33,6 +34,7 @@ public class ExpressionTypingComponents {
/*package*/ ControlStructureTypingUtils controlStructureTypingUtils;
/*package*/ ForLoopConventionsChecker forLoopConventionsChecker;
/*package*/ ReflectionTypes reflectionTypes;
/*package*/ AdditionalCheckerProvider additionalCheckerProvider;
@Inject
public void setGlobalContext(@NotNull GlobalContext globalContext) {
@@ -74,6 +76,11 @@ public class ExpressionTypingComponents {
this.reflectionTypes = reflectionTypes;
}
@Inject
public void setAdditionalCheckerProvider(AdditionalCheckerProvider additionalCheckerProvider) {
this.additionalCheckerProvider = additionalCheckerProvider;
}
@NotNull
public ForLoopConventionsChecker getForLoopConventionsChecker() {
return forLoopConventionsChecker;
@@ -89,7 +89,8 @@ public class ExpressionTypingVisitorForStatements extends ExpressionTypingVisito
public JetTypeInfo visitObjectDeclaration(@NotNull JetObjectDeclaration declaration, ExpressionTypingContext context) {
TopDownAnalyzer.processClassOrObject(
components.globalContext,
scope, context.replaceScope(scope).replaceContextDependency(INDEPENDENT), scope.getContainingDeclaration(), declaration);
scope, context.replaceScope(scope).replaceContextDependency(INDEPENDENT), scope.getContainingDeclaration(), declaration,
components.additionalCheckerProvider);
return DataFlowUtils.checkStatementType(declaration, context, context.dataFlowInfo);
}
@@ -185,7 +186,8 @@ public class ExpressionTypingVisitorForStatements extends ExpressionTypingVisito
public JetTypeInfo visitClass(@NotNull JetClass klass, ExpressionTypingContext context) {
TopDownAnalyzer.processClassOrObject(
components.globalContext,
scope, context.replaceScope(scope).replaceContextDependency(INDEPENDENT), scope.getContainingDeclaration(), klass);
scope, context.replaceScope(scope).replaceContextDependency(INDEPENDENT), scope.getContainingDeclaration(), klass,
components.additionalCheckerProvider);
return DataFlowUtils.checkStatementType(klass, context, context.dataFlowInfo);
}