From f10baa830bb733443c6387ae93c53a7e9199dc0e Mon Sep 17 00:00:00 2001 From: peter Date: Fri, 16 Dec 2011 17:13:03 +0100 Subject: [PATCH] IDEA-69920 Support additional imports added by the Griffon compiler --- plugins/gradle/src/META-INF/plugin.xml | 1 + .../GradleDefaultImportContributor.java | 62 ++++++++++ .../gradle/config/GradleScriptType.java | 31 ----- plugins/groovy/src/META-INF/plugin.xml | 2 + .../GriffonDefaultImportContributor.java | 114 ++++++++++++++++++ .../groovy/lang/psi/impl/GroovyFileImpl.java | 13 +- .../resolve/DefaultImportContributor.java | 35 ++++++ 7 files changed, 222 insertions(+), 36 deletions(-) create mode 100644 plugins/gradle/src/org/jetbrains/plugins/gradle/config/GradleDefaultImportContributor.java create mode 100644 plugins/groovy/src/org/jetbrains/plugins/groovy/griffon/GriffonDefaultImportContributor.java create mode 100644 plugins/groovy/src/org/jetbrains/plugins/groovy/lang/resolve/DefaultImportContributor.java diff --git a/plugins/gradle/src/META-INF/plugin.xml b/plugins/gradle/src/META-INF/plugin.xml index 9dea0a91e319..d317fcd0aece 100644 --- a/plugins/gradle/src/META-INF/plugin.xml +++ b/plugins/gradle/src/META-INF/plugin.xml @@ -46,6 +46,7 @@ + diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/config/GradleDefaultImportContributor.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/config/GradleDefaultImportContributor.java new file mode 100644 index 000000000000..21da0843bebe --- /dev/null +++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/config/GradleDefaultImportContributor.java @@ -0,0 +1,62 @@ +/* + * Copyright 2000-2011 JetBrains s.r.o. + * + * 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 org.jetbrains.plugins.gradle.config; + +import org.jetbrains.annotations.NotNull; +import org.jetbrains.plugins.groovy.extensions.GroovyScriptTypeDetector; +import org.jetbrains.plugins.groovy.lang.psi.GroovyFile; +import org.jetbrains.plugins.groovy.lang.resolve.DefaultImportContributor; + +import java.util.Arrays; +import java.util.Collections; +import java.util.List; + +/** + * @author peter + */ +public class GradleDefaultImportContributor extends DefaultImportContributor { + + @Override + public List appendImplicitlyImportedPackages(@NotNull GroovyFile file) { + if (file.isScript() && GroovyScriptTypeDetector.getScriptType(file) instanceof GradleScriptType) { + return Arrays.asList( + "org.gradle", + "org.gradle.util", + "org.gradle.api", + "org.gradle.api.artifacts", + "org.gradle.api.artifacts.dsl", + "org.gradle.api.artifacts.specs", + "org.gradle.api.dependencies", + "org.gradle.api.execution", + "org.gradle.api.file", + "org.gradle.api.logging", + "org.gradle.api.initialization", + "org.gradle.api.invocation", + "org.gradle.api.plugins", + "org.gradle.api.plugins.quality", + "org.gradle.api.specs", + "org.gradle.api.tasks", + "org.gradle.api.tasks.bundling", + "org.gradle.api.tasks.compile", + "org.gradle.api.tasks.javadoc", + "org.gradle.api.tasks.testing", + "org.gradle.api.tasks.util", + "org.gradle.api.tasks.wrapper" + ); + } + return Collections.emptyList(); + } +} diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/config/GradleScriptType.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/config/GradleScriptType.java index ad65a832013a..1bbe0aeabd1b 100644 --- a/plugins/gradle/src/org/jetbrains/plugins/gradle/config/GradleScriptType.java +++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/config/GradleScriptType.java @@ -57,9 +57,7 @@ import org.jetbrains.plugins.groovy.util.GroovyUtils; import javax.swing.*; import java.io.File; import java.io.IOException; -import java.util.Arrays; import java.util.Collection; -import java.util.List; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -279,33 +277,4 @@ public class GradleScriptType extends GroovyScriptType { return result; } - - @Override - public List appendImplicitImports(@NotNull GroovyFile file) { - return Arrays.asList( - "org.gradle", - "org.gradle.util", - "org.gradle.api", - "org.gradle.api.artifacts", - "org.gradle.api.artifacts.dsl", - "org.gradle.api.artifacts.specs", - "org.gradle.api.dependencies", - "org.gradle.api.execution", - "org.gradle.api.file", - "org.gradle.api.logging", - "org.gradle.api.initialization", - "org.gradle.api.invocation", - "org.gradle.api.plugins", - "org.gradle.api.plugins.quality", - "org.gradle.api.specs", - "org.gradle.api.tasks", - "org.gradle.api.tasks.bundling", - "org.gradle.api.tasks.compile", - "org.gradle.api.tasks.javadoc", - "org.gradle.api.tasks.testing", - "org.gradle.api.tasks.util", - "org.gradle.api.tasks.wrapper" - - ); - } } diff --git a/plugins/groovy/src/META-INF/plugin.xml b/plugins/groovy/src/META-INF/plugin.xml index 0bf08464e550..85c4a56a3cc8 100644 --- a/plugins/groovy/src/META-INF/plugin.xml +++ b/plugins/groovy/src/META-INF/plugin.xml @@ -29,6 +29,7 @@ + @@ -117,6 +118,7 @@ + diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/griffon/GriffonDefaultImportContributor.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/griffon/GriffonDefaultImportContributor.java new file mode 100644 index 000000000000..8a2f59d81848 --- /dev/null +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/griffon/GriffonDefaultImportContributor.java @@ -0,0 +1,114 @@ +/* + * Copyright 2000-2011 JetBrains s.r.o. + * + * 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 org.jetbrains.plugins.groovy.griffon; + +import com.intellij.lang.properties.IProperty; +import com.intellij.lang.properties.psi.PropertiesFile; +import com.intellij.openapi.module.Module; +import com.intellij.openapi.module.ModuleUtil; +import com.intellij.openapi.util.Pair; +import com.intellij.openapi.util.text.StringUtil; +import com.intellij.openapi.vfs.VfsUtilCore; +import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.psi.JavaPsiFacade; +import com.intellij.psi.PsiDirectory; +import com.intellij.psi.PsiFile; +import com.intellij.psi.PsiPackage; +import com.intellij.psi.search.GlobalSearchScope; +import com.intellij.psi.util.CachedValueProvider; +import com.intellij.psi.util.CachedValuesManager; +import com.intellij.psi.util.PsiModificationTracker; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.plugins.groovy.lang.psi.GroovyFile; +import org.jetbrains.plugins.groovy.lang.resolve.DefaultImportContributor; +import org.jetbrains.plugins.groovy.mvc.MvcFramework; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +/** + * @author peter + */ +public class GriffonDefaultImportContributor extends DefaultImportContributor { + + private Pair, List> getDefaultImports(@NotNull final Module module) { + return CachedValuesManager.getManager(module.getProject()).getCachedValue(module, new CachedValueProvider, List>>() { + @Override + public Result, List>> compute() { + PsiPackage aPackage = JavaPsiFacade.getInstance(module.getProject()).findPackage("META-INF"); + if (aPackage != null) { + for (PsiDirectory directory : aPackage.getDirectories(GlobalSearchScope.moduleWithDependenciesAndLibrariesScope(module))) { + PsiFile file = directory.findFile("griffon-default-imports.properties"); + if (file instanceof PropertiesFile) { + List modelImports = tokenize(((PropertiesFile)file).findPropertyByKey("models")); + List viewImports = tokenize(((PropertiesFile)file).findPropertyByKey("views")); + return Result.create(Pair.create(modelImports, viewImports), PsiModificationTracker.MODIFICATION_COUNT); + } + } + } + + return Result.create(new Pair, List>(new ArrayList(), new ArrayList()), + PsiModificationTracker.MODIFICATION_COUNT); + } + + private List tokenize(IProperty models) { + List modelImports = new ArrayList(); + if (models != null) { + String value = models.getValue(); + if (value != null) { + String[] split = value.split(", "); + for (String s : split) { + modelImports.add(StringUtil.trimEnd(s, ".")); + } + } + } + return modelImports; + } + }); + } + + @Override + public List appendImplicitlyImportedPackages(@NotNull GroovyFile file) { + Module module = ModuleUtil.findModuleForPsiElement(file); + MvcFramework framework = MvcFramework.getInstance(module); + if (framework instanceof GriffonFramework) { + ArrayList result = new ArrayList(); + result.add("griffon.core"); + result.add("griffon.util"); + + VirtualFile griffonApp = framework.findAppDirectory(file); + if (griffonApp != null) { + VirtualFile models = griffonApp.findChild("models"); + VirtualFile views = griffonApp.findChild("views"); + VirtualFile vFile = file.getOriginalFile().getVirtualFile(); + + assert vFile != null; + assert module != null; + if (models != null && VfsUtilCore.isAncestor(models, vFile, true)) { + result.addAll(getDefaultImports(module).first); + } + else if (views != null && VfsUtilCore.isAncestor(views, vFile, true)) { + result.addAll(getDefaultImports(module).second); + } + } + + return result; + } + + return Collections.emptyList(); + } +} diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/GroovyFileImpl.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/GroovyFileImpl.java index 3dd8327bd876..9c7ac07496bb 100644 --- a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/GroovyFileImpl.java +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/psi/impl/GroovyFileImpl.java @@ -24,7 +24,6 @@ import com.intellij.openapi.util.text.StringUtil; import com.intellij.psi.*; import com.intellij.psi.codeStyle.CodeStyleManager; import com.intellij.psi.impl.ElementBase; -import com.intellij.psi.impl.file.PsiPackageImpl; import com.intellij.psi.scope.DelegatingScopeProcessor; import com.intellij.psi.scope.PsiScopeProcessor; import com.intellij.psi.stubs.StubElement; @@ -55,12 +54,14 @@ import org.jetbrains.plugins.groovy.lang.psi.api.types.GrCodeReferenceElement; import org.jetbrains.plugins.groovy.lang.psi.impl.synthetic.GrLightParameter; import org.jetbrains.plugins.groovy.lang.psi.impl.synthetic.GroovyScriptClass; import org.jetbrains.plugins.groovy.lang.psi.stubs.GrFileStub; +import org.jetbrains.plugins.groovy.lang.resolve.DefaultImportContributor; import org.jetbrains.plugins.groovy.lang.resolve.MethodTypeInferencer; import org.jetbrains.plugins.groovy.lang.resolve.ResolveUtil; import org.jetbrains.plugins.groovy.lang.resolve.processors.ClassHint; import javax.swing.*; import java.util.ArrayList; +import java.util.LinkedHashSet; import java.util.List; /** @@ -222,12 +223,14 @@ public class GroovyFileImpl extends GroovyFileBaseImpl implements GroovyFile { } - private List getImplicitlyImportedPackages() { - final ArrayList result = new ArrayList(); + private LinkedHashSet getImplicitlyImportedPackages() { + final LinkedHashSet result = new LinkedHashSet(); ContainerUtil.addAll(result, IMPLICITLY_IMPORTED_PACKAGES); - if (isScript()) { - result.addAll(GroovyScriptTypeDetector.getScriptType(this).appendImplicitImports(this)); + + for (DefaultImportContributor contributor : DefaultImportContributor.EP_NAME.getExtensions()) { + result.addAll(contributor.appendImplicitlyImportedPackages(this)); } + return result; } diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/resolve/DefaultImportContributor.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/resolve/DefaultImportContributor.java new file mode 100644 index 000000000000..98710b0888de --- /dev/null +++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/lang/resolve/DefaultImportContributor.java @@ -0,0 +1,35 @@ +/* + * Copyright 2000-2011 JetBrains s.r.o. + * + * 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 org.jetbrains.plugins.groovy.lang.resolve; + +import com.intellij.openapi.extensions.ExtensionPointName; +import org.jetbrains.annotations.NotNull; +import org.jetbrains.plugins.groovy.lang.psi.GroovyFile; + +import java.util.Collections; +import java.util.List; + +/** + * @author peter + */ +public abstract class DefaultImportContributor { + public static final ExtensionPointName EP_NAME = ExtensionPointName.create("org.intellij.groovy.defaultImportContributor"); + + public List appendImplicitlyImportedPackages(@NotNull GroovyFile file) { + return Collections.emptyList(); + } + +}