Skip to content

Commit

Permalink
Angular - deduplicate code and fix issue with structural directives s…
Browse files Browse the repository at this point in the history
…copes in Pug templates
  • Loading branch information
piotrtomiak committed Nov 27, 2018
1 parent a25dda7 commit 7714d70
Show file tree
Hide file tree
Showing 3 changed files with 38 additions and 73 deletions.
73 changes: 24 additions & 49 deletions AngularJS/src/org/angular2/codeInsight/Angular2Processor.java
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFile;
import com.intellij.psi.XmlRecursiveElementVisitor;
import com.intellij.psi.search.GlobalSearchScope;
import com.intellij.psi.util.CachedValueProvider;
import com.intellij.psi.util.CachedValuesManager;
Expand Down Expand Up @@ -235,13 +234,13 @@ else if (subType instanceof JSFunctionType) {
return JSCompositeTypeImpl.getCommonType(result, type.getSource(), false);
}

private static class Angular2TemplateScopeBuilder extends Angular2HtmlRecursiveElementVisitor {
private static class Angular2BaseScopeBuilder extends Angular2HtmlRecursiveElementVisitor {

@NotNull
private final PsiFile myTemplateFile;
private final Stack<Angular2TemplateScope> scopes = new Stack<>();

private Angular2TemplateScopeBuilder(@NotNull PsiFile templateFile) {
Angular2BaseScopeBuilder(@NotNull PsiFile templateFile) {
myTemplateFile = templateFile;
scopes.add(new Angular2TemplateScope(templateFile, null));
}
Expand All @@ -253,22 +252,34 @@ public Angular2TemplateScope getTopLevelScope() {
return scopes.peek();
}

private Angular2TemplateScope currentScope() {
Angular2TemplateScope currentScope() {
return scopes.peek();
}

private void popScope() {
void popScope() {
scopes.pop();
}

private void pushScope(@NotNull XmlTag tag) {
void pushScope(@NotNull XmlTag tag) {
scopes.push(new Angular2TemplateScope(tag, currentScope()));
}

private void addElement(@NotNull JSPsiElementBase element) {
void addElement(@NotNull JSPsiElementBase element) {
currentScope().add(element);
}

@NotNull
Angular2TemplateScope prevScope() {
return scopes.get(scopes.size() - 2);
}
}

private static class Angular2TemplateScopeBuilder extends Angular2BaseScopeBuilder {

Angular2TemplateScopeBuilder(@NotNull PsiFile templateFile) {
super(templateFile);
}

@Override
public void visitXmlTag(XmlTag tag) {
boolean isTemplateTag = Stream.of(tag.getChildren()).anyMatch(Angular2HtmlTemplateBindings.class::isInstance)
Expand Down Expand Up @@ -301,11 +312,6 @@ public void visitReference(Angular2HtmlReference reference) {
}
}

@NotNull
private Angular2TemplateScope prevScope() {
return scopes.get(scopes.size() - 2);
}

@Override
public void visitVariable(Angular2HtmlVariable variable) {
addElement(createVariable(variable.getVariableName(), variable));
Expand All @@ -323,43 +329,17 @@ public void visitTemplateBindings(Angular2HtmlTemplateBindingsImpl bindings) {
}
}

private static class Angular2ForeignTemplateScopeBuilder extends XmlRecursiveElementVisitor {

@NotNull
private final PsiFile myTemplateFile;
private final Stack<Angular2TemplateScope> scopes = new Stack<>();

private Angular2ForeignTemplateScopeBuilder(@NotNull PsiFile templateFile) {
myTemplateFile = templateFile;
scopes.add(new Angular2TemplateScope(templateFile, null));
}

@NotNull
public Angular2TemplateScope getTopLevelScope() {
myTemplateFile.accept(this);
assert scopes.size() == 1;
return scopes.peek();
}
private static class Angular2ForeignTemplateScopeBuilder extends Angular2BaseScopeBuilder {

private Angular2TemplateScope currentScope() {
return scopes.peek();
}

private void popScope() {
scopes.pop();
}

private void pushScope(@NotNull XmlTag tag) {
scopes.push(new Angular2TemplateScope(tag, currentScope()));
}

private void addElement(@NotNull JSPsiElementBase element) {
currentScope().add(element);
Angular2ForeignTemplateScopeBuilder(@NotNull PsiFile templateFile) {
super(templateFile);
}

@Override
public void visitXmlTag(XmlTag tag) {
boolean isTemplateTag = Stream.of(tag.getChildren()).anyMatch(Angular2HtmlTemplateBindings.class::isInstance)
boolean isTemplateTag = StreamEx.of(tag.getChildren())
.select(XmlAttribute.class)
.anyMatch(attr -> attr.getName().startsWith("*"))
|| isTemplateTag(tag.getName());
if (isTemplateTag) {
pushScope(tag);
Expand Down Expand Up @@ -403,11 +383,6 @@ public void addReference(@NotNull XmlAttribute attribute, @NotNull AttributeInfo
}
}

@NotNull
private Angular2TemplateScope prevScope() {
return scopes.get(scopes.size() - 2);
}

public void addVariable(@NotNull XmlAttribute attribute, @NotNull AttributeInfo info) {
addElement(createVariable(info.name, attribute));
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
import com.intellij.xml.XmlAttributeDescriptor;
import com.intellij.xml.XmlAttributeDescriptorsProvider;
import org.angular2.codeInsight.Angular2Processor;
import org.angular2.codeInsight.tags.Angular2TagDescriptorsProvider;
import org.angular2.entities.Angular2Directive;
import org.angular2.entities.Angular2DirectiveProperty;
import org.angular2.entities.Angular2DirectiveSelector.SimpleSelectorWithPsi;
Expand All @@ -30,8 +31,6 @@
import org.angular2.lang.html.psi.Angular2HtmlElementVisitor;
import org.angular2.lang.html.psi.Angular2HtmlReference;
import org.angular2.lang.html.psi.Angular2HtmlVariable;
import org.angular2.lang.selector.Angular2DirectiveSimpleSelector;
import org.angular2.lang.selector.Angular2SelectorMatcher;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

Expand Down Expand Up @@ -105,33 +104,21 @@ public XmlAttributeDescriptor getAttributeDescriptor(@Nullable final String attr
return getAttributeDescriptor(attrName, xmlTag, this::getAttributeDescriptors);
}

public static Set<Angular2Directive> getApplicableDirectives(@NotNull XmlTag xmlTag) {
public static List<Angular2Directive> getApplicableDirectives(@NotNull XmlTag xmlTag) {
return getApplicableDirectives(xmlTag, new HashSet<>());
}

private static Set<Angular2Directive> getApplicableDirectives(@NotNull XmlTag xmlTag,
private static List<Angular2Directive> getApplicableDirectives(@NotNull XmlTag xmlTag,
@NotNull Set<Angular2Directive> directiveCandidates) {
directiveCandidates.addAll(findElementDirectivesCandidates(xmlTag.getProject(), xmlTag.getName()));
directiveCandidates.addAll(findElementDirectivesCandidates(xmlTag.getProject(), ""));

Angular2SelectorMatcher<Angular2Directive> matcher = new Angular2SelectorMatcher<>();
directiveCandidates.forEach(d -> matcher.addSelectables(d.getSelector().getSimpleSelectors(), d));

boolean isTemplateTag = Angular2Processor.isTemplateTag(xmlTag.getName());
Set<Angular2Directive> matchedDirectives = new HashSet<>();
Angular2DirectiveSimpleSelector tagInfo = Angular2DirectiveSimpleSelector.createElementCssSelector(xmlTag);
matcher.match(tagInfo, (selector, directive) -> {
if (!directive.isTemplate() || isTemplateTag) {
matchedDirectives.add(directive);
}
});
return matchedDirectives;
return Angular2TagDescriptorsProvider.matchDirectives(xmlTag, directiveCandidates);
}

@NotNull
public static Collection<XmlAttributeDescriptor> getDirectiveDescriptors(@NotNull XmlTag xmlTag) {
Set<Angular2Directive> directiveCandidates = new HashSet<>();
Set<Angular2Directive> matchedDirectives = getApplicableDirectives(xmlTag, directiveCandidates);
List<Angular2Directive> matchedDirectives = getApplicableDirectives(xmlTag, directiveCandidates);

boolean isTemplateTag = Angular2Processor.isTemplateTag(xmlTag.getName());
List<XmlAttributeDescriptor> result = new ArrayList<>();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,7 @@
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.*;

public class Angular2TagDescriptorsProvider implements XmlElementDescriptorProvider, XmlTagNameProvider {
private static final String NG_CONTAINER = "ng-container";
Expand Down Expand Up @@ -91,6 +88,13 @@ public XmlElementDescriptor getDescriptor(@NotNull XmlTag xmlTag) {
if (directiveCandidates.isEmpty()) {
return null;
}
List<Angular2Directive> matchedDirectives = matchDirectives(xmlTag, directiveCandidates);
return new Angular2TagDescriptor(tagName, (matchedDirectives.isEmpty() ? directiveCandidates : matchedDirectives).get(0).getSelector()
.getPsiElementForElement(tagName));
}

@NotNull
public static List<Angular2Directive> matchDirectives(@NotNull XmlTag xmlTag, @NotNull Collection<Angular2Directive> directiveCandidates) {
Angular2SelectorMatcher<Angular2Directive> matcher = new Angular2SelectorMatcher<>();
directiveCandidates.forEach(d -> matcher.addSelectables(d.getSelector().getSimpleSelectors(), d));

Expand All @@ -102,8 +106,7 @@ public XmlElementDescriptor getDescriptor(@NotNull XmlTag xmlTag) {
matchedDirectives.add(directive);
}
});
return new Angular2TagDescriptor(tagName, (matchedDirectives.isEmpty() ? directiveCandidates : matchedDirectives).get(0).getSelector()
.getPsiElementForElement(tagName));
return matchedDirectives;
}

@NotNull
Expand Down

0 comments on commit 7714d70

Please sign in to comment.