Basic version of CONFLICTING_PLATFORM_DECLARATIONS diagnostic
#KT-1 In Progress
This commit is contained in:
+95
@@ -0,0 +1,95 @@
|
||||
/*
|
||||
* 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.codegen
|
||||
|
||||
import com.intellij.psi.PsiElement
|
||||
import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor
|
||||
import org.jetbrains.org.objectweb.asm.FieldVisitor
|
||||
import org.jetbrains.org.objectweb.asm.MethodVisitor
|
||||
import com.intellij.util.containers.MultiMap
|
||||
|
||||
public enum class MemberKind { FIELD; METHOD }
|
||||
public data class RawSignature(val name: String, val desc: String, val field: MemberKind)
|
||||
|
||||
public class JvmDeclarationOrigin(
|
||||
val element: PsiElement?,
|
||||
val descriptor: DeclarationDescriptor?
|
||||
)
|
||||
|
||||
public val NO_ORIGIN: JvmDeclarationOrigin = JvmDeclarationOrigin(null, null)
|
||||
|
||||
public abstract class SignatureCollectingClassBuilderFactory(
|
||||
private val delegate: ClassBuilderFactory
|
||||
|
||||
) : ClassBuilderFactory by delegate {
|
||||
|
||||
protected abstract fun handleClashingSignatures(
|
||||
classInternalName: String?,
|
||||
classOrigin: JvmDeclarationOrigin,
|
||||
signature: RawSignature,
|
||||
origins: Collection<JvmDeclarationOrigin>
|
||||
)
|
||||
|
||||
override fun newClassBuilder(forElement: PsiElement?, forDescriptor: DeclarationDescriptor?): SignatureCollectingClassBuilder {
|
||||
return SignatureCollectingClassBuilder(JvmDeclarationOrigin(forElement, forDescriptor), delegate.newClassBuilder(forElement, forDescriptor))
|
||||
}
|
||||
|
||||
public override fun asBytes(builder: ClassBuilder?): ByteArray? {
|
||||
return delegate.asBytes((builder as SignatureCollectingClassBuilder)._delegate)
|
||||
}
|
||||
|
||||
private inner class SignatureCollectingClassBuilder(
|
||||
private val classCreatedFor: JvmDeclarationOrigin,
|
||||
internal val _delegate: ClassBuilder
|
||||
) : DelegatingClassBuilder() {
|
||||
|
||||
override fun getDelegate() = _delegate
|
||||
|
||||
private var classInternalName: String? = null
|
||||
|
||||
private val signatures = MultiMap<RawSignature, JvmDeclarationOrigin>()
|
||||
|
||||
override fun defineClass(origin: PsiElement?, version: Int, access: Int, name: String, signature: String?, superName: String, interfaces: Array<out String>) {
|
||||
classInternalName = name
|
||||
super.defineClass(origin, version, access, name, signature, superName, interfaces)
|
||||
}
|
||||
|
||||
override fun newField(origin: PsiElement?, descriptor: DeclarationDescriptor?, access: Int, name: String, desc: String, signature: String?, value: Any?): FieldVisitor {
|
||||
signatures.putValue(RawSignature(name, desc, MemberKind.FIELD), JvmDeclarationOrigin(origin, descriptor))
|
||||
return super.newField(origin, descriptor, access, name, desc, signature, value)
|
||||
}
|
||||
|
||||
override fun newMethod(origin: PsiElement?, descriptor: DeclarationDescriptor?, access: Int, name: String, desc: String, signature: String?, exceptions: Array<out String>?): MethodVisitor {
|
||||
signatures.putValue(RawSignature(name, desc, MemberKind.METHOD), JvmDeclarationOrigin(origin, descriptor))
|
||||
return super.newMethod(origin, descriptor, access, name, desc, signature, exceptions)
|
||||
}
|
||||
|
||||
override fun done() {
|
||||
for ((signature, elementsAndDescriptors) in signatures.entrySet()!!) {
|
||||
if (elementsAndDescriptors.size == 1) continue // no clash
|
||||
handleClashingSignatures(
|
||||
classInternalName,
|
||||
classCreatedFor,
|
||||
signature,
|
||||
elementsAndDescriptors
|
||||
)
|
||||
}
|
||||
super.done()
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -17,6 +17,7 @@
|
||||
package org.jetbrains.jet.codegen.state;
|
||||
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.jet.codegen.*;
|
||||
@@ -26,6 +27,7 @@ import org.jetbrains.jet.codegen.intrinsics.IntrinsicMethods;
|
||||
import org.jetbrains.jet.lang.descriptors.ModuleDescriptor;
|
||||
import org.jetbrains.jet.lang.descriptors.ScriptDescriptor;
|
||||
import org.jetbrains.jet.lang.diagnostics.DiagnosticHolder;
|
||||
import org.jetbrains.jet.lang.diagnostics.Errors;
|
||||
import org.jetbrains.jet.lang.psi.JetClassOrObject;
|
||||
import org.jetbrains.jet.lang.psi.JetFile;
|
||||
import org.jetbrains.jet.lang.reflect.ReflectionTypes;
|
||||
@@ -36,6 +38,7 @@ import org.jetbrains.jet.lang.resolve.name.FqName;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.List;
|
||||
|
||||
public class GenerationState {
|
||||
@@ -152,7 +155,7 @@ public class GenerationState {
|
||||
this.typeMapper = new JetTypeMapper(this.bindingContext, classBuilderMode);
|
||||
|
||||
this.intrinsics = new IntrinsicMethods();
|
||||
this.classFileFactory = new ClassFileFactory(this, builderFactory);
|
||||
this.classFileFactory = new ClassFileFactory(this, new BuilderfactoryForDuplicateSignatureDiagnostics(builderFactory, diagnostics));
|
||||
|
||||
this.generateNotNullAssertions = generateNotNullAssertions;
|
||||
this.generateNotNullParamAssertions = generateNotNullParamAssertions;
|
||||
@@ -273,4 +276,38 @@ public class GenerationState {
|
||||
public String getModuleId() {
|
||||
return moduleId;
|
||||
}
|
||||
|
||||
private static class BuilderfactoryForDuplicateSignatureDiagnostics extends SignatureCollectingClassBuilderFactory {
|
||||
|
||||
private final DiagnosticHolder diagnostics;
|
||||
|
||||
public BuilderfactoryForDuplicateSignatureDiagnostics(@NotNull ClassBuilderFactory builderFactory, DiagnosticHolder diagnostics) {
|
||||
super(builderFactory);
|
||||
this.diagnostics = diagnostics;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void handleClashingSignatures(
|
||||
@Nullable String classInternalName,
|
||||
@NotNull JvmDeclarationOrigin classOrigin,
|
||||
@NotNull RawSignature signature,
|
||||
@NotNull Collection<? extends JvmDeclarationOrigin> origins
|
||||
) {
|
||||
Collection<PsiElement> elements = new LinkedHashSet<PsiElement>();
|
||||
|
||||
for (JvmDeclarationOrigin origin : origins) {
|
||||
PsiElement element = origin.getElement();
|
||||
if (element == null) {
|
||||
element = classOrigin.getElement();
|
||||
}
|
||||
if (element != null) {
|
||||
elements.add(element);
|
||||
}
|
||||
}
|
||||
|
||||
for (PsiElement element : elements) {
|
||||
diagnostics.report(Errors.CONFLICTING_PLATFORM_DECLARATIONS.on(element, signature.getName() + signature.getDesc()));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -203,6 +203,7 @@ public interface Errors {
|
||||
DiagnosticFactory0<JetNamedDeclaration> PUBLIC_MEMBER_SHOULD_SPECIFY_TYPE = DiagnosticFactory0.create(ERROR, NAMED_ELEMENT);
|
||||
|
||||
DiagnosticFactory2<JetDeclaration, CallableMemberDescriptor, String> CONFLICTING_OVERLOADS = DiagnosticFactory2.create(ERROR, DECLARATION);
|
||||
DiagnosticFactory1<PsiElement, String> CONFLICTING_PLATFORM_DECLARATIONS = DiagnosticFactory1.create(ERROR);
|
||||
|
||||
DiagnosticFactory0<JetNamedDeclaration> NON_FINAL_MEMBER_IN_FINAL_CLASS = DiagnosticFactory0.create(WARNING, modifierSetPosition(
|
||||
JetTokens.OPEN_KEYWORD));
|
||||
|
||||
+1
@@ -392,6 +392,7 @@ public class DefaultErrorMessages {
|
||||
RENDER_CLASS_OR_OBJECT, FQ_NAMES_IN_TYPES);
|
||||
|
||||
MAP.put(CONFLICTING_OVERLOADS, "''{0}'' is already defined in {1}", COMPACT_WITH_MODIFIERS, STRING);
|
||||
MAP.put(CONFLICTING_PLATFORM_DECLARATIONS, "Platform declaration clash: ''{0}''", STRING);
|
||||
|
||||
MAP.put(FUNCTION_EXPECTED, "Expression ''{0}''{1} cannot be invoked as a function. The function 'invoke()' is not found", ELEMENT_TEXT, new Renderer<JetType>() {
|
||||
@NotNull
|
||||
|
||||
Reference in New Issue
Block a user