diff --git a/latte-plugin.jar b/latte-plugin.jar
index 64e693f..c84ce3c 100644
Binary files a/latte-plugin.jar and b/latte-plugin.jar differ
diff --git a/resources/META-INF/plugin.xml b/resources/META-INF/plugin.xml
index bc90385..9a6b63c 100644
--- a/resources/META-INF/plugin.xml
+++ b/resources/META-INF/plugin.xml
@@ -1,7 +1,7 @@
com.jantvrdik.intellij.latte
Latte
- 1.0.1
+ 1.0.2
Jan TvrdĂk
1.0.2
+
+ - added code style settings (settings for use tabs or spaces) (issue #46, #30)
+ - added support for define variable in tag {default $foo = 123}
+ - added class namespaces completion
+ - added support for define variables by {php [$foo, $bar] = $arr}
+ - implemented some performance improvements
+ - fixed resolving methods if a type is more classes FooClass|BarClass
+ - fixed completion for unpaired macro after if missing end }
+ - fixed filters on variables (issue #47)
+ - fixed wrong indent for elseifset (issue #42)
+ - fixed multiple variable definitions in for/foreach cycles
+ - fixed auto-complete (disabled in strings, more improvements)
+ - increased minimum compatibility to 2018.3
+
1.0.1
- - Fixed compatibility issues
- - Fixed structure view (added n:tags and images)
+ - fixed compatibility issues
+ - fixed structure view (added n:tags and images)
1.0.0
@@ -141,7 +156,7 @@
-
+
com.intellij.modules.lang
@@ -174,6 +189,9 @@
+
+
+
getSupportedFields(SettingsType type) {
+ if (type == SettingsType.BLANK_LINES_SETTINGS) {
+ return Collections.emptySet();
+ }
+ return super.getSupportedFields(type);
+ }
+
+ @Override
+ public @Nullable IndentOptionsEditor getIndentOptionsEditor() {
+ return new IndentOptionsEditor();
+ }
+
+ @Override
+ public String getCodeSample(@NotNull SettingsType settingsType) {
+ return "{contentType text/html}\n" +
+ "{* comment *}\n" +
+ "{var $string = \"abc\", $number = 123}\n\n" +
+ "{foreach $data as $key => $value}\n" +
+ " {$key} {$value}\n" +
+ "{/foreach}";
+ }
+}
\ No newline at end of file
diff --git a/src/com/jantvrdik/intellij/latte/completion/LatteCompletionContributor.java b/src/com/jantvrdik/intellij/latte/completion/LatteCompletionContributor.java
index ef579df..ffc16c4 100644
--- a/src/com/jantvrdik/intellij/latte/completion/LatteCompletionContributor.java
+++ b/src/com/jantvrdik/intellij/latte/completion/LatteCompletionContributor.java
@@ -12,7 +12,6 @@
import com.jantvrdik.intellij.latte.completion.handlers.AttrMacroInsertHandler;
import com.jantvrdik.intellij.latte.completion.handlers.MacroInsertHandler;
import com.jantvrdik.intellij.latte.completion.providers.LattePhpCompletionProvider;
-import com.jantvrdik.intellij.latte.completion.providers.LatteVariableCompletionProvider;
import com.jantvrdik.intellij.latte.config.LatteConfiguration;
import com.jantvrdik.intellij.latte.config.LatteMacro;
import com.jantvrdik.intellij.latte.config.LatteModifier;
@@ -87,9 +86,11 @@ protected void addCompletions(@NotNull CompletionParameters parameters, Processi
return;
}
- LatteMacro macro = LatteConfiguration.INSTANCE.getMacro(element.getProject(), macroClassic.getOpenTag().getMacroName());
- if (macro == null || !macro.allowedModifiers) {
- return;
+ if (!((LatteMacroModifier) element).isVariableModifier()) {
+ LatteMacro macro = LatteConfiguration.INSTANCE.getMacro(element.getProject(), macroClassic.getOpenTag().getMacroName());
+ if (macro == null || !macro.allowedModifiers) {
+ return;
+ }
}
Map customModifiers = LatteConfiguration.INSTANCE.getCustomModifiers(element.getProject());
@@ -98,12 +99,6 @@ protected void addCompletions(@NotNull CompletionParameters parameters, Processi
}
});
- extend(
- CompletionType.BASIC,
- PlatformPatterns.psiElement(LatteTypes.T_MACRO_ARGS_VAR).withLanguage(LatteLanguage.INSTANCE),
- new LatteVariableCompletionProvider()
- );
-
extend(
CompletionType.BASIC,
PlatformPatterns.psiElement().withLanguage(LatteLanguage.INSTANCE),
diff --git a/src/com/jantvrdik/intellij/latte/completion/handlers/MacroInsertHandler.java b/src/com/jantvrdik/intellij/latte/completion/handlers/MacroInsertHandler.java
index 697f327..51737ad 100644
--- a/src/com/jantvrdik/intellij/latte/completion/handlers/MacroInsertHandler.java
+++ b/src/com/jantvrdik/intellij/latte/completion/handlers/MacroInsertHandler.java
@@ -62,28 +62,26 @@ public void handleInsert(@NotNull InsertionContext context, @NotNull LookupEleme
spaceInserted = 1;
}
- if (isCloseTag || resolvePairMacro) {
- int lastBraceOffset = text.indexOf("}", offset);
- int endOfLineOffset = text.indexOf("\n", offset);
+ int lastBraceOffset = text.indexOf("}", offset);
+ int endOfLineOffset = text.indexOf("\n", offset);
- if (endOfLineOffset == -1) {
- endOfLineOffset = text.length();
- }
- if (lastBraceOffset == -1 || lastBraceOffset > endOfLineOffset) {
- caretModel.moveToOffset(endOfLineOffset + spaceInserted);
- EditorModificationUtil.insertStringAtCaret(editor, "}");
- lastBraceOffset = endOfLineOffset;
- endOfLineOffset++;
- }
+ if (endOfLineOffset == -1) {
+ endOfLineOffset = text.length();
+ }
+ if (lastBraceOffset == -1 || lastBraceOffset > endOfLineOffset) {
+ caretModel.moveToOffset(endOfLineOffset + spaceInserted);
+ EditorModificationUtil.insertStringAtCaret(editor, "}");
+ lastBraceOffset = endOfLineOffset;
+ endOfLineOffset++;
+ }
- if (resolvePairMacro) {
- String endTag = "{/" + macroName + "}";
+ if (resolvePairMacro) {
+ String endTag = "{/" + macroName + "}";
- int endTagOffset = text.indexOf(endTag, offset);
- if (endTagOffset == -1 || endTagOffset > endOfLineOffset) {
- caretModel.moveToOffset(lastBraceOffset + spaceInserted + 1);
- EditorModificationUtil.insertStringAtCaret(editor, endTag);
- }
+ int endTagOffset = text.indexOf(endTag, offset);
+ if (endTagOffset == -1 || endTagOffset > endOfLineOffset) {
+ caretModel.moveToOffset(lastBraceOffset + spaceInserted + 1);
+ EditorModificationUtil.insertStringAtCaret(editor, endTag);
}
}
diff --git a/src/com/jantvrdik/intellij/latte/completion/providers/LattePhpCompletionProvider.java b/src/com/jantvrdik/intellij/latte/completion/providers/LattePhpCompletionProvider.java
index 308ef28..b5696a8 100644
--- a/src/com/jantvrdik/intellij/latte/completion/providers/LattePhpCompletionProvider.java
+++ b/src/com/jantvrdik/intellij/latte/completion/providers/LattePhpCompletionProvider.java
@@ -26,11 +26,15 @@ public class LattePhpCompletionProvider extends BaseLatteCompletionProvider {
private final LattePhpFunctionCompletionProvider functionCompletionProvider;
private final LattePhpClassCompletionProvider classCompletionProvider;
+ private final LattePhpNamespaceCompletionProvider namespaceCompletionProvider;
+ private final LatteVariableCompletionProvider variableCompletionProvider;
public LattePhpCompletionProvider() {
super();
functionCompletionProvider = new LattePhpFunctionCompletionProvider();
classCompletionProvider = new LattePhpClassCompletionProvider();
+ namespaceCompletionProvider = new LattePhpNamespaceCompletionProvider();
+ variableCompletionProvider = new LatteVariableCompletionProvider();
}
@Override
@@ -49,13 +53,15 @@ protected void addCompletions(
} else if (element instanceof LattePhpProperty || (element instanceof LattePhpMethod && !((LattePhpMethod) element).isStatic())) {
attachPhpCompletions(result, (BaseLattePhpElement) element, false);
- } else {
+ } else if (!(element instanceof LatteMacroModifier) && !(element instanceof LattePhpString)) {
+ classCompletionProvider.addCompletions(parameters, context, result);
+ namespaceCompletionProvider.addCompletions(parameters, context, result);
+
if (LatteUtil.matchParentMacroName(element, "varType") || LatteUtil.matchParentMacroName(element, "var")) {
attachVarTypes(result);
- }
- if (!(element instanceof LatteMacroModifier)) {
- classCompletionProvider.addCompletions(parameters, context, result);
+ } else {
+ variableCompletionProvider.addCompletions(parameters, context, result);
functionCompletionProvider.addCompletions(parameters, context, result);
}
}
diff --git a/src/com/jantvrdik/intellij/latte/completion/providers/LattePhpNamespaceCompletionProvider.java b/src/com/jantvrdik/intellij/latte/completion/providers/LattePhpNamespaceCompletionProvider.java
new file mode 100644
index 0000000..39d5370
--- /dev/null
+++ b/src/com/jantvrdik/intellij/latte/completion/providers/LattePhpNamespaceCompletionProvider.java
@@ -0,0 +1,38 @@
+package com.jantvrdik.intellij.latte.completion.providers;
+
+import com.intellij.codeInsight.completion.CompletionParameters;
+import com.intellij.codeInsight.completion.CompletionProvider;
+import com.intellij.codeInsight.completion.CompletionResultSet;
+import com.intellij.psi.PsiElement;
+import com.intellij.psi.util.PsiTreeUtil;
+import com.intellij.util.ProcessingContext;
+import com.jantvrdik.intellij.latte.psi.LattePhpContent;
+import com.jetbrains.php.PhpIndex;
+import com.jetbrains.php.completion.PhpCompletionUtil;
+import com.jetbrains.php.completion.insert.PhpNamespaceInsertHandler;
+import org.jetbrains.annotations.NotNull;
+
+
+public class LattePhpNamespaceCompletionProvider extends CompletionProvider {
+
+ public LattePhpNamespaceCompletionProvider() {
+ }
+
+ @Override
+ protected void addCompletions(@NotNull CompletionParameters params, ProcessingContext context, @NotNull CompletionResultSet result) {
+ PsiElement curr = params.getPosition().getOriginalElement();
+ if (PsiTreeUtil.getParentOfType(curr, LattePhpContent.class) == null) {
+ return;
+ }
+
+ PhpIndex phpIndex = PhpIndex.getInstance(curr.getProject());
+ String prefix = result.getPrefixMatcher().getPrefix();
+ String namespace = "";
+ if (prefix.contains("\\")) {
+ int index = prefix.lastIndexOf("\\");
+ namespace = prefix.substring(0, index) + "\\";
+ prefix = prefix.substring(index + 1);
+ }
+ PhpCompletionUtil.addSubNamespaces(namespace, result.withPrefixMatcher(prefix), phpIndex, PhpNamespaceInsertHandler.getInstance());
+ }
+}
diff --git a/src/com/jantvrdik/intellij/latte/completion/providers/LatteVariableCompletionProvider.java b/src/com/jantvrdik/intellij/latte/completion/providers/LatteVariableCompletionProvider.java
index 8b73c3a..c7b6a4c 100644
--- a/src/com/jantvrdik/intellij/latte/completion/providers/LatteVariableCompletionProvider.java
+++ b/src/com/jantvrdik/intellij/latte/completion/providers/LatteVariableCompletionProvider.java
@@ -37,7 +37,7 @@ protected void addCompletions(
@NotNull CompletionResultSet result
) {
PsiElement element = parameters.getPosition().getParent();
- if (!(element instanceof LattePhpVariable) || ((LattePhpVariable) element).isDefinition()) {
+ if ((element instanceof LattePhpVariable) && ((LattePhpVariable) element).isDefinition()) {
return;
}
diff --git a/src/com/jantvrdik/intellij/latte/formatter/LatteBlock.java b/src/com/jantvrdik/intellij/latte/formatter/LatteBlock.java
index 68f802c..5a7c915 100644
--- a/src/com/jantvrdik/intellij/latte/formatter/LatteBlock.java
+++ b/src/com/jantvrdik/intellij/latte/formatter/LatteBlock.java
@@ -51,7 +51,7 @@ protected Indent getChildIndent(@NotNull ASTNode astNode) {
}
PsiElement el = astNode.getPsi();
LatteMacroTag openTag = ((LatteMacroClassic) el).getOpenTag();
- if (openTag.getMacroName().equals("else") || openTag.getMacroName().equals("elseif")) {
+ if (openTag.matchMacroName("else") || openTag.matchMacroName("elseif") || openTag.matchMacroName("elseifset")) {
return Indent.getNoneIndent();
}
return Indent.getNormalIndent();
diff --git a/src/com/jantvrdik/intellij/latte/inspections/MacroTemplateTypeInspection.java b/src/com/jantvrdik/intellij/latte/inspections/MacroTemplateTypeInspection.java
index 6db8ccb..86de8e3 100644
--- a/src/com/jantvrdik/intellij/latte/inspections/MacroTemplateTypeInspection.java
+++ b/src/com/jantvrdik/intellij/latte/inspections/MacroTemplateTypeInspection.java
@@ -36,7 +36,7 @@ public ProblemDescriptor[] checkFile(@NotNull PsiFile file, @NotNull final Inspe
file.acceptChildren(new PsiRecursiveElementWalkingVisitor() {
@Override
public void visitElement(PsiElement element) {
- if (element instanceof LatteMacroTag && ((LatteMacroTag) element).getMacroName().equals("templateType")) {
+ if (element instanceof LatteMacroTag && ((LatteMacroTag) element).matchMacroName("templateType")) {
List allMacros = new ArrayList();
LatteUtil.findLatteMacroTemplateType(allMacros, (LatteFile) file);
if (allMacros.size() > 1) {
diff --git a/src/com/jantvrdik/intellij/latte/inspections/MacroVarInspection.java b/src/com/jantvrdik/intellij/latte/inspections/MacroVarInspection.java
index 233d3b3..60bbf50 100644
--- a/src/com/jantvrdik/intellij/latte/inspections/MacroVarInspection.java
+++ b/src/com/jantvrdik/intellij/latte/inspections/MacroVarInspection.java
@@ -36,7 +36,7 @@ public ProblemDescriptor[] checkFile(@NotNull PsiFile file, @NotNull final Inspe
file.acceptChildren(new PsiRecursiveElementWalkingVisitor() {
@Override
public void visitElement(PsiElement element) {
- if (element instanceof LatteMacroTag && ((LatteMacroTag) element).getMacroName().equals("var")) {
+ if (element instanceof LatteMacroTag && ((LatteMacroTag) element).matchMacroName("var")) {
LatteMacroContent macroContent = PsiTreeUtil.findChildOfType(element, LatteMacroContent.class);
if (macroContent != null) {
List phpContent = new ArrayList<>(macroContent.getPhpContentList());
diff --git a/src/com/jantvrdik/intellij/latte/inspections/MacroVarTypeInspection.java b/src/com/jantvrdik/intellij/latte/inspections/MacroVarTypeInspection.java
index 4da702e..e9af244 100644
--- a/src/com/jantvrdik/intellij/latte/inspections/MacroVarTypeInspection.java
+++ b/src/com/jantvrdik/intellij/latte/inspections/MacroVarTypeInspection.java
@@ -34,7 +34,7 @@ public ProblemDescriptor[] checkFile(@NotNull PsiFile file, @NotNull final Inspe
file.acceptChildren(new PsiRecursiveElementWalkingVisitor() {
@Override
public void visitElement(PsiElement element) {
- if (element instanceof LatteMacroTag && ((LatteMacroTag) element).getMacroName().equals("varType")) {
+ if (element instanceof LatteMacroTag && ((LatteMacroTag) element).matchMacroName("varType")) {
LatteMacroContent macroContent = PsiTreeUtil.findChildOfType(element, LatteMacroContent.class);
if (macroContent != null) {
List phpContent = new ArrayList<>(macroContent.getPhpContentList());
diff --git a/src/com/jantvrdik/intellij/latte/inspections/ModifierNotAllowedInspection.java b/src/com/jantvrdik/intellij/latte/inspections/ModifierNotAllowedInspection.java
index d277581..d2ebbff 100644
--- a/src/com/jantvrdik/intellij/latte/inspections/ModifierNotAllowedInspection.java
+++ b/src/com/jantvrdik/intellij/latte/inspections/ModifierNotAllowedInspection.java
@@ -67,7 +67,7 @@ private static void checkClassicMacro(
content.acceptChildren(new PsiRecursiveElementWalkingVisitor() {
@Override
public void visitElement(PsiElement element) {
- if (element instanceof LatteMacroModifier) {
+ if (element instanceof LatteMacroModifier && !((LatteMacroModifier) element).isVariableModifier()) {
String description = "Modifiers are not allowed here";
ProblemDescriptor problem = manager.createProblemDescriptor(element, description, true, ProblemHighlightType.GENERIC_ERROR, isOnTheFly);
problems.add(problem);
diff --git a/src/com/jantvrdik/intellij/latte/inspections/VariablesInspection.java b/src/com/jantvrdik/intellij/latte/inspections/VariablesInspection.java
index b14e2f2..bc06b9f 100644
--- a/src/com/jantvrdik/intellij/latte/inspections/VariablesInspection.java
+++ b/src/com/jantvrdik/intellij/latte/inspections/VariablesInspection.java
@@ -45,6 +45,7 @@ public void visitElement(PsiElement element) {
String variableName = ((LattePhpVariable) element).getVariableName();
VirtualFile file = element.getContainingFile().getVirtualFile();
List all = LatteUtil.findVariablesInFile(element.getProject(), file, variableName);
+ List afterElement = LatteUtil.findVariablesInFileAfterElement(element, file, variableName);
List definitions = all.stream()
.filter(variableElement -> variableElement.getElement() instanceof LattePhpVariable && ((LattePhpVariable) variableElement.getElement()).isDefinition())
.collect(Collectors.toList());
@@ -53,22 +54,32 @@ public void visitElement(PsiElement element) {
List beforeElement = definitions.stream()
.filter(variableElement -> variableElement.getPosition() <= offset)
.collect(Collectors.toList());
- List varDefinitions = definitions.stream()
+ int varDefinitions = (int) definitions.stream()
.filter(variableElement -> variableElement.getElement() instanceof LattePhpVariable && !((LattePhpVariable) variableElement.getElement()).isVarTypeDefinition())
- .collect(Collectors.toList());
+ .count();
+ int cyclesDefinitions = (int) definitions.stream()
+ .filter(
+ variableElement -> variableElement.getElement() instanceof LattePhpVariable
+ && !((LattePhpVariable) variableElement.getElement()).isVarTypeDefinition()
+ && (
+ ((LattePhpVariable) variableElement.getElement()).isDefinitionInFor()
+ || ((LattePhpVariable) variableElement.getElement()).isDefinitionInForeach()
+ )
+ ).count();
+ int normalVarDefinitions = varDefinitions - cyclesDefinitions;
ProblemHighlightType type = null;
String description = null;
boolean isUndefined = false;
if (((LattePhpVariable) element).isDefinition()) {
- List usages = all.stream()
+ List usages = afterElement.stream()
.filter(
variableElement -> variableElement.getElement() instanceof LattePhpVariable
&& !((LattePhpVariable) variableElement.getElement()).isDefinition()
)
.collect(Collectors.toList());
- if (varDefinitions.size() > 0 && !((LattePhpVariable) element).isVarTypeDefinition()) {
+ if (varDefinitions > 0 && !((LattePhpVariable) element).isVarTypeDefinition()) {
LatteVariableSettings defaultVariable = LatteConfiguration.INSTANCE.getVariable(element.getProject(), variableName);
if (defaultVariable != null) {
ProblemDescriptor descriptor = manager.createProblemDescriptor(
@@ -82,10 +93,14 @@ public void visitElement(PsiElement element) {
}
}
- if (varDefinitions.size() > 1) {
+ if (normalVarDefinitions > 1) {
type = ProblemHighlightType.GENERIC_ERROR_OR_WARNING;
description = "Multiple definitions for variable '" + variableName + "'";
+ } else if (normalVarDefinitions == 1 && cyclesDefinitions > 0) {
+ type = ProblemHighlightType.GENERIC_ERROR_OR_WARNING;
+ description = "Multiple definitions for variable '" + variableName + "'. Defined in for/foreach and normally.";
+
} else if (usages.size() == 0) {
type = ProblemHighlightType.LIKE_UNUSED_SYMBOL;
description = "Unused variable '" + variableName + "'";
diff --git a/src/com/jantvrdik/intellij/latte/parser/LatteParser.bnf b/src/com/jantvrdik/intellij/latte/parser/LatteParser.bnf
index ca0b0a3..89f46ed 100644
--- a/src/com/jantvrdik/intellij/latte/parser/LatteParser.bnf
+++ b/src/com/jantvrdik/intellij/latte/parser/LatteParser.bnf
@@ -50,6 +50,8 @@ fake
macroTag ::= classicMacroContent {
methods = [
getMacroName
+ matchMacroName
+ getMacroNameLength
macroContent="macroContent"
]
}
@@ -58,7 +60,7 @@ macroOpenTag ::= T_MACRO_OPEN_TAG_OPEN classicMacroContent T_MACRO_TAG_CLOSE
pin=1
mixin="com.jantvrdik.intellij.latte.psi.impl.elements.LatteMacroTagElementImpl"
implements="com.jantvrdik.intellij.latte.psi.elements.LatteMacroTagElement"
- methods=[getName setName getNameIdentifier getMacroName]
+ methods=[getName setName getNameIdentifier getMacroName matchMacroName getMacroNameLength]
extends = macroTag
}
@@ -66,7 +68,7 @@ macroCloseTag ::= T_MACRO_CLOSE_TAG_OPEN classicMacroContent T_MACRO_TAG_CLOS
pin=1
mixin="com.jantvrdik.intellij.latte.psi.impl.elements.LatteMacroTagElementImpl"
implements="com.jantvrdik.intellij.latte.psi.elements.LatteMacroTagElement"
- methods=[getName setName getNameIdentifier getMacroName]
+ methods=[getName setName getNameIdentifier getMacroName matchMacroName getMacroNameLength]
extends = macroTag
}
@@ -115,43 +117,43 @@ phpContent ::= (phpForeach | phpFor | phpExpression)+
phpVariable ::= T_MACRO_ARGS_VAR {
mixin="com.jantvrdik.intellij.latte.psi.impl.elements.LattePhpVariableElementImpl"
implements="com.jantvrdik.intellij.latte.psi.elements.LattePhpVariableElement"
- methods=[getName setName getNameIdentifier getVariableName isDefinition getPhpType isVarTypeDefinition]
+ methods=[getName setName getNameIdentifier getTextElement getVariableName isDefinition isDefinitionInFor isDefinitionInForeach getPhpType isVarTypeDefinition]
}
phpStaticVariable ::= T_MACRO_ARGS_VAR {
mixin="com.jantvrdik.intellij.latte.psi.impl.elements.LattePhpStaticVariableElementImpl"
implements="com.jantvrdik.intellij.latte.psi.elements.LattePhpStaticVariableElement"
- methods=[getName setName getNameIdentifier getVariableName getPhpType getPropertyType]
+ methods=[getName setName getNameIdentifier getTextElement getVariableName getPhpType getPropertyType]
}
phpMethod ::= T_PHP_METHOD {
mixin="com.jantvrdik.intellij.latte.psi.impl.elements.LattePhpMethodElementImpl"
implements="com.jantvrdik.intellij.latte.psi.elements.LattePhpMethodElement"
- methods=[getName setName getNameIdentifier getMethodName getPhpType getReturnType isStatic isFunction]
+ methods=[getName setName getNameIdentifier getTextElement getMethodName getPhpType getReturnType isStatic isFunction]
}
phpConstant ::= T_PHP_IDENTIFIER {
mixin="com.jantvrdik.intellij.latte.psi.impl.elements.LattePhpConstantElementImpl"
implements="com.jantvrdik.intellij.latte.psi.elements.LattePhpConstantElement"
- methods=[getName setName getNameIdentifier getConstantName getPhpType getConstantType]
+ methods=[getName setName getNameIdentifier getTextElement getConstantName getPhpType getConstantType]
}
phpProperty ::= T_PHP_IDENTIFIER {
mixin="com.jantvrdik.intellij.latte.psi.impl.elements.LattePhpPropertyElementImpl"
implements="com.jantvrdik.intellij.latte.psi.elements.LattePhpPropertyElement"
- methods=[getName setName getNameIdentifier getPropertyName getPhpType getPropertyType isStatic]
+ methods=[getName setName getNameIdentifier getTextElement getPropertyName getPhpType getPropertyType isStatic]
}
phpClass ::= T_PHP_CLASS_NAME {
mixin="com.jantvrdik.intellij.latte.psi.impl.elements.LattePhpClassElementImpl"
implements="com.jantvrdik.intellij.latte.psi.elements.LattePhpClassElement"
- methods=[getName setName getNameIdentifier getClassName getPhpType isTemplateType]
+ methods=[getName setName getNameIdentifier getTextElement getClassName getPhpType isTemplateType]
}
macroModifier ::= T_MACRO_FILTERS {
mixin="com.jantvrdik.intellij.latte.psi.impl.elements.LatteMacroModifierElementImpl"
implements="com.jantvrdik.intellij.latte.psi.elements.LatteMacroModifierElement"
- methods=[getName setName getNameIdentifier getModifierName]
+ methods=[getName setName getNameIdentifier getTextElement getModifierName isVariableModifier]
}
phpForeach ::= T_WHITESPACE? phpExpression T_WHITESPACE? T_PHP_AS T_WHITESPACE? (phpVariable | phpArrayOfVariables) (T_WHITESPACE? T_PHP_DOUBLE_ARROW T_WHITESPACE? (phpVariable | phpArrayOfVariables))?
@@ -166,13 +168,14 @@ phpMethodDefinition ::= T_WHITESPACE? (T_PHP_DOUBLE_COLON | T_PHP_OBJECT_O
private
phpArgumentList ::= (T_PHP_LEFT_NORMAL_BRACE T_WHITESPACE? T_PHP_RIGHT_NORMAL_BRACE) | (T_PHP_LEFT_NORMAL_BRACE phpMethodArgs T_PHP_RIGHT_NORMAL_BRACE)
-private
phpInBrackets ::= T_PHP_LEFT_NORMAL_BRACE T_WHITESPACE? phpArgument+ T_WHITESPACE? T_PHP_RIGHT_NORMAL_BRACE
phpMethodArgs ::= T_WHITESPACE? phpArgument+ ( T_WHITESPACE? "," T_WHITESPACE? phpArgument+ )* T_WHITESPACE?
+phpString ::= phpSingleQuotedString | phpDoubleQuotedString | T_MACRO_ARGS_STRING
+
private
-phpArgument ::= phpSingleQuotedString | phpDoubleQuotedString | T_MACRO_ARGS_STRING | T_MACRO_ARGS_NUMBER | phpClass | phpDefinition
+phpArgument ::= phpString | T_MACRO_ARGS_NUMBER | phpArrayOfVariables | phpClass | phpDefinition
| phpStatic | phpFunctionCall | phpInBrackets | phpVariable | T_PHP_CONTENT_TYPE | T_PHP_OBJECT_OPERATOR
| T_PHP_OPERATOR | T_PHP_DOUBLE_COLON | T_PHP_DOUBLE_ARROW | T_PHP_METHOD | T_PHP_TYPE | T_PHP_KEYWORD
| T_PHP_CLASS | T_PHP_AS | T_PHP_CAST | T_PHP_EXPRESSION | T_PHP_LEFT_BRACKET | T_PHP_RIGHT_BRACKET | T_PHP_NULL
diff --git a/src/com/jantvrdik/intellij/latte/psi/elements/BaseLattePhpElement.java b/src/com/jantvrdik/intellij/latte/psi/elements/BaseLattePhpElement.java
index 781dfb3..d98d387 100644
--- a/src/com/jantvrdik/intellij/latte/psi/elements/BaseLattePhpElement.java
+++ b/src/com/jantvrdik/intellij/latte/psi/elements/BaseLattePhpElement.java
@@ -1,7 +1,9 @@
package com.jantvrdik.intellij.latte.psi.elements;
+import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiNameIdentifierOwner;
import com.jantvrdik.intellij.latte.utils.LattePhpType;
+import org.jetbrains.annotations.Nullable;
public interface BaseLattePhpElement extends PsiNameIdentifierOwner {
@@ -9,4 +11,7 @@ public interface BaseLattePhpElement extends PsiNameIdentifierOwner {
public abstract String getPhpElementName();
+ @Nullable
+ public abstract PsiElement getTextElement();
+
}
\ No newline at end of file
diff --git a/src/com/jantvrdik/intellij/latte/psi/impl/LattePsiImplUtil.java b/src/com/jantvrdik/intellij/latte/psi/impl/LattePsiImplUtil.java
index 9d9fe39..1b4c34c 100644
--- a/src/com/jantvrdik/intellij/latte/psi/impl/LattePsiImplUtil.java
+++ b/src/com/jantvrdik/intellij/latte/psi/impl/LattePsiImplUtil.java
@@ -28,16 +28,45 @@
public class LattePsiImplUtil {
@NotNull
public static String getMacroName(LatteMacroTag element) {
- ASTNode elementNode = element.getNode();
- ASTNode nameNode = elementNode.findChildByType(T_MACRO_NAME);
+ ASTNode nameNode = getMacroNameNode(element);
if (nameNode != null) {
return nameNode.getText();
}
+ return createMacroName(element);
+ }
+
+ public static boolean matchMacroName(LatteMacroTag element, @NotNull String name) {
+ ASTNode nameNode = getMacroNameNode(element);
+ if (nameNode == null) {
+ return createMacroName(element).equals(name);
+ }
+ return matchPsiElement(nameNode, name);
+ }
- nameNode = elementNode.findChildByType(T_MACRO_SHORTNAME);
+ public static int getMacroNameLength(LatteMacroTag element) {
+ ASTNode nameNode = getMacroNameNode(element);
if (nameNode != null) {
- return nameNode.getText();
+ return nameNode.getTextLength();
+ }
+ return createMacroName(element).length();
+ }
+
+ private static boolean matchPsiElement(ASTNode element, @NotNull String text) {
+ return element.getTextLength() == text.length() && element.getText().equals(text);
+ }
+
+ @Nullable
+ private static ASTNode getMacroNameNode(LatteMacroTag element) {
+ ASTNode elementNode = element.getNode();
+ ASTNode nameNode = elementNode.findChildByType(T_MACRO_NAME);
+ if (nameNode != null) {
+ return nameNode;
}
+ return elementNode.findChildByType(T_MACRO_SHORTNAME);
+ }
+
+ @NotNull
+ private static String createMacroName(LatteMacroTag element) {
LatteMacroContent content = element.getMacroContent();
if (content == null || element instanceof LatteMacroCloseTag) {
return "";
@@ -51,35 +80,76 @@ public static LattePhpContent getFirstPhpContent(@NotNull LatteMacroContent macr
return phpContents.stream().findFirst().isPresent() ? phpContents.stream().findFirst().get() : null;
}
- public static String getVariableName(@NotNull PsiElement element) {
- PsiElement found = findFirstChildWithType(element, T_MACRO_ARGS_VAR);
+ public static String getVariableName(@NotNull LattePhpVariable element) {
+ PsiElement found = getTextElement(element);
+ return found != null ? LattePhpUtil.normalizePhpVariable(found.getText()) : null;
+ }
+
+ public static String getVariableName(@NotNull LattePhpStaticVariable element) {
+ PsiElement found = getTextElement(element);
return found != null ? LattePhpUtil.normalizePhpVariable(found.getText()) : null;
}
- public static String getConstantName(@NotNull PsiElement element) {
- return getPropertyName(element);
+ @Nullable
+ public static PsiElement getTextElement(@NotNull LattePhpStaticVariable element) {
+ return findFirstChildWithType(element, T_MACRO_ARGS_VAR);
+ }
+
+ @Nullable
+ public static PsiElement getTextElement(@NotNull LattePhpVariable element) {
+ return findFirstChildWithType(element, T_MACRO_ARGS_VAR);
+ }
+
+ public static String getConstantName(@NotNull LattePhpConstant element) {
+ PsiElement found = getTextElement(element);
+ return found != null ? found.getText() : null;
}
- public static String getMethodName(@NotNull PsiElement element) {
+ public static String getMethodName(@NotNull LattePhpMethod element) {
PsiElement found = findFirstChildWithType(element, T_PHP_METHOD);
return found != null ? found.getText() : null;
}
- public static String getPropertyName(@NotNull PsiElement element) {
- PsiElement found = findFirstChildWithType(element, T_PHP_IDENTIFIER);
+ public static String getPropertyName(@NotNull LattePhpProperty element) {
+ PsiElement found = getTextElement(element);
return found != null ? found.getText() : null;
}
- public static String getClassName(@NotNull PsiElement element) {
- PsiElement found = findFirstChildWithType(element, T_PHP_CLASS_NAME);
+ @Nullable
+ public static PsiElement getTextElement(@NotNull LattePhpMethod element) {
+ return findFirstChildWithType(element, T_PHP_METHOD);
+ }
+
+ @Nullable
+ public static PsiElement getTextElement(@NotNull LattePhpClass element) {
+ return findFirstChildWithType(element, T_PHP_CLASS_NAME);
+ }
+
+ @Nullable
+ public static PsiElement getTextElement(@NotNull LatteMacroModifier element) {
+ return findFirstChildWithType(element, T_MACRO_FILTERS);
+ }
+
+ @Nullable
+ public static PsiElement getTextElement(@NotNull PsiElement element) {
+ return findFirstChildWithType(element, T_PHP_IDENTIFIER);
+ }
+
+ public static String getClassName(@NotNull LattePhpClass element) {
+ PsiElement found = getTextElement(element);
return found != null ? LattePhpUtil.normalizeClassName(found.getText()) : null;
}
public static String getModifierName(@NotNull LatteMacroModifier element) {
- PsiElement found = findFirstChildWithType(element, T_MACRO_FILTERS);
+ PsiElement found = getTextElement(element);
return found != null ? LatteUtil.normalizeMacroModifier(found.getText()) : null;
}
+ public static boolean isVariableModifier(@NotNull LatteMacroModifier element) {
+ LattePhpInBrackets variableModifier = PsiTreeUtil.getParentOfType(element, LattePhpInBrackets.class);
+ return variableModifier != null;
+ }
+
@Nullable
public static LattePhpType detectVariableTypeFromTemplateType(@NotNull PsiElement element, @NotNull String variableName)
{
@@ -215,16 +285,18 @@ public static boolean isFunction(@NotNull PsiElement element) {
public static LattePhpType getReturnType(@NotNull LattePhpMethod element) {
LattePhpType type = element.getPhpType();
- PhpClass first = type.getFirstPhpClass(element.getProject());
+ Collection phpClasses = type.getPhpClasses(element.getProject());
String name = element.getMethodName();
- if (first == null) {
+ if (phpClasses.size() == 0) {
LatteCustomFunctionSettings customFunction = LatteConfiguration.INSTANCE.getFunction(element.getProject(), name);
return customFunction == null ? null : new LattePhpType(customFunction.getFunctionReturnType());
}
- for (Method phpMethod : first.getMethods()) {
- if (phpMethod.getName().equals(name)) {
- return new LattePhpType(phpMethod.getType().toString(), LattePhpUtil.isNullable(phpMethod.getType()));
+ for (PhpClass phpClass : phpClasses) {
+ for (Method phpMethod : phpClass.getMethods()) {
+ if (phpMethod.getName().equals(name)) {
+ return new LattePhpType(phpMethod.getType().toString(), LattePhpUtil.isNullable(phpMethod.getType()));
+ }
}
}
return null;
@@ -243,14 +315,16 @@ public static LattePhpType getPropertyType(@NotNull LattePhpProperty element) {
}
private static LattePhpType getPropertyType(@NotNull Project project, @NotNull LattePhpType type, @NotNull String elementName) {
- PhpClass first = type.getFirstPhpClass(project);
- if (first == null) {
+ Collection phpClasses = type.getPhpClasses(project);
+ if (phpClasses.size() == 0) {
return null;
}
- for (Field field : first.getFields()) {
- if (field.getName().equals(LattePhpUtil.normalizePhpVariable(elementName))) {
- return new LattePhpType(field.getType().toString(), LattePhpUtil.isNullable(field.getType()));
+ for (PhpClass phpClass : phpClasses) {
+ for (Field field : phpClass.getFields()) {
+ if (field.getName().equals(LattePhpUtil.normalizePhpVariable(elementName))) {
+ return new LattePhpType(field.getType().toString(), LattePhpUtil.isNullable(field.getType()));
+ }
}
}
return null;
@@ -269,31 +343,23 @@ public static boolean isVarTypeDefinition(@NotNull LattePhpVariable element) {
}
public static boolean isVarDefinition(@NotNull LattePhpVariable element) {
- return LatteUtil.matchParentMacroName(element, "var");
+ return LatteUtil.matchParentMacroName(element, "var") || LatteUtil.matchParentMacroName(element, "default");
}
- public static boolean isDefinition(@NotNull LattePhpVariable element) {
- if (isVarTypeDefinition(element) || LatteUtil.matchParentMacroName(element, "capture")) {
- return true;
- }
-
+ public static boolean isDefinitionInForeach(@NotNull PsiElement element) {
PsiElement parent = element.getParent();
- if (parent == null) {
- return false;
- }
-
- if (parent.getNode().getElementType() == PHP_ARRAY_OF_VARIABLES) {
- PsiElement parentPrevElement = PsiTreeUtil.skipWhitespacesBackward(parent);
- IElementType type = parentPrevElement != null ? parentPrevElement.getNode().getElementType() : null;
- return type == T_PHP_AS || type == T_PHP_DOUBLE_ARROW;
- }
-
- if (parent.getNode().getElementType() == PHP_FOREACH) {
+ if (parent != null && parent.getNode().getElementType() == PHP_FOREACH) {
PsiElement prevElement = PsiTreeUtil.skipWhitespacesBackward(element);
IElementType type = prevElement != null ? prevElement.getNode().getElementType() : null;
return type == T_PHP_AS || type == T_PHP_DOUBLE_ARROW;
+
+ } else if (parent != null && parent.getNode().getElementType() == PHP_ARRAY_OF_VARIABLES) {
+ return isDefinitionInForeach(parent);
}
+ return false;
+ }
+ public static boolean isDefinitionInFor(@NotNull LattePhpVariable element) {
LatteNetteAttrValue parentAttr = PsiTreeUtil.getParentOfType(element, LatteNetteAttrValue.class);
if (parentAttr != null) {
PsiElement nextElement = PsiTreeUtil.skipWhitespacesForward(element);
@@ -308,15 +374,41 @@ public static boolean isDefinition(@NotNull LattePhpVariable element) {
prevElement = PsiTreeUtil.skipWhitespacesBackward(prevElement);
return prevElement != null && prevElement.getText().equals("n:for");
}
+ return LatteUtil.matchParentMacroName(element, "for") && isNextDefinitionOperator(element);
+ }
- if (LatteUtil.matchParentMacroName(element, "for") || isVarDefinition(element)) {
- PsiElement nextElement = PsiTreeUtil.skipWhitespacesForward(element);
- if (nextElement != null && nextElement.getNode().getElementType() == LatteTypes.T_PHP_DEFINITION_OPERATOR) {
+ private static boolean isNextDefinitionOperator(@NotNull PsiElement element) {
+ PsiElement nextElement = PsiTreeUtil.skipWhitespacesForward(element);
+ return nextElement != null && nextElement.getNode().getElementType() == LatteTypes.T_PHP_DEFINITION_OPERATOR;
+ }
+
+ public static boolean isDefinition(@NotNull LattePhpVariable element) {
+ if (isVarTypeDefinition(element) || LatteUtil.matchParentMacroName(element, "capture")) {
+ return true;
+ }
+
+ if (isVarDefinition(element)) {
+ if (isNextDefinitionOperator(element)) {
return true;
}
}
- return false;
+ PsiElement parent = element.getParent();
+ if (parent == null) {
+ return false;
+ }
+
+ if (parent.getNode().getElementType() == PHP_ARRAY_OF_VARIABLES) {
+ if (isNextDefinitionOperator(parent)) {
+ return true;
+ }
+ }
+
+ if (isDefinitionInForeach(element)) {
+ return true;
+ }
+
+ return isDefinitionInFor(element);
}
public static String getName(LattePhpVariable element) {
@@ -471,4 +563,9 @@ private static PsiElement findFirstChildWithType(PsiElement element, @NotNull IE
return null;
}
}
+
+ @Nullable
+ private static ASTNode findFirstChildNodeWithType(PsiElement element, @NotNull IElementType type) {
+ return element.getNode().findChildByType(type);
+ }
}
diff --git a/src/com/jantvrdik/intellij/latte/reference/LatteReferenceContributor.java b/src/com/jantvrdik/intellij/latte/reference/LatteReferenceContributor.java
index cffeaed..413b677 100644
--- a/src/com/jantvrdik/intellij/latte/reference/LatteReferenceContributor.java
+++ b/src/com/jantvrdik/intellij/latte/reference/LatteReferenceContributor.java
@@ -20,11 +20,11 @@ public PsiReference[] getReferencesByElement(@NotNull PsiElement element, @NotNu
return PsiReference.EMPTY_ARRAY;
}
- LattePhpVariable variableElement = (LattePhpVariable) element;
- String value = variableElement.getVariableName();
- if (value != null) {
+ PsiElement value = ((LattePhpVariable) element).getTextElement();
+ if (value != null && value.getTextLength() > 0) {
return new PsiReference[]{
- new LattePhpVariableReference((LattePhpVariable) element, new TextRange(0, value.length() + 1))};
+ new LattePhpVariableReference((LattePhpVariable) element, new TextRange(0, value.getTextLength()))
+ };
}
return PsiReference.EMPTY_ARRAY;
@@ -41,10 +41,11 @@ public PsiReference[] getReferencesByElement(@NotNull PsiElement element, @NotNu
return PsiReference.EMPTY_ARRAY;
}
- LattePhpMethod methodElement = (LattePhpMethod) element;
- String value = methodElement.getMethodName();
- if (value != null) {
- return new PsiReference[]{new LattePhpMethodReference(methodElement, new TextRange(0, value.length()))};
+ PsiElement value = ((LattePhpMethod) element).getTextElement();
+ if (value != null && value.getTextLength() > 0) {
+ return new PsiReference[]{
+ new LattePhpMethodReference((LattePhpMethod) element, new TextRange(0, value.getTextLength()))
+ };
}
return PsiReference.EMPTY_ARRAY;
@@ -61,10 +62,11 @@ public PsiReference[] getReferencesByElement(@NotNull PsiElement element, @NotNu
return PsiReference.EMPTY_ARRAY;
}
- LattePhpProperty propertyElement = (LattePhpProperty) element;
- String value = propertyElement.getPropertyName();
- if (value != null) {
- return new PsiReference[]{new LattePhpPropertyReference(propertyElement, new TextRange(0, value.length()))};
+ PsiElement value = ((LattePhpProperty) element).getTextElement();
+ if (value != null && value.getTextLength() > 0) {
+ return new PsiReference[]{
+ new LattePhpPropertyReference((LattePhpProperty) element, new TextRange(0, value.getTextLength()))
+ };
}
return PsiReference.EMPTY_ARRAY;
@@ -81,10 +83,11 @@ public PsiReference[] getReferencesByElement(@NotNull PsiElement element, @NotNu
return PsiReference.EMPTY_ARRAY;
}
- LattePhpConstant constantElement = (LattePhpConstant) element;
- String value = constantElement.getConstantName();
- if (value != null) {
- return new PsiReference[]{new LattePhpConstantReference(constantElement, new TextRange(0, value.length()))};
+ PsiElement value = ((LattePhpConstant) element).getTextElement();
+ if (value != null && value.getTextLength() > 0) {
+ return new PsiReference[]{
+ new LattePhpConstantReference((LattePhpConstant) element, new TextRange(0, value.getTextLength()))
+ };
}
return PsiReference.EMPTY_ARRAY;
@@ -101,10 +104,11 @@ public PsiReference[] getReferencesByElement(@NotNull PsiElement element, @NotNu
return PsiReference.EMPTY_ARRAY;
}
- LattePhpStaticVariable constantElement = (LattePhpStaticVariable) element;
- String value = constantElement.getVariableName();
- if (value != null) {
- return new PsiReference[]{new LattePhpStaticVariableReference(constantElement, new TextRange(0, value.length() + 1))};
+ PsiElement value = ((LattePhpStaticVariable) element).getTextElement();
+ if (value != null && value.getTextLength() > 0) {
+ return new PsiReference[]{
+ new LattePhpStaticVariableReference((LattePhpStaticVariable) element, new TextRange(0, value.getTextLength()))
+ };
}
return PsiReference.EMPTY_ARRAY;
@@ -121,10 +125,9 @@ public PsiReference[] getReferencesByElement(@NotNull PsiElement element, @NotNu
return PsiReference.EMPTY_ARRAY;
}
- LattePhpClass constantElement = (LattePhpClass) element;
- String value = constantElement.getClassName();
- if (value != null) {
- return new PsiReference[]{new LattePhpClassReference(constantElement, new TextRange(0, value.length()))};
+ PsiElement value = ((LattePhpClass) element).getTextElement();
+ if (value != null && value.getTextLength() > 0) {
+ return new PsiReference[]{new LattePhpClassReference((LattePhpClass) element, new TextRange(0, value.getTextLength()))};
}
return PsiReference.EMPTY_ARRAY;
@@ -144,13 +147,12 @@ public PsiReference[] getReferencesByElement(@NotNull PsiElement element, @NotNu
return PsiReference.EMPTY_ARRAY;
}
- LatteMacroTag constantElement = (LatteMacroTag) element;
- String value = constantElement.getMacroName();
- if (value.length() == 0) {
+ int valueLength = ((LatteMacroTag) element).getMacroNameLength();
+ if (valueLength == 0) {
return PsiReference.EMPTY_ARRAY;
}
int length = element instanceof LatteMacroCloseTag ? 2 : 1;
- return new PsiReference[]{new LatteMacroTagReference(constantElement, new TextRange(1, value.length() + length))};
+ return new PsiReference[]{new LatteMacroTagReference((LatteMacroTag) element, new TextRange(1, valueLength + length))};
}
});
@@ -167,11 +169,11 @@ public PsiReference[] getReferencesByElement(@NotNull PsiElement element, @NotNu
}
LatteMacroModifier constantElement = (LatteMacroModifier) element;
- String value = constantElement.getModifierName();
- if (value.length() == 0) {
- return PsiReference.EMPTY_ARRAY;
+ PsiElement textElement = ((LatteMacroModifier) element).getTextElement();
+ if (textElement != null && textElement.getTextLength() > 0) {
+ return new PsiReference[]{new LatteMacroModifierReference(constantElement, new TextRange(0, textElement.getTextLength()))};
}
- return new PsiReference[]{new LatteMacroModifierReference(constantElement, new TextRange(0, value.length()))};
+ return PsiReference.EMPTY_ARRAY;
}
});
}
diff --git a/src/com/jantvrdik/intellij/latte/reference/references/LattePhpClassReference.java b/src/com/jantvrdik/intellij/latte/reference/references/LattePhpClassReference.java
index 3696613..89a68a9 100644
--- a/src/com/jantvrdik/intellij/latte/reference/references/LattePhpClassReference.java
+++ b/src/com/jantvrdik/intellij/latte/reference/references/LattePhpClassReference.java
@@ -3,7 +3,6 @@
import com.intellij.openapi.util.TextRange;
import com.intellij.psi.*;
import com.jantvrdik.intellij.latte.psi.LattePhpClass;
-import com.jantvrdik.intellij.latte.psi.elements.BaseLattePhpElement;
import com.jantvrdik.intellij.latte.utils.LattePhpUtil;
import com.jantvrdik.intellij.latte.utils.LatteUtil;
import com.jetbrains.php.lang.psi.elements.PhpClass;
@@ -11,22 +10,23 @@
import org.jetbrains.annotations.Nullable;
import java.util.ArrayList;
+import java.util.Collection;
import java.util.List;
public class LattePhpClassReference extends PsiReferenceBase implements PsiPolyVariantReference {
private String className;
- private PhpClass phpClass;
+ private Collection phpClasses;
public LattePhpClassReference(@NotNull LattePhpClass element, TextRange textRange) {
super(element, textRange);
className = element.getClassName();
- phpClass = element.getPhpType().getFirstPhpClass(element.getProject());
+ phpClasses = element.getPhpType().getPhpClasses(element.getProject());
}
@NotNull
@Override
public ResolveResult[] multiResolve(boolean b) {
- if (phpClass == null) {
+ if (phpClasses.size() == 0) {
return new ResolveResult[0];
}
@@ -68,23 +68,32 @@ public PsiElement handleElementRename(@NotNull String newName) {
@Override
public boolean isReferenceTo(@NotNull PsiElement element) {
if (element instanceof LattePhpClass) {
- PhpClass originalClass = ((LattePhpClass) element).getPhpType().getFirstPhpClass(element.getProject());
- if (originalClass != null) {
+ Collection originalClasses = ((LattePhpClass) element).getPhpType().getPhpClasses(element.getProject());
+ if (originalClasses.size() > 0) {
for (ResolveResult result : multiResolve(false)) {
if (!(result.getElement() instanceof LattePhpClass)) {
continue;
}
- PhpClass target = ((LattePhpClass) result.getElement()).getPhpType().getFirstPhpClass(element.getProject());
- if (target == null) {
+ Collection targetClasses = ((LattePhpClass) result.getElement()).getPhpType().getPhpClasses(element.getProject());
+ if (targetClasses.size() == 0) {
continue;
}
- if (originalClass.getFQN().equals(target.getFQN())) {
- return true;
+
+ for (PhpClass targetClass : targetClasses) {
+ String targetFqn = targetClass.getFQN();
+ for (PhpClass originalClass : originalClasses) {
+ if (originalClass.getFQN().equals(targetFqn)) {
+ return true;
+ }
+ }
}
}
- if (LattePhpUtil.isReferenceTo(originalClass, multiResolve(false), element, ((LattePhpClass) element).getClassName())) {
- return true;
+
+ for (PhpClass originalClass : originalClasses) {
+ if (LattePhpUtil.isReferenceTo(originalClass, multiResolve(false), element, ((LattePhpClass) element).getClassName())) {
+ return true;
+ }
}
}
}
diff --git a/src/com/jantvrdik/intellij/latte/reference/references/LattePhpConstantReference.java b/src/com/jantvrdik/intellij/latte/reference/references/LattePhpConstantReference.java
index 053087f..3aab8e5 100644
--- a/src/com/jantvrdik/intellij/latte/reference/references/LattePhpConstantReference.java
+++ b/src/com/jantvrdik/intellij/latte/reference/references/LattePhpConstantReference.java
@@ -17,22 +17,22 @@
public class LattePhpConstantReference extends PsiReferenceBase implements PsiPolyVariantReference {
private String key;
- private PhpClass phpClass;
+ private Collection phpClasses;
public LattePhpConstantReference(@NotNull LattePhpConstant element, TextRange textRange) {
super(element, textRange);
key = element.getConstantName();
- phpClass = element.getPhpType().getFirstPhpClass(element.getProject());
+ phpClasses = element.getPhpType().getPhpClasses(element.getProject());
}
@NotNull
@Override
public ResolveResult[] multiResolve(boolean b) {
- if (phpClass == null) {
+ if (phpClasses.size() == 0) {
return new ResolveResult[0];
}
- final Collection methods = LatteUtil.findConstants(getElement().getProject(), key, phpClass);
+ final Collection methods = LatteUtil.findConstants(getElement().getProject(), key, phpClasses);
List results = new ArrayList();
for (BaseLattePhpElement method : methods) {
results.add(new PsiElementResolveResult(method));
@@ -65,10 +65,12 @@ public Object[] getVariants() {
@Override
public boolean isReferenceTo(@NotNull PsiElement element) {
if (element instanceof LattePhpConstant) {
- PhpClass originalClass = ((LattePhpConstant) element).getPhpType().getFirstPhpClass(element.getProject());
- if (originalClass != null) {
- if (LattePhpUtil.isReferenceTo(originalClass, multiResolve(false), element, ((LattePhpConstant) element).getConstantName())) {
- return true;
+ Collection originalClasses = ((LattePhpConstant) element).getPhpType().getPhpClasses(element.getProject());
+ if (originalClasses.size() > 0) {
+ for (PhpClass originalClass : originalClasses) {
+ if (LattePhpUtil.isReferenceTo(originalClass, multiResolve(false), element, ((LattePhpConstant) element).getConstantName())) {
+ return true;
+ }
}
}
}
diff --git a/src/com/jantvrdik/intellij/latte/reference/references/LattePhpMethodReference.java b/src/com/jantvrdik/intellij/latte/reference/references/LattePhpMethodReference.java
index 1cb7c7d..047d36f 100644
--- a/src/com/jantvrdik/intellij/latte/reference/references/LattePhpMethodReference.java
+++ b/src/com/jantvrdik/intellij/latte/reference/references/LattePhpMethodReference.java
@@ -18,12 +18,12 @@
public class LattePhpMethodReference extends PsiReferenceBase implements PsiPolyVariantReference {
private String methodName;
- private PhpClass phpClass;
+ private Collection phpClasses;
public LattePhpMethodReference(@NotNull LattePhpMethod element, TextRange textRange) {
super(element, textRange);
methodName = element.getMethodName();
- phpClass = element.getPhpType().getFirstPhpClass(element.getProject());
+ phpClasses = element.getPhpType().getPhpClasses(element.getProject());
}
@NotNull
@@ -31,7 +31,7 @@ public LattePhpMethodReference(@NotNull LattePhpMethod element, TextRange textRa
public ResolveResult[] multiResolve(boolean b) {
if (((LattePhpMethod) getElement()).isFunction()) {
return multiResolveFunction();
- } else if (phpClass == null) {
+ } else if (phpClasses.size() == 0) {
return new ResolveResult[0];
}
return multiResolveMethod();
@@ -40,7 +40,7 @@ public ResolveResult[] multiResolve(boolean b) {
@NotNull
public ResolveResult[] multiResolveMethod() {
List results = new ArrayList();
- final Collection methods = LatteUtil.findMethods(getElement().getProject(), methodName, phpClass);
+ final Collection methods = LatteUtil.findMethods(getElement().getProject(), methodName, phpClasses);
for (BaseLattePhpElement method : methods) {
results.add(new PsiElementResolveResult(method));
}
@@ -100,10 +100,12 @@ public Object[] getVariants() {
@Override
public boolean isReferenceTo(@NotNull PsiElement element) {
if (element instanceof LattePhpMethod) {
- PhpClass originalClass = ((LattePhpMethod) element).getPhpType().getFirstPhpClass(element.getProject());
- if (originalClass != null) {
- if (LattePhpUtil.isReferenceTo(originalClass, multiResolve(false), element, ((LattePhpMethod) element).getMethodName())) {
- return true;
+ Collection originalClasses = ((LattePhpMethod) element).getPhpType().getPhpClasses(element.getProject());
+ if (originalClasses.size() > 0) {
+ for (PhpClass originalClass : originalClasses) {
+ if (LattePhpUtil.isReferenceTo(originalClass, multiResolve(false), element, ((LattePhpMethod) element).getMethodName())) {
+ return true;
+ }
}
}
}
diff --git a/src/com/jantvrdik/intellij/latte/reference/references/LattePhpPropertyReference.java b/src/com/jantvrdik/intellij/latte/reference/references/LattePhpPropertyReference.java
index c38f4e5..bd9c245 100644
--- a/src/com/jantvrdik/intellij/latte/reference/references/LattePhpPropertyReference.java
+++ b/src/com/jantvrdik/intellij/latte/reference/references/LattePhpPropertyReference.java
@@ -17,22 +17,22 @@
public class LattePhpPropertyReference extends PsiReferenceBase implements PsiPolyVariantReference {
private String key;
- private PhpClass phpClass;
+ private Collection phpClasses;
public LattePhpPropertyReference(@NotNull LattePhpProperty element, TextRange textRange) {
super(element, textRange);
key = element.getPropertyName();
- phpClass = element.getPhpType().getFirstPhpClass(element.getProject());
+ phpClasses = element.getPhpType().getPhpClasses(element.getProject());
}
@NotNull
@Override
public ResolveResult[] multiResolve(boolean b) {
- if (phpClass == null) {
+ if (phpClasses.size() == 0) {
return new ResolveResult[0];
}
- final Collection methods = LatteUtil.findProperties(getElement().getProject(), key, phpClass);
+ final Collection methods = LatteUtil.findProperties(getElement().getProject(), key, phpClasses);
List results = new ArrayList();
for (BaseLattePhpElement method : methods) {
results.add(new PsiElementResolveResult(method));
@@ -65,10 +65,12 @@ public Object[] getVariants() {
@Override
public boolean isReferenceTo(@NotNull PsiElement element) {
if (element instanceof LattePhpProperty) {
- PhpClass originalClass = ((LattePhpProperty) element).getPhpType().getFirstPhpClass(element.getProject());
- if (originalClass != null) {
- if (LattePhpUtil.isReferenceTo(originalClass, multiResolve(false), element, ((LattePhpProperty) element).getPropertyName())) {
- return true;
+ Collection originalClasses = ((LattePhpProperty) element).getPhpType().getPhpClasses(element.getProject());
+ if (originalClasses.size() > 0) {
+ for (PhpClass originalClass : originalClasses) {
+ if (LattePhpUtil.isReferenceTo(originalClass, multiResolve(false), element, ((LattePhpProperty) element).getPropertyName())) {
+ return true;
+ }
}
}
}
diff --git a/src/com/jantvrdik/intellij/latte/reference/references/LattePhpStaticVariableReference.java b/src/com/jantvrdik/intellij/latte/reference/references/LattePhpStaticVariableReference.java
index 406a7f1..abc5af4 100644
--- a/src/com/jantvrdik/intellij/latte/reference/references/LattePhpStaticVariableReference.java
+++ b/src/com/jantvrdik/intellij/latte/reference/references/LattePhpStaticVariableReference.java
@@ -17,22 +17,22 @@
public class LattePhpStaticVariableReference extends PsiReferenceBase implements PsiPolyVariantReference {
private String variableName;
- private PhpClass phpClass;
+ private Collection phpClasses;
public LattePhpStaticVariableReference(@NotNull LattePhpStaticVariable element, TextRange textRange) {
super(element, textRange);
variableName = element.getVariableName();
- phpClass = element.getPhpType().getFirstPhpClass(element.getProject());
+ phpClasses = element.getPhpType().getPhpClasses(element.getProject());
}
@NotNull
@Override
public ResolveResult[] multiResolve(boolean b) {
- if (phpClass == null) {
+ if (phpClasses.size() == 0) {
return new ResolveResult[0];
}
- final Collection methods = LatteUtil.findStaticVariables(getElement().getProject(), variableName, phpClass);
+ final Collection methods = LatteUtil.findStaticVariables(getElement().getProject(), variableName, phpClasses);
List results = new ArrayList();
for (BaseLattePhpElement method : methods) {
results.add(new PsiElementResolveResult(method));
diff --git a/src/com/jantvrdik/intellij/latte/utils/LattePhpType.java b/src/com/jantvrdik/intellij/latte/utils/LattePhpType.java
index a5f0ee8..2df1e91 100644
--- a/src/com/jantvrdik/intellij/latte/utils/LattePhpType.java
+++ b/src/com/jantvrdik/intellij/latte/utils/LattePhpType.java
@@ -3,7 +3,6 @@
import com.intellij.openapi.project.Project;
import com.jetbrains.php.lang.psi.elements.PhpClass;
import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
import java.util.ArrayList;
import java.util.Collection;
@@ -87,6 +86,18 @@ public boolean hasClass(String className) {
return types.stream().anyMatch(typePart -> typePart.isClass && typePart.getPart().equals(normalizedName));
}
+ public boolean hasClass(Collection phpClasses) {
+ if (!containsClasses()) {
+ return false;
+ }
+ for (PhpClass phpClass : phpClasses) {
+ if (hasClass(phpClass.getFQN())) {
+ return true;
+ }
+ }
+ return false;
+ }
+
public boolean isNullable() {
return nullable;
}
@@ -109,17 +120,6 @@ String[] findClasses() {
.toArray(String[]::new);
}
- @Nullable
- public PhpClass getFirstPhpClass(Project project) {
- for (String wholeType : findClasses()) {
- List classes = new ArrayList<>(LattePhpUtil.getClassesByFQN(project, wholeType));
- if (classes.size() > 0) {
- return classes.get(0);
- }
- }
- return null;
- }
-
@Override
public String toString() {
return toReadableString();
diff --git a/src/com/jantvrdik/intellij/latte/utils/LattePhpUtil.java b/src/com/jantvrdik/intellij/latte/utils/LattePhpUtil.java
index cec0d33..db36d44 100644
--- a/src/com/jantvrdik/intellij/latte/utils/LattePhpUtil.java
+++ b/src/com/jantvrdik/intellij/latte/utils/LattePhpUtil.java
@@ -54,13 +54,15 @@ public static boolean isReferenceTo(@NotNull PhpClass originalClass, @NotNull Re
continue;
}
- PhpClass phpClass = ((BaseLattePhpElement) result.getElement()).getPhpType().getFirstPhpClass(element.getProject());
- if (phpClass == null) {
+ Collection phpClasses = ((BaseLattePhpElement) result.getElement()).getPhpType().getPhpClasses(element.getProject());
+ if (phpClasses.size() == 0) {
continue;
}
- if (isReferenceFor(originalClass, phpClass)) {
- return true;
+ for (PhpClass phpClass : phpClasses) {
+ if (isReferenceFor(originalClass, phpClass)) {
+ return true;
+ }
}
}
return false;
diff --git a/src/com/jantvrdik/intellij/latte/utils/LatteUtil.java b/src/com/jantvrdik/intellij/latte/utils/LatteUtil.java
index 04d41dd..87a13b8 100644
--- a/src/com/jantvrdik/intellij/latte/utils/LatteUtil.java
+++ b/src/com/jantvrdik/intellij/latte/utils/LatteUtil.java
@@ -75,8 +75,8 @@ public static List findVariablesInFile(@NotNull Project pr
return result != null ? result : Collections.emptyList();
}
- public static Collection findMethods(Project project, String key, @Nullable PhpClass phpClass) {
- return findElementsInAllFiles(project, key, LattePhpMethod.class, phpClass);
+ public static Collection findMethods(Project project, String key, @Nullable Collection phpClasses) {
+ return findElementsInAllFiles(project, key, LattePhpMethod.class, phpClasses);
}
public static Collection findFunctions(Project project, String key) {
@@ -85,11 +85,11 @@ public static Collection findFunctions(Project project, Str
.collect(Collectors.toList());
}
- public static Collection findProperties(Project project, String key, @NotNull PhpClass phpClass) {
+ public static Collection findProperties(Project project, String key, @NotNull Collection phpClass) {
return findElementsInAllFiles(project, key, LattePhpProperty.class, phpClass);
}
- public static Collection findConstants(Project project, String key, @NotNull PhpClass phpClass) {
+ public static Collection findConstants(Project project, String key, @NotNull Collection phpClass) {
return findElementsInAllFiles(project, key, LattePhpConstant.class, phpClass);
}
@@ -97,7 +97,7 @@ public static Collection findClasses(Project project, String key)
return findElementsInAllFiles(project, key, LattePhpClass.class, null);
}
- public static Collection findStaticVariables(Project project, String key, @NotNull PhpClass phpClass) {
+ public static Collection findStaticVariables(Project project, String key, @NotNull Collection phpClass) {
return findElementsInAllFiles(project, key, LattePhpStaticVariable.class, phpClass);
}
@@ -142,7 +142,7 @@ public static boolean isStringAtCaret(@NotNull Editor editor, @NotNull String st
return fileText.length() >= startOffset + string.length() && fileText.substring(startOffset, startOffset + string.length()).equals(string);
}
- private static Collection findElementsInAllFiles(Project project, String key, Class className, @Nullable PhpClass phpClass) {
+ private static Collection findElementsInAllFiles(Project project, String key, Class className, @Nullable Collection phpClass) {
List result = new ArrayList();
Collection virtualFiles =
FileTypeIndex.getFiles(LatteFileType.INSTANCE, GlobalSearchScope.allScope(project));
@@ -160,10 +160,14 @@ private static Collection findElementsInAllF
return result;
}
- private static void attachResults(@NotNull List result, String key, List elements, @Nullable PhpClass phpClass)
+ private static void attachResults(@NotNull List result, String key, List elements, @Nullable Collection phpClasses)
{
for (PsiElement element : elements) {
- if (!(element instanceof BaseLattePhpElement) || (phpClass != null && !((BaseLattePhpElement) element).getPhpType().hasClass(phpClass.getFQN()))) {
+ if (!(element instanceof BaseLattePhpElement)) {
+ continue;
+ }
+
+ if ((phpClasses != null && phpClasses.size() > 0 && !((BaseLattePhpElement) element).getPhpType().hasClass(phpClasses))) {
continue;
}
@@ -224,7 +228,7 @@ public static void findLatteMacroTemplateType(List classes, Latte
file.acceptChildren(new PsiRecursiveElementWalkingVisitor() {
@Override
public void visitElement(PsiElement element) {
- if (element instanceof LatteMacroTag && ((LatteMacroTag) element).getMacroName().equals("templateType")) {
+ if (element instanceof LatteMacroTag && ((LatteMacroTag) element).matchMacroName("templateType")) {
classes.add((LatteMacroTag) element);
} else {
super.visitElement(element);