JS frontend: added checkers for nativeInvoke, nativeGetter, nativeSetter.
This commit is contained in:
@@ -367,6 +367,7 @@
|
|||||||
|
|
||||||
<fileset dir="idea/src">
|
<fileset dir="idea/src">
|
||||||
<include name="META-INF/extensions/common.xml"/>
|
<include name="META-INF/extensions/common.xml"/>
|
||||||
|
<include name="META-INF/extensions/kotlin2jvm.xml"/>
|
||||||
<include name="META-INF/extensions/kotlin2js.xml"/>
|
<include name="META-INF/extensions/kotlin2js.xml"/>
|
||||||
</fileset>
|
</fileset>
|
||||||
|
|
||||||
|
|||||||
-1
@@ -1 +0,0 @@
|
|||||||
org.jetbrains.jet.lang.resolve.java.diagnostics.DefaultErrorMessagesJvm
|
|
||||||
+5
-2
@@ -17,6 +17,8 @@
|
|||||||
package org.jetbrains.jet.lang.diagnostics.rendering;
|
package org.jetbrains.jet.lang.diagnostics.rendering;
|
||||||
|
|
||||||
import com.google.common.collect.ImmutableList;
|
import com.google.common.collect.ImmutableList;
|
||||||
|
import com.intellij.openapi.extensions.ExtensionPointName;
|
||||||
|
import com.intellij.openapi.extensions.Extensions;
|
||||||
import kotlin.Function1;
|
import kotlin.Function1;
|
||||||
import kotlin.KotlinPackage;
|
import kotlin.KotlinPackage;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
@@ -35,7 +37,6 @@ import java.lang.reflect.Field;
|
|||||||
import java.lang.reflect.Modifier;
|
import java.lang.reflect.Modifier;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.ServiceLoader;
|
|
||||||
|
|
||||||
import static org.jetbrains.jet.lang.diagnostics.Errors.*;
|
import static org.jetbrains.jet.lang.diagnostics.Errors.*;
|
||||||
import static org.jetbrains.jet.lang.diagnostics.rendering.Renderers.*;
|
import static org.jetbrains.jet.lang.diagnostics.rendering.Renderers.*;
|
||||||
@@ -44,6 +45,8 @@ import static org.jetbrains.jet.renderer.DescriptorRenderer.*;
|
|||||||
public class DefaultErrorMessages {
|
public class DefaultErrorMessages {
|
||||||
|
|
||||||
public interface Extension {
|
public interface Extension {
|
||||||
|
ExtensionPointName<Extension> EP_NAME = ExtensionPointName.create("org.jetbrains.kotlin.defaultErrorMessages");
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
DiagnosticFactoryToRendererMap getMap();
|
DiagnosticFactoryToRendererMap getMap();
|
||||||
}
|
}
|
||||||
@@ -52,7 +55,7 @@ public class DefaultErrorMessages {
|
|||||||
public static final List<DiagnosticFactoryToRendererMap> MAPS = ImmutableList.<DiagnosticFactoryToRendererMap>builder()
|
public static final List<DiagnosticFactoryToRendererMap> MAPS = ImmutableList.<DiagnosticFactoryToRendererMap>builder()
|
||||||
.addAll(
|
.addAll(
|
||||||
KotlinPackage.map(
|
KotlinPackage.map(
|
||||||
ServiceLoader.load(Extension.class, DefaultErrorMessages.class.getClassLoader()),
|
Extensions.getExtensions(Extension.EP_NAME),
|
||||||
new Function1<Extension, DiagnosticFactoryToRendererMap>() {
|
new Function1<Extension, DiagnosticFactoryToRendererMap>() {
|
||||||
@Override
|
@Override
|
||||||
public DiagnosticFactoryToRendererMap invoke(Extension extension) {
|
public DiagnosticFactoryToRendererMap invoke(Extension extension) {
|
||||||
|
|||||||
@@ -24,6 +24,6 @@
|
|||||||
<orderEntry type="library" scope="TEST" name="kotlin-runtime" level="project" />
|
<orderEntry type="library" scope="TEST" name="kotlin-runtime" level="project" />
|
||||||
<orderEntry type="library" scope="TEST" name="jps-test" level="project" />
|
<orderEntry type="library" scope="TEST" name="jps-test" level="project" />
|
||||||
<orderEntry type="module" module-name="js.dart-ast" />
|
<orderEntry type="module" module-name="js.dart-ast" />
|
||||||
|
<orderEntry type="module" module-name="js.frontend" />
|
||||||
</component>
|
</component>
|
||||||
</module>
|
</module>
|
||||||
|
|
||||||
|
|||||||
@@ -48,6 +48,7 @@ import org.jetbrains.jet.context.LazyResolveToken
|
|||||||
import org.jetbrains.jet.lang.resolve.java.JavaLazyAnalyzerPostConstruct
|
import org.jetbrains.jet.lang.resolve.java.JavaLazyAnalyzerPostConstruct
|
||||||
import org.jetbrains.jet.lang.resolve.java.JavaDescriptorResolverPostConstruct
|
import org.jetbrains.jet.lang.resolve.java.JavaDescriptorResolverPostConstruct
|
||||||
import org.jetbrains.jet.lang.resolve.lazy.ScopeProvider
|
import org.jetbrains.jet.lang.resolve.lazy.ScopeProvider
|
||||||
|
import org.jetbrains.k2js.resolve.KotlinJsDeclarationCheckerProvider
|
||||||
|
|
||||||
// NOTE: After making changes, you need to re-generate the injectors.
|
// NOTE: After making changes, you need to re-generate the injectors.
|
||||||
// To do that, you can run main in this file.
|
// To do that, you can run main in this file.
|
||||||
@@ -132,7 +133,7 @@ private fun generatorForTopDownAnalyzerForJs() =
|
|||||||
|
|
||||||
field(javaClass<MutablePackageFragmentProvider>())
|
field(javaClass<MutablePackageFragmentProvider>())
|
||||||
field(javaClass<AdditionalCheckerProvider>(),
|
field(javaClass<AdditionalCheckerProvider>(),
|
||||||
init = GivenExpression(javaClass<AdditionalCheckerProvider.Empty>().getCanonicalName() + ".INSTANCE$"))
|
init = GivenExpression(javaClass<KotlinJsDeclarationCheckerProvider>().getName() + ".INSTANCE$"))
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun generatorForTopDownAnalyzerForJvm() =
|
private fun generatorForTopDownAnalyzerForJvm() =
|
||||||
|
|||||||
@@ -18,8 +18,6 @@ package org.jetbrains.jet.plugin.caches.resolve
|
|||||||
|
|
||||||
import org.jetbrains.jet.lang.resolve.lazy.ResolveSession
|
import org.jetbrains.jet.lang.resolve.lazy.ResolveSession
|
||||||
import org.jetbrains.jet.analyzer.ResolverForModule
|
import org.jetbrains.jet.analyzer.ResolverForModule
|
||||||
import org.jetbrains.jet.lang.psi.JetFile
|
|
||||||
import com.intellij.psi.search.GlobalSearchScope
|
|
||||||
import org.jetbrains.jet.analyzer.PlatformAnalysisParameters
|
import org.jetbrains.jet.analyzer.PlatformAnalysisParameters
|
||||||
import org.jetbrains.jet.analyzer.AnalyzerFacade
|
import org.jetbrains.jet.analyzer.AnalyzerFacade
|
||||||
import com.intellij.openapi.project.Project
|
import com.intellij.openapi.project.Project
|
||||||
@@ -33,7 +31,7 @@ import org.jetbrains.jet.di.InjectorForLazyResolve
|
|||||||
import org.jetbrains.jet.lang.descriptors.impl.ModuleDescriptorImpl
|
import org.jetbrains.jet.lang.descriptors.impl.ModuleDescriptorImpl
|
||||||
import org.jetbrains.jet.analyzer.ModuleInfo
|
import org.jetbrains.jet.analyzer.ModuleInfo
|
||||||
import org.jetbrains.jet.analyzer.ModuleContent
|
import org.jetbrains.jet.analyzer.ModuleContent
|
||||||
import org.jetbrains.jet.lang.resolve.AdditionalCheckerProvider
|
import org.jetbrains.k2js.resolve.KotlinJsDeclarationCheckerProvider
|
||||||
|
|
||||||
public class JsResolverForModule(
|
public class JsResolverForModule(
|
||||||
override val lazyResolveSession: ResolveSession
|
override val lazyResolveSession: ResolveSession
|
||||||
@@ -55,7 +53,7 @@ public object JsAnalyzerFacade : AnalyzerFacade<JsResolverForModule, PlatformAna
|
|||||||
project, globalContext.storageManager, syntheticFiles, moduleContentScope
|
project, globalContext.storageManager, syntheticFiles, moduleContentScope
|
||||||
)
|
)
|
||||||
|
|
||||||
val injector = InjectorForLazyResolve(project, globalContext, moduleDescriptor, declarationProviderFactory, BindingTraceContext(), AdditionalCheckerProvider.Empty)
|
val injector = InjectorForLazyResolve(project, globalContext, moduleDescriptor, declarationProviderFactory, BindingTraceContext(), KotlinJsDeclarationCheckerProvider)
|
||||||
val resolveSession = injector.getResolveSession()!!
|
val resolveSession = injector.getResolveSession()!!
|
||||||
moduleDescriptor.initialize(resolveSession.getPackageFragmentProvider())
|
moduleDescriptor.initialize(resolveSession.getPackageFragmentProvider())
|
||||||
return JsResolverForModule(resolveSession)
|
return JsResolverForModule(resolveSession)
|
||||||
|
|||||||
@@ -19,11 +19,12 @@ package org.jetbrains.jet.plugin.project;
|
|||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.jet.lang.resolve.AdditionalCheckerProvider;
|
import org.jetbrains.jet.lang.resolve.AdditionalCheckerProvider;
|
||||||
import org.jetbrains.jet.lang.resolve.kotlin.JavaDeclarationCheckerProvider;
|
import org.jetbrains.jet.lang.resolve.kotlin.JavaDeclarationCheckerProvider;
|
||||||
|
import org.jetbrains.k2js.resolve.KotlinJsDeclarationCheckerProvider;
|
||||||
|
|
||||||
public interface TargetPlatform {
|
public interface TargetPlatform {
|
||||||
@NotNull
|
@NotNull
|
||||||
AdditionalCheckerProvider getAdditionalCheckerProvider();
|
AdditionalCheckerProvider getAdditionalCheckerProvider();
|
||||||
|
|
||||||
TargetPlatform JVM = new TargetPlatformImpl("JVM", JavaDeclarationCheckerProvider.INSTANCE$);
|
TargetPlatform JVM = new TargetPlatformImpl("JVM", JavaDeclarationCheckerProvider.INSTANCE$);
|
||||||
TargetPlatform JS = new TargetPlatformImpl("JS");
|
TargetPlatform JS = new TargetPlatformImpl("JS", KotlinJsDeclarationCheckerProvider.INSTANCE$);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,6 +2,8 @@
|
|||||||
<id>org.jetbrains.kotlin</id>
|
<id>org.jetbrains.kotlin</id>
|
||||||
|
|
||||||
<extensionPoints>
|
<extensionPoints>
|
||||||
|
<extensionPoint name="defaultErrorMessages"
|
||||||
|
interface="org.jetbrains.jet.lang.diagnostics.rendering.DefaultErrorMessages$Extension"/>
|
||||||
<extensionPoint name="suppressStringProvider"
|
<extensionPoint name="suppressStringProvider"
|
||||||
interface="org.jetbrains.jet.lang.resolve.DiagnosticsWithSuppression$SuppressStringProvider"/>
|
interface="org.jetbrains.jet.lang.resolve.DiagnosticsWithSuppression$SuppressStringProvider"/>
|
||||||
<extensionPoint name="diagnosticSuppressor"
|
<extensionPoint name="diagnosticSuppressor"
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
<id>org.jetbrains.kotlin</id>
|
<id>org.jetbrains.kotlin</id>
|
||||||
|
|
||||||
<extensions defaultExtensionNs="org.jetbrains.kotlin">
|
<extensions defaultExtensionNs="org.jetbrains.kotlin">
|
||||||
|
<defaultErrorMessages implementation="org.jetbrains.k2js.resolve.diagnostics.DefaultErrorMessagesJs"/>
|
||||||
<suppressStringProvider implementation="org.jetbrains.k2js.analyze.SuppressUnusedParameterForJsNative"/>
|
<suppressStringProvider implementation="org.jetbrains.k2js.analyze.SuppressUnusedParameterForJsNative"/>
|
||||||
<diagnosticSuppressor implementation="org.jetbrains.k2js.analyze.SuppressWarningsFromExternalModules"/>
|
<diagnosticSuppressor implementation="org.jetbrains.k2js.analyze.SuppressWarningsFromExternalModules"/>
|
||||||
</extensions>
|
</extensions>
|
||||||
|
|||||||
@@ -0,0 +1,7 @@
|
|||||||
|
<idea-plugin>
|
||||||
|
<id>org.jetbrains.kotlin</id>
|
||||||
|
|
||||||
|
<extensions defaultExtensionNs="org.jetbrains.kotlin">
|
||||||
|
<defaultErrorMessages implementation="org.jetbrains.jet.lang.resolve.java.diagnostics.DefaultErrorMessagesJvm"/>
|
||||||
|
</extensions>
|
||||||
|
</idea-plugin>
|
||||||
@@ -827,6 +827,7 @@
|
|||||||
</extensionPoints>
|
</extensionPoints>
|
||||||
|
|
||||||
<extensions defaultExtensionNs="org.jetbrains.kotlin">
|
<extensions defaultExtensionNs="org.jetbrains.kotlin">
|
||||||
|
<xi:include href="extensions/kotlin2jvm.xml" xpointer="xpointer(/idea-plugin/extensions/*)"/>
|
||||||
<xi:include href="extensions/kotlin2js.xml" xpointer="xpointer(/idea-plugin/extensions/*)"/>
|
<xi:include href="extensions/kotlin2js.xml" xpointer="xpointer(/idea-plugin/extensions/*)"/>
|
||||||
</extensions>
|
</extensions>
|
||||||
|
|
||||||
|
|||||||
@@ -137,7 +137,7 @@ public class InjectorForTopDownAnalyzerForJs {
|
|||||||
this.resolveSession = new ResolveSession(project, globalContext, module, declarationProviderFactory, bindingTrace);
|
this.resolveSession = new ResolveSession(project, globalContext, module, declarationProviderFactory, bindingTrace);
|
||||||
this.lazyTopDownAnalyzer = new LazyTopDownAnalyzer();
|
this.lazyTopDownAnalyzer = new LazyTopDownAnalyzer();
|
||||||
this.mutablePackageFragmentProvider = new MutablePackageFragmentProvider(module);
|
this.mutablePackageFragmentProvider = new MutablePackageFragmentProvider(module);
|
||||||
this.additionalCheckerProvider = org.jetbrains.jet.lang.resolve.AdditionalCheckerProvider.Empty.INSTANCE$;
|
this.additionalCheckerProvider = org.jetbrains.k2js.resolve.KotlinJsDeclarationCheckerProvider.INSTANCE$;
|
||||||
this.annotationResolver = new AnnotationResolver();
|
this.annotationResolver = new AnnotationResolver();
|
||||||
this.callResolver = new CallResolver();
|
this.callResolver = new CallResolver();
|
||||||
this.argumentTypeResolver = new ArgumentTypeResolver();
|
this.argumentTypeResolver = new ArgumentTypeResolver();
|
||||||
|
|||||||
@@ -17,14 +17,17 @@
|
|||||||
package org.jetbrains.k2js
|
package org.jetbrains.k2js
|
||||||
|
|
||||||
import kotlin.properties.Delegates
|
import kotlin.properties.Delegates
|
||||||
|
import org.jetbrains.jet.lang.resolve.name.FqName
|
||||||
|
|
||||||
public enum class PredefinedAnnotation(public val fqName: String) {
|
public enum class PredefinedAnnotation(fqName: String) {
|
||||||
LIBRARY : PredefinedAnnotation("kotlin.js.library")
|
LIBRARY : PredefinedAnnotation("kotlin.js.library")
|
||||||
NATIVE : PredefinedAnnotation("kotlin.js.native")
|
NATIVE : PredefinedAnnotation("kotlin.js.native")
|
||||||
NATIVE_INVOKE : PredefinedAnnotation("kotlin.js.nativeInvoke")
|
NATIVE_INVOKE : PredefinedAnnotation("kotlin.js.nativeInvoke")
|
||||||
NATIVE_GETTER : PredefinedAnnotation("kotlin.js.nativeGetter")
|
NATIVE_GETTER : PredefinedAnnotation("kotlin.js.nativeGetter")
|
||||||
NATIVE_SETTER : PredefinedAnnotation("kotlin.js.nativeSetter")
|
NATIVE_SETTER : PredefinedAnnotation("kotlin.js.nativeSetter")
|
||||||
|
|
||||||
|
public val fqName: FqName = FqName(fqName)
|
||||||
|
|
||||||
class object {
|
class object {
|
||||||
// TODO: replace with straight assignment when KT-5761 will be fixed
|
// TODO: replace with straight assignment when KT-5761 will be fixed
|
||||||
val WITH_CUSTOM_NAME by Delegates.lazy { setOf(LIBRARY, NATIVE) }
|
val WITH_CUSTOM_NAME by Delegates.lazy { setOf(LIBRARY, NATIVE) }
|
||||||
|
|||||||
@@ -19,7 +19,6 @@ package org.jetbrains.k2js.analyze
|
|||||||
import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor
|
import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor
|
||||||
import org.jetbrains.jet.lang.resolve.DescriptorUtils
|
import org.jetbrains.jet.lang.resolve.DescriptorUtils
|
||||||
import org.jetbrains.jet.lang.diagnostics.Errors
|
import org.jetbrains.jet.lang.diagnostics.Errors
|
||||||
import org.jetbrains.jet.lang.resolve.name.FqNameUnsafe
|
|
||||||
import org.jetbrains.jet.lang.resolve.DiagnosticsWithSuppression
|
import org.jetbrains.jet.lang.resolve.DiagnosticsWithSuppression
|
||||||
import org.jetbrains.k2js.PredefinedAnnotation
|
import org.jetbrains.k2js.PredefinedAnnotation
|
||||||
import org.jetbrains.jet.lang.diagnostics.Diagnostic
|
import org.jetbrains.jet.lang.diagnostics.Diagnostic
|
||||||
@@ -30,7 +29,7 @@ import org.jetbrains.k2js.config.LibrarySourcesConfig
|
|||||||
class SuppressUnusedParameterForJsNative : DiagnosticsWithSuppression.SuppressStringProvider {
|
class SuppressUnusedParameterForJsNative : DiagnosticsWithSuppression.SuppressStringProvider {
|
||||||
override fun get(annotationDescriptor: AnnotationDescriptor): List<String> {
|
override fun get(annotationDescriptor: AnnotationDescriptor): List<String> {
|
||||||
val descriptor = DescriptorUtils.getClassDescriptorForType(annotationDescriptor.getType())
|
val descriptor = DescriptorUtils.getClassDescriptorForType(annotationDescriptor.getType())
|
||||||
if (PredefinedAnnotation.NATIVE.fqName == DescriptorUtils.getFqName(descriptor).asString()) {
|
if (PredefinedAnnotation.NATIVE.fqName == DescriptorUtils.getFqNameSafe(descriptor)) {
|
||||||
return listOf(Errors.UNUSED_PARAMETER.getName().toLowerCase())
|
return listOf(Errors.UNUSED_PARAMETER.getName().toLowerCase())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,101 @@
|
|||||||
|
/*
|
||||||
|
* 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.k2js.resolve
|
||||||
|
|
||||||
|
import org.jetbrains.jet.lang.resolve.AdditionalCheckerProvider
|
||||||
|
import org.jetbrains.jet.lang.resolve.AnnotationChecker
|
||||||
|
import org.jetbrains.jet.lang.psi.JetDeclaration
|
||||||
|
import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor
|
||||||
|
import org.jetbrains.jet.lang.diagnostics.DiagnosticSink
|
||||||
|
import org.jetbrains.jet.lang.descriptors.FunctionDescriptor
|
||||||
|
import org.jetbrains.jet.lang.psi.JetNamedFunction
|
||||||
|
import org.jetbrains.k2js.resolve.diagnostics.ErrorsJs
|
||||||
|
import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns
|
||||||
|
import org.jetbrains.jet.lang.types.TypeUtils
|
||||||
|
import org.jetbrains.k2js.PredefinedAnnotation
|
||||||
|
import org.jetbrains.jet.lang.resolve.DescriptorUtils
|
||||||
|
import org.jetbrains.k2js.translate.utils.AnnotationsUtils
|
||||||
|
import org.jetbrains.jet.lang.descriptors.Visibilities
|
||||||
|
|
||||||
|
public object KotlinJsDeclarationCheckerProvider : AdditionalCheckerProvider {
|
||||||
|
override val annotationCheckers: List<AnnotationChecker> = listOf(NativeInvokeChecker(), NativeGetterChecker(), NativeSetterChecker())
|
||||||
|
}
|
||||||
|
|
||||||
|
private abstract class AbstractNativeAnnotationsChecker(private val requiredAnnotation: PredefinedAnnotation) : AnnotationChecker {
|
||||||
|
|
||||||
|
open fun additionalCheck(declaration: JetNamedFunction, descriptor: FunctionDescriptor, diagnosticHolder: DiagnosticSink) {}
|
||||||
|
|
||||||
|
override fun check(declaration: JetDeclaration, descriptor: DeclarationDescriptor, diagnosticHolder: DiagnosticSink) {
|
||||||
|
val annotationDescriptor = descriptor.getAnnotations().findAnnotation(requiredAnnotation.fqName)
|
||||||
|
if (annotationDescriptor == null) return
|
||||||
|
|
||||||
|
if (declaration !is JetNamedFunction || descriptor !is FunctionDescriptor) {
|
||||||
|
diagnosticHolder.report(ErrorsJs.NATIVE_ANNOTATIONS_ALLOWED_ONLY_ON_MEMBER_OR_EXTENSION_FUN.on(declaration, annotationDescriptor.getType()))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
val isTopLevel = DescriptorUtils.isTopLevelDeclaration(descriptor)
|
||||||
|
val hasLocalVisibility = descriptor.getVisibility() == Visibilities.LOCAL
|
||||||
|
val isExtension = DescriptorUtils.isExtension(descriptor)
|
||||||
|
|
||||||
|
if (!isTopLevel && !hasLocalVisibility && isExtension ||
|
||||||
|
(isTopLevel || hasLocalVisibility) && !isExtension ||
|
||||||
|
!((isTopLevel || hasLocalVisibility) && isExtension) && !AnnotationsUtils.isNativeObject(descriptor)
|
||||||
|
) {
|
||||||
|
diagnosticHolder.report(ErrorsJs.NATIVE_ANNOTATIONS_ALLOWED_ONLY_ON_MEMBER_OR_EXTENSION_FUN.on(declaration, annotationDescriptor.getType()))
|
||||||
|
}
|
||||||
|
|
||||||
|
additionalCheck(declaration, descriptor, diagnosticHolder)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class NativeInvokeChecker : AbstractNativeAnnotationsChecker(PredefinedAnnotation.NATIVE_INVOKE)
|
||||||
|
|
||||||
|
private abstract class AbstractNativeIndexerChecker(
|
||||||
|
requiredAnnotation: PredefinedAnnotation,
|
||||||
|
private val indexerKind: String,
|
||||||
|
private val requiredParametersCount: Int
|
||||||
|
) : AbstractNativeAnnotationsChecker(requiredAnnotation) {
|
||||||
|
|
||||||
|
override fun additionalCheck(declaration: JetNamedFunction, descriptor: FunctionDescriptor, diagnosticHolder: DiagnosticSink) {
|
||||||
|
val parameters = descriptor.getValueParameters()
|
||||||
|
if (parameters.size() > 0) {
|
||||||
|
val firstParamClassDescriptor = DescriptorUtils.getClassDescriptorForType(parameters.get(0).getType())
|
||||||
|
if (firstParamClassDescriptor != KotlinBuiltIns.getInstance().getString() &&
|
||||||
|
!DescriptorUtils.isSubclass(firstParamClassDescriptor, KotlinBuiltIns.getInstance().getNumber())
|
||||||
|
) {
|
||||||
|
diagnosticHolder.report(ErrorsJs.NATIVE_INDEXER_KEY_SHOULD_BE_STRING_OR_NUMBER.on(declaration.getValueParameters().first, indexerKind))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (parameters.size() != requiredParametersCount) {
|
||||||
|
diagnosticHolder.report(ErrorsJs.NATIVE_INDEXER_WRONG_PARAMETER_COUNT.on(declaration, requiredParametersCount, indexerKind))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class NativeGetterChecker : AbstractNativeIndexerChecker(PredefinedAnnotation.NATIVE_GETTER, "getter", requiredParametersCount = 1) {
|
||||||
|
override fun additionalCheck(declaration: JetNamedFunction, descriptor: FunctionDescriptor, diagnosticHolder: DiagnosticSink) {
|
||||||
|
super.additionalCheck(declaration, descriptor, diagnosticHolder)
|
||||||
|
|
||||||
|
if (!TypeUtils.isNullableType(descriptor.getReturnType())) {
|
||||||
|
diagnosticHolder.report(ErrorsJs.NATIVE_GETTER_RETURN_TYPE_SHOULD_BE_NULLABLE.on(declaration))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class NativeSetterChecker : AbstractNativeIndexerChecker(PredefinedAnnotation.NATIVE_SETTER, "setter", requiredParametersCount = 2)
|
||||||
@@ -0,0 +1,39 @@
|
|||||||
|
/*
|
||||||
|
* 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.k2js.resolve.diagnostics
|
||||||
|
|
||||||
|
import org.jetbrains.jet.lang.diagnostics.rendering.DefaultErrorMessages
|
||||||
|
import org.jetbrains.jet.lang.diagnostics.rendering.DiagnosticFactoryToRendererMap
|
||||||
|
import org.jetbrains.jet.lang.diagnostics.rendering.Renderers
|
||||||
|
import kotlin.properties.Delegates
|
||||||
|
|
||||||
|
private val DIAGNOSTIC_FACTORY_TO_RENDERER by Delegates.lazy {
|
||||||
|
with(DiagnosticFactoryToRendererMap()) {
|
||||||
|
|
||||||
|
put(ErrorsJs.NATIVE_ANNOTATIONS_ALLOWED_ONLY_ON_MEMBER_OR_EXTENSION_FUN,
|
||||||
|
"Annotation ''{0}'' is allowed only on member functions of declaration annotated as ''kotlin.js.native'' or on toplevel extension functions", Renderers.RENDER_TYPE)
|
||||||
|
put(ErrorsJs.NATIVE_INDEXER_KEY_SHOULD_BE_STRING_OR_NUMBER, "Native {0}''s first parameter type should be ''kotlin.String'' or subtype of ''kotlin.Number''", Renderers.STRING)
|
||||||
|
put(ErrorsJs.NATIVE_GETTER_RETURN_TYPE_SHOULD_BE_NULLABLE, "Native getter''s return type should be nullable")
|
||||||
|
put(ErrorsJs.NATIVE_INDEXER_WRONG_PARAMETER_COUNT, "Expected {0} parameters for native {1}", Renderers.TO_STRING, Renderers.STRING)
|
||||||
|
|
||||||
|
this
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class DefaultErrorMessagesJs : DefaultErrorMessages.Extension {
|
||||||
|
override fun getMap(): DiagnosticFactoryToRendererMap = DIAGNOSTIC_FACTORY_TO_RENDERER
|
||||||
|
}
|
||||||
@@ -0,0 +1,44 @@
|
|||||||
|
/*
|
||||||
|
* 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.k2js.resolve.diagnostics;
|
||||||
|
|
||||||
|
import org.jetbrains.jet.lang.diagnostics.DiagnosticFactory0;
|
||||||
|
import org.jetbrains.jet.lang.diagnostics.DiagnosticFactory1;
|
||||||
|
import org.jetbrains.jet.lang.diagnostics.DiagnosticFactory2;
|
||||||
|
import org.jetbrains.jet.lang.diagnostics.Errors;
|
||||||
|
import org.jetbrains.jet.lang.psi.JetDeclaration;
|
||||||
|
import org.jetbrains.jet.lang.psi.JetElement;
|
||||||
|
import org.jetbrains.jet.lang.types.JetType;
|
||||||
|
|
||||||
|
import static org.jetbrains.jet.lang.diagnostics.PositioningStrategies.DECLARATION_RETURN_TYPE;
|
||||||
|
import static org.jetbrains.jet.lang.diagnostics.PositioningStrategies.DECLARATION_SIGNATURE_OR_DEFAULT;
|
||||||
|
import static org.jetbrains.jet.lang.diagnostics.Severity.ERROR;
|
||||||
|
|
||||||
|
public interface ErrorsJs {
|
||||||
|
|
||||||
|
DiagnosticFactory1<JetElement, JetType> NATIVE_ANNOTATIONS_ALLOWED_ONLY_ON_MEMBER_OR_EXTENSION_FUN = DiagnosticFactory1.create(ERROR, DECLARATION_SIGNATURE_OR_DEFAULT);
|
||||||
|
DiagnosticFactory1<JetElement, String> NATIVE_INDEXER_KEY_SHOULD_BE_STRING_OR_NUMBER = DiagnosticFactory1.create(ERROR, DECLARATION_SIGNATURE_OR_DEFAULT);
|
||||||
|
DiagnosticFactory0<JetDeclaration> NATIVE_GETTER_RETURN_TYPE_SHOULD_BE_NULLABLE = DiagnosticFactory0.create(ERROR, DECLARATION_RETURN_TYPE);
|
||||||
|
DiagnosticFactory2<JetElement, Integer, String> NATIVE_INDEXER_WRONG_PARAMETER_COUNT = DiagnosticFactory2.create(ERROR, DECLARATION_SIGNATURE_OR_DEFAULT);
|
||||||
|
|
||||||
|
@SuppressWarnings("UnusedDeclaration")
|
||||||
|
Object _initializer = new Object() {
|
||||||
|
{
|
||||||
|
Errors.Initializer.initializeFactoryNames(ErrorsJs.class);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -106,14 +106,16 @@ public final class AnnotationsUtils {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
private static AnnotationDescriptor getAnnotationByName(@NotNull DeclarationDescriptor descriptor,
|
private static AnnotationDescriptor getAnnotationByName(
|
||||||
@NotNull PredefinedAnnotation annotation) {
|
@NotNull DeclarationDescriptor descriptor,
|
||||||
|
@NotNull PredefinedAnnotation annotation
|
||||||
|
) {
|
||||||
return getAnnotationByName(descriptor, annotation.getFqName());
|
return getAnnotationByName(descriptor, annotation.getFqName());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
private static AnnotationDescriptor getAnnotationByName(@NotNull DeclarationDescriptor descriptor, @NotNull String fqn) {
|
private static AnnotationDescriptor getAnnotationByName(@NotNull DeclarationDescriptor descriptor, @NotNull FqName fqName) {
|
||||||
return descriptor.getAnnotations().findAnnotation(new FqName(fqn));
|
return descriptor.getAnnotations().findAnnotation(fqName);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean isNativeObject(@NotNull DeclarationDescriptor descriptor) {
|
public static boolean isNativeObject(@NotNull DeclarationDescriptor descriptor) {
|
||||||
@@ -133,16 +135,18 @@ public final class AnnotationsUtils {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean hasAnnotationOrInsideAnnotatedClass(@NotNull DeclarationDescriptor descriptor,
|
public static boolean hasAnnotationOrInsideAnnotatedClass(
|
||||||
@NotNull PredefinedAnnotation annotation) {
|
@NotNull DeclarationDescriptor descriptor,
|
||||||
|
@NotNull PredefinedAnnotation annotation
|
||||||
|
) {
|
||||||
return hasAnnotationOrInsideAnnotatedClass(descriptor, annotation.getFqName());
|
return hasAnnotationOrInsideAnnotatedClass(descriptor, annotation.getFqName());
|
||||||
}
|
}
|
||||||
|
|
||||||
private static boolean hasAnnotationOrInsideAnnotatedClass(@NotNull DeclarationDescriptor descriptor, @NotNull String fqn) {
|
private static boolean hasAnnotationOrInsideAnnotatedClass(@NotNull DeclarationDescriptor descriptor, @NotNull FqName fqName) {
|
||||||
if (getAnnotationByName(descriptor, fqn) != null) {
|
if (getAnnotationByName(descriptor, fqName) != null) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
ClassDescriptor containingClass = DescriptorUtils.getContainingClass(descriptor);
|
ClassDescriptor containingClass = DescriptorUtils.getContainingClass(descriptor);
|
||||||
return containingClass != null && hasAnnotationOrInsideAnnotatedClass(containingClass, fqn);
|
return containingClass != null && hasAnnotationOrInsideAnnotatedClass(containingClass, fqName);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user