Package org.angularjs.codeInsight.attributes

Source Code of org.angularjs.codeInsight.attributes.AngularJSAttributeDescriptorsProvider

package org.angularjs.codeInsight.attributes;

import com.intellij.lang.javascript.index.JSNamedElementProxy;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.psi.xml.XmlTag;
import com.intellij.util.ThreeState;
import com.intellij.util.indexing.ID;
import com.intellij.xml.XmlAttributeDescriptor;
import com.intellij.xml.XmlAttributeDescriptorsProvider;
import org.angularjs.codeInsight.DirectiveUtil;
import org.angularjs.index.AngularDirectivesDocIndex;
import org.angularjs.index.AngularDirectivesIndex;
import org.angularjs.index.AngularIndexUtil;
import org.jetbrains.annotations.Nullable;

import java.util.Collection;
import java.util.LinkedHashMap;
import java.util.Map;

import static org.angularjs.codeInsight.attributes.AngularAttributesRegistry.createDescriptor;

/**
* @author Dennis.Ushakov
*/
public class AngularJSAttributeDescriptorsProvider implements XmlAttributeDescriptorsProvider {
  @Override
  public XmlAttributeDescriptor[] getAttributeDescriptors(XmlTag xmlTag) {
    if (xmlTag != null) {
      final Project project = xmlTag.getProject();
      final Map<String, XmlAttributeDescriptor> result = new LinkedHashMap<String, XmlAttributeDescriptor>();
      final Collection<String> docDirectives = AngularIndexUtil.getAllKeys(AngularDirectivesDocIndex.INDEX_ID, project);
      for (String directiveName : docDirectives) {
        if (isApplicable(project, directiveName, xmlTag.getName(), AngularDirectivesDocIndex.INDEX_ID) == ThreeState.YES) {
          addAttributes(project, result, directiveName);
        }
      }
      for (String directiveName : AngularIndexUtil.getAllKeys(AngularDirectivesIndex.INDEX_ID, project)) {
        if (!docDirectives.contains(directiveName) &&
            isApplicable(project, directiveName, xmlTag.getName(), AngularDirectivesIndex.INDEX_ID) == ThreeState.YES) {
          addAttributes(project, result, directiveName);
        }
      }
      return result.values().toArray(new XmlAttributeDescriptor[result.size()]);
    }
    return XmlAttributeDescriptor.EMPTY;
  }

  protected void addAttributes(Project project, Map<String, XmlAttributeDescriptor> result, String directiveName) {
    result.put(directiveName, createDescriptor(project, directiveName));
    if ("ng-repeat".equals(directiveName)) {
      result.put(directiveName + "-start", createDescriptor(project, directiveName + "-start"));
      result.put(directiveName + "-end", createDescriptor(project, directiveName + "-end"));
    }
  }

  private static ThreeState isApplicable(Project project, String directiveName, String tagName, final ID<String, Void> index) {
    final JSNamedElementProxy directive = AngularIndexUtil.resolve(project, index, directiveName);
    if (directive == null) {
      return ThreeState.UNSURE;
    }

    final String restrictions = directive.getIndexItem().getTypeString();
    if (restrictions != null) {
      final String[] split = restrictions.split(";", -1);
      final String restrict = AngularIndexUtil.convertRestrictions(project, split[0]);
      final String tag = split[1];
      if (!StringUtil.isEmpty(restrict) && !StringUtil.containsIgnoreCase(restrict, "A")) {
        return ThreeState.NO;
      }
      if (!tagMatches(tagName, tag)) {
        return ThreeState.NO;
      }
    }

    return ThreeState.YES;
  }

  private static boolean tagMatches(String tagName, String tag) {
    if (StringUtil.isEmpty(tag) || StringUtil.equalsIgnoreCase(tag, "ANY")) {
      return true;
    }
    for (String s : tag.split(",")) {
      if (StringUtil.equalsIgnoreCase(tagName, s.trim())) {
        return true;
      }
    }
    return false;
  }

  @Nullable
  @Override
  public XmlAttributeDescriptor getAttributeDescriptor(final String attrName, XmlTag xmlTag) {
    final String attributeName = DirectiveUtil.normalizeAttributeName(attrName);
    if (xmlTag != null) {
      final Project project = xmlTag.getProject();
      final String tagName = xmlTag.getName();
      ThreeState attributeAvailable = isApplicable(project, attributeName, tagName, AngularDirectivesDocIndex.INDEX_ID);
      if (attributeAvailable == ThreeState.UNSURE) {
        attributeAvailable = isApplicable(project, attributeName, tagName, AngularDirectivesIndex.INDEX_ID);
      }
      return attributeAvailable == ThreeState.YES ? createDescriptor(project, attributeName) : null;
    }
    return null;
  }
}
TOP

Related Classes of org.angularjs.codeInsight.attributes.AngularJSAttributeDescriptorsProvider

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.