Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Coldfusion language and code intelligence updates #756

Open
wants to merge 20 commits into
base: 193.5233
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
c653a55
[CFML] catch for uncaught null pointer exception
Jan 3, 2020
f18bee4
[CFML] version and project info adjustment
Jan 3, 2020
5de3ac9
[CFML] implemented documentation lookup for cfcs
Jan 3, 2020
1466755
[CFML] fix: new expression followed by method call
Jan 3, 2020
b539152
[CFML] added support for wildcard imports
Jan 3, 2020
817a5dd
[CFML] fix: type definition as string
Jan 3, 2020
3d532ef
[CFML] fix: keywords as variable names
Jan 3, 2020
17356f6
[CFML] <cfparam> implementation
adventurous-gerbil Jan 10, 2020
6910910
minor changes to tests to get them to run
adventurous-gerbil Jan 10, 2020
6eab87f
[CFML] fix: tag no-value attributes are now valid
adventurous-gerbil Jan 15, 2020
0cafd73
[CFML] implemented typing for compoment properties
adventurous-gerbil Jan 15, 2020
df79e12
implemented typing for script component properties
adventurous-gerbil Jan 16, 2020
465c19b
[CFML] fixed cfimport tag not returning references
adventurous-gerbil Feb 5, 2020
6f3a1a4
[CFML] PsiType resolution for short imported names
adventurous-gerbil Feb 5, 2020
ac46d3f
added documentation provider for cfc properties
adventurous-gerbil Feb 12, 2020
a3205f8
[CFML] fix for unbalanced tree at new expressions
adventurous-gerbil Mar 6, 2020
891772f
[CFML] added support for typed arrays
adventurous-gerbil Mar 6, 2020
78a8d2d
[CFML] now uses PsiArrayType
adventurous-gerbil Mar 6, 2020
7e05ac9
[CFML] added TypeDeclarationProvider for GotoType
adventurous-gerbil Mar 6, 2020
6a4d304
[CFML] fix for functions to return typed arrays
adventurous-gerbil Mar 10, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 5 additions & 10 deletions CFML/.idea/runConfigurations/CFML_Tests.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 3 additions & 3 deletions CFML/CFML-plugin.iml
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="PLUGIN_MODULE" version="4">
<component name="DevKit.ModuleBuildProperties" url="file://$MODULE_DIR$/resources/META-INF/plugin.xml" />
<component name="NewModuleRootManager" inherit-compiler-output="true">
<component name="NewModuleRootManager" LANGUAGE_LEVEL="JDK_1_8" inherit-compiler-output="true">
<exclude-output />
<content url="file://$MODULE_DIR$">
<sourceFolder url="file://$MODULE_DIR$/resources" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/tests" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/gen" isTestSource="false" generated="true" />
<excludeFolder url="file://$MODULE_DIR$/source_for_IDEA8" />
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
</module>

