Skip to content

Commit

Permalink
backporting 1.4.14 changes to 2022_3
Browse files Browse the repository at this point in the history
  • Loading branch information
m0rkeulv committed Sep 25, 2023
1 parent bbd3156 commit 269470a
Show file tree
Hide file tree
Showing 213 changed files with 18,066 additions and 17,366 deletions.
12 changes: 11 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,17 @@
# Changelog

## 1.4.14-223
* NOTE: Builds for idea 2022.3 are no longer actively maintained (consider upgrading)
* Fixed: Allow module level keywords for module fields. (#1135)
* Fixed: Allow trailing commas in anonymousTypeField list
* Fixed: Incorrect resolve order (defined in function vs inherited class member)
* Fixed: incorrect error highlighting on abstract classes with interfaces (#1136)
* Fixed: incorrect error highlighting on bitwise xor (#1137)
* Fixed: Regular expressions where incorrectly shown as dynamic in inlays
* Change: Regex rules changed from Java to JS to better match Haxe rules.
* Reworked resolving logic to better support modules and EnumValues.

## 1.4.13-223
* NOTE: Builds for idea 2022.3 are no longer actively maintained
* Added: Quick fix for incorrect extends and implements (#940)
* Fixed: Resolving type from inline method calls (#868)
* Fixed: Automatic import was placed after class Doc comment (#842)
Expand Down
2 changes: 1 addition & 1 deletion gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ pluginName = Haxe Toolkit Support
pluginRepositoryUrl = https://github.com/HaxeFoundation/intellij-haxe

# SemVer format -> https://semver.org
pluginVersion = 1.4.13-223
pluginVersion = 1.4.14-223

# IntelliJ Platform Properties -> https://github.com/JetBrains/gradle-intellij-plugin#intellij-platform-properties
platformType = IU
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
package com.intellij.plugins.haxe.buildsystem.haxelib;

import com.intellij.json.JsonFileType;
import com.intellij.json.JsonLanguage;
import com.intellij.plugins.haxe.HaxeBundle;
import org.jetbrains.annotations.NotNull;

import javax.swing.*;

public class HaxelibJsonFileType extends JsonFileType {

public static final HaxelibJsonFileType INSTANCE = new HaxelibJsonFileType();
public static final String DEFAULT_EXTENSION = "json";

public HaxelibJsonFileType() {
super(JsonLanguage.INSTANCE);
}

@NotNull
@Override
public String getName() {
return HaxeBundle.message("haxelib.project.file.name");
}

@NotNull
@Override
public String getDescription() {
return HaxeBundle.message("haxelib.project.file.description");
}

@NotNull
@Override
public String getDefaultExtension() {
return DEFAULT_EXTENSION;
}

@Override
public Icon getIcon() {
return icons.HaxeIcons.HAXELIB_JSON;
}


}
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
package com.intellij.plugins.haxe.buildsystem.haxelib;

import com.intellij.openapi.project.Project;
import com.intellij.openapi.vfs.VfsUtil;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.plugins.haxe.HaxeBundle;
import com.jetbrains.jsonSchema.extension.JsonSchemaFileProvider;
import com.jetbrains.jsonSchema.extension.JsonSchemaProviderFactory;
import com.jetbrains.jsonSchema.extension.SchemaType;
import org.jetbrains.annotations.Nls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import java.net.URL;
import java.util.List;

public class HaxelibJsonSchemaProviderFactory implements JsonSchemaProviderFactory {


@Override
public @NotNull List<JsonSchemaFileProvider> getProviders(@NotNull Project project) {
return List.of(new haxelibSchemaProvider());
}

private static class haxelibSchemaProvider implements JsonSchemaFileProvider {

@Override
public boolean isAvailable(@NotNull VirtualFile file) {
return file.getName().equalsIgnoreCase("haxelib.json");
}

@Override
public @NotNull @Nls String getName() {
return HaxeBundle.message("haxelib.project.file.name");
}

@Override
public @Nullable VirtualFile getSchemaFile() {
URL resource = HaxelibJsonSchemaProviderFactory.class.getResource("/schema/haxelib/schema.json");
return VfsUtil.findFileByURL(resource);
}

@Override
public @NotNull SchemaType getSchemaType() {
return SchemaType.embeddedSchema;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
public class LimeXmlSchemaProvider extends XmlSchemaProvider {
@Override
public XmlFile getSchema(@NotNull @NonNls String url, @Nullable Module module, @NotNull PsiFile baseFile) {
final URL resource = LimeXmlSchemaProvider.class.getResource("/xsd/lime/lime-project.xsd");
final URL resource = LimeXmlSchemaProvider.class.getResource("/schema/lime/lime-project.xsd");
final VirtualFile fileByURL = VfsUtil.findFileByURL(resource);
PsiFile result = baseFile.getManager().findFile(fileByURL);
if (result instanceof XmlFile) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@
public class NMMLSchemaProvider extends XmlSchemaProvider {
@Override
public XmlFile getSchema(@NotNull @NonNls String url, @Nullable Module module, @NotNull PsiFile baseFile) {
final URL resource = NMMLSchemaProvider.class.getResource("/xsd/nmml/nmml.xsd");
final URL resource = NMMLSchemaProvider.class.getResource("/schema/nmml/nmml.xsd");
final VirtualFile fileByURL = VfsUtil.findFileByURL(resource);
PsiFile result = baseFile.getManager().findFile(fileByURL);
if (result instanceof XmlFile) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,7 @@
import com.intellij.lang.ASTNode;
import com.intellij.openapi.editor.Editor;
import com.intellij.plugins.haxe.lang.lexer.HaxeTokenTypes;
import com.intellij.plugins.haxe.lang.psi.HaxeClass;
import com.intellij.plugins.haxe.lang.psi.HaxeClassBody;
import com.intellij.plugins.haxe.lang.psi.HaxeComponentName;
import com.intellij.plugins.haxe.lang.psi.HaxeFile;
import com.intellij.plugins.haxe.lang.psi.*;
import com.intellij.plugins.haxe.util.HaxeCodeGenerateUtil;
import com.intellij.plugins.haxe.util.UsefulPsiTreeUtil;
import com.intellij.psi.PsiElement;
Expand All @@ -41,7 +38,7 @@ public class MissingClassBodyFixer implements Fixer {

@Override
public void apply(Editor editor, HaxeSmartEnterProcessor processor, PsiElement psiElement) throws IncorrectOperationException {
if (isTopLevel(psiElement)) {
if (isModuleComponent(psiElement)) {
if (psiElement instanceof HaxeClass) {
fixMissingBody(editor, (HaxeClass)psiElement);
}
Expand All @@ -51,8 +48,8 @@ else if (psiElement.getNode().getElementType() == HaxeTokenTypes.PLCURLY) {
}
}

private boolean isTopLevel(@NotNull PsiElement element) {
return element.getParent() instanceof HaxeFile;
private boolean isModuleComponent(@NotNull PsiElement element) {
return element.getParent() instanceof HaxeModule;
}

private boolean isMissingBody(@NotNull HaxeClass haxeClass) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -365,10 +365,11 @@ private void processVariable(HtmlBuilder builder, HaxeNamedComponent component,
resolveTypeAndMakeHeader(builder, captureVar);
//builder.br();
}
else if (component instanceof HaxeLocalVarDeclaration varDeclaration) {
else if (component instanceof HaxeLocalVarDeclaration varDeclaration
&& component.getParent() instanceof HaxeLocalVarDeclarationList varDeclarationList) {
//builder.br();

String modifier = ((HaxeLocalVarDeclarationList)component.getParent()).getMutabilityModifier().getText();
String modifier = varDeclarationList.getMutabilityModifier().getText();
String signature = modifier + " " + varDeclaration.getText();

String highlighting = renderer.languageHighlighting(signature);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,8 +44,8 @@ private void checkClass(@NotNull HaxeClass aClass, @NotNull AnnotationHolder hol
}


List<HaxeMethodModel> methods = classModel.getMethods(null);
boolean containsAbstractMethod = methods.stream().anyMatch(HaxeMethodModel::isAbstract);
List<HaxeMethodModel> currentClassMethods = classModel.getMethodsSelf(null);
boolean containsAbstractMethod = currentClassMethods.stream().anyMatch(HaxeMethodModel::isAbstract);

if (containsAbstractMethod && !isAbstractClass) {
PsiElement element = classModel.getNamePsi();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,8 +53,10 @@ public static void check(final HaxeBinaryExpression binaryExpression, final Anno
ResultHolder lhsType = HaxeTypeResolver.getPsiElementType(LeftChild, binaryExpression, lhsResolver);
ResultHolder rhsType = HaxeTypeResolver.getPsiElementType(rightChild, binaryExpression, rhsResolver);

// ignoring macro values as we dont always know the type
boolean containsMacroExpression = HaxeMacroUtil.isMacroType(lhsType) | HaxeMacroUtil.isMacroType(rhsType);
// ignore unknown and dynamic for now
if (lhsType.isUnknown() || lhsType.isDynamic() || rhsType.isUnknown() || rhsType.isDynamic() ) {
if (lhsType.isUnknown() || lhsType.isDynamic() || rhsType.isUnknown() || rhsType.isDynamic() || containsMacroExpression) {
return;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,14 @@
import org.jetbrains.annotations.Nullable;

import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

import static com.intellij.plugins.haxe.ide.annotator.HaxeSemanticAnnotatorInspections.*;
import static com.intellij.plugins.haxe.ide.annotator.semantics.HaxeMethodAnnotator.checkIfMethodSignatureDiffers;
import static com.intellij.plugins.haxe.ide.annotator.semantics.HaxeMethodAnnotator.checkMethodsSignatureCompatibility;
import static com.intellij.plugins.haxe.model.type.HaxeTypeCompatible.canAssignToFrom;
import static java.util.function.Predicate.not;
import static java.util.stream.Collectors.toList;

public class HaxeClassAnnotator implements Annotator {
Expand All @@ -49,16 +52,19 @@ static public void check(final HaxeClass clazzPsi, final AnnotationHolder holder
// avoiding unnecessary extra annotations when HaxeAnonymousType is part of other non-anonymous types like typedefs etc.
return;
}
// TODO mlo:
// check abstract keyword for methods without body in classes

checkModifiers(clazz, holder);
checkDuplicatedFields(clazz, holder);
checkClassName(clazz, holder);
checkExtends(clazz, holder);
checkInterfaces(clazz, holder);
if (!clazzPsi.isInterface() && !clazzPsi.isTypeDef()) {
checkInterfacesMethods(clazz, holder);
checkInterfacesAndAbstractMethods(clazz, holder);
checkInterfacesFields(clazz, holder);
}

}

static private void checkModifiers(final HaxeClassModel clazz, final AnnotationHolder holder) {
Expand Down Expand Up @@ -231,7 +237,7 @@ private static void checkInterfaces(final HaxeClassModel clazz, final Annotation
}
}

private static void checkInterfacesMethods(final HaxeClassModel clazz, final AnnotationHolder holder) {
private static void checkInterfacesAndAbstractMethods(final HaxeClassModel clazz, final AnnotationHolder holder) {
PsiElement clazzPsi = clazz.getPsi();
boolean checkMissingInterfaceMethods = MISSING_INTERFACE_METHODS.isEnabled(clazzPsi);
boolean checkInterfaceMethodSignature = INTERFACE_METHOD_SIGNATURE.isEnabled(clazzPsi);
Expand All @@ -240,11 +246,72 @@ private static void checkInterfacesMethods(final HaxeClassModel clazz, final Ann
if (!checkMissingInterfaceMethods && !checkInterfaceMethodSignature && !checkInheritedInterfaceMethodSignature) {
return;
}
if (clazz.isClass() && !clazz.isAbstractClass()) {
// check inferfaces
for (HaxeClassReferenceModel reference : clazz.getImplementingInterfaces()) {
checkInterfaceMethods(clazz, reference, holder, checkMissingInterfaceMethods, checkInterfaceMethodSignature,
checkInheritedInterfaceMethodSignature);
}
}
// check abstract class methods
List<HaxeClassReferenceModel> types = clazz.getExtendingTypes();
// for classes its only allowed to extend one sub-class so we can look for frist element
if (!types.isEmpty()) {
HaxeClassReferenceModel model = types.get(0);
if (model.getHaxeClass() != null && model.getHaxeClass().isAbstractClass()) {
checkAbstractMethods(clazz, model, holder);
}
}
}

for (HaxeClassReferenceModel reference : clazz.getImplementingInterfaces()) {
checkInterfaceMethods(clazz, reference, holder, checkMissingInterfaceMethods, checkInterfaceMethodSignature,
checkInheritedInterfaceMethodSignature);
private static void checkAbstractMethods(HaxeClassModel clazz, HaxeClassReferenceModel abstractClass, AnnotationHolder holder) {
final List<HaxeMethodModel> missingMethods = new ArrayList<>();
final List<String> missingMethodsNames = new ArrayList<String>();



List<HaxeMethod> allMethodList = clazz.haxeClass.getAllHaxeMethods(HaxeComponentType.CLASS, HaxeComponentType.INTERFACE);
List<HaxeMethod> extendedClassMethodList = abstractClass.getHaxeClass().haxeClass.getAllHaxeMethods(HaxeComponentType.CLASS, HaxeComponentType.INTERFACE);

Map<String, HaxeMethodModel> abstractMethods = extendedClassMethodList.stream()
.map(HaxeMethodPsiMixin::getModel)
.filter(m -> m.isAbstract() || m.isInInterface())
.collect(Collectors.toMap(m -> m.getMethod().getName(), Function.identity(), (m1, m2) -> m1));

Map<String, HaxeMethodModel> nonAbstractMethods = allMethodList.stream()
.map(HaxeMethodPsiMixin::getModel)
.filter(not(HaxeMethodModel::isAbstract))
.filter(not(HaxeMethodModel::isInInterface))
.collect(Collectors.toMap(m -> m.getMethod().getName(), Function.identity(), (m1, m2) -> m1));

for (String name : abstractMethods.keySet()) {
if (!nonAbstractMethods.containsKey(name)) {
missingMethods.add(abstractMethods.get(name));
missingMethodsNames.add(name);
}
}

if (!missingMethods.isEmpty()) {
// @TODO: Move to bundle
holder.newAnnotation(HighlightSeverity.ERROR, "Not implemented methods: " + StringUtils.join(missingMethodsNames, ", "))
.range(abstractClass.getPsi())
.withFix(new HaxeFixer("Implement methods") {
@Override
public void run() {
OverrideImplementMethodFix fix = new OverrideImplementMethodFix(clazz.haxeClass, false);
for (HaxeMethodModel mm : missingMethods) {
fix.addElementToProcess(mm.getMethodPsi());
}

PsiElement basePsi = clazz.getBasePsi();
Project p = basePsi.getProject();
fix.invoke(p, FileEditorManager.getInstance(p).getSelectedTextEditor(), basePsi.getContainingFile());
}
})
.create();
}

//TODO check abstract classes for abstract methods to implement
}

private static void checkInterfacesFields(final HaxeClassModel clazz, final AnnotationHolder holder) {
Expand Down Expand Up @@ -415,6 +482,7 @@ private static void checkInterfaceMethods(
if (intReference.getHaxeClass() != null) {
List<HaxeMethodModel> methods = clazz.haxeClass.getAllHaxeMethods(HaxeComponentType.CLASS, HaxeComponentType.ENUM).stream()
.map(HaxeMethodPsiMixin::getModel)
.filter(not(HaxeMethodModel::isAbstract))
.toList();

for (HaxeMethodModel intMethod : intReference.getHaxeClass().getMethods(null)) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -177,7 +177,10 @@ else if (parentMethod != null) {
.create();
}
else {
if (!currentClass.isInterface() && !currentClass.isAnonymous()) {
if (!currentClass.isInterface()
&& !currentClass.isAnonymous()
&& !parentMethod.isAbstract()
&& !parentMethod.getDeclaringClass().isInterface()) {
requiredOverride = true;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,9 @@
import com.intellij.psi.PsiClass;
import com.intellij.psi.PsiMember;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.util.Function;

import java.util.Arrays;
import java.util.List;

/**
* @author: Fedor.Korotkov
Expand All @@ -53,14 +55,14 @@ protected String buildFunctionsText(HaxeNamedComponent element) {
if (addOverride) {
result.append("override ");
}
final HaxePsiModifier[] declarationAttributeList = PsiTreeUtil.getChildrenOfType(element, HaxePsiModifier.class);
if (declarationAttributeList != null) {
result.append(StringUtil.join(declarationAttributeList, new Function<HaxePsiModifier, String>() {
@Override
public String fun(HaxePsiModifier attribute) {
return attribute.getText();
}
}, " "));
final HaxePsiModifier[] declarationAttributeArray = PsiTreeUtil.getChildrenOfType(element, HaxePsiModifier.class);

if (declarationAttributeArray != null) {
List<HaxePsiModifier> declarationAttributeList = Arrays.stream(declarationAttributeArray)
.filter(modifier -> !modifier.textMatches("abstract"))// keep all modifiers except abstract
.toList();

result.append(StringUtil.join(declarationAttributeList, attribute -> attribute.getText(), " "));
result.append(" ");
}
if (isInterfaceElement && !result.toString().contains("public")) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,8 @@ public static HaxeClass[] getClassArray(@NotNull HaxeFile psiRoot) {
public static List<HaxeClass> getClassList(@NotNull HaxeFile psiRoot) {
return CachedValuesManager.getCachedValue(psiRoot, () -> {
ArrayList<HaxeClass> classes = new ArrayList<>();
for (PsiElement child : psiRoot.getChildren()) {
@NotNull PsiElement[] children = psiRoot.getModel().getModuleBodyChildren();
for (PsiElement child : children) {
if (child instanceof HaxeClass haxeClass) {
classes.add(haxeClass);
}
Expand Down
Loading

0 comments on commit 269470a

Please sign in to comment.