All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.intellij.codeInspection.reference.RefFieldImpl Maven / Gradle / Ivy

Go to download

A packaging of the IntelliJ Community Edition java-analysis-impl library. This is release number 1 of trunk branch 142.

The newest version!
/*
 * Copyright 2000-2015 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.codeInspection.reference;

import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.util.Computable;
import com.intellij.psi.*;
import com.intellij.psi.util.ClassUtil;
import com.intellij.psi.util.PsiFormatUtil;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.psi.util.PsiUtil;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

/**
 * @author max
 * Date: Oct 21, 2001
 */
public class RefFieldImpl extends RefJavaElementImpl implements RefField {
  private static final int USED_FOR_READING_MASK = 0x10000;
  private static final int USED_FOR_WRITING_MASK = 0x20000;
  private static final int ASSIGNED_ONLY_IN_INITIALIZER_MASK = 0x40000;

  RefFieldImpl(@NotNull RefClass ownerClass, PsiField field, RefManager manager) {
    super(field, manager);

    ((RefClassImpl)ownerClass).add(this);

    if (ownerClass.isInterface()) {
      setIsStatic(true);
      setIsFinal(true);
    }
    if (field instanceof PsiEnumConstant) {
      putUserData(ENUM_CONSTANT, true);
    }
  }

  @Override
  public PsiField getElement() {
    return (PsiField)super.getElement();
  }

  @Override
  protected void markReferenced(RefElementImpl refFrom, PsiElement psiFrom, PsiElement psiWhat, boolean forWriting, boolean forReading, PsiReferenceExpression expressionFrom) {
    addInReference(refFrom);

    boolean referencedFromClassInitializer = false;

    if (forWriting && expressionFrom != null) {
      PsiClassInitializer initializer = PsiTreeUtil.getParentOfType(expressionFrom, PsiClassInitializer.class);
      if (initializer != null) {
        if (initializer.getParent() instanceof PsiClass && psiFrom == initializer.getParent() && !expressionFrom.isQualified()) {
          referencedFromClassInitializer = true;
        }
      }
    }

    if (forWriting) {
      setUsedForWriting(true);
    }

    if (forReading) {
      setUsedForReading(true);
    }
    getRefManager().fireNodeMarkedReferenced(this, refFrom, referencedFromClassInitializer, forReading, forWriting);
  }

  @Override
  public boolean isUsedForReading() {
    return checkFlag(USED_FOR_READING_MASK);
  }

  private void setUsedForReading(boolean usedForReading) {
    setFlag(usedForReading, USED_FOR_READING_MASK);
  }

  @Override
  public boolean isUsedForWriting() {
    return checkFlag(USED_FOR_WRITING_MASK);
  }

  private void setUsedForWriting(boolean usedForWriting) {
    setFlag(false, ASSIGNED_ONLY_IN_INITIALIZER_MASK);
    setFlag(usedForWriting, USED_FOR_WRITING_MASK);
  }

  @Override
  public boolean isOnlyAssignedInInitializer() {
    return checkFlag(ASSIGNED_ONLY_IN_INITIALIZER_MASK);
  }

  @Override
  public void accept(@NotNull final RefVisitor visitor) {
    if (visitor instanceof RefJavaVisitor) {
      ApplicationManager.getApplication().runReadAction(new Runnable() {
        @Override
        public void run() {
          ((RefJavaVisitor)visitor).visitField(RefFieldImpl.this);
        }
      });
    }  else {
      super.accept(visitor);
    }
  }

  @Override
  public void buildReferences() {
    PsiField psiField = getElement();
    if (psiField != null) {
      final RefJavaUtil refUtil = RefJavaUtil.getInstance();
      refUtil.addReferences(psiField, this, psiField.getInitializer());
      refUtil.addReferences(psiField, this, psiField.getModifierList());
      if (psiField instanceof PsiEnumConstant) {
        refUtil.addReferences(psiField, this, psiField);
      }

      if (psiField.getInitializer() != null || psiField instanceof PsiEnumConstant) {
        if (!checkFlag(USED_FOR_WRITING_MASK)) {
          setFlag(true, ASSIGNED_ONLY_IN_INITIALIZER_MASK);
          setFlag(true, USED_FOR_WRITING_MASK);
        }
      }
      PsiType psiType = psiField.getType();
      RefClass ownerClass = refUtil.getOwnerClass(getRefManager(), psiField);

      if (ownerClass != null) {
        psiType = psiType.getDeepComponentType();
        if (psiType instanceof PsiClassType) {
          PsiClass psiClass = PsiUtil.resolveClassInType(psiType);
          if (psiClass != null && getRefManager().belongsToScope(psiClass)) {
              RefClassImpl refClass = (RefClassImpl)getRefManager().getReference(psiClass);
            if (refClass != null) {
              refClass.addTypeReference(ownerClass);
              refClass.addClassExporter(this);
            }
          }
        }

      }
      getRefManager().fireBuildReferences(this);
    }
  }

  @Override
  public RefClass getOwnerClass() {
    return (RefClass) getOwner();
  }

  @Override
  public String getExternalName() {
    return ApplicationManager.getApplication().runReadAction(new Computable() {
      @Override
      public String compute() {
        PsiField psiField = getElement();
        return psiField != null ? PsiFormatUtil.getExternalName(psiField) : null;
      }
    });
  }

  @Nullable
  public static RefField fieldFromExternalName(RefManager manager, String externalName) {
    return (RefField)manager.getReference(findPsiField(PsiManager.getInstance(manager.getProject()), externalName));
  }

  @Nullable
  public static PsiField findPsiField(PsiManager manager, String externalName) {
    int classNameDelimeter = externalName.lastIndexOf(' ');
    if (classNameDelimeter > 0 && classNameDelimeter < externalName.length() - 1) {
      final String className = externalName.substring(0, classNameDelimeter);
      final String fieldName = externalName.substring(classNameDelimeter + 1);
      final PsiClass psiClass = ClassUtil.findPsiClass(manager, className);
      if (psiClass != null) {
        return psiClass.findFieldByName(fieldName, false);
      }
    }
    return null;
  }

  @Override
  public boolean isSuspicious() {
    if (isEntry()) return false;
    if (super.isSuspicious()) return true;
    return isUsedForReading() != isUsedForWriting();
  }

  @Override
  protected void initialize() {
  }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy