diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetClassOrObject.java b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetClassOrObject.java index 8a4c580f8c6..633a4da507c 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetClassOrObject.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetClassOrObject.java @@ -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(); diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/DeclarationsChecker.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/DeclarationsChecker.java index d8eb0da6cac..9a84889bf44 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/DeclarationsChecker.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/DeclarationsChecker.java @@ -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 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 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 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 nodes = getNodesCorrespondingToModifiers(getterModifierList, Sets.newHashSet(JetTokens.PUBLIC_KEYWORD, JetTokens.PROTECTED_KEYWORD, JetTokens.PRIVATE_KEYWORD, JetTokens.INTERNAL_KEYWORD)); + Map 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.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 availableModifiers, Collection... availableCombinations) { - if (modifierList == null) return; - Collection presentModifiers = Sets.newLinkedHashSet(); - for (JetKeywordToken modifier : availableModifiers) { - if (modifierList.hasModifier(modifier)) { - presentModifiers.add(modifier); - } - } - if (presentModifiers.size() == 1) { - return; - } - for (Collection 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... redundantBundles) { - for (Pair 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 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 getNodesCorrespondingToModifiers(@NotNull JetModifierList modifierList, Collection possibleModifiers) { - Map 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; diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/DescriptorResolver.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/DescriptorResolver.java index 762f262c882..b1e75e858aa 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/DescriptorResolver.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/DescriptorResolver.java @@ -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 diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/ModifiersChecker.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/ModifiersChecker.java new file mode 100644 index 00000000000..f1bbb9d0f99 --- /dev/null +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/ModifiersChecker.java @@ -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 MODALITY_MODIFIERS = + Lists.newArrayList(ABSTRACT_KEYWORD, OPEN_KEYWORD, FINAL_KEYWORD, OVERRIDE_KEYWORD); + + private static final Collection 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.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 availableModifiers, Collection... availableCombinations) { + if (modifierList == null) return; + Collection presentModifiers = Sets.newLinkedHashSet(); + for (JetKeywordToken modifier : availableModifiers) { + if (modifierList.hasModifier(modifier)) { + presentModifiers.add(modifier); + } + } + if (presentModifiers.size() == 1) { + return; + } + for (Collection 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... redundantBundles) { + for (Pair 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 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 getNodesCorrespondingToModifiers(@NotNull JetModifierList modifierList, @NotNull Collection possibleModifiers) { + Map 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; + } +} diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/TypeHierarchyResolver.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/TypeHierarchyResolver.java index cc2f6575523..5ebe4012f22 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/TypeHierarchyResolver.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/TypeHierarchyResolver.java @@ -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(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(0)); descriptor.createTypeConstructor(); } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/lazy/LazyClassDescriptor.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/lazy/LazyClassDescriptor.java index 75a2c786be6..8999a04517c 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/lazy/LazyClassDescriptor.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/lazy/LazyClassDescriptor.java @@ -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