<commit_before>/*
 * Copyright 2000-2017 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 com.intellij.psi.impl.source;

import static com.intellij.psi.PsiModifier.*;

import gnu.trove.THashMap;

import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import com.intellij.codeInsight.AnnotationTargetUtil;
import com.intellij.lang.ASTNode;
import com.intellij.psi.*;
import com.intellij.psi.augment.PsiAugmentProvider;
import com.intellij.psi.impl.CheckUtil;
import com.intellij.psi.impl.PsiImplUtil;
import com.intellij.psi.impl.cache.ModifierFlags;
import com.intellij.psi.impl.java.stubs.JavaStubElementTypes;
import com.intellij.psi.impl.java.stubs.PsiModifierListStub;
import com.intellij.psi.impl.source.codeStyle.CodeEditUtil;
import com.intellij.psi.impl.source.tree.CompositeElement;
import com.intellij.psi.impl.source.tree.Factory;
import com.intellij.psi.impl.source.tree.TreeElement;
import com.intellij.psi.tree.IElementType;
import com.intellij.util.ArrayUtil;
import com.intellij.util.BitUtil;
import com.intellij.util.IncorrectOperationException;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.containers.WeakInterner;

public class PsiModifierListImpl extends JavaStubPsiElement<PsiModifierListStub> implements PsiModifierList
{
	private static final Map<String, IElementType> NAME_TO_KEYWORD_TYPE_MAP;
	private static final Map<IElementType, String> KEYWORD_TYPE_TO_NAME_MAP;

	static
	{
		NAME_TO_KEYWORD_TYPE_MAP = new THashMap<>();
		NAME_TO_KEYWORD_TYPE_MAP.put(PUBLIC, JavaTokenType.PUBLIC_KEYWORD);
		NAME_TO_KEYWORD_TYPE_MAP.put(PROTECTED, JavaTokenType.PROTECTED_KEYWORD);
		NAME_TO_KEYWORD_TYPE_MAP.put(PRIVATE, JavaTokenType.PRIVATE_KEYWORD);
		NAME_TO_KEYWORD_TYPE_MAP.put(STATIC, JavaTokenType.STATIC_KEYWORD);
		NAME_TO_KEYWORD_TYPE_MAP.put(ABSTRACT, JavaTokenType.ABSTRACT_KEYWORD);
		NAME_TO_KEYWORD_TYPE_MAP.put(FINAL, JavaTokenType.FINAL_KEYWORD);
		NAME_TO_KEYWORD_TYPE_MAP.put(NATIVE, JavaTokenType.NATIVE_KEYWORD);
		NAME_TO_KEYWORD_TYPE_MAP.put(SYNCHRONIZED, JavaTokenType.SYNCHRONIZED_KEYWORD);
		NAME_TO_KEYWORD_TYPE_MAP.put(STRICTFP, JavaTokenType.STRICTFP_KEYWORD);
		NAME_TO_KEYWORD_TYPE_MAP.put(TRANSIENT, JavaTokenType.TRANSIENT_KEYWORD);
		NAME_TO_KEYWORD_TYPE_MAP.put(VOLATILE, JavaTokenType.VOLATILE_KEYWORD);
		NAME_TO_KEYWORD_TYPE_MAP.put(DEFAULT, JavaTokenType.DEFAULT_KEYWORD);
		NAME_TO_KEYWORD_TYPE_MAP.put(OPEN, JavaTokenType.OPEN_KEYWORD);
		NAME_TO_KEYWORD_TYPE_MAP.put(TRANSITIVE, JavaTokenType.TRANSITIVE_KEYWORD);

		KEYWORD_TYPE_TO_NAME_MAP = ContainerUtil.newTroveMap();
		for(String name : NAME_TO_KEYWORD_TYPE_MAP.keySet())
		{
			KEYWORD_TYPE_TO_NAME_MAP.put(NAME_TO_KEYWORD_TYPE_MAP.get(name), name);
		}
	}

	private volatile ModifierCache myModifierCache;

	public PsiModifierListImpl(final PsiModifierListStub stub)
	{
		super(stub, JavaStubElementTypes.MODIFIER_LIST);
	}

	public PsiModifierListImpl(final ASTNode node)
	{
		super(node);
	}

	@Override
	public boolean hasModifierProperty(@NotNull String name)
	{
		ModifierCache modifierCache = myModifierCache;
		if(modifierCache == null || !modifierCache.isUpToDate())
		{
			myModifierCache = modifierCache = calcModifiers();
		}
		return modifierCache.modifiers.contains(name);
	}

	private ModifierCache calcModifiers()
	{
		Set<String> modifiers = calcExplicitModifiers();
		modifiers.addAll(calcImplicitModifiers(modifiers));
		if(!modifiers.contains(PUBLIC) && !modifiers.contains(PROTECTED) && !modifiers.contains(PRIVATE))
		{
			modifiers.add(PACKAGE_LOCAL);
		}
		PsiFile file = getContainingFile();
		return new ModifierCache(file, PsiAugmentProvider.transformModifierProperties(this, file.getProject(), modifiers));
	}

	private Set<String> calcExplicitModifiers()
	{
		Set<String> explicitModifiers = ContainerUtil.newHashSet();
		PsiModifierListStub stub = getGreenStub();
		if(stub != null)
		{
			int mask = stub.getModifiersMask();
			for(int i = 0; i < 31; i++)
			{
				int flag = 1 << i;
				if(BitUtil.isSet(mask, flag))
				{
					ContainerUtil.addIfNotNull(explicitModifiers, ModifierFlags.MODIFIER_FLAG_TO_NAME_MAP.get(flag));
				}
			}
		}
		else
		{
			for(ASTNode child : getNode().getChildren(null))
			{
				ContainerUtil.addIfNotNull(explicitModifiers, KEYWORD_TYPE_TO_NAME_MAP.get(child.getElementType()));
			}
		}

		return explicitModifiers;
	}

	private Set<String> calcImplicitModifiers(Set<String> explicitModifiers)
	{
		Set<String> implicitModifiers = ContainerUtil.newHashSet();
		PsiElement parent = getParent();
		if(parent instanceof PsiClass)
		{
			PsiElement grandParent = parent.getContext();
			if(grandParent instanceof PsiClass && ((PsiClass) grandParent).isInterface())
			{
				Collections.addAll(implicitModifiers, PUBLIC, STATIC);
			}
			if(((PsiClass) parent).isInterface())
			{
				implicitModifiers.add(ABSTRACT);

				// nested interface is implicitly static
				if(grandParent instanceof PsiClass)
				{
					implicitModifiers.add(STATIC);
				}
			}
			if(((PsiClass) parent).isEnum())
			{
				if(!(grandParent instanceof PsiFile))
				{
					implicitModifiers.add(STATIC);
				}
				List<PsiField> fields = parent instanceof PsiExtensibleClass ? ((PsiExtensibleClass) parent).getOwnFields() : Arrays.asList(((PsiClass) parent).getFields());
				boolean hasSubClass = ContainerUtil.find(fields, field -> field instanceof PsiEnumConstant && ((PsiEnumConstant) field).getInitializingClass() != null) != null;
				if(!hasSubClass)
				{
					implicitModifiers.add(FINAL);
				}

				List<PsiMethod> methods = parent instanceof PsiExtensibleClass ? ((PsiExtensibleClass) parent).getOwnMethods() : Arrays.asList(((PsiClass) parent).getMethods());
				for(PsiMethod method : methods)
				{
					if(method.hasModifierProperty(ABSTRACT))<commit_msg>change logic for static modifier for interfaces<commit_after>/*
 * Copyright 2000-2017 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 com.intellij.psi.impl.source;

import static com.intellij.psi.PsiModifier.*;

import gnu.trove.THashMap;

import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import com.intellij.codeInsight.AnnotationTargetUtil;
import com.intellij.lang.ASTNode;
import com.intellij.psi.*;
import com.intellij.psi.augment.PsiAugmentProvider;
import com.intellij.psi.impl.CheckUtil;
import com.intellij.psi.impl.PsiImplUtil;
import com.intellij.psi.impl.cache.ModifierFlags;
import com.intellij.psi.impl.java.stubs.JavaStubElementTypes;
import com.intellij.psi.impl.java.stubs.PsiModifierListStub;
import com.intellij.psi.impl.source.codeStyle.CodeEditUtil;
import com.intellij.psi.impl.source.tree.CompositeElement;
import com.intellij.psi.impl.source.tree.Factory;
import com.intellij.psi.impl.source.tree.TreeElement;
import com.intellij.psi.tree.IElementType;
import com.intellij.util.ArrayUtil;
import com.intellij.util.BitUtil;
import com.intellij.util.IncorrectOperationException;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.containers.WeakInterner;

public class PsiModifierListImpl extends JavaStubPsiElement<PsiModifierListStub> implements PsiModifierList
{
	private static final Map<String, IElementType> NAME_TO_KEYWORD_TYPE_MAP;
	private static final Map<IElementType, String> KEYWORD_TYPE_TO_NAME_MAP;

	static
	{
		NAME_TO_KEYWORD_TYPE_MAP = new THashMap<>();
		NAME_TO_KEYWORD_TYPE_MAP.put(PUBLIC, JavaTokenType.PUBLIC_KEYWORD);
		NAME_TO_KEYWORD_TYPE_MAP.put(PROTECTED, JavaTokenType.PROTECTED_KEYWORD);
		NAME_TO_KEYWORD_TYPE_MAP.put(PRIVATE, JavaTokenType.PRIVATE_KEYWORD);
		NAME_TO_KEYWORD_TYPE_MAP.put(STATIC, JavaTokenType.STATIC_KEYWORD);
		NAME_TO_KEYWORD_TYPE_MAP.put(ABSTRACT, JavaTokenType.ABSTRACT_KEYWORD);
		NAME_TO_KEYWORD_TYPE_MAP.put(FINAL, JavaTokenType.FINAL_KEYWORD);
		NAME_TO_KEYWORD_TYPE_MAP.put(NATIVE, JavaTokenType.NATIVE_KEYWORD);
		NAME_TO_KEYWORD_TYPE_MAP.put(SYNCHRONIZED, JavaTokenType.SYNCHRONIZED_KEYWORD);
		NAME_TO_KEYWORD_TYPE_MAP.put(STRICTFP, JavaTokenType.STRICTFP_KEYWORD);
		NAME_TO_KEYWORD_TYPE_MAP.put(TRANSIENT, JavaTokenType.TRANSIENT_KEYWORD);
		NAME_TO_KEYWORD_TYPE_MAP.put(VOLATILE, JavaTokenType.VOLATILE_KEYWORD);
		NAME_TO_KEYWORD_TYPE_MAP.put(DEFAULT, JavaTokenType.DEFAULT_KEYWORD);
		NAME_TO_KEYWORD_TYPE_MAP.put(OPEN, JavaTokenType.OPEN_KEYWORD);
		NAME_TO_KEYWORD_TYPE_MAP.put(TRANSITIVE, JavaTokenType.TRANSITIVE_KEYWORD);

		KEYWORD_TYPE_TO_NAME_MAP = ContainerUtil.newTroveMap();
		for(String name : NAME_TO_KEYWORD_TYPE_MAP.keySet())
		{
			KEYWORD_TYPE_TO_NAME_MAP.put(NAME_TO_KEYWORD_TYPE_MAP.get(name), name);
		}
	}

	private volatile ModifierCache myModifierCache;

	public PsiModifierListImpl(final PsiModifierListStub stub)
	{
		super(stub, JavaStubElementTypes.MODIFIER_LIST);
	}

	public PsiModifierListImpl(final ASTNode node)
	{
		super(node);
	}

	@Override
	public boolean hasModifierProperty(@NotNull String name)
	{
		ModifierCache modifierCache = myModifierCache;
		if(modifierCache == null || !modifierCache.isUpToDate())
		{
			myModifierCache = modifierCache = calcModifiers();
		}
		return modifierCache.modifiers.contains(name);
	}

	private ModifierCache calcModifiers()
	{
		Set<String> modifiers = calcExplicitModifiers();
		modifiers.addAll(calcImplicitModifiers(modifiers));
		if(!modifiers.contains(PUBLIC) && !modifiers.contains(PROTECTED) && !modifiers.contains(PRIVATE))
		{
			modifiers.add(PACKAGE_LOCAL);
		}
		PsiFile file = getContainingFile();
		return new ModifierCache(file, PsiAugmentProvider.transformModifierProperties(this, file.getProject(), modifiers));
	}

	private Set<String> calcExplicitModifiers()
	{
		Set<String> explicitModifiers = ContainerUtil.newHashSet();
		PsiModifierListStub stub = getGreenStub();
		if(stub != null)
		{
			int mask = stub.getModifiersMask();
			for(int i = 0; i < 31; i++)
			{
				int flag = 1 << i;
				if(BitUtil.isSet(mask, flag))
				{
					ContainerUtil.addIfNotNull(explicitModifiers, ModifierFlags.MODIFIER_FLAG_TO_NAME_MAP.get(flag));
				}
			}
		}
		else
		{
			for(ASTNode child : getNode().getChildren(null))
			{
				ContainerUtil.addIfNotNull(explicitModifiers, KEYWORD_TYPE_TO_NAME_MAP.get(child.getElementType()));
			}
		}

		return explicitModifiers;
	}

	private Set<String> calcImplicitModifiers(Set<String> explicitModifiers)
	{
		Set<String> implicitModifiers = ContainerUtil.newHashSet();
		PsiElement parent = getParent();
		if(parent instanceof PsiClass)
		{
			PsiElement grandParent = ((PsiClass) parent).getContainingClass();
			if(grandParent != null && ((PsiClass) grandParent).isInterface())
			{
				Collections.addAll(implicitModifiers, PUBLIC, STATIC);
			}
			if(((PsiClass) parent).isInterface())
			{
				implicitModifiers.add(ABSTRACT);

				// nested interface is implicitly static
				if(grandParent != null)
				{
					implicitModifiers.add(STATIC);
				}
			}
			if(((PsiClass) parent).isEnum())
			{
				// parent is file
				if(grandParent == null)
				{
					implicitModifiers.add(STATIC);
				}
				List<PsiField> fields = parent instanceof PsiExtensibleClass ? ((PsiExtensibleClass) parent).getOwnFields() : Arrays.asList(((PsiClass) parent).getFields());
				boolean hasSubClass = ContainerUtil.find(fields, field -> field instanceof PsiEnumConstant && ((PsiEnumConstant) field).getInitializingClass() != null) != null;
				if(!hasSubClass)
				{
					implicitModifiers.add(FINAL);
				}

				List<PsiMethod> methods = parent instanceof PsiExtensibleClass ? ((PsiExtensibleClass) parent).getOwnMethods() : Arrays.asList(((PsiClass) parent).getMethods());
				for(PsiMethod method : methods)
				{
					if(method.hasModifierProperty(ABSTRACT))
{'fraction_non_alphanumeric': 0.10497408524793068, 'fraction_numerical': 0.002475439003635801, 'mean_word_length': 5.549138804457954, 'pattern_counts': {'":': 0, '<': 33, '<?xml version=': 0, '>': 29, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3634850', 'n_tokens_mistral': 4690, 'n_tokens_neox': 4293, 'n_words': 736}