Skip to content

Commit

Permalink
add support for opening openFL/lime nme and hxml files as projects
Browse files Browse the repository at this point in the history
  • Loading branch information
m0rkeulv committed May 27, 2023
1 parent 9b09707 commit d3d685f
Show file tree
Hide file tree
Showing 13 changed files with 514 additions and 11 deletions.
40 changes: 40 additions & 0 deletions src/main/java/com/intellij/plugins/haxe/haxelib/HaxeSdkFinder.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
/*
* Copyright 2000-2013 JetBrains s.r.o.
* Copyright 2014-2014 AS3Boyan
* Copyright 2014-2014 Elias Ku
* Copyright 2017 Eric Bishton
*
* 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.intellij.plugins.haxe.haxelib;

import com.intellij.openapi.projectRoots.ProjectJdkTable;
import com.intellij.openapi.projectRoots.Sdk;
import com.intellij.openapi.roots.impl.SdkFinder;
import com.intellij.plugins.haxe.config.sdk.HaxeSdkType;
import lombok.CustomLog;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

@CustomLog
public class HaxeSdkFinder extends SdkFinder {

@Override
public @Nullable Sdk findSdk(@NotNull String name, @NotNull String sdkType) {
if (HaxeSdkType.getInstance().getName().equals(sdkType)) {
return ProjectJdkTable.getInstance().findJdk(name, sdkType);
}

return null;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -108,9 +108,13 @@ public static List<String> issueHaxelibCommand(@NotNull Sdk sdk, String ... args
return Collections.EMPTY_LIST;
}

// TODO mlo: try to clean up code so it only uses either dir or file
File haxelibCmd = new File(haxelibPath);
VirtualFile dir = haxelibCmd.isFile() ? LocalFileSystem.getInstance().findFileByPath(haxelibCmd.getParent()) : null;

VirtualFile dir = haxelibCmd.isFile() ? LocalFileSystem.getInstance().findFileByPath(haxelibCmd.getParent()) : LocalFileSystem.getInstance().findFileByPath(haxelibPath);
if(dir == null) {
log.error("unable to execute haxelib command, haxelib path is null");
return List.of();
}
List<String> stdout = new ArrayList<String>();
int exitvalue = HaxeProcessUtil.runProcess(commandLineArguments, true, dir, sdkData,
stdout, null, null, false);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,32 +19,31 @@

import com.intellij.codeInsight.completion.*;
import com.intellij.codeInsight.lookup.LookupElementBuilder;
import com.intellij.openapi.progress.ProgressManager;
import com.intellij.patterns.PlatformPatterns;
import com.intellij.plugins.haxe.buildsystem.hxml.HXMLLanguage;
import com.intellij.plugins.haxe.haxelib.HaxelibCache;
import com.intellij.plugins.haxe.hxml.psi.HXMLLib;
import com.intellij.plugins.haxe.hxml.psi.HXMLTypes;
import com.intellij.plugins.haxe.hxml.psi.HXMLValue;
import com.intellij.util.ProcessingContext;
import lombok.CustomLog;
import org.jetbrains.annotations.NotNull;

import java.util.Collections;
import java.util.List;

import static com.intellij.patterns.PlatformPatterns.psiElement;

/**
* Created by as3boyan on 15.11.14.
*/
@CustomLog
public class HXMLHaxelibCompletionContributor extends CompletionContributor {

protected static List<String> availableHaxelibs = null;
protected static List<String> localHaxelibs = null;

private HaxelibCache haxelibCache;
protected static List<String> availableHaxelibs = Collections.emptyList();
protected static List<String> localHaxelibs = Collections.emptyList();

public HXMLHaxelibCompletionContributor() {
ProgressManager.getInstance().runProcessWithProgressSynchronously(() -> haxelibCache = HaxelibCache.getInstance(), "Fetching haxelib list", false, null);

// intelliJ 2018 and older
extend(CompletionType.BASIC, psiElement(HXMLTypes.VALUE).withParent(HXMLLib.class).withLanguage(HXMLLanguage.INSTANCE), getProvider());
Expand Down Expand Up @@ -75,8 +74,8 @@ protected void addCompletions(@NotNull CompletionParameters parameters,
}

private void getLatestFromCache() {
availableHaxelibs = haxelibCache.getAvailableHaxelibs();
localHaxelibs = haxelibCache.getLocalHaxelibs();
availableHaxelibs = HaxelibCache.getInstance().getAvailableHaxelibs();
localHaxelibs = HaxelibCache.getInstance().getLocalHaxelibs();
}
};
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
package com.intellij.plugins.haxe.ide.projectStructure;

import com.intellij.ide.highlighter.ModuleFileType;
import com.intellij.ide.util.projectWizard.ModuleBuilder;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.module.ModifiableModuleModel;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.module.ModuleManager;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.projectRoots.ProjectJdkTable;
import com.intellij.openapi.projectRoots.Sdk;
import com.intellij.openapi.roots.ContentEntry;
import com.intellij.openapi.roots.ModifiableRootModel;
import com.intellij.openapi.roots.ModuleRootManager;
import com.intellij.openapi.roots.impl.ModifiableModelCommitter;
import com.intellij.openapi.roots.ui.configuration.ModulesProvider;
import com.intellij.openapi.vfs.LocalFileSystem;
import com.intellij.packaging.artifacts.ModifiableArtifactModel;
import com.intellij.plugins.haxe.HaxeBundle;
import com.intellij.plugins.haxe.config.HaxeConfiguration;
import com.intellij.plugins.haxe.config.sdk.HaxeSdkType;
import com.intellij.plugins.haxe.ide.module.HaxeModuleSettings;
import com.intellij.plugins.haxe.ide.module.HaxeModuleType;
import com.intellij.plugins.haxe.ide.projectStructure.detection.HaxeProjectData;
import com.intellij.projectImport.ProjectImportBuilder;
import icons.HaxeIcons;
import org.jetbrains.annotations.Nls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import javax.swing.*;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class HaxeProjectImportBuilder extends ProjectImportBuilder<Object> {

@Override
public @NotNull @Nls(capitalization = Nls.Capitalization.Sentence) String getName() {
return HaxeBundle.message("haxe.project");
}


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

@Override
public boolean isMarked(Object element) {
return true;
}

@Override
public void setOpenProjectSettingsAfter(boolean on) {

}


@Override
public @Nullable List<Module> commit(Project project,
ModifiableModuleModel model,
ModulesProvider modulesProvider,
ModifiableArtifactModel artifactModel) {
final ModifiableModuleModel moduleModel = model != null ? model : ModuleManager.getInstance(project).getModifiableModel();


final Map<Module, ModifiableRootModel> moduleToModifiableModelMap = new HashMap<>();

final HaxeProjectData haxeProjectData = new HaxeProjectData(getFileToImport());
final String moduleName = haxeProjectData.getName();

final String moduleFilePath = haxeProjectData.getProjectRootPath() + "/" + moduleName + ModuleFileType.DOT_DEFAULT_EXTENSION;
final Module module = moduleModel.newModule(moduleFilePath, HaxeModuleType.getInstance().getId());

if (LocalFileSystem.getInstance().findFileByPath(moduleFilePath) != null) {
ApplicationManager.getApplication().runWriteAction(() -> ModuleBuilder.deleteModuleFile(moduleFilePath));
}

final ModifiableRootModel rootModel = ModuleRootManager.getInstance(module).getModifiableModel();
final HaxeModuleSettings instance = HaxeModuleSettings.getInstance(module);

configureProjectSettings(haxeProjectData, instance);
configureContentRoots(haxeProjectData, rootModel);
moduleToModifiableModelMap.put(module, rootModel);

final Sdk mostRecentSdk = ProjectJdkTable.getInstance().findMostRecentSdkOfType(HaxeSdkType.getInstance());
rootModel.setSdk(mostRecentSdk);

ApplicationManager.getApplication()
.runWriteAction(() -> ModifiableModelCommitter.multiCommit(moduleToModifiableModelMap.values(), moduleModel));


return List.of(module);
}

private static void configureProjectSettings(HaxeProjectData haxeProjectData, HaxeModuleSettings instance) {
HaxeConfiguration type = haxeProjectData.getProjectType();
instance.setOutputFolder(haxeProjectData.getOutputFolder());
instance.setBuildConfig(type.asBuildConfigValue());
switch (type) {
case OPENFL -> instance.setOpenFLPath(haxeProjectData.getProjectFilePath());
case HXML -> instance.setHxmlPath(haxeProjectData.getProjectFilePath());
case NMML -> instance.setNmmlPath(haxeProjectData.getProjectFilePath());
}
}

private static void configureContentRoots(HaxeProjectData haxeProjectData, ModifiableRootModel rootModel) {
ContentEntry contentRoot = rootModel.addContentEntry(haxeProjectData.getProjectRoot());
haxeProjectData.getSourcePaths().forEach(source -> contentRoot.addSourceFolder(source, false));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
package com.intellij.plugins.haxe.ide.projectStructure.detection;

import com.intellij.openapi.vfs.VfsUtil;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.plugins.haxe.config.HaxeConfiguration;

import java.io.File;
import java.nio.file.Path;
import java.util.List;
import java.util.Objects;

public class HaxeProjectData {

private String projectFile;

public HaxeProjectData(String projectFile) {
this.projectFile = projectFile;
}

public String getName() {
return getProjectRoot().getName();
}

public String getProjectRootPath() {
return new File(projectFile).getParent();
}

public VirtualFile getProjectRoot() {
return VfsUtil.findFile(Path.of(getProjectRootPath()), true);
}
public VirtualFile getProjectFile() {
return VfsUtil.findFile(Path.of(getProjectFilePath()), true);
}

public List<VirtualFile> getSourcePaths() {
VirtualFile root = getProjectRoot();
VirtualFile projectFile = VfsUtil.findFile(Path.of(getProjectFilePath()), true);

List<String> paths = HaxeProjectFileDetectionUtil.sourcePaths(projectFile);
return paths.stream().map(root::findChild).filter(Objects::nonNull).toList();

}

public HaxeConfiguration getProjectType() {
VirtualFile file = getProjectFile();
if (HaxeProjectFileDetectionUtil.isLimeProject(file)
|| HaxeProjectFileDetectionUtil.isOpenFLProject(file)) {
return HaxeConfiguration.OPENFL;
}
if (HaxeProjectFileDetectionUtil.isHxmlProject(file)) {
return HaxeConfiguration.HXML;
}
if (HaxeProjectFileDetectionUtil.isNMMLProject(file)) {
return HaxeConfiguration.NMML;
}

return HaxeConfiguration.CUSTOM;
}

public String getProjectFilePath() {
return projectFile;
}

public String getOutputFolder() {
String path = getProjectRootPath();
assert path.length() > 0;
return path + "/out";
}
}
Loading

0 comments on commit d3d685f

Please sign in to comment.