/* * Copyright 2000-2013 JetBrains s.r.o. * Copyright 2014-2014 AS3Boyan * Copyright 2014-2014 Elias Ku * * 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.ide.projectStructure.detection; import com.intellij.ide.util.DelegatingProgressIndicator; import com.intellij.ide.util.importProject.LibrariesDetectionStep; import com.intellij.ide.util.importProject.ModulesDetectionStep; import com.intellij.ide.util.importProject.ProjectDescriptor; import com.intellij.ide.util.projectWizard.ModuleWizardStep; import com.intellij.ide.util.projectWizard.ProjectJdkForModuleStep; import com.intellij.ide.util.projectWizard.importSources.DetectedProjectRoot; import com.intellij.ide.util.projectWizard.importSources.ProjectFromSourcesBuilder; import com.intellij.ide.util.projectWizard.importSources.ProjectStructureDetector; import com.intellij.ide.util.projectWizard.importSources.util.CommonSourceRootDetectionUtil; import com.intellij.lang.LanguageParserDefinitions; import com.intellij.lexer.Lexer; import com.intellij.openapi.util.Pair; import com.intellij.openapi.util.text.StringUtil; import com.intellij.plugins.haxe.HaxeFileType; import com.intellij.plugins.haxe.HaxeLanguage; import com.intellij.plugins.haxe.config.sdk.HaxeSdkType; import com.intellij.plugins.haxe.lang.lexer.HaxeTokenTypeSets; import com.intellij.plugins.haxe.lang.lexer.HaxeTokenTypes; import com.intellij.util.NullableFunction; import com.intellij.util.StringBuilderSpinAllocator; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import javax.swing.*; import java.io.File; import java.util.ArrayList; import java.util.List; /** * @author: Fedor.Korotkov */ public class HaxeProjectStructureDetector extends ProjectStructureDetector { public static final NullableFunction<CharSequence, String> PACKAGE_NAME_FETCHER = new NullableFunction<CharSequence, String>() { public String fun(final CharSequence charSequence) { Lexer lexer = LanguageParserDefinitions.INSTANCE.forLanguage(HaxeLanguage.INSTANCE).createLexer(null); lexer.start(charSequence); return readPackageName(charSequence, lexer); } }; @NotNull @Override public DirectoryProcessingResult detectRoots(@NotNull File dir, @NotNull File[] children, @NotNull File base, @NotNull List<DetectedProjectRoot> result) { for (File child : children) { if (child.isFile() && child.getName().endsWith(HaxeFileType.DEFAULT_EXTENSION)) { Pair<File, String> root = CommonSourceRootDetectionUtil.IO_FILE.suggestRootForFileWithPackageStatement(child, base, PACKAGE_NAME_FETCHER, false); if (root != null) { result.add(new HaxeModuleSourceRoot(root.getFirst())); return DirectoryProcessingResult.skipChildrenAndParentsUpTo(root.getFirst()); } else { return DirectoryProcessingResult.SKIP_CHILDREN; } } } return DirectoryProcessingResult.PROCESS_CHILDREN; } @Override public List<ModuleWizardStep> createWizardSteps(ProjectFromSourcesBuilder builder, ProjectDescriptor projectDescriptor, Icon stepIcon) { HaxeModuleInsight moduleInsight = new HaxeModuleInsight(new DelegatingProgressIndicator(), builder.getExistingModuleNames(), builder.getExistingProjectLibraryNames()); final List<ModuleWizardStep> steps = new ArrayList<ModuleWizardStep>(); steps.add( new LibrariesDetectionStep(builder, projectDescriptor, moduleInsight, stepIcon, "reference.dialogs.new.project.fromCode.page1")); steps.add( new ModulesDetectionStep(this, builder, projectDescriptor, moduleInsight, stepIcon, "reference.dialogs.new.project.fromCode.page2")); steps.add(new ProjectJdkForModuleStep(builder.getContext(), HaxeSdkType.getInstance())); return steps; } @Nullable public static String readPackageName(final CharSequence charSequence, final Lexer lexer) { skipWhiteSpaceAndComments(lexer); if (!HaxeTokenTypes.KPACKAGE.equals(lexer.getTokenType())) { return ""; } lexer.advance(); skipWhiteSpaceAndComments(lexer); return readQualifiedName(charSequence, lexer, false); } @Nullable static String readQualifiedName(final CharSequence charSequence, final Lexer lexer, boolean allowStar) { final StringBuilder buffer = StringBuilderSpinAllocator.alloc(); try { while (true) { if (lexer.getTokenType() != HaxeTokenTypes.ID && !(allowStar && lexer.getTokenType() != HaxeTokenTypes.OMUL)) break; buffer.append(charSequence, lexer.getTokenStart(), lexer.getTokenEnd()); if (lexer.getTokenType() == HaxeTokenTypes.OMUL) break; lexer.advance(); if (lexer.getTokenType() != HaxeTokenTypes.ODOT) break; buffer.append('.'); lexer.advance(); } String packageName = buffer.toString(); if (StringUtil.endsWithChar(packageName, '.')) return null; return packageName; } finally { StringBuilderSpinAllocator.dispose(buffer); } } public static void skipWhiteSpaceAndComments(Lexer lexer) { while (HaxeTokenTypeSets.COMMENTS.contains(lexer.getTokenType()) || HaxeTokenTypeSets.WHITESPACES.contains(lexer.getTokenType())) { lexer.advance(); } } }