</module>
6 changes: 6 additions & 0 deletions CFML/resources/META-INF/plugin.xml
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
<idea-plugin>
<id>CFML Support</id>
<name>CFML</name>
<version>2019.3.0-BETA</version>
<description>
<![CDATA[
Adds support for ColdFusion Markup Language (CFML).
Expand All @@ -17,6 +18,9 @@ To configure path mappings, open the <b>Settings / Preferences</b> dialog and se
<depends>com.intellij.modules.java</depends>
<depends>com.intellij.modules.ultimate</depends>
<depends>com.intellij.modules.idea.ultimate</depends>

<!-- Minimum and maximum build of IDE compatible with the plugin -->
<idea-version since-build="193" until-build="193.*"/>

<extensions defaultExtensionNs="com.intellij">
<psi.referenceContributor language="CFML"
Expand Down Expand Up @@ -103,6 +107,8 @@ To configure path mappings, open the <b>Settings / Preferences</b> dialog and se

<multiHostInjector implementation="com.intellij.coldFusion.injection.CfmlSqlMultiHostInjector" order="first"/>
<editorHighlighterProvider filetype="CFML" implementationClass="com.intellij.coldFusion.model.files.CfmlEditorHighlighterProvider"/>

<typeDeclarationProvider implementation="com.intellij.coldFusion.navigation.actions.CfmlTypeDeclarationProvider"/>
</extensions>

<actions>
Expand Down
16 changes: 15 additions & 1 deletion CFML/src/com/intellij/coldFusion/UI/CfmlLookUpItemUtil.java
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
import com.intellij.codeInsight.lookup.PsiTypeLookupItem;
import com.intellij.coldFusion.UI.editorActions.completionProviders.CfmlMethodInsertHandler;
import com.intellij.coldFusion.model.info.CfmlFunctionDescription;
import com.intellij.coldFusion.model.info.CfmlPropertyDescription;
import com.intellij.coldFusion.model.psi.*;
import com.intellij.coldFusion.model.psi.impl.CfmlNamedAttributeImpl;
import com.intellij.openapi.util.text.StringUtil;
Expand Down Expand Up @@ -132,10 +133,23 @@ public static CfmlFunctionDescription getFunctionDescription(CfmlFunction functi
PsiType returnType = function.getReturnType();
CfmlFunctionDescription functionInfo = new CfmlFunctionDescription(function.getName(),
returnType != null ? returnType.getCanonicalText() : null);

functionInfo.setDescription(function.getDescription());
CfmlParameter[] params = function.getParameters();
for (CfmlParameter param : params) {
functionInfo.addParameter(new CfmlFunctionDescription.CfmlParameterDescription(param.getName(), param.getType(), param.isRequired()));
CfmlFunctionDescription.CfmlParameterDescription description =
new CfmlFunctionDescription.CfmlParameterDescription(param.getName(), param.getType(), param.getDefault(), param.isRequired());
description.setDescription(param.getDescription());
functionInfo.addParameter(description);
}
return functionInfo;
}

public static CfmlPropertyDescription getPropertyDescription(CfmlProperty property) {
PsiType type = property.getPsiType();
CfmlPropertyDescription propertyInfo = new CfmlPropertyDescription(property.getName(),
type != null ? type.getCanonicalText() : null);
propertyInfo.setDescription(property.getDescription());
return propertyInfo;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@
package com.intellij.coldFusion.UI.editorActions;

import com.intellij.coldFusion.model.CfmlUtil;
import com.intellij.coldFusion.model.psi.CfmlComponent;
import com.intellij.coldFusion.model.psi.CfmlFunction;
import com.intellij.coldFusion.model.psi.CfmlProperty;
import com.intellij.coldFusion.model.psi.CfmlTag;
import com.intellij.coldFusion.model.psi.impl.CfmlAttributeImpl;
import com.intellij.coldFusion.model.psi.impl.CfmlAttributeNameImpl;
Expand All @@ -21,7 +24,16 @@ public class CfmlDocumentProvider extends DocumentationProviderEx {

@Override
public String generateDoc(PsiElement element, PsiElement originalElement) {
if (element instanceof CfmlAttributeImpl && element.getParent() instanceof CfmlTag) {
if (element instanceof CfmlComponent) {
return CfmlUtil.getComponentDescription((CfmlComponent)element, element.getProject());
}
else if (element instanceof CfmlFunction) {
return CfmlUtil.getFunctionDescription((CfmlFunction)element, element.getProject());
}
else if (element instanceof CfmlProperty) {
return CfmlUtil.getPropertyDescription((CfmlProperty)element, element.getProject());
}
else if (element instanceof CfmlAttributeImpl && element.getParent() instanceof CfmlTag) {
String tagName = StringUtil.toLowerCase(((CfmlTag)element.getParent()).getTagName());
String attributeName = (element instanceof CfmlAttributeNameImpl) ?
"name" :
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -114,9 +114,11 @@ else if (element1 instanceof PsiMethod) {
new CfmlFunctionDescription(function.getName(), function.getReturnType().getPresentableText());
final PsiParameter[] psiParameters = function.getParameterList().getParameters();
for (PsiParameter psiParameter : psiParameters) {
PsiExpression initializerElement = psiParameter.getInitializer();
String initializerValue = initializerElement == null ? null : initializerElement.getText();
javaMethodDescr.addParameter(new CfmlFunctionDescription.CfmlParameterDescription(psiParameter.getName(),
psiParameter.getType()
.getPresentableText(), true));
.getPresentableText(), initializerValue, true));
}
return javaMethodDescr;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ public class CfmllFindUsagesProvider implements FindUsagesProvider {
public boolean canFindUsagesFor(@NotNull final PsiElement psiElement) {
return psiElement instanceof CfmlReferenceExpression || (psiElement instanceof CfmlTagFunctionImpl) ||
(psiElement instanceof CfmlTag && ((CfmlTag)psiElement).getTagName().equalsIgnoreCase("cfargument")) ||
(psiElement instanceof CfmlTag && ((CfmlTag)psiElement).getTagName().equalsIgnoreCase("cfparam")) ||
psiElement instanceof CfmlFunctionImpl || psiElement instanceof CfmlFunctionParameterImpl;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ public void addCompletions(@NotNull final CompletionParameters parameters,
String[] attributeValue = CfmlUtil.getAttributeValues(tagName, attributeName, parameters.getPosition().getProject());

if ("type".equalsIgnoreCase(attributeName) && "cfargument".equalsIgnoreCase(tagName) ||
"type".equalsIgnoreCase(attributeName) && "cfproperty".equalsIgnoreCase(tagName) ||
"returntype".equalsIgnoreCase(attributeName) && "cffunction".equalsIgnoreCase(tagName)
) {
Object[] objects =
Expand Down
12 changes: 8 additions & 4 deletions CFML/src/com/intellij/coldFusion/injection/CfqueryEscaper.kt
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,14 @@ class CfqueryEscaper(tag: CfmlTagImpl) : LiteralTextEscaper<CfmlTagImpl>(tag) {

//exclude cfquery tags from TextRange
override fun getRelevantTextRange(): TextRange {
val startOffset = Regex("<cfquery[^>]*>").find(myHost.text)!!.range.endInclusive + 1
val closeTagOffset = Regex("</cfquery[^>]*>").find(myHost.text) ?: return TextRange(startOffset, startOffset)
val endOffset = closeTagOffset.range.start
return TextRange(startOffset, endOffset)
try {
val startOffset = Regex("<cfquery[^>]*>").find(myHost.text)!!.range.endInclusive + 1
val closeTagOffset = Regex("</cfquery[^>]*>").find(myHost.text) ?: return TextRange(startOffset, startOffset)
val endOffset = closeTagOffset.range.start
return TextRange(startOffset, endOffset)
} catch (e: KotlinNullPointerException) {
return TextRange(0, 0)
}
}

}
58 changes: 58 additions & 0 deletions CFML/src/com/intellij/coldFusion/model/CfmlDocUtil.kt
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,13 @@ import com.intellij.coldFusion.model.info.CfmlAttributeDescription
import com.intellij.coldFusion.model.info.CfmlLangInfo
import com.intellij.coldFusion.model.info.CfmlTagDescription
import com.intellij.coldFusion.model.info.CfmlTypesInfo
import com.intellij.coldFusion.model.psi.CfmlComponent
import com.intellij.coldFusion.model.psi.CfmlFunction
import com.intellij.coldFusion.model.psi.CfmlProperty
import com.intellij.openapi.project.Project
import com.intellij.util.containers.isNullOrEmpty
import com.intellij.xml.util.XmlStringUtil
import java.util.*

object CfmlDocUtil {

Expand Down Expand Up @@ -117,4 +121,58 @@ object CfmlDocUtil {
return "<b>$this</b>"
}

private fun String.faint(): String {
return "<span style=\"font-weight: lighter;\">$this</span>"
}

@JvmStatic
fun componentDescription(component: CfmlComponent, project: Project): String {
var description = p { (component.name ?: "Unknown component name").bold() }

val hintDescription = component.description
if (hintDescription != null) {
description += p { hintDescription }
}

val init = Arrays.stream(component.getFunctionsWithSupers(false)).filter { f: CfmlFunction -> f.name == "init" }
.findFirst()
if (init.isPresent) {
description += "<p></p>" + functionDescription(init.get(), project)
}
return description
}

@JvmStatic
fun functionDescription(function: CfmlFunction, project: Project): String {
val info = function.functionInfo
var paramsLabel = "Params: ".faint()
return p {
info.name.trim().bold() + if (info.parameters.isEmpty()) "()" else "(...)" + " : " + (info.returnType ?: "any")
} + p {
info.description?.trim() ?: ""
} + table {
info.parameters.map {
tr {
td {
paramsLabel
} + td {
paramsLabel = ""
it.presetableText.bold() + " "
} + td {
it.description?.trim() ?: ""
}
}
}.joinToString("")
}
}

@JvmStatic
fun propertyDescription(property: CfmlProperty, project: Project): String {
val info = property.propertyInfo
return p {
info.name.trim().bold() + " : " + (info.type ?: "any")
} + p {
info.description?.trim() ?: ""
}
}
}
37 changes: 35 additions & 2 deletions CFML/src/com/intellij/coldFusion/model/CfmlUtil.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,14 @@
package com.intellij.coldFusion.model;

import com.intellij.codeInsight.AutoPopupController;
import com.intellij.coldFusion.model.files.CfmlFile;
import com.intellij.coldFusion.model.info.CfmlAttributeDescription;
import com.intellij.coldFusion.model.info.CfmlLangInfo;
import com.intellij.coldFusion.model.info.CfmlTagDescription;
import com.intellij.coldFusion.model.lexer.CfmlTokenTypes;
import com.intellij.coldFusion.model.lexer.CfscriptTokenTypes;
import com.intellij.coldFusion.model.parsers.CfmlKeywords;
import com.intellij.coldFusion.model.psi.CfmlImport;
import com.intellij.coldFusion.model.psi.CfmlReferenceExpression;
import com.intellij.coldFusion.model.psi.*;
import com.intellij.coldFusion.model.psi.impl.CfmlTagImpl;
import com.intellij.lang.Language;
import com.intellij.lang.PsiBuilder;
Expand All @@ -25,6 +25,7 @@
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFile;
import com.intellij.psi.PsiType;
import com.intellij.psi.tree.IElementType;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.util.ArrayUtil;
Expand Down Expand Up @@ -167,6 +168,18 @@ public static boolean isEndTagRequired(String tagName, Project project) {
return getCfmlLangInfo(project).getTagAttributes().get(tagName).isEndTagRequired();
}

public static String getComponentDescription(CfmlComponent component, Project project) {
return CfmlDocUtil.componentDescription(component, project);
}

public static String getFunctionDescription(CfmlFunction function, Project project) {
return CfmlDocUtil.functionDescription(function, project);
}

public static String getPropertyDescription(CfmlProperty property, Project project) {
return CfmlDocUtil.propertyDescription(property, project);
}

public static String getTagDescription(String tagName, Project project) {
return CfmlDocUtil.tagDescription(tagName, project);
}
Expand Down Expand Up @@ -294,4 +307,24 @@ public static Couple<String> getPrefixAndName(String name) {
}
return Couple.of(name.substring(0, index), name.substring(index + 1));
}

@Nullable
public static PsiType getTypeFromName(CfmlFile file, String typeName, Project project) {
if (file == null || typeName == null) return null;

final boolean isArray = typeName.endsWith("[]");
final String qualifiedTypeString;
if (isArray) {
qualifiedTypeString = file.getComponentQualifiedName(typeName.substring(0, typeName.length() - 2));
}
else {
qualifiedTypeString = file.getComponentQualifiedName(typeName);
}
if (qualifiedTypeString == null) return null;
PsiType type = new CfmlComponentType(qualifiedTypeString, file, project);
if (isArray) {
type = type.createArrayType();
}
return type;
}
}
8 changes: 3 additions & 5 deletions CFML/src/com/intellij/coldFusion/model/files/CfmlFile.java
Original file line number Diff line number Diff line change
Expand Up @@ -178,7 +178,7 @@ public String getComponentQualifiedName(@NotNull String componentName) {
CfmlImport[] childrenByClass = findChildrenByClass(CfmlImport.class);
for (CfmlImport importStatement : childrenByClass) {
if (importStatement.isImported(componentName)) {
String importString = importStatement.getImportString();
String importString = importStatement.getComponentQualifiedName(componentName);
return importString != null ? importString : "";
}
}
Expand All @@ -189,10 +189,8 @@ public Collection<String> getImportStrings() {
Set<String> result = new HashSet<>();
CfmlImport[] childrenByClass = findChildrenByClass(CfmlImport.class);
for (CfmlImport importStatement : childrenByClass) {
String importString = importStatement.getImportString();
if (importString != null) {
result.add(importString);
}
Set<String> importStrings = importStatement.getAllComponentQualifiedNames();
result.addAll(importStrings);
}
return result;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,12 +59,14 @@ public void setDescription(String description) {
public static class CfmlParameterDescription {
private final String myName;
private final String myType;
private final String myDefault;
private final boolean myIsRequired;
private String myDescription;

public CfmlParameterDescription(String name, String type, boolean isRequired) {
public CfmlParameterDescription(String name, String type, String defaultValue, boolean isRequired) {
myName = name;
myType = type;
myDefault = defaultValue;
myIsRequired = isRequired;
}

Expand All @@ -75,6 +77,10 @@ public String getName() {
public String getType() {
return myType;
}

public String getDefault() {
return myDefault;
}

public boolean isRequired() {
return myIsRequired;
Expand All @@ -95,6 +101,10 @@ public String getPresetableText() {
if (type != null) {
paramDescription = paramDescription + " : " + type;
}
final String defaultValue = getDefault();
if (defaultValue != null) {
paramDescription = paramDescription + " = \"" + defaultValue + "\"";
}
if (!isRequired()) {
sb.append("[");
sb.append(paramDescription);
Expand Down
Loading