feat: Replace psi util class with mixins

This commit is contained in:
FalsePattern 2023-08-16 14:00:39 +02:00 committed by FalsePattern
parent d45a99ceae
commit 9c20e69c18
Signed by: falsepattern
GPG key ID: FDF7126A9E124447
8 changed files with 180 additions and 71 deletions

View file

@ -39,6 +39,13 @@
LINE_STRING='multiline string'
BAD_STRING='unterminated string'
]
//Mixins
mixin("struct")="com.falsepattern.zigbrains.zon.psi.impl.mixins.ZonStructMixinImpl"
implements("struct")="com.falsepattern.zigbrains.zon.psi.mixins.ZonStructMixin"
mixin("identifier")="com.falsepattern.zigbrains.zon.psi.impl.mixins.ZonIdentifierMixinImpl"
implements("identifier")="com.falsepattern.zigbrains.zon.psi.mixins.ZonIdentifierMixin"
}
zonFile ::= struct

View file

@ -0,0 +1,37 @@
/*
* Copyright 2023 FalsePattern
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.falsepattern.zigbrains.common.util;
import com.intellij.psi.PsiElement;
import java.util.Optional;
public class PsiElementUtil {
public static <T> Optional<T> parent(PsiElement element, Class<T> parentType) {
if (element == null) {
return Optional.empty();
}
var parent = element.getParent();
while (parent != null) {
if (parentType.isInstance(parent)) {
return Optional.of(parentType.cast(parent));
}
parent = parent.getParent();
}
return Optional.empty();
}
}

View file

@ -21,7 +21,6 @@ import com.falsepattern.zigbrains.zon.psi.ZonProperty;
import com.falsepattern.zigbrains.zon.psi.ZonPropertyPlaceholder;
import com.falsepattern.zigbrains.zon.psi.ZonStruct;
import com.falsepattern.zigbrains.zon.psi.ZonTypes;
import com.falsepattern.zigbrains.zon.psi.impl.ZonPsiImplUtil;
import com.intellij.codeInsight.completion.CompletionContributor;
import com.intellij.codeInsight.completion.CompletionParameters;
import com.intellij.codeInsight.completion.CompletionProvider;
@ -35,6 +34,8 @@ import org.jetbrains.annotations.NotNull;
import java.util.List;
import java.util.Set;
import static com.falsepattern.zigbrains.common.util.PsiElementUtil.parent;
public class ZonCompletionContributor extends CompletionContributor {
private static final List<String> ZON_ROOT_KEYS = List.of("name", "version", "dependencies");
private static final List<String> ZON_DEP_KEYS = List.of("url", "hash");
@ -47,12 +48,9 @@ public class ZonCompletionContributor extends CompletionContributor {
new CompletionProvider<>() {
@Override
protected void addCompletions(@NotNull CompletionParameters parameters, @NotNull ProcessingContext context, @NotNull CompletionResultSet result) {
var placeholder = ZonPsiImplUtil.parent(parameters.getPosition(), ZonPropertyPlaceholder.class);
assert placeholder != null;
var zonStruct = ZonPsiImplUtil.parent(placeholder, ZonStruct.class);
assert zonStruct != null;
var keys = ZonPsiImplUtil.getKeys(zonStruct);
var placeholder = parent(parameters.getPosition(), ZonPropertyPlaceholder.class).orElseThrow();
var zonStruct = parent(placeholder, ZonStruct.class).orElseThrow();
var keys = zonStruct.getKeys();
doAddCompletions(placeholder.getText().startsWith("."), keys, ZON_ROOT_KEYS, result);
}
});
@ -65,18 +63,13 @@ public class ZonCompletionContributor extends CompletionContributor {
new CompletionProvider<>() {
@Override
protected void addCompletions(@NotNull CompletionParameters parameters, @NotNull ProcessingContext context, @NotNull CompletionResultSet result) {
var placeholder = ZonPsiImplUtil.parent(parameters.getPosition(), ZonPropertyPlaceholder.class);
assert placeholder != null;
var depStruct = ZonPsiImplUtil.parent(placeholder, ZonStruct.class);
assert depStruct != null;
var parentProperty = ZonPsiImplUtil.parent(depStruct, ZonProperty.class);
assert parentProperty != null;
parentProperty = ZonPsiImplUtil.parent(parentProperty, ZonProperty.class);
assert parentProperty != null;
if (!"dependencies".equals(ZonPsiImplUtil.getText(parentProperty.getIdentifier()))) {
var placeholder = parent(parameters.getPosition(), ZonPropertyPlaceholder.class).orElseThrow();
var depStruct = parent(placeholder, ZonStruct.class).orElseThrow();
var parentProperty = parent(depStruct, ZonProperty.class).flatMap(e -> parent(e, ZonProperty.class)).orElseThrow();
if (!"dependencies".equals(parentProperty.getIdentifier().getName())) {
return;
}
doAddCompletions(placeholder.getText().startsWith("."), ZonPsiImplUtil.getKeys(depStruct), ZON_DEP_KEYS, result);
doAddCompletions(placeholder.getText().startsWith("."), depStruct.getKeys(), ZON_DEP_KEYS, result);
}
});
}

View file

@ -1,54 +0,0 @@
/*
* Copyright 2023 FalsePattern
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.falsepattern.zigbrains.zon.psi.impl;
import com.falsepattern.zigbrains.zon.psi.ZonIdentifier;
import com.falsepattern.zigbrains.zon.psi.ZonStruct;
import com.intellij.psi.PsiElement;
import java.util.HashSet;
import java.util.Set;
public class ZonPsiImplUtil {
public static Set<String> getKeys(ZonStruct struct) {
var result = new HashSet<String>();
for (var property : struct.getPropertyList()) {
result.add(getText(property.getIdentifier()));
}
return result;
}
public static <T> T parent(PsiElement element, Class<T> parentType) {
var parent = element.getParent();
while (parent != null) {
if (parentType.isInstance(parent)) {
return parentType.cast(parent);
}
parent = parent.getParent();
}
return null;
}
public static String getText(ZonIdentifier identifier) {
var idStr = identifier.getText();
if (idStr.startsWith("@")) {
return idStr.substring(2, idStr.length() - 2);
} else {
return idStr;
}
}
}

View file

@ -0,0 +1,38 @@
/*
* Copyright 2023 FalsePattern
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.falsepattern.zigbrains.zon.psi.impl.mixins;
import com.falsepattern.zigbrains.zon.psi.ZonIdentifier;
import com.intellij.extapi.psi.ASTWrapperPsiElement;
import com.intellij.lang.ASTNode;
import org.jetbrains.annotations.NotNull;
public abstract class ZonIdentifierMixinImpl extends ASTWrapperPsiElement implements ZonIdentifier {
public ZonIdentifierMixinImpl(@NotNull ASTNode node) {
super(node);
}
@Override
public String getName() {
var idStr = getText();
if (idStr.startsWith("@")) {
return idStr.substring(2, idStr.length() - 2);
} else {
return idStr;
}
}
}

View file

@ -0,0 +1,40 @@
/*
* Copyright 2023 FalsePattern
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.falsepattern.zigbrains.zon.psi.impl.mixins;
import com.falsepattern.zigbrains.zon.psi.ZonStruct;
import com.intellij.extapi.psi.ASTWrapperPsiElement;
import com.intellij.lang.ASTNode;
import org.jetbrains.annotations.NotNull;
import java.util.HashSet;
import java.util.Set;
public abstract class ZonStructMixinImpl extends ASTWrapperPsiElement implements ZonStruct {
public ZonStructMixinImpl(@NotNull ASTNode node) {
super(node);
}
@Override
public Set<String> getKeys() {
var result = new HashSet<String>();
for (var property : getPropertyList()) {
result.add(property.getIdentifier().getName());
}
return result;
}
}

View file

@ -0,0 +1,23 @@
/*
* Copyright 2023 FalsePattern
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.falsepattern.zigbrains.zon.psi.mixins;
import com.intellij.psi.PsiElement;
public interface ZonIdentifierMixin extends PsiElement {
String getName();
}

View file

@ -0,0 +1,25 @@
/*
* Copyright 2023 FalsePattern
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.falsepattern.zigbrains.zon.psi.mixins;
import com.intellij.psi.PsiElement;
import java.util.Set;
public interface ZonStructMixin extends PsiElement {
Set<String> getKeys();
}