all modifiers checks/resolve moved to ModifiersChecker
This commit is contained in:
@@ -26,7 +26,7 @@ import java.util.List;
|
||||
/**
|
||||
* @author max
|
||||
*/
|
||||
public interface JetClassOrObject extends PsiNameIdentifierOwner, JetDeclarationContainer, JetElement {
|
||||
public interface JetClassOrObject extends PsiNameIdentifierOwner, JetDeclarationContainer, JetElement, JetModifierListOwner {
|
||||
@Nullable
|
||||
JetDelegationSpecifierList getDelegationSpecifierList();
|
||||
|
||||
@@ -42,6 +42,7 @@ public interface JetClassOrObject extends PsiNameIdentifierOwner, JetDeclaration
|
||||
@Nullable
|
||||
Name getNameAsName();
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
JetModifierList getModifierList();
|
||||
|
||||
|
||||
@@ -16,24 +16,18 @@
|
||||
|
||||
package org.jetbrains.jet.lang.resolve;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import com.google.common.collect.Maps;
|
||||
import com.google.common.collect.Sets;
|
||||
import com.intellij.lang.ASTNode;
|
||||
import com.intellij.openapi.util.Pair;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.jet.lang.descriptors.*;
|
||||
import org.jetbrains.jet.lang.diagnostics.Errors;
|
||||
import org.jetbrains.jet.lang.psi.*;
|
||||
import org.jetbrains.jet.lang.types.DeferredType;
|
||||
import org.jetbrains.jet.lang.types.JetType;
|
||||
import org.jetbrains.jet.lexer.JetKeywordToken;
|
||||
import org.jetbrains.jet.lexer.JetToken;
|
||||
import org.jetbrains.jet.lexer.JetTokens;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
@@ -46,10 +40,13 @@ import static org.jetbrains.jet.lang.resolve.BindingContext.TYPE;
|
||||
public class DeclarationsChecker {
|
||||
@NotNull
|
||||
private BindingTrace trace;
|
||||
@NotNull
|
||||
private ModifiersChecker modifiersChecker;
|
||||
|
||||
@Inject
|
||||
public void setTrace(@NotNull BindingTrace trace) {
|
||||
this.trace = trace;
|
||||
this.modifiersChecker = new ModifiersChecker(trace);
|
||||
}
|
||||
|
||||
public void process(@NotNull BodiesResolveContext bodiesResolveContext) {
|
||||
@@ -60,7 +57,7 @@ public class DeclarationsChecker {
|
||||
if (!bodiesResolveContext.completeAnalysisNeeded(aClass)) continue;
|
||||
|
||||
checkClass(aClass, classDescriptor);
|
||||
checkModifiers(aClass.getModifierList(), classDescriptor);
|
||||
modifiersChecker.checkModifiersForDeclaration(aClass, classDescriptor);
|
||||
}
|
||||
|
||||
Map<JetObjectDeclaration, MutableClassDescriptor> objects = bodiesResolveContext.getObjects();
|
||||
@@ -69,7 +66,7 @@ public class DeclarationsChecker {
|
||||
MutableClassDescriptor objectDescriptor = entry.getValue();
|
||||
|
||||
if (!bodiesResolveContext.completeAnalysisNeeded(objectDeclaration)) continue;
|
||||
checkObject(objectDeclaration, objectDescriptor);
|
||||
modifiersChecker.checkIllegalModalityModifiers(objectDeclaration);
|
||||
}
|
||||
|
||||
Map<JetNamedFunction, SimpleFunctionDescriptor> functions = bodiesResolveContext.getFunctions();
|
||||
@@ -79,7 +76,7 @@ public class DeclarationsChecker {
|
||||
|
||||
if (!bodiesResolveContext.completeAnalysisNeeded(function)) continue;
|
||||
checkFunction(function, functionDescriptor);
|
||||
checkModifiers(function.getModifierList(), functionDescriptor);
|
||||
modifiersChecker.checkModifiersForDeclaration(function, functionDescriptor);
|
||||
}
|
||||
|
||||
Map<JetProperty, PropertyDescriptor> properties = bodiesResolveContext.getProperties();
|
||||
@@ -89,7 +86,7 @@ public class DeclarationsChecker {
|
||||
|
||||
if (!bodiesResolveContext.completeAnalysisNeeded(property)) continue;
|
||||
checkProperty(property, propertyDescriptor);
|
||||
checkModifiers(property.getModifierList(), propertyDescriptor);
|
||||
modifiersChecker.checkModifiersForDeclaration(property, propertyDescriptor);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -116,10 +113,6 @@ public class DeclarationsChecker {
|
||||
}
|
||||
|
||||
|
||||
private void checkObject(JetObjectDeclaration objectDeclaration, MutableClassDescriptor classDescriptor) {
|
||||
checkIllegalInThisContextModifiers(objectDeclaration.getModifierList(), Sets.newHashSet(JetTokens.ABSTRACT_KEYWORD, JetTokens.OPEN_KEYWORD, JetTokens.OVERRIDE_KEYWORD));
|
||||
}
|
||||
|
||||
private void checkOpenMembers(MutableClassDescriptor classDescriptor) {
|
||||
for (CallableMemberDescriptor memberDescriptor : classDescriptor.getDeclaredCallableMembers()) {
|
||||
if (memberDescriptor.getKind() != CallableMemberDescriptor.Kind.DECLARATION) continue;
|
||||
@@ -274,15 +267,17 @@ public class DeclarationsChecker {
|
||||
}
|
||||
}
|
||||
|
||||
private void checkAccessors(JetProperty property, PropertyDescriptor propertyDescriptor) {
|
||||
private void checkAccessors(@NotNull JetProperty property, @NotNull PropertyDescriptor propertyDescriptor) {
|
||||
for (JetPropertyAccessor accessor : property.getAccessors()) {
|
||||
checkIllegalInThisContextModifiers(accessor.getModifierList(), Sets.newHashSet(JetTokens.ABSTRACT_KEYWORD, JetTokens.OPEN_KEYWORD, JetTokens.FINAL_KEYWORD, JetTokens.OVERRIDE_KEYWORD));
|
||||
modifiersChecker.checkIllegalModalityModifiers(accessor);
|
||||
}
|
||||
JetPropertyAccessor getter = property.getGetter();
|
||||
PropertyGetterDescriptor getterDescriptor = propertyDescriptor.getGetter();
|
||||
JetModifierList getterModifierList = getter != null ? getter.getModifierList() : null;
|
||||
if (getterModifierList != null && getterDescriptor != null) {
|
||||
Map<JetKeywordToken, ASTNode> nodes = getNodesCorrespondingToModifiers(getterModifierList, Sets.newHashSet(JetTokens.PUBLIC_KEYWORD, JetTokens.PROTECTED_KEYWORD, JetTokens.PRIVATE_KEYWORD, JetTokens.INTERNAL_KEYWORD));
|
||||
Map<JetKeywordToken, ASTNode> nodes = ModifiersChecker.getNodesCorrespondingToModifiers(getterModifierList, Sets
|
||||
.newHashSet(JetTokens.PUBLIC_KEYWORD, JetTokens.PROTECTED_KEYWORD, JetTokens.PRIVATE_KEYWORD,
|
||||
JetTokens.INTERNAL_KEYWORD));
|
||||
if (getterDescriptor.getVisibility() != propertyDescriptor.getVisibility()) {
|
||||
for (ASTNode node : nodes.values()) {
|
||||
trace.report(Errors.GETTER_VISIBILITY_DIFFERS_FROM_PROPERTY_VISIBILITY.on(node.getPsi()));
|
||||
@@ -296,82 +291,7 @@ public class DeclarationsChecker {
|
||||
}
|
||||
}
|
||||
|
||||
private void checkModifiers(@Nullable JetModifierList modifierList, @NotNull DeclarationDescriptor descriptor) {
|
||||
checkModalityModifiers(modifierList);
|
||||
checkVisibilityModifiers(modifierList, descriptor);
|
||||
}
|
||||
|
||||
private void checkModalityModifiers(@Nullable JetModifierList modifierList) {
|
||||
if (modifierList == null) return;
|
||||
checkRedundantModifier(modifierList, Pair.create(JetTokens.OPEN_KEYWORD, JetTokens.ABSTRACT_KEYWORD), Pair.create(JetTokens.OPEN_KEYWORD, JetTokens.OVERRIDE_KEYWORD));
|
||||
|
||||
checkCompatibility(modifierList, Lists.newArrayList(JetTokens.ABSTRACT_KEYWORD, JetTokens.OPEN_KEYWORD, JetTokens.FINAL_KEYWORD),
|
||||
Lists.<JetToken>newArrayList(JetTokens.ABSTRACT_KEYWORD, JetTokens.OPEN_KEYWORD));
|
||||
}
|
||||
|
||||
private void checkVisibilityModifiers(@Nullable JetModifierList modifierList, @NotNull DeclarationDescriptor descriptor) {
|
||||
if (modifierList == null) return;
|
||||
|
||||
DeclarationDescriptor containingDeclaration = descriptor.getContainingDeclaration();
|
||||
if (containingDeclaration instanceof NamespaceDescriptor) {
|
||||
if (modifierList.hasModifier(JetTokens.PROTECTED_KEYWORD)) {
|
||||
trace.report(Errors.PACKAGE_MEMBER_CANNOT_BE_PROTECTED.on(modifierList.getModifierNode(JetTokens.PROTECTED_KEYWORD).getPsi()));
|
||||
}
|
||||
}
|
||||
|
||||
checkCompatibility(modifierList, Lists.newArrayList(JetTokens.PRIVATE_KEYWORD, JetTokens.PROTECTED_KEYWORD, JetTokens.PUBLIC_KEYWORD, JetTokens.INTERNAL_KEYWORD));
|
||||
}
|
||||
|
||||
private void checkCompatibility(@Nullable JetModifierList modifierList, Collection<JetKeywordToken> availableModifiers, Collection<JetToken>... availableCombinations) {
|
||||
if (modifierList == null) return;
|
||||
Collection<JetKeywordToken> presentModifiers = Sets.newLinkedHashSet();
|
||||
for (JetKeywordToken modifier : availableModifiers) {
|
||||
if (modifierList.hasModifier(modifier)) {
|
||||
presentModifiers.add(modifier);
|
||||
}
|
||||
}
|
||||
if (presentModifiers.size() == 1) {
|
||||
return;
|
||||
}
|
||||
for (Collection<JetToken> combination : availableCombinations) {
|
||||
if (presentModifiers.containsAll(combination) && combination.containsAll(presentModifiers)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
for (JetKeywordToken token : presentModifiers) {
|
||||
trace.report(Errors.INCOMPATIBLE_MODIFIERS.on(modifierList.getModifierNode(token).getPsi(), presentModifiers));
|
||||
}
|
||||
}
|
||||
|
||||
private void checkRedundantModifier(@NotNull JetModifierList modifierList, Pair<JetKeywordToken, JetKeywordToken>... redundantBundles) {
|
||||
for (Pair<JetKeywordToken, JetKeywordToken> tokenPair : redundantBundles) {
|
||||
JetKeywordToken redundantModifier = tokenPair.getFirst();
|
||||
JetKeywordToken sufficientModifier = tokenPair.getSecond();
|
||||
if (modifierList.hasModifier(redundantModifier) && modifierList.hasModifier(sufficientModifier)) {
|
||||
trace.report(Errors.REDUNDANT_MODIFIER.on(modifierList.getModifierNode(redundantModifier).getPsi(), redundantModifier, sufficientModifier));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void checkIllegalInThisContextModifiers(@Nullable JetModifierList modifierList, Collection<JetKeywordToken> illegalModifiers) {
|
||||
if (modifierList == null) return;
|
||||
for (JetKeywordToken modifier : illegalModifiers) {
|
||||
if (modifierList.hasModifier(modifier)) {
|
||||
trace.report(Errors.ILLEGAL_MODIFIER.on(modifierList.getModifierNode(modifier).getPsi(), modifier));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static Map<JetKeywordToken, ASTNode> getNodesCorrespondingToModifiers(@NotNull JetModifierList modifierList, Collection<JetKeywordToken> possibleModifiers) {
|
||||
Map<JetKeywordToken, ASTNode> nodes = Maps.newHashMap();
|
||||
for (JetKeywordToken modifier : possibleModifiers) {
|
||||
if (modifierList.hasModifier(modifier)) {
|
||||
nodes.put(modifier, modifierList.getModifierNode(modifier));
|
||||
}
|
||||
}
|
||||
return nodes;
|
||||
}
|
||||
|
||||
private void checkEnum(JetClass aClass, ClassDescriptor classDescriptor) {
|
||||
if (classDescriptor.getKind() != ClassKind.ENUM_ENTRY) return;
|
||||
|
||||
@@ -103,8 +103,8 @@ public class DescriptorResolver {
|
||||
}
|
||||
descriptor.setTypeParameterDescriptors(typeParameters);
|
||||
Modality defaultModality = descriptor.getKind() == ClassKind.TRAIT ? Modality.ABSTRACT : Modality.FINAL;
|
||||
descriptor.setModality(resolveModalityFromModifiers(classElement.getModifierList(), defaultModality));
|
||||
descriptor.setVisibility(resolveVisibilityFromModifiers(classElement.getModifierList()));
|
||||
descriptor.setModality(ModifiersChecker.resolveModalityFromModifiers(classElement, defaultModality));
|
||||
descriptor.setVisibility(ModifiersChecker.resolveVisibilityFromModifiers(classElement));
|
||||
|
||||
trace.record(BindingContext.CLASS, classElement, descriptor);
|
||||
}
|
||||
@@ -272,8 +272,8 @@ public class DescriptorResolver {
|
||||
}
|
||||
}
|
||||
boolean hasBody = function.getBodyExpression() != null;
|
||||
Modality modality = resolveModalityFromModifiers(function.getModifierList(), getDefaultModality(containingDescriptor, hasBody));
|
||||
Visibility visibility = resolveVisibilityFromModifiers(function.getModifierList());
|
||||
Modality modality = ModifiersChecker.resolveModalityFromModifiers(function, getDefaultModality(containingDescriptor, hasBody));
|
||||
Visibility visibility = ModifiersChecker.resolveVisibilityFromModifiers(function);
|
||||
JetModifierList modifierList = function.getModifierList();
|
||||
boolean isInline = (modifierList != null) && modifierList.hasModifier(JetTokens.INLINE_KEYWORD);
|
||||
functionDescriptor.initialize(
|
||||
@@ -675,7 +675,7 @@ public class DescriptorResolver {
|
||||
containingDeclaration,
|
||||
annotationResolver.createAnnotationStubs(modifierList, trace),
|
||||
Modality.FINAL,
|
||||
resolveVisibilityFromModifiers(modifierList),
|
||||
ModifiersChecker.resolveVisibilityFromModifiers(objectDeclaration),
|
||||
false,
|
||||
JetPsiUtil.safeName(objectDeclaration.getName()),
|
||||
CallableMemberDescriptor.Kind.DECLARATION
|
||||
@@ -732,7 +732,7 @@ public class DescriptorResolver {
|
||||
public PropertyDescriptor resolvePropertyDescriptor(
|
||||
@NotNull DeclarationDescriptor containingDeclaration,
|
||||
@NotNull JetScope scope,
|
||||
JetProperty property,
|
||||
@NotNull JetProperty property,
|
||||
BindingTrace trace
|
||||
) {
|
||||
|
||||
@@ -744,8 +744,8 @@ public class DescriptorResolver {
|
||||
PropertyDescriptor propertyDescriptor = new PropertyDescriptor(
|
||||
containingDeclaration,
|
||||
annotationResolver.resolveAnnotations(scope, modifierList, trace),
|
||||
resolveModalityFromModifiers(property.getModifierList(), defaultModality),
|
||||
resolveVisibilityFromModifiers(property.getModifierList()),
|
||||
ModifiersChecker.resolveModalityFromModifiers(property, defaultModality),
|
||||
ModifiersChecker.resolveVisibilityFromModifiers(property),
|
||||
isVar,
|
||||
JetPsiUtil.safeName(property.getName()),
|
||||
CallableMemberDescriptor.Kind.DECLARATION
|
||||
@@ -851,49 +851,6 @@ public class DescriptorResolver {
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static Modality resolveModalityFromModifiers(@Nullable JetModifierList modifierList, @NotNull Modality defaultModality) {
|
||||
if (modifierList == null) return defaultModality;
|
||||
boolean hasAbstractModifier = modifierList.hasModifier(JetTokens.ABSTRACT_KEYWORD);
|
||||
boolean hasOverrideModifier = modifierList.hasModifier(JetTokens.OVERRIDE_KEYWORD);
|
||||
|
||||
if (modifierList.hasModifier(JetTokens.OPEN_KEYWORD)) {
|
||||
if (hasAbstractModifier || defaultModality == Modality.ABSTRACT) {
|
||||
return Modality.ABSTRACT;
|
||||
}
|
||||
return Modality.OPEN;
|
||||
}
|
||||
if (hasAbstractModifier) {
|
||||
return Modality.ABSTRACT;
|
||||
}
|
||||
boolean hasFinalModifier = modifierList.hasModifier(JetTokens.FINAL_KEYWORD);
|
||||
if (hasOverrideModifier && !hasFinalModifier && !(defaultModality == Modality.ABSTRACT)) {
|
||||
return Modality.OPEN;
|
||||
}
|
||||
if (hasFinalModifier) {
|
||||
return Modality.FINAL;
|
||||
}
|
||||
return defaultModality;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
/*package*/ static Visibility resolveVisibilityFromModifiers(@Nullable JetModifierList modifierList) {
|
||||
Visibility defaultVisibility = modifierList != null && modifierList.hasModifier(JetTokens.OVERRIDE_KEYWORD)
|
||||
? Visibilities.INHERITED
|
||||
: Visibilities.INTERNAL;
|
||||
return resolveVisibilityFromModifiers(modifierList, defaultVisibility);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static Visibility resolveVisibilityFromModifiers(@Nullable JetModifierList modifierList, @NotNull Visibility defaultVisibility) {
|
||||
if (modifierList == null) return defaultVisibility;
|
||||
if (modifierList.hasModifier(JetTokens.PRIVATE_KEYWORD)) return Visibilities.PRIVATE;
|
||||
if (modifierList.hasModifier(JetTokens.PUBLIC_KEYWORD)) return Visibilities.PUBLIC;
|
||||
if (modifierList.hasModifier(JetTokens.PROTECTED_KEYWORD)) return Visibilities.PROTECTED;
|
||||
if (modifierList.hasModifier(JetTokens.INTERNAL_KEYWORD)) return Visibilities.INTERNAL;
|
||||
return defaultVisibility;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private PropertySetterDescriptor resolvePropertySetterDescriptor(
|
||||
@NotNull JetScope scope,
|
||||
@@ -909,8 +866,8 @@ public class DescriptorResolver {
|
||||
|
||||
setterDescriptor = new PropertySetterDescriptor(
|
||||
propertyDescriptor, annotations,
|
||||
resolveModalityFromModifiers(setter.getModifierList(), propertyDescriptor.getModality()),
|
||||
resolveVisibilityFromModifiers(setter.getModifierList(), propertyDescriptor.getVisibility()),
|
||||
ModifiersChecker.resolveModalityFromModifiers(setter, propertyDescriptor.getModality()),
|
||||
ModifiersChecker.resolveVisibilityFromModifiers(setter, propertyDescriptor.getVisibility()),
|
||||
setter.getBodyExpression() != null, false, CallableMemberDescriptor.Kind.DECLARATION);
|
||||
if (parameter != null) {
|
||||
|
||||
@@ -995,8 +952,8 @@ public class DescriptorResolver {
|
||||
|
||||
getterDescriptor = new PropertyGetterDescriptor(
|
||||
propertyDescriptor, annotations,
|
||||
resolveModalityFromModifiers(getter.getModifierList(), propertyDescriptor.getModality()),
|
||||
resolveVisibilityFromModifiers(getter.getModifierList(), propertyDescriptor.getVisibility()),
|
||||
ModifiersChecker.resolveModalityFromModifiers(getter, propertyDescriptor.getModality()),
|
||||
ModifiersChecker.resolveVisibilityFromModifiers(getter, propertyDescriptor.getVisibility()),
|
||||
getter.getBodyExpression() != null, false, CallableMemberDescriptor.Kind.DECLARATION);
|
||||
getterDescriptor.initialize(returnType);
|
||||
trace.record(BindingContext.PROPERTY_ACCESSOR, getter, getterDescriptor);
|
||||
@@ -1041,7 +998,7 @@ public class DescriptorResolver {
|
||||
constructorDescriptor,
|
||||
parameterScope,
|
||||
valueParameters, trace),
|
||||
resolveVisibilityFromModifiers(modifierList, Visibilities.PUBLIC));
|
||||
ModifiersChecker.resolveVisibilityFromModifiers(modifierList, Visibilities.PUBLIC));
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@@ -1083,8 +1040,8 @@ public class DescriptorResolver {
|
||||
PropertyDescriptor propertyDescriptor = new PropertyDescriptor(
|
||||
classDescriptor,
|
||||
valueParameter.getAnnotations(),
|
||||
resolveModalityFromModifiers(parameter.getModifierList(), Modality.FINAL),
|
||||
resolveVisibilityFromModifiers(parameter.getModifierList()),
|
||||
ModifiersChecker.resolveModalityFromModifiers(parameter, Modality.FINAL),
|
||||
ModifiersChecker.resolveVisibilityFromModifiers(parameter),
|
||||
isMutable,
|
||||
name,
|
||||
CallableMemberDescriptor.Kind.DECLARATION
|
||||
|
||||
@@ -0,0 +1,202 @@
|
||||
/*
|
||||
* Copyright 2010-2012 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 com.google.common.collect.Lists;
|
||||
import com.google.common.collect.Maps;
|
||||
import com.google.common.collect.Sets;
|
||||
import com.intellij.lang.ASTNode;
|
||||
import com.intellij.openapi.util.Pair;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.jet.lang.descriptors.*;
|
||||
import org.jetbrains.jet.lang.diagnostics.Errors;
|
||||
import org.jetbrains.jet.lang.psi.JetModifierList;
|
||||
import org.jetbrains.jet.lang.psi.JetModifierListOwner;
|
||||
import org.jetbrains.jet.lexer.JetKeywordToken;
|
||||
import org.jetbrains.jet.lexer.JetToken;
|
||||
import org.jetbrains.jet.lexer.JetTokens;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Map;
|
||||
|
||||
import static org.jetbrains.jet.lexer.JetTokens.*;
|
||||
|
||||
/**
|
||||
* @author svtk
|
||||
*/
|
||||
public class ModifiersChecker {
|
||||
private static final Collection<JetKeywordToken> MODALITY_MODIFIERS =
|
||||
Lists.newArrayList(ABSTRACT_KEYWORD, OPEN_KEYWORD, FINAL_KEYWORD, OVERRIDE_KEYWORD);
|
||||
|
||||
private static final Collection<JetKeywordToken> VISIBILITY_MODIFIERS =
|
||||
Lists.newArrayList(PRIVATE_KEYWORD, PROTECTED_KEYWORD, PUBLIC_KEYWORD, INTERNAL_KEYWORD);
|
||||
|
||||
@NotNull
|
||||
private final BindingTrace trace;
|
||||
|
||||
public ModifiersChecker(@NotNull BindingTrace trace) {
|
||||
this.trace = trace;
|
||||
}
|
||||
|
||||
public static ModifiersChecker create(@NotNull BindingTrace trace) {
|
||||
return new ModifiersChecker(trace);
|
||||
}
|
||||
|
||||
public void checkModifiersForDeclaration(@NotNull JetModifierListOwner modifierListOwner, @NotNull DeclarationDescriptor descriptor) {
|
||||
JetModifierList modifierList = modifierListOwner.getModifierList();
|
||||
checkModalityModifiers(modifierList);
|
||||
checkVisibilityModifiers(modifierList, descriptor);
|
||||
}
|
||||
|
||||
public void checkModifiersForLocalDeclaration(@NotNull JetModifierListOwner modifierListOwner) {
|
||||
checkIllegalModalityModifiers(modifierListOwner);
|
||||
checkIllegalVisibilityModifiers(modifierListOwner);
|
||||
}
|
||||
|
||||
public void checkIllegalModalityModifiers(@NotNull JetModifierListOwner modifierListOwner) {
|
||||
checkIllegalInThisContextModifiers(modifierListOwner.getModifierList(), MODALITY_MODIFIERS);
|
||||
}
|
||||
|
||||
public void checkIllegalVisibilityModifiers(@NotNull JetModifierListOwner modifierListOwner) {
|
||||
checkIllegalInThisContextModifiers(modifierListOwner.getModifierList(), VISIBILITY_MODIFIERS);
|
||||
}
|
||||
|
||||
private void checkModalityModifiers(@Nullable JetModifierList modifierList) {
|
||||
if (modifierList == null) return;
|
||||
checkRedundantModifier(modifierList, Pair.create(OPEN_KEYWORD, ABSTRACT_KEYWORD), Pair.create(OPEN_KEYWORD, OVERRIDE_KEYWORD));
|
||||
|
||||
checkCompatibility(modifierList, Lists.newArrayList(ABSTRACT_KEYWORD, OPEN_KEYWORD, FINAL_KEYWORD),
|
||||
Lists.<JetToken>newArrayList(ABSTRACT_KEYWORD, OPEN_KEYWORD));
|
||||
}
|
||||
|
||||
private void checkVisibilityModifiers(@Nullable JetModifierList modifierList, @NotNull DeclarationDescriptor descriptor) {
|
||||
if (modifierList == null) return;
|
||||
|
||||
DeclarationDescriptor containingDeclaration = descriptor.getContainingDeclaration();
|
||||
if (containingDeclaration instanceof NamespaceDescriptor) {
|
||||
if (modifierList.hasModifier(PROTECTED_KEYWORD)) {
|
||||
trace.report(Errors.PACKAGE_MEMBER_CANNOT_BE_PROTECTED.on(modifierList.getModifierNode(PROTECTED_KEYWORD).getPsi()));
|
||||
}
|
||||
}
|
||||
|
||||
checkCompatibility(modifierList, VISIBILITY_MODIFIERS);
|
||||
}
|
||||
|
||||
private void checkCompatibility(@Nullable JetModifierList modifierList, Collection<JetKeywordToken> availableModifiers, Collection<JetToken>... availableCombinations) {
|
||||
if (modifierList == null) return;
|
||||
Collection<JetKeywordToken> presentModifiers = Sets.newLinkedHashSet();
|
||||
for (JetKeywordToken modifier : availableModifiers) {
|
||||
if (modifierList.hasModifier(modifier)) {
|
||||
presentModifiers.add(modifier);
|
||||
}
|
||||
}
|
||||
if (presentModifiers.size() == 1) {
|
||||
return;
|
||||
}
|
||||
for (Collection<JetToken> combination : availableCombinations) {
|
||||
if (presentModifiers.containsAll(combination) && combination.containsAll(presentModifiers)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
for (JetKeywordToken token : presentModifiers) {
|
||||
trace.report(Errors.INCOMPATIBLE_MODIFIERS.on(modifierList.getModifierNode(token).getPsi(), presentModifiers));
|
||||
}
|
||||
}
|
||||
|
||||
private void checkRedundantModifier(@NotNull JetModifierList modifierList, Pair<JetKeywordToken, JetKeywordToken>... redundantBundles) {
|
||||
for (Pair<JetKeywordToken, JetKeywordToken> tokenPair : redundantBundles) {
|
||||
JetKeywordToken redundantModifier = tokenPair.getFirst();
|
||||
JetKeywordToken sufficientModifier = tokenPair.getSecond();
|
||||
if (modifierList.hasModifier(redundantModifier) && modifierList.hasModifier(sufficientModifier)) {
|
||||
trace.report(Errors.REDUNDANT_MODIFIER.on(modifierList.getModifierNode(redundantModifier).getPsi(), redundantModifier, sufficientModifier));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void checkIllegalInThisContextModifiers(@Nullable JetModifierList modifierList, @NotNull Collection<JetKeywordToken> illegalModifiers) {
|
||||
if (modifierList == null) return;
|
||||
for (JetKeywordToken modifier : illegalModifiers) {
|
||||
if (modifierList.hasModifier(modifier)) {
|
||||
trace.report(Errors.ILLEGAL_MODIFIER.on(modifierList.getModifierNode(modifier).getPsi(), modifier));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static Map<JetKeywordToken, ASTNode> getNodesCorrespondingToModifiers(@NotNull JetModifierList modifierList, @NotNull Collection<JetKeywordToken> possibleModifiers) {
|
||||
Map<JetKeywordToken, ASTNode> nodes = Maps.newHashMap();
|
||||
for (JetKeywordToken modifier : possibleModifiers) {
|
||||
if (modifierList.hasModifier(modifier)) {
|
||||
nodes.put(modifier, modifierList.getModifierNode(modifier));
|
||||
}
|
||||
}
|
||||
return nodes;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static Modality resolveModalityFromModifiers(@NotNull JetModifierListOwner modifierListOwner, @NotNull Modality defaultModality) {
|
||||
return resolveModalityFromModifiers(modifierListOwner.getModifierList(), defaultModality);
|
||||
}
|
||||
|
||||
public static Modality resolveModalityFromModifiers(@Nullable JetModifierList modifierList, @NotNull Modality defaultModality) {
|
||||
if (modifierList == null) return defaultModality;
|
||||
boolean hasAbstractModifier = modifierList.hasModifier(ABSTRACT_KEYWORD);
|
||||
boolean hasOverrideModifier = modifierList.hasModifier(OVERRIDE_KEYWORD);
|
||||
|
||||
if (modifierList.hasModifier(OPEN_KEYWORD)) {
|
||||
if (hasAbstractModifier || defaultModality == Modality.ABSTRACT) {
|
||||
return Modality.ABSTRACT;
|
||||
}
|
||||
return Modality.OPEN;
|
||||
}
|
||||
if (hasAbstractModifier) {
|
||||
return Modality.ABSTRACT;
|
||||
}
|
||||
boolean hasFinalModifier = modifierList.hasModifier(FINAL_KEYWORD);
|
||||
if (hasOverrideModifier && !hasFinalModifier && !(defaultModality == Modality.ABSTRACT)) {
|
||||
return Modality.OPEN;
|
||||
}
|
||||
if (hasFinalModifier) {
|
||||
return Modality.FINAL;
|
||||
}
|
||||
return defaultModality;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static Visibility resolveVisibilityFromModifiers(@NotNull JetModifierListOwner modifierListOwner) {
|
||||
JetModifierList modifierList = modifierListOwner.getModifierList();
|
||||
Visibility defaultVisibility = modifierList != null && modifierList.hasModifier(OVERRIDE_KEYWORD)
|
||||
? Visibilities.INHERITED
|
||||
: Visibilities.INTERNAL;
|
||||
return resolveVisibilityFromModifiers(modifierListOwner, defaultVisibility);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static Visibility resolveVisibilityFromModifiers(@NotNull JetModifierListOwner modifierListOwner, @NotNull Visibility defaultVisibility) {
|
||||
return resolveVisibilityFromModifiers(modifierListOwner.getModifierList(), defaultVisibility);
|
||||
}
|
||||
|
||||
public static Visibility resolveVisibilityFromModifiers(@Nullable JetModifierList modifierList, @NotNull Visibility defaultVisibility) {
|
||||
if (modifierList == null) return defaultVisibility;
|
||||
if (modifierList.hasModifier(PRIVATE_KEYWORD)) return Visibilities.PRIVATE;
|
||||
if (modifierList.hasModifier(PUBLIC_KEYWORD)) return Visibilities.PUBLIC;
|
||||
if (modifierList.hasModifier(PROTECTED_KEYWORD)) return Visibilities.PROTECTED;
|
||||
if (modifierList.hasModifier(INTERNAL_KEYWORD)) return Visibilities.INTERNAL;
|
||||
return defaultVisibility;
|
||||
}
|
||||
}
|
||||
@@ -297,7 +297,7 @@ public class TypeHierarchyResolver {
|
||||
getClassObjectName(klass.getName()));
|
||||
mutableClassDescriptor.getBuilder().setClassObjectDescriptor(classObjectDescriptor);
|
||||
classObjectDescriptor.setModality(Modality.FINAL);
|
||||
classObjectDescriptor.setVisibility(DescriptorResolver.resolveVisibilityFromModifiers(klass.getModifierList()));
|
||||
classObjectDescriptor.setVisibility(ModifiersChecker.resolveVisibilityFromModifiers(klass));
|
||||
classObjectDescriptor.setTypeParameterDescriptors(new ArrayList<TypeParameterDescriptor>(0));
|
||||
classObjectDescriptor.createTypeConstructor();
|
||||
ConstructorDescriptorImpl primaryConstructorForObject =
|
||||
@@ -388,7 +388,7 @@ public class TypeHierarchyResolver {
|
||||
JetObjectDeclaration objectDeclaration = entry.getKey();
|
||||
MutableClassDescriptor descriptor = entry.getValue();
|
||||
descriptor.setModality(Modality.FINAL);
|
||||
descriptor.setVisibility(DescriptorResolver.resolveVisibilityFromModifiers(objectDeclaration.getModifierList()));
|
||||
descriptor.setVisibility(ModifiersChecker.resolveVisibilityFromModifiers(objectDeclaration));
|
||||
descriptor.setTypeParameterDescriptors(new ArrayList<TypeParameterDescriptor>(0));
|
||||
descriptor.createTypeConstructor();
|
||||
}
|
||||
|
||||
@@ -25,10 +25,7 @@ import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.jet.lang.descriptors.*;
|
||||
import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor;
|
||||
import org.jetbrains.jet.lang.psi.*;
|
||||
import org.jetbrains.jet.lang.resolve.AnnotationResolver;
|
||||
import org.jetbrains.jet.lang.resolve.BindingContext;
|
||||
import org.jetbrains.jet.lang.resolve.DescriptorResolver;
|
||||
import org.jetbrains.jet.lang.resolve.DescriptorUtils;
|
||||
import org.jetbrains.jet.lang.resolve.*;
|
||||
import org.jetbrains.jet.lang.resolve.lazy.data.FilteringClassLikeInfo;
|
||||
import org.jetbrains.jet.lang.resolve.lazy.data.JetClassInfoUtil;
|
||||
import org.jetbrains.jet.lang.resolve.lazy.data.JetClassLikeInfo;
|
||||
@@ -111,10 +108,10 @@ public class LazyClassDescriptor extends ClassDescriptorBase implements ClassDes
|
||||
else {
|
||||
Modality defaultModality = kind == ClassKind.TRAIT ? Modality.ABSTRACT : Modality.FINAL;
|
||||
JetModifierList modifierList = classLikeInfo.getModifierList();
|
||||
this.modality = DescriptorResolver.resolveModalityFromModifiers(modifierList, defaultModality);
|
||||
this.modality = ModifiersChecker.resolveModalityFromModifiers(modifierList, defaultModality);
|
||||
}
|
||||
JetModifierList modifierList = classLikeInfo.getModifierList();
|
||||
this.visibility = DescriptorResolver.resolveVisibilityFromModifiers(modifierList, Visibilities.INTERNAL);
|
||||
this.visibility = ModifiersChecker.resolveVisibilityFromModifiers(modifierList, Visibilities.INTERNAL);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
Reference in New Issue
Block a user