forked from open-policy-agent/opa-idea-plugin
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Implement References - wip (open-policy-agent#113)
- Loading branch information
Andrea Canonica
committed
Apr 6, 2023
1 parent
b64ca67
commit 2db426d
Showing
13 changed files
with
266 additions
and
5 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
33 changes: 33 additions & 0 deletions
33
src/main/kotlin/org/openpolicyagent/ideaplugin/ide/reference/RegoReferenceContributor.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
/* | ||
* Use of this source code is governed by the MIT license that can be | ||
* found in the LICENSE file. | ||
*/ | ||
|
||
package org.openpolicyagent.ideaplugin.ide.reference | ||
|
||
import com.intellij.openapi.util.TextRange | ||
import com.intellij.patterns.PlatformPatterns | ||
import com.intellij.psi.* | ||
import com.intellij.util.ProcessingContext | ||
import org.openpolicyagent.ideaplugin.lang.psi.RegoReference | ||
|
||
class RegoReferenceContributor : PsiReferenceContributor() { | ||
override fun registerReferenceProviders(registrar: PsiReferenceRegistrar) { | ||
registrar.registerReferenceProvider( | ||
PlatformPatterns.psiElement(PsiLiteralExpression::class.java), | ||
object : PsiReferenceProvider() { | ||
override fun getReferencesByElement( | ||
element: PsiElement, | ||
context: ProcessingContext | ||
): Array<out PsiReference> { | ||
val literalExpression = element as PsiLiteralExpression | ||
val value = if (literalExpression.value is String) literalExpression.value as String else null | ||
if (value != null && value.matches(Regex(".+\\{"))) { | ||
val rule = TextRange(0, value.indexOf("{")) | ||
return arrayOf<PsiReference>(RegoReference(element, rule)) | ||
} | ||
return PsiReference.EMPTY_ARRAY | ||
} | ||
}) | ||
} | ||
} |
57 changes: 57 additions & 0 deletions
57
src/main/kotlin/org/openpolicyagent/ideaplugin/lang/RegoUtil.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
/* | ||
* Use of this source code is governed by the MIT license that can be | ||
* found in the LICENSE file. | ||
*/ | ||
|
||
package org.openpolicyagent.ideaplugin.lang | ||
|
||
import com.intellij.openapi.project.Project | ||
import com.intellij.psi.PsiManager | ||
import com.intellij.psi.search.FileTypeIndex | ||
import com.intellij.psi.search.GlobalSearchScope | ||
import com.intellij.psi.util.PsiTreeUtil | ||
import org.openpolicyagent.ideaplugin.lang.psi.RegoFile | ||
import org.openpolicyagent.ideaplugin.lang.psi.RegoRule | ||
|
||
object RegoUtil { | ||
/** | ||
* Searches the entire project for Rego language files with instances of the Rego-Rule with the given key. | ||
* | ||
* @param project current project | ||
* @param ruleName to check | ||
* @return matching properties | ||
*/ | ||
fun findRules(project: Project, ruleName: String): List<RegoRule> { | ||
val result = mutableListOf<RegoRule>() | ||
val virtualFiles = FileTypeIndex.getFiles(RegoFileType, GlobalSearchScope.allScope(project)) | ||
for (virtualFile in virtualFiles) { | ||
val simpleFile = PsiManager.getInstance(project).findFile(virtualFile!!) as RegoFile? | ||
if (simpleFile != null) { | ||
val rules = PsiTreeUtil.getChildrenOfType(simpleFile, RegoRule::class.java) | ||
if (rules != null) { | ||
for (rule in rules) { | ||
if (ruleName == rule.name) { | ||
result.add(rule) | ||
} | ||
} | ||
} | ||
} | ||
} | ||
return result | ||
} | ||
|
||
fun findRules(project: Project?): List<RegoRule> { | ||
val result = mutableListOf<RegoRule>() | ||
val virtualFiles = FileTypeIndex.getFiles(RegoFileType, GlobalSearchScope.allScope(project!!)) | ||
for (virtualFile in virtualFiles) { | ||
val regoFile = PsiManager.getInstance(project).findFile(virtualFile!!) as RegoFile? | ||
if (regoFile != null) { | ||
val rules = PsiTreeUtil.getChildrenOfType(regoFile, RegoRule::class.java) | ||
if (rules != null) { | ||
result.addAll(rules) | ||
} | ||
} | ||
} | ||
return result | ||
} | ||
} |
23 changes: 23 additions & 0 deletions
23
src/main/kotlin/org/openpolicyagent/ideaplugin/lang/psi/RegoElementFactory.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
/* | ||
* Use of this source code is governed by the MIT license that can be | ||
* found in the LICENSE file. | ||
*/ | ||
|
||
package org.openpolicyagent.ideaplugin.lang.psi | ||
|
||
import com.intellij.openapi.project.Project | ||
import com.intellij.psi.PsiFileFactory | ||
import org.openpolicyagent.ideaplugin.lang.RegoFileType | ||
|
||
|
||
object RegoElementFactory { | ||
fun createRule(project: Project?, name: String): RegoRule { | ||
val file = createFile(project, name) | ||
return file.firstChild as RegoRule | ||
} | ||
|
||
fun createFile(project: Project?, text: String): RegoFile { | ||
val name = "dummy.rego" | ||
return PsiFileFactory.getInstance(project).createFileFromText(name, RegoFileType, text) as RegoFile | ||
} | ||
} |
55 changes: 55 additions & 0 deletions
55
src/main/kotlin/org/openpolicyagent/ideaplugin/lang/psi/RegoReference.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,55 @@ | ||
/* | ||
* Use of this source code is governed by the MIT license that can be | ||
* found in the LICENSE file. | ||
*/ | ||
|
||
package org.openpolicyagent.ideaplugin.lang.psi | ||
|
||
import com.intellij.codeInsight.lookup.LookupElement | ||
import com.intellij.codeInsight.lookup.LookupElementBuilder | ||
import com.intellij.openapi.util.TextRange | ||
import com.intellij.psi.* | ||
import org.openpolicyagent.ideaplugin.lang.RegoIcons | ||
import org.openpolicyagent.ideaplugin.lang.RegoUtil | ||
|
||
|
||
class RegoReference(element: PsiElement, textRange: TextRange) : PsiReferenceBase<PsiElement>(element, textRange), | ||
PsiPolyVariantReference { | ||
private val key: String | ||
|
||
init { | ||
key = element.text.substring(textRange.startOffset, textRange.endOffset) | ||
} | ||
|
||
override fun multiResolve(incompleteCode: Boolean): Array<out ResolveResult> { | ||
val project = myElement!!.project | ||
val rules = RegoUtil.findRules(project, key) | ||
val results = mutableListOf<ResolveResult>() | ||
for (rule in rules) { | ||
results.add(PsiElementResolveResult(rule)) | ||
} | ||
return results.toTypedArray() | ||
} | ||
|
||
override fun resolve(): PsiElement? { | ||
val resolveResults = multiResolve(false) | ||
return if (resolveResults.size == 1) resolveResults[0].element else null | ||
} | ||
|
||
override fun getVariants(): Array<out Any> { | ||
val project = myElement!!.project | ||
val rules = RegoUtil.findRules(project) | ||
val variants = mutableListOf<LookupElement>() | ||
for (rule in rules) { | ||
if (rule.name != null && rule.name!!.isNotEmpty()) { | ||
variants.add( | ||
LookupElementBuilder | ||
.create(rule) | ||
.withIcon(RegoIcons.OPA) | ||
.withTypeText(rule.containingFile.name) | ||
) | ||
} | ||
} | ||
return variants.toTypedArray() | ||
} | ||
} |
45 changes: 45 additions & 0 deletions
45
src/main/kotlin/org/openpolicyagent/ideaplugin/lang/psi/ruleelements/RegoPsiImplUtil.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
/* | ||
* Use of this source code is governed by the MIT license that can be | ||
* found in the LICENSE file. | ||
*/ | ||
|
||
package org.openpolicyagent.ideaplugin.lang.psi.ruleelements | ||
|
||
import com.intellij.psi.PsiElement | ||
import org.openpolicyagent.ideaplugin.lang.psi.RegoElementFactory | ||
import org.openpolicyagent.ideaplugin.lang.psi.RegoRule | ||
import org.openpolicyagent.ideaplugin.lang.psi.RegoTypes | ||
|
||
|
||
class RegoPsiImplUtil { | ||
companion object { | ||
|
||
@JvmStatic | ||
fun getRuleHead(element: RegoRule): String? { | ||
val keyNode = element.node.findChildByType(RegoTypes.RULE_HEAD) | ||
return keyNode?.text | ||
} | ||
|
||
@JvmStatic | ||
fun getName(element: RegoRule): String? { | ||
return getRuleHead(element) | ||
} | ||
|
||
@JvmStatic | ||
fun setName(element: RegoRule, newName: String): PsiElement { | ||
val keyNode = element.node.findChildByType(RegoTypes.RULE_HEAD) | ||
if (keyNode != null) { | ||
val property = RegoElementFactory.createRule(element.project, newName) | ||
val newKeyNode = property.firstChild.node | ||
element.node.replaceChild(keyNode, newKeyNode) | ||
} | ||
return element | ||
} | ||
|
||
@JvmStatic | ||
fun getNameIdentifier(element: RegoRule): PsiElement? { | ||
val keyNode = element.node.findChildByType(RegoTypes.RULE_HEAD) | ||
return keyNode?.psi | ||
} | ||
} | ||
} |
10 changes: 10 additions & 0 deletions
10
src/main/kotlin/org/openpolicyagent/ideaplugin/lang/psi/ruleelements/RegoRuleElement.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
/* | ||
* Use of this source code is governed by the MIT license that can be | ||
* found in the LICENSE file. | ||
*/ | ||
|
||
package org.openpolicyagent.ideaplugin.lang.psi.ruleelements | ||
|
||
import com.intellij.psi.PsiNameIdentifierOwner | ||
|
||
interface RegoRuleElement : PsiNameIdentifierOwner |
28 changes: 28 additions & 0 deletions
28
src/main/kotlin/org/openpolicyagent/ideaplugin/lang/psi/ruleelements/RegoRuleElementImpl.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
/* | ||
* Use of this source code is governed by the MIT license that can be | ||
* found in the LICENSE file. | ||
*/ | ||
|
||
package org.openpolicyagent.ideaplugin.lang.psi.ruleelements | ||
|
||
import com.intellij.extapi.psi.ASTWrapperPsiElement | ||
import com.intellij.lang.ASTNode | ||
import com.intellij.psi.PsiElement | ||
import org.openpolicyagent.ideaplugin.lang.psi.RegoRule | ||
import org.openpolicyagent.ideaplugin.lang.psi.ruleelements.RegoPsiImplUtil.Companion.getName | ||
import org.openpolicyagent.ideaplugin.lang.psi.ruleelements.RegoPsiImplUtil.Companion.getNameIdentifier | ||
import org.openpolicyagent.ideaplugin.lang.psi.ruleelements.RegoPsiImplUtil.Companion.setName | ||
|
||
abstract class RegoRuleElementImpl(node: ASTNode) : ASTWrapperPsiElement(node), RegoRuleElement { | ||
override fun getName(): String? { | ||
return getName(this as RegoRule) | ||
} | ||
|
||
override fun setName(newName: String): PsiElement { | ||
return setName(this as RegoRule, newName) | ||
} | ||
|
||
override fun getNameIdentifier(): PsiElement? { | ||
return getNameIdentifier(this as RegoRule) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters