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;
|
package org.jetbrains.jet.codegen.state;
|
||||||
|
|
||||||
import com.intellij.openapi.project.Project;
|
import com.intellij.openapi.project.Project;
|
||||||
|
import com.intellij.psi.PsiElement;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
import org.jetbrains.jet.codegen.*;
|
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.ModuleDescriptor;
|
||||||
import org.jetbrains.jet.lang.descriptors.ScriptDescriptor;
|
import org.jetbrains.jet.lang.descriptors.ScriptDescriptor;
|
||||||
import org.jetbrains.jet.lang.diagnostics.DiagnosticHolder;
|
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.JetClassOrObject;
|
||||||
import org.jetbrains.jet.lang.psi.JetFile;
|
import org.jetbrains.jet.lang.psi.JetFile;
|
||||||
import org.jetbrains.jet.lang.reflect.ReflectionTypes;
|
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.Collection;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
|
import java.util.LinkedHashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
public class GenerationState {
|
public class GenerationState {
|
||||||
@@ -152,7 +155,7 @@ public class GenerationState {
|
|||||||
this.typeMapper = new JetTypeMapper(this.bindingContext, classBuilderMode);
|
this.typeMapper = new JetTypeMapper(this.bindingContext, classBuilderMode);
|
||||||
|
|
||||||
this.intrinsics = new IntrinsicMethods();
|
this.intrinsics = new IntrinsicMethods();
|
||||||
this.classFileFactory = new ClassFileFactory(this, builderFactory);
|
this.classFileFactory = new ClassFileFactory(this, new BuilderfactoryForDuplicateSignatureDiagnostics(builderFactory, diagnostics));
|
||||||
|
|
||||||
this.generateNotNullAssertions = generateNotNullAssertions;
|
this.generateNotNullAssertions = generateNotNullAssertions;
|
||||||
this.generateNotNullParamAssertions = generateNotNullParamAssertions;
|
this.generateNotNullParamAssertions = generateNotNullParamAssertions;
|
||||||
@@ -273,4 +276,38 @@ public class GenerationState {
|
|||||||
public String getModuleId() {
|
public String getModuleId() {
|
||||||
return moduleId;
|
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);
|
DiagnosticFactory0<JetNamedDeclaration> PUBLIC_MEMBER_SHOULD_SPECIFY_TYPE = DiagnosticFactory0.create(ERROR, NAMED_ELEMENT);
|
||||||
|
|
||||||
DiagnosticFactory2<JetDeclaration, CallableMemberDescriptor, String> CONFLICTING_OVERLOADS = DiagnosticFactory2.create(ERROR, DECLARATION);
|
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(
|
DiagnosticFactory0<JetNamedDeclaration> NON_FINAL_MEMBER_IN_FINAL_CLASS = DiagnosticFactory0.create(WARNING, modifierSetPosition(
|
||||||
JetTokens.OPEN_KEYWORD));
|
JetTokens.OPEN_KEYWORD));
|
||||||
|
|||||||
+1
@@ -392,6 +392,7 @@ public class DefaultErrorMessages {
|
|||||||
RENDER_CLASS_OR_OBJECT, FQ_NAMES_IN_TYPES);
|
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_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>() {
|
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
|
@NotNull
|
||||||
|
|||||||
Reference in New Issue
Block a